Exemple #1
0
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);
    }
  }
}