Skip to content

Commit 3aa1f42

Browse files
author
Willi Braun
committed
- fixed bisection by calculating the maximum needed iterations for a given tolerance
- 04_HandleEvents.mos needs a finer grid, since otherwise some events are missed. git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@23948 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent da4d075 commit 3aa1f42

File tree

1 file changed

+12
-15
lines changed
  • SimulationRuntime/c/simulation/solver

1 file changed

+12
-15
lines changed

SimulationRuntime/c/simulation/solver/events.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -451,24 +451,22 @@ void findRoot(DATA* data, LIST *eventList, double *eventTime)
451451
*/
452452
double bisection(DATA* data, double* a, double* b, double* states_a, double* states_b, LIST *tmpEventList, LIST *eventList)
453453
{
454-
double TTOL = MINIMAL_STEP_SIZE;
454+
double TTOL = MINIMAL_STEP_SIZE + MINIMAL_STEP_SIZE*fabs(*b-*a); /* absTol + relTol*abs(b-a) */
455455
double c;
456456
long i=0;
457-
458-
double *backup_gout = (double*) malloc(data->modelData.nZeroCrossings * sizeof(double));
457+
/* n >= log(2)/log(2) + log(|b-a|/TOL)/log(2) + 2 (to go for sure)*/
458+
unsigned int n = 1 + log(fabs(*b - *a)/TTOL)/log(2) + 2;
459459

460460
TRACE_PUSH
461461

462-
assert(backup_gout);
463-
464-
memcpy(backup_gout, data->simulationInfo.zeroCrossings, data->modelData.nZeroCrossings * sizeof(double));
462+
memcpy(data->simulationInfo.zeroCrossingsBackup, data->simulationInfo.zeroCrossings, data->modelData.nZeroCrossings * sizeof(modelica_real));
465463

466464
infoStreamPrint(LOG_ZEROCROSSINGS, 0, "bisection method starts in interval [%e, %e]", *a, *b);
467-
infoStreamPrint(LOG_ZEROCROSSINGS, 0, "TTOL is set to: %e", TTOL);
465+
infoStreamPrint(LOG_ZEROCROSSINGS, 0, "TTOL is set to %e and maximum number of intersections %d.", TTOL, n);
468466

469-
while(fabs(*b - *a) > TTOL + fabs(*b)*TTOL)
467+
while(n-- > 0)
470468
{
471-
c = 0.5* (*a + *b);
469+
c = 0.5 * (*a + *b);
472470
data->localData[0]->timeValue = c;
473471

474472
/*calculates states at time c */
@@ -488,19 +486,18 @@ double bisection(DATA* data, double* a, double* b, double* states_a, double* sta
488486

489487
if(checkZeroCrossings(data, tmpEventList, eventList)) /* If Zerocrossing in left Section */
490488
{
491-
memcpy(states_b, data->localData[0]->realVars, data->modelData.nStates * sizeof(double));
489+
memcpy(states_b, data->localData[0]->realVars, data->modelData.nStates * sizeof(modelica_real));
492490
*b = c;
493-
memcpy(backup_gout, data->simulationInfo.zeroCrossings, data->modelData.nZeroCrossings * sizeof(double));
491+
memcpy(data->simulationInfo.zeroCrossingsBackup, data->simulationInfo.zeroCrossings, data->modelData.nZeroCrossings * sizeof(modelica_real));
494492
}
495493
else /*else Zerocrossing in right Section */
496494
{
497-
memcpy(states_a, data->localData[0]->realVars, data->modelData.nStates * sizeof(double));
495+
memcpy(states_a, data->localData[0]->realVars, data->modelData.nStates * sizeof(modelica_real));
498496
*a = c;
499-
memcpy(data->simulationInfo.zeroCrossingsPre, data->simulationInfo.zeroCrossings, data->modelData.nZeroCrossings * sizeof(double));
500-
memcpy(data->simulationInfo.zeroCrossings, backup_gout, data->modelData.nZeroCrossings * sizeof(double));
497+
memcpy(data->simulationInfo.zeroCrossingsPre, data->simulationInfo.zeroCrossings, data->modelData.nZeroCrossings * sizeof(modelica_real));
498+
memcpy(data->simulationInfo.zeroCrossings, data->simulationInfo.zeroCrossingsBackup, data->modelData.nZeroCrossings * sizeof(modelica_real));
501499
}
502500
}
503-
free(backup_gout);
504501
c = 0.5*(*a + *b);
505502

506503
TRACE_POP

0 commit comments

Comments
 (0)