void radau_solout(int *nr, double *xold, double *x, double *y, double *cont, int *lrc, int *n, double *rpar, int *ipar, int *irtrn) { int TotEvts = 0; int termFound = 0; *irtrn = 0; // stop-flag unset /* Reset event flags */ gIData->eventFound = 0; gIData->lastTime = *x; gIData->lastPoint = y; /* Update globals with cont'n data for this point */ gIData->contdata = cont; gIData->contdim = lrc; /* Just output the initial point */ if (gIData->timeIdx == 0) { OutputPoint(gIData, gIData->lastTime, gIData->lastPoint); return; } /* Check for events */ if( gIData->haveActive > 0 ) { TotEvts = DetectEvents(gIData, *xold, gIData->lastTime, gIData->lastPoint, irtrn, &termFound); /* If negative TotEvts, exit because we've exceeded maxevtpts */ if( TotEvts < 0 ) { *irtrn = -8; return; } } /* Do refinement */ if ( gIData->refine > 0) refine(*n, *xold, gIData->lastTime); SavePoints(gIData, TotEvts, termFound); /* Check limit on number of points */ if (gIData->timeIdx >= gIData->maxPts) *irtrn = -6; /* Max points return code */ }
void SavePoints(IData *GS, int TotEvents, int foundTerm) { int i, j, term = 0; /* Negative TotEvents means a terminal event was found */ if( TotEvents < 0 ) { TotEvents = -TotEvents; term = 1; } term = foundTerm; /* !!!!!!!!! Mergesort on output the contents of the refine, event buffers */ /* Remember to account for terminal events being last! */ /* If no events were found, just output refinement points, if necessary, and the last integration point */ if ( TotEvents == 0 ) { if ( GS->refine > 0 ) { for( i = 0; i < GS->refine; i++ ) { OutputPoint(GS, GS->gRefineTimes[i], GS->gRefinePoints[i]); } } // Output the last point (not an event point if no terminal events) OutputPoint(GS, GS->lastTime, GS->lastPoint); } /* If events were found, output is more complicated */ else if ( TotEvents > 0 ) { i = 0; j = 0; /* If there are no refinement points, just output event points */ if ( GS->refine <= 0 ) { for( i = 0; i < TotEvents; i++ ) { OutputPoint(GS, GS->gEventTimeBuf[i], GS->gEventPointBuf[i]); } } else { int k = 0; /* Merge the event points and refinement points */ while ( i + j < TotEvents + GS->refine ) { /* If there are no more event points to include, or if the current refinement point is earlier than the current event point, save the current refinement point */ if ( (i >= TotEvents) || (( j < GS->refine) && (GS->gRefineTimes[j] < GS->gEventTimeBuf[i])) ) { OutputPoint(GS, GS->gRefineTimes[j], GS->gRefinePoints[j]); j++; } /* If there are no more refinement points to include, or if the current event point is earlier than the current refinement point, save the current event point */ else if ( (j >= GS->refine) || (( i < TotEvents) && (GS->gEventTimeBuf[i] < GS->gRefineTimes[j])) ) { OutputPoint(GS, GS->gEventTimeBuf[i], GS->gEventPointBuf[i]); i++; } else { /* The current event time and the current refine time are identical. Only save one. */ OutputPoint(GS, GS->gRefineTimes[j], GS->gRefinePoints[j]); i++; j++; } } } if( term == 0 ) { /* If there were no terminal events, we need to output the last integrated point, too */ OutputPoint(GS, GS->lastTime, GS->lastPoint); } } }