xref: /petsc/src/ts/event/tsevent.c (revision db84a1fe0400b170ffc035d8aefb389bbc7c9ab5)
12dc7a7e3SShri Abhyankar 
2af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I  "petscts.h" I*/
32dc7a7e3SShri Abhyankar 
42dc7a7e3SShri Abhyankar #undef __FUNCT__
56fea3669SShri Abhyankar #define __FUNCT__ "TSEventMonitorInitialize"
66fea3669SShri Abhyankar /*
76fea3669SShri Abhyankar   TSEventMonitorInitialize - Initializes TSEvent for TSSolve
86fea3669SShri Abhyankar */
96fea3669SShri Abhyankar PetscErrorCode TSEventMonitorInitialize(TS ts)
106fea3669SShri Abhyankar {
116fea3669SShri Abhyankar   PetscErrorCode ierr;
126fea3669SShri Abhyankar   PetscReal      t;
136fea3669SShri Abhyankar   Vec            U;
146fea3669SShri Abhyankar   TSEvent        event=ts->event;
156fea3669SShri Abhyankar 
166fea3669SShri Abhyankar   PetscFunctionBegin;
176fea3669SShri Abhyankar 
186fea3669SShri Abhyankar   ierr = TSGetTime(ts,&t);CHKERRQ(ierr);
196fea3669SShri Abhyankar   ierr = TSGetTimeStep(ts,&event->initial_timestep);CHKERRQ(ierr);
206fea3669SShri Abhyankar   ierr = TSGetSolution(ts,&U);CHKERRQ(ierr);
216fea3669SShri Abhyankar   event->ptime_prev = t;
226fea3669SShri Abhyankar   ierr = (*event->monitor)(ts,t,U,event->fvalue_prev,event->monitorcontext);CHKERRQ(ierr);
236fea3669SShri Abhyankar 
246fea3669SShri Abhyankar   /* Initialize the event recorder */
256fea3669SShri Abhyankar   event->recorder.ctr = 0;
266fea3669SShri Abhyankar 
276fea3669SShri Abhyankar   PetscFunctionReturn(0);
286fea3669SShri Abhyankar }
296fea3669SShri Abhyankar 
306fea3669SShri Abhyankar #undef __FUNCT__
312dc7a7e3SShri Abhyankar #define __FUNCT__ "TSSetEventMonitor"
322dc7a7e3SShri Abhyankar /*@C
332dc7a7e3SShri Abhyankar    TSSetEventMonitor - Sets a monitoring function used for detecting events
342dc7a7e3SShri Abhyankar 
352dc7a7e3SShri Abhyankar    Logically Collective on TS
362dc7a7e3SShri Abhyankar 
372dc7a7e3SShri Abhyankar    Input Parameters:
382dc7a7e3SShri Abhyankar +  ts - the TS context obtained from TSCreate()
392dc7a7e3SShri Abhyankar .  nevents - number of local events
40d94325d3SShri Abhyankar .  direction - direction of zero crossing to be detected. -1 => Zero crossing in negative direction,
41d94325d3SShri Abhyankar                +1 => Zero crossing in positive direction, 0 => both ways (one for each event)
42d94325d3SShri Abhyankar .  terminate - flag to indicate whether time stepping should be terminated after
43d94325d3SShri Abhyankar                event is detected (one for each event)
442dc7a7e3SShri Abhyankar .  eventmonitor - event monitoring routine
452dc7a7e3SShri Abhyankar .  postevent - [optional] post-event function
462dc7a7e3SShri Abhyankar -  mectx - [optional] user-defined context for private data for the
472dc7a7e3SShri Abhyankar               event monitor and post event routine (use NULL if no
482dc7a7e3SShri Abhyankar               context is desired)
492dc7a7e3SShri Abhyankar 
502dc7a7e3SShri Abhyankar    Calling sequence of eventmonitor:
51d94325d3SShri Abhyankar    PetscErrorCode EventMonitor(TS ts,PetscReal t,Vec U,PetscScalar *fvalue,void* mectx)
522dc7a7e3SShri Abhyankar 
532dc7a7e3SShri Abhyankar    Input Parameters:
542dc7a7e3SShri Abhyankar +  ts  - the TS context
552dc7a7e3SShri Abhyankar .  t   - current time
562dc7a7e3SShri Abhyankar .  U   - current iterate
572dc7a7e3SShri Abhyankar -  ctx - [optional] context passed with eventmonitor
582dc7a7e3SShri Abhyankar 
592dc7a7e3SShri Abhyankar    Output parameters:
60d94325d3SShri Abhyankar .  fvalue    - function value of events at time t
612dc7a7e3SShri Abhyankar 
622dc7a7e3SShri Abhyankar    Calling sequence of postevent:
63031fbad4SShri Abhyankar    PetscErrorCode PostEvent(TS ts,PetscInt nevents_zero, PetscInt events_zero, PetscReal t,Vec U,PetscBool forwardsolve,void* ctx)
642dc7a7e3SShri Abhyankar 
652dc7a7e3SShri Abhyankar    Input Parameters:
662dc7a7e3SShri Abhyankar +  ts - the TS context
672dc7a7e3SShri Abhyankar .  nevents_zero - number of local events whose event function is zero
682dc7a7e3SShri Abhyankar .  events_zero  - indices of local events which have reached zero
692dc7a7e3SShri Abhyankar .  t            - current time
702dc7a7e3SShri Abhyankar .  U            - current solution
71031fbad4SShri Abhyankar .  forwardsolve - Flag to indicate whether TS is doing a forward solve (1) or adjoint solve (0)
722dc7a7e3SShri Abhyankar -  ctx          - the context passed with eventmonitor
732dc7a7e3SShri Abhyankar 
742dc7a7e3SShri Abhyankar    Level: intermediate
752dc7a7e3SShri Abhyankar 
762dc7a7e3SShri Abhyankar .keywords: TS, event, set, monitor
772dc7a7e3SShri Abhyankar 
782dc7a7e3SShri Abhyankar .seealso: TSCreate(), TSSetTimeStep(), TSSetConvergedReason()
792dc7a7e3SShri Abhyankar @*/
80031fbad4SShri Abhyankar PetscErrorCode TSSetEventMonitor(TS ts,PetscInt nevents,PetscInt *direction,PetscBool *terminate,PetscErrorCode (*eventmonitor)(TS,PetscReal,Vec,PetscScalar*,void*),PetscErrorCode (*postevent)(TS,PetscInt,PetscInt[],PetscReal,Vec,PetscBool,void*),void *mectx)
812dc7a7e3SShri Abhyankar {
822dc7a7e3SShri Abhyankar   PetscErrorCode ierr;
832dc7a7e3SShri Abhyankar   TSEvent        event;
84d94325d3SShri Abhyankar   PetscInt       i;
852dc7a7e3SShri Abhyankar 
862dc7a7e3SShri Abhyankar   PetscFunctionBegin;
8742ea6711SShri   ierr = PetscNew(&event);CHKERRQ(ierr);
88854ce69bSBarry Smith   ierr = PetscMalloc1(nevents,&event->fvalue);CHKERRQ(ierr);
89854ce69bSBarry Smith   ierr = PetscMalloc1(nevents,&event->fvalue_prev);CHKERRQ(ierr);
90854ce69bSBarry Smith   ierr = PetscMalloc1(nevents,&event->direction);CHKERRQ(ierr);
91854ce69bSBarry Smith   ierr = PetscMalloc1(nevents,&event->terminate);CHKERRQ(ierr);
92d94325d3SShri Abhyankar   for (i=0; i < nevents; i++) {
93d94325d3SShri Abhyankar     event->direction[i] = direction[i];
94d94325d3SShri Abhyankar     event->terminate[i] = terminate[i];
95d94325d3SShri Abhyankar   }
96854ce69bSBarry Smith   ierr = PetscMalloc1(nevents,&event->events_zero);CHKERRQ(ierr);
972dc7a7e3SShri Abhyankar   event->monitor = eventmonitor;
982dc7a7e3SShri Abhyankar   event->postevent = postevent;
992dc7a7e3SShri Abhyankar   event->monitorcontext = (void*)mectx;
1002dc7a7e3SShri Abhyankar   event->nevents = nevents;
1012dc7a7e3SShri Abhyankar 
102f7aea88cSShri Abhyankar   for(i=0; i < MAXEVENTRECORDERS; i++) {
103f7aea88cSShri Abhyankar     ierr = PetscMalloc1(nevents,&event->recorder.eventidx[i]);CHKERRQ(ierr);
104f7aea88cSShri Abhyankar   }
105f7aea88cSShri Abhyankar 
1062dc7a7e3SShri Abhyankar   ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"TS Event options","");CHKERRQ(ierr);
1072dc7a7e3SShri Abhyankar   {
1082dc7a7e3SShri Abhyankar     event->tol = 1.0e-6;
1092dc7a7e3SShri Abhyankar     ierr = PetscOptionsReal("-ts_event_tol","","",event->tol,&event->tol,NULL);CHKERRQ(ierr);
1102dc7a7e3SShri Abhyankar   }
1112dc7a7e3SShri Abhyankar   ierr = PetscOptionsEnd();CHKERRQ(ierr);
112d94325d3SShri Abhyankar   ts->event = event;
1132dc7a7e3SShri Abhyankar   PetscFunctionReturn(0);
1142dc7a7e3SShri Abhyankar }
1152dc7a7e3SShri Abhyankar 
1162dc7a7e3SShri Abhyankar #undef __FUNCT__
1172dc7a7e3SShri Abhyankar #define __FUNCT__ "TSPostEvent"
118031fbad4SShri Abhyankar /*
119031fbad4SShri Abhyankar    TSPostEvent - Does post event processing by calling the user-defined postevent function
120031fbad4SShri Abhyankar 
121031fbad4SShri Abhyankar    Logically Collective on TS
122031fbad4SShri Abhyankar 
123031fbad4SShri Abhyankar    Input Parameters:
124031fbad4SShri Abhyankar +  ts - the TS context
125031fbad4SShri Abhyankar .  nevents_zero - number of local events whose event function is zero
126031fbad4SShri Abhyankar .  events_zero  - indices of local events which have reached zero
127031fbad4SShri Abhyankar .  t            - current time
128031fbad4SShri Abhyankar .  U            - current solution
129031fbad4SShri Abhyankar .  forwardsolve - Flag to indicate whether TS is doing a forward solve (1) or adjoint solve (0)
130031fbad4SShri Abhyankar -  ctx          - the context passed with eventmonitor
131031fbad4SShri Abhyankar 
132031fbad4SShri Abhyankar    Level: intermediate
133031fbad4SShri Abhyankar 
134031fbad4SShri Abhyankar .keywords: TS, event, set, monitor
135031fbad4SShri Abhyankar 
136031fbad4SShri Abhyankar .seealso: TSSetEventMonitor(),TSEvent
137031fbad4SShri Abhyankar */
138031fbad4SShri Abhyankar #undef __FUNCT__
139031fbad4SShri Abhyankar #define __FUNCT__ "TSPostEvent"
140031fbad4SShri Abhyankar PetscErrorCode TSPostEvent(TS ts,PetscInt nevents_zero,PetscInt events_zero[],PetscReal t,Vec U,PetscBool forwardsolve,void *ctx)
1412dc7a7e3SShri Abhyankar {
1422dc7a7e3SShri Abhyankar   PetscErrorCode ierr;
1432dc7a7e3SShri Abhyankar   TSEvent        event=ts->event;
1442dc7a7e3SShri Abhyankar   PetscBool      terminate=PETSC_FALSE;
145d0578d90SShri Abhyankar   PetscInt       i,ctr,stepnum;
1462dc7a7e3SShri Abhyankar   PetscBool      ts_terminate;
1472dc7a7e3SShri Abhyankar 
1482dc7a7e3SShri Abhyankar   PetscFunctionBegin;
1492dc7a7e3SShri Abhyankar   if (event->postevent) {
150031fbad4SShri Abhyankar     ierr = (*event->postevent)(ts,nevents_zero,events_zero,t,U,forwardsolve,ctx);CHKERRQ(ierr);
1512dc7a7e3SShri Abhyankar   }
1522dc7a7e3SShri Abhyankar   for(i = 0; i < nevents_zero;i++) {
153e105d053SSatish Balay     terminate = (PetscBool)(terminate || event->terminate[events_zero[i]]);
1542dc7a7e3SShri Abhyankar   }
155b4549700SJed Brown   ierr = MPI_Allreduce(&terminate,&ts_terminate,1,MPIU_BOOL,MPI_LOR,((PetscObject)ts)->comm);CHKERRQ(ierr);
1562dc7a7e3SShri Abhyankar   if (terminate) {
1572dc7a7e3SShri Abhyankar     ierr = TSSetConvergedReason(ts,TS_CONVERGED_EVENT);CHKERRQ(ierr);
1582dc7a7e3SShri Abhyankar     event->status = TSEVENT_NONE;
1592dc7a7e3SShri Abhyankar   } else {
1602dc7a7e3SShri Abhyankar     event->status = TSEVENT_RESET_NEXTSTEP;
1612dc7a7e3SShri Abhyankar   }
162f7aea88cSShri Abhyankar 
163d0578d90SShri Abhyankar   /* Record the event in the event recorder */
164d0578d90SShri Abhyankar   ierr = TSGetTimeStepNumber(ts,&stepnum);CHKERRQ(ierr);
165f7aea88cSShri Abhyankar   ctr = event->recorder.ctr;
166f7aea88cSShri Abhyankar   if (ctr == MAXEVENTRECORDERS) {
167f7aea88cSShri Abhyankar     SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Exceeded limit (=%d) for number of events recorded",MAXEVENTRECORDERS);
168f7aea88cSShri Abhyankar   }
169f7aea88cSShri Abhyankar   event->recorder.time[ctr] = t;
170d0578d90SShri Abhyankar   event->recorder.stepnum[ctr] = stepnum;
171f7aea88cSShri Abhyankar   event->recorder.nevents[ctr] = nevents_zero;
172f7aea88cSShri Abhyankar   for(i=0; i < nevents_zero; i++) event->recorder.eventidx[ctr][i] = events_zero[i];
173f7aea88cSShri Abhyankar   event->recorder.ctr++;
174f7aea88cSShri Abhyankar 
17573967516SShri Abhyankar   /* Reset the event residual functions as states might get changed by the postevent callback */
17673967516SShri Abhyankar   ierr = (*event->monitor)(ts,t,U,event->fvalue_prev,event->monitorcontext);CHKERRQ(ierr);
17773967516SShri Abhyankar   event->ptime_prev  = t;
17873967516SShri Abhyankar 
1792dc7a7e3SShri Abhyankar   PetscFunctionReturn(0);
1802dc7a7e3SShri Abhyankar }
1812dc7a7e3SShri Abhyankar 
1822dc7a7e3SShri Abhyankar #undef __FUNCT__
1832dc7a7e3SShri Abhyankar #define __FUNCT__ "TSEventMonitorDestroy"
1842dc7a7e3SShri Abhyankar PetscErrorCode TSEventMonitorDestroy(TSEvent *event)
1852dc7a7e3SShri Abhyankar {
1862dc7a7e3SShri Abhyankar   PetscErrorCode ierr;
187f7aea88cSShri Abhyankar   PetscInt       i;
1882dc7a7e3SShri Abhyankar 
1892dc7a7e3SShri Abhyankar   PetscFunctionBegin;
1902dc7a7e3SShri Abhyankar   ierr = PetscFree((*event)->fvalue);CHKERRQ(ierr);
1912dc7a7e3SShri Abhyankar   ierr = PetscFree((*event)->fvalue_prev);CHKERRQ(ierr);
1922dc7a7e3SShri Abhyankar   ierr = PetscFree((*event)->direction);CHKERRQ(ierr);
193d94325d3SShri Abhyankar   ierr = PetscFree((*event)->terminate);CHKERRQ(ierr);
1942dc7a7e3SShri Abhyankar   ierr = PetscFree((*event)->events_zero);CHKERRQ(ierr);
195f7aea88cSShri Abhyankar   for(i=0; i < MAXEVENTRECORDERS; i++) {
196302440fdSBarry Smith     ierr = PetscFree((*event)->recorder.eventidx[i]);CHKERRQ(ierr);
197f7aea88cSShri Abhyankar   }
1982dc7a7e3SShri Abhyankar   ierr = PetscFree(*event);CHKERRQ(ierr);
1992dc7a7e3SShri Abhyankar   *event = NULL;
2002dc7a7e3SShri Abhyankar   PetscFunctionReturn(0);
2012dc7a7e3SShri Abhyankar }
2022dc7a7e3SShri Abhyankar 
2032dc7a7e3SShri Abhyankar #undef __FUNCT__
2042dc7a7e3SShri Abhyankar #define __FUNCT__ "TSEventMonitor"
2052dc7a7e3SShri Abhyankar PetscErrorCode TSEventMonitor(TS ts)
2062dc7a7e3SShri Abhyankar {
2072dc7a7e3SShri Abhyankar   PetscErrorCode ierr;
2082dc7a7e3SShri Abhyankar   TSEvent        event=ts->event;
2092dc7a7e3SShri Abhyankar   PetscReal      t;
2102dc7a7e3SShri Abhyankar   Vec            U;
2112dc7a7e3SShri Abhyankar   PetscInt       i;
2122dc7a7e3SShri Abhyankar   PetscReal      dt;
213b4549700SJed Brown   TSEventStatus  status = event->status;
2142dc7a7e3SShri Abhyankar   PetscInt       rollback=0,in[2],out[2];
215031fbad4SShri Abhyankar   PetscBool      forwardsolve=PETSC_TRUE; /* Flag indicating that TS is doing a forward solve */
2162dc7a7e3SShri Abhyankar 
2172dc7a7e3SShri Abhyankar   PetscFunctionBegin;
2182dc7a7e3SShri Abhyankar 
2192dc7a7e3SShri Abhyankar   ierr = TSGetTime(ts,&t);CHKERRQ(ierr);
2202dc7a7e3SShri Abhyankar   ierr = TSGetSolution(ts,&U);CHKERRQ(ierr);
2212dc7a7e3SShri Abhyankar 
2222dc7a7e3SShri Abhyankar   ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr);
2232dc7a7e3SShri Abhyankar   if (event->status == TSEVENT_RESET_NEXTSTEP) {
2242dc7a7e3SShri Abhyankar     /* Take initial time step */
2252dc7a7e3SShri Abhyankar     dt = event->initial_timestep;
2262dc7a7e3SShri Abhyankar     ts->time_step = dt;
2272dc7a7e3SShri Abhyankar     event->status = TSEVENT_NONE;
2282dc7a7e3SShri Abhyankar   }
2292dc7a7e3SShri Abhyankar 
2302dc7a7e3SShri Abhyankar   if (event->status == TSEVENT_NONE) {
2312dc7a7e3SShri Abhyankar     event->tstepend   = t;
2322dc7a7e3SShri Abhyankar   }
2332dc7a7e3SShri Abhyankar 
2342dc7a7e3SShri Abhyankar   event->nevents_zero = 0;
2352dc7a7e3SShri Abhyankar 
236d94325d3SShri Abhyankar   ierr = (*event->monitor)(ts,t,U,event->fvalue,event->monitorcontext);CHKERRQ(ierr);
2372dc7a7e3SShri Abhyankar   for (i=0; i < event->nevents; i++) {
238e105d053SSatish Balay     if (PetscAbsScalar(event->fvalue[i]) < event->tol) {
2392dc7a7e3SShri Abhyankar       event->status = TSEVENT_ZERO;
2402dc7a7e3SShri Abhyankar       event->events_zero[event->nevents_zero++] = i;
2412dc7a7e3SShri Abhyankar     }
2422dc7a7e3SShri Abhyankar   }
2432dc7a7e3SShri Abhyankar 
2442dc7a7e3SShri Abhyankar   status = event->status;
245b4549700SJed Brown   ierr = MPI_Allreduce((PetscEnum*)&status,(PetscEnum*)&event->status,1,MPIU_ENUM,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr);
2462dc7a7e3SShri Abhyankar 
2472dc7a7e3SShri Abhyankar   if (event->status == TSEVENT_ZERO) {
248031fbad4SShri Abhyankar     ierr = TSPostEvent(ts,event->nevents_zero,event->events_zero,t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr);
249c540466cSShri Abhyankar     dt = event->tstepend-t;
250bcbf8bb3SShri Abhyankar     if(PetscAbsReal(dt) < PETSC_SMALL) dt += event->initial_timestep;
25193fbeba1SShri Abhyankar     ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr);
2522dc7a7e3SShri Abhyankar     PetscFunctionReturn(0);
2532dc7a7e3SShri Abhyankar   }
2542dc7a7e3SShri Abhyankar 
2552dc7a7e3SShri Abhyankar   for (i = 0; i < event->nevents; i++) {
256d94325d3SShri Abhyankar     PetscInt fvalue_sign,fvalueprev_sign;
257d94325d3SShri Abhyankar     fvalue_sign = PetscSign(PetscRealPart(event->fvalue[i]));
258d94325d3SShri Abhyankar     fvalueprev_sign = PetscSign(PetscRealPart(event->fvalue_prev[i]));
25993fbeba1SShri Abhyankar     if (fvalueprev_sign != 0 && (fvalue_sign != fvalueprev_sign) && (PetscAbsScalar(event->fvalue_prev[i]) > event->tol)) {
260d94325d3SShri Abhyankar       switch (event->direction[i]) {
261d94325d3SShri Abhyankar       case -1:
262d94325d3SShri Abhyankar 	if (fvalue_sign < 0) {
2632dc7a7e3SShri Abhyankar 	  rollback = 1;
2642dc7a7e3SShri Abhyankar 	  /* Compute linearly interpolated new time step */
265e105d053SSatish Balay 	  dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i])));
2662dc7a7e3SShri Abhyankar 	}
267d94325d3SShri Abhyankar 	break;
268d94325d3SShri Abhyankar       case 1:
269d94325d3SShri Abhyankar 	if (fvalue_sign > 0) {
270d94325d3SShri Abhyankar 	  rollback = 1;
271d94325d3SShri Abhyankar 	  /* Compute linearly interpolated new time step */
272d94325d3SShri Abhyankar 	  dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i])));
2732dc7a7e3SShri Abhyankar 	}
274d94325d3SShri Abhyankar 	break;
275d94325d3SShri Abhyankar       case 0:
276d94325d3SShri Abhyankar 	rollback = 1;
277d94325d3SShri Abhyankar 	/* Compute linearly interpolated new time step */
278d94325d3SShri Abhyankar 	dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i])));
279d94325d3SShri Abhyankar 	break;
280d94325d3SShri Abhyankar       }
281d94325d3SShri Abhyankar     }
282d94325d3SShri Abhyankar   }
283d94325d3SShri Abhyankar   if (rollback) event->status = TSEVENT_LOCATED_INTERVAL;
284d94325d3SShri Abhyankar 
2852dc7a7e3SShri Abhyankar   in[0] = event->status;
2862dc7a7e3SShri Abhyankar   in[1] = rollback;
2872dc7a7e3SShri Abhyankar   ierr = MPI_Allreduce(in,out,2,MPIU_INT,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr);
2882dc7a7e3SShri Abhyankar 
2892dc7a7e3SShri Abhyankar   rollback = out[1];
2902dc7a7e3SShri Abhyankar   if (rollback) {
2912dc7a7e3SShri Abhyankar     event->status = TSEVENT_LOCATED_INTERVAL;
2922dc7a7e3SShri Abhyankar   }
2932dc7a7e3SShri Abhyankar 
2942dc7a7e3SShri Abhyankar   if (event->status == TSEVENT_LOCATED_INTERVAL) {
2952dc7a7e3SShri Abhyankar     ierr = TSRollBack(ts);CHKERRQ(ierr);
296c540466cSShri Abhyankar     ts->steps--;
297c540466cSShri Abhyankar     ts->total_steps--;
298*db84a1feSShri Abhyankar     ts->reason = TS_CONVERGED_ITERATING;
2992dc7a7e3SShri Abhyankar     event->status = TSEVENT_PROCESSING;
3002dc7a7e3SShri Abhyankar   } else {
3012dc7a7e3SShri Abhyankar     for (i = 0; i < event->nevents; i++) {
3022dc7a7e3SShri Abhyankar       event->fvalue_prev[i] = event->fvalue[i];
3032dc7a7e3SShri Abhyankar     }
3042dc7a7e3SShri Abhyankar     event->ptime_prev  = t;
3052dc7a7e3SShri Abhyankar     if (event->status == TSEVENT_PROCESSING) {
3062dc7a7e3SShri Abhyankar       dt = event->tstepend - event->ptime_prev;
3072dc7a7e3SShri Abhyankar     }
3082dc7a7e3SShri Abhyankar   }
309a9b180a6SBarry Smith   ierr = MPI_Allreduce(&dt,&(ts->time_step),1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr);
3102dc7a7e3SShri Abhyankar   PetscFunctionReturn(0);
3112dc7a7e3SShri Abhyankar }
3122dc7a7e3SShri Abhyankar 
313d0578d90SShri Abhyankar #undef __FUNCT__
314d0578d90SShri Abhyankar #define __FUNCT__ "TSAdjointEventMonitor"
315d0578d90SShri Abhyankar PetscErrorCode TSAdjointEventMonitor(TS ts)
316d0578d90SShri Abhyankar {
317d0578d90SShri Abhyankar   PetscErrorCode ierr;
318d0578d90SShri Abhyankar   TSEvent        event=ts->event;
319d0578d90SShri Abhyankar   PetscReal      t;
320d0578d90SShri Abhyankar   Vec            U;
321d0578d90SShri Abhyankar   PetscInt       ctr;
322d0578d90SShri Abhyankar   PetscBool      forwardsolve=PETSC_FALSE; /* Flag indicating that TS is doing an adjoint solve */
323d0578d90SShri Abhyankar 
324d0578d90SShri Abhyankar   PetscFunctionBegin;
325d0578d90SShri Abhyankar 
326d0578d90SShri Abhyankar   ierr = TSGetTime(ts,&t);CHKERRQ(ierr);
327d0578d90SShri Abhyankar   ierr = TSGetSolution(ts,&U);CHKERRQ(ierr);
328d0578d90SShri Abhyankar 
329d0578d90SShri Abhyankar   ctr = event->recorder.ctr-1;
330bcbf8bb3SShri Abhyankar   if(ctr >= 0 && PetscAbsReal(t - event->recorder.time[ctr]) < PETSC_SMALL) {
331d0578d90SShri Abhyankar     /* Call the user postevent function */
332d0578d90SShri Abhyankar     if(event->postevent) {
333d0578d90SShri Abhyankar       ierr = (*event->postevent)(ts,event->recorder.nevents[ctr],event->recorder.eventidx[ctr],t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr);
334d0578d90SShri Abhyankar       event->recorder.ctr--;
335d0578d90SShri Abhyankar     }
336d0578d90SShri Abhyankar   }
337d0578d90SShri Abhyankar 
338d0578d90SShri Abhyankar   PetscBarrier((PetscObject)ts);
339d0578d90SShri Abhyankar   PetscFunctionReturn(0);
340d0578d90SShri Abhyankar }
341d0578d90SShri Abhyankar 
342d0578d90SShri Abhyankar 
343d0578d90SShri Abhyankar 
344