xref: /petsc/src/ts/event/tsevent.c (revision bcbf8bb334a05651890ebf4178c2e24cfa57f8e2)
12dc7a7e3SShri Abhyankar 
22dc7a7e3SShri Abhyankar #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++) {
196f7aea88cSShri Abhyankar     ierr = PetscFree((*event)->recorder.eventidx[i]);
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   if (event->status != TSEVENT_NONE) {
2382dc7a7e3SShri Abhyankar     for (i=0; i < event->nevents; i++) {
239e105d053SSatish Balay       if (PetscAbsScalar(event->fvalue[i]) < event->tol) {
2402dc7a7e3SShri Abhyankar 	event->status = TSEVENT_ZERO;
2412dc7a7e3SShri Abhyankar 	event->events_zero[event->nevents_zero++] = i;
2422dc7a7e3SShri Abhyankar       }
2432dc7a7e3SShri Abhyankar     }
2442dc7a7e3SShri Abhyankar   }
2452dc7a7e3SShri Abhyankar 
2462dc7a7e3SShri Abhyankar   status = event->status;
247b4549700SJed Brown   ierr = MPI_Allreduce((PetscEnum*)&status,(PetscEnum*)&event->status,1,MPIU_ENUM,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr);
2482dc7a7e3SShri Abhyankar 
2492dc7a7e3SShri Abhyankar   if (event->status == TSEVENT_ZERO) {
250031fbad4SShri Abhyankar     ierr = TSPostEvent(ts,event->nevents_zero,event->events_zero,t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr);
251c540466cSShri Abhyankar     dt = event->tstepend-t;
252*bcbf8bb3SShri Abhyankar     if(PetscAbsReal(dt) < PETSC_SMALL) dt += event->initial_timestep;
253c540466cSShri Abhyankar     ts->time_step = dt;
2542dc7a7e3SShri Abhyankar     PetscFunctionReturn(0);
2552dc7a7e3SShri Abhyankar   }
2562dc7a7e3SShri Abhyankar 
2572dc7a7e3SShri Abhyankar   for (i = 0; i < event->nevents; i++) {
258d94325d3SShri Abhyankar     PetscInt fvalue_sign,fvalueprev_sign;
259d94325d3SShri Abhyankar     fvalue_sign = PetscSign(PetscRealPart(event->fvalue[i]));
260d94325d3SShri Abhyankar     fvalueprev_sign = PetscSign(PetscRealPart(event->fvalue_prev[i]));
2617a728e9fSShri Abhyankar     if (fvalueprev_sign != 0 && (fvalue_sign != fvalueprev_sign)) {
262d94325d3SShri Abhyankar       switch (event->direction[i]) {
263d94325d3SShri Abhyankar       case -1:
264d94325d3SShri Abhyankar 	if (fvalue_sign < 0) {
2652dc7a7e3SShri Abhyankar 	  rollback = 1;
2662dc7a7e3SShri Abhyankar 	  /* Compute linearly interpolated new time step */
267e105d053SSatish Balay 	  dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i])));
2682dc7a7e3SShri Abhyankar 	}
269d94325d3SShri Abhyankar 	break;
270d94325d3SShri Abhyankar       case 1:
271d94325d3SShri Abhyankar 	if (fvalue_sign > 0) {
272d94325d3SShri Abhyankar 	  rollback = 1;
273d94325d3SShri Abhyankar 	  /* Compute linearly interpolated new time step */
274d94325d3SShri Abhyankar 	  dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i])));
2752dc7a7e3SShri Abhyankar 	}
276d94325d3SShri Abhyankar 	break;
277d94325d3SShri Abhyankar       case 0:
278d94325d3SShri Abhyankar 	rollback = 1;
279d94325d3SShri Abhyankar 	/* Compute linearly interpolated new time step */
280d94325d3SShri Abhyankar 	dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i])));
281d94325d3SShri Abhyankar 	break;
282d94325d3SShri Abhyankar       }
283d94325d3SShri Abhyankar     }
284d94325d3SShri Abhyankar   }
285d94325d3SShri Abhyankar   if (rollback) event->status = TSEVENT_LOCATED_INTERVAL;
286d94325d3SShri Abhyankar 
2872dc7a7e3SShri Abhyankar   in[0] = event->status;
2882dc7a7e3SShri Abhyankar   in[1] = rollback;
2892dc7a7e3SShri Abhyankar   ierr = MPI_Allreduce(in,out,2,MPIU_INT,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr);
2902dc7a7e3SShri Abhyankar 
2912dc7a7e3SShri Abhyankar   rollback = out[1];
2922dc7a7e3SShri Abhyankar   if (rollback) {
2932dc7a7e3SShri Abhyankar     event->status = TSEVENT_LOCATED_INTERVAL;
2942dc7a7e3SShri Abhyankar   }
2952dc7a7e3SShri Abhyankar 
2962dc7a7e3SShri Abhyankar   if (event->status == TSEVENT_LOCATED_INTERVAL) {
2972dc7a7e3SShri Abhyankar     ierr = TSRollBack(ts);CHKERRQ(ierr);
298c540466cSShri Abhyankar     ts->steps--;
299c540466cSShri Abhyankar     ts->total_steps--;
3002dc7a7e3SShri Abhyankar     event->status = TSEVENT_PROCESSING;
3012dc7a7e3SShri Abhyankar   } else {
3022dc7a7e3SShri Abhyankar     for (i = 0; i < event->nevents; i++) {
3032dc7a7e3SShri Abhyankar       event->fvalue_prev[i] = event->fvalue[i];
3042dc7a7e3SShri Abhyankar     }
3052dc7a7e3SShri Abhyankar     event->ptime_prev  = t;
3062dc7a7e3SShri Abhyankar     if (event->status == TSEVENT_PROCESSING) {
3072dc7a7e3SShri Abhyankar       dt = event->tstepend - event->ptime_prev;
3082dc7a7e3SShri Abhyankar     }
3092dc7a7e3SShri Abhyankar   }
310e6b5be14SSatish Balay   ierr = MPI_Allreduce(&dt,&(ts->time_step),1,MPIU_REAL,MPI_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr);
3112dc7a7e3SShri Abhyankar   PetscFunctionReturn(0);
3122dc7a7e3SShri Abhyankar }
3132dc7a7e3SShri Abhyankar 
314d0578d90SShri Abhyankar #undef __FUNCT__
315d0578d90SShri Abhyankar #define __FUNCT__ "TSAdjointEventMonitor"
316d0578d90SShri Abhyankar PetscErrorCode TSAdjointEventMonitor(TS ts)
317d0578d90SShri Abhyankar {
318d0578d90SShri Abhyankar   PetscErrorCode ierr;
319d0578d90SShri Abhyankar   TSEvent        event=ts->event;
320d0578d90SShri Abhyankar   PetscReal      t;
321d0578d90SShri Abhyankar   Vec            U;
322d0578d90SShri Abhyankar   PetscInt       ctr;
323d0578d90SShri Abhyankar   PetscBool      forwardsolve=PETSC_FALSE; /* Flag indicating that TS is doing an adjoint solve */
324d0578d90SShri Abhyankar 
325d0578d90SShri Abhyankar   PetscFunctionBegin;
326d0578d90SShri Abhyankar 
327d0578d90SShri Abhyankar   ierr = TSGetTime(ts,&t);CHKERRQ(ierr);
328d0578d90SShri Abhyankar   ierr = TSGetSolution(ts,&U);CHKERRQ(ierr);
329d0578d90SShri Abhyankar 
330d0578d90SShri Abhyankar   ctr = event->recorder.ctr-1;
331*bcbf8bb3SShri Abhyankar   if(ctr >= 0 && PetscAbsReal(t - event->recorder.time[ctr]) < PETSC_SMALL) {
332d0578d90SShri Abhyankar     /* Call the user postevent function */
333d0578d90SShri Abhyankar     if(event->postevent) {
334d0578d90SShri Abhyankar       ierr = (*event->postevent)(ts,event->recorder.nevents[ctr],event->recorder.eventidx[ctr],t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr);
335d0578d90SShri Abhyankar       event->recorder.ctr--;
336d0578d90SShri Abhyankar     }
337d0578d90SShri Abhyankar   }
338d0578d90SShri Abhyankar 
339d0578d90SShri Abhyankar   PetscBarrier((PetscObject)ts);
340d0578d90SShri Abhyankar   PetscFunctionReturn(0);
341d0578d90SShri Abhyankar }
342d0578d90SShri Abhyankar 
343d0578d90SShri Abhyankar 
344d0578d90SShri Abhyankar 
345