12dc7a7e3SShri Abhyankar 22dc7a7e3SShri Abhyankar #include <petsc-private/tsimpl.h> /*I "petscts.h" I*/ 32dc7a7e3SShri Abhyankar 42dc7a7e3SShri Abhyankar #undef __FUNCT__ 52dc7a7e3SShri Abhyankar #define __FUNCT__ "TSSetEventMonitor" 62dc7a7e3SShri Abhyankar /*@C 72dc7a7e3SShri Abhyankar TSSetEventMonitor - Sets a monitoring function used for detecting events 82dc7a7e3SShri Abhyankar 92dc7a7e3SShri Abhyankar Logically Collective on TS 102dc7a7e3SShri Abhyankar 112dc7a7e3SShri Abhyankar Input Parameters: 122dc7a7e3SShri Abhyankar + ts - the TS context obtained from TSCreate() 132dc7a7e3SShri Abhyankar . nevents - number of local events 14d94325d3SShri Abhyankar . direction - direction of zero crossing to be detected. -1 => Zero crossing in negative direction, 15d94325d3SShri Abhyankar +1 => Zero crossing in positive direction, 0 => both ways (one for each event) 16d94325d3SShri Abhyankar . terminate - flag to indicate whether time stepping should be terminated after 17d94325d3SShri Abhyankar event is detected (one for each event) 182dc7a7e3SShri Abhyankar . eventmonitor - event monitoring routine 192dc7a7e3SShri Abhyankar . postevent - [optional] post-event function 202dc7a7e3SShri Abhyankar - mectx - [optional] user-defined context for private data for the 212dc7a7e3SShri Abhyankar event monitor and post event routine (use NULL if no 222dc7a7e3SShri Abhyankar context is desired) 232dc7a7e3SShri Abhyankar 242dc7a7e3SShri Abhyankar Calling sequence of eventmonitor: 25d94325d3SShri Abhyankar PetscErrorCode EventMonitor(TS ts,PetscReal t,Vec U,PetscScalar *fvalue,void* mectx) 262dc7a7e3SShri Abhyankar 272dc7a7e3SShri Abhyankar Input Parameters: 282dc7a7e3SShri Abhyankar + ts - the TS context 292dc7a7e3SShri Abhyankar . t - current time 302dc7a7e3SShri Abhyankar . U - current iterate 312dc7a7e3SShri Abhyankar - ctx - [optional] context passed with eventmonitor 322dc7a7e3SShri Abhyankar 332dc7a7e3SShri Abhyankar Output parameters: 34d94325d3SShri Abhyankar . fvalue - function value of events at time t 352dc7a7e3SShri Abhyankar 362dc7a7e3SShri Abhyankar Calling sequence of postevent: 37031fbad4SShri Abhyankar PetscErrorCode PostEvent(TS ts,PetscInt nevents_zero, PetscInt events_zero, PetscReal t,Vec U,PetscBool forwardsolve,void* ctx) 382dc7a7e3SShri Abhyankar 392dc7a7e3SShri Abhyankar Input Parameters: 402dc7a7e3SShri Abhyankar + ts - the TS context 412dc7a7e3SShri Abhyankar . nevents_zero - number of local events whose event function is zero 422dc7a7e3SShri Abhyankar . events_zero - indices of local events which have reached zero 432dc7a7e3SShri Abhyankar . t - current time 442dc7a7e3SShri Abhyankar . U - current solution 45031fbad4SShri Abhyankar . forwardsolve - Flag to indicate whether TS is doing a forward solve (1) or adjoint solve (0) 462dc7a7e3SShri Abhyankar - ctx - the context passed with eventmonitor 472dc7a7e3SShri Abhyankar 482dc7a7e3SShri Abhyankar Level: intermediate 492dc7a7e3SShri Abhyankar 502dc7a7e3SShri Abhyankar .keywords: TS, event, set, monitor 512dc7a7e3SShri Abhyankar 522dc7a7e3SShri Abhyankar .seealso: TSCreate(), TSSetTimeStep(), TSSetConvergedReason() 532dc7a7e3SShri Abhyankar @*/ 54031fbad4SShri 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) 552dc7a7e3SShri Abhyankar { 562dc7a7e3SShri Abhyankar PetscErrorCode ierr; 572dc7a7e3SShri Abhyankar PetscReal t; 582dc7a7e3SShri Abhyankar Vec U; 592dc7a7e3SShri Abhyankar TSEvent event; 60d94325d3SShri Abhyankar PetscInt i; 612dc7a7e3SShri Abhyankar 622dc7a7e3SShri Abhyankar PetscFunctionBegin; 6342ea6711SShri ierr = PetscNew(&event);CHKERRQ(ierr); 64854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->fvalue);CHKERRQ(ierr); 65854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->fvalue_prev);CHKERRQ(ierr); 66854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->direction);CHKERRQ(ierr); 67854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->terminate);CHKERRQ(ierr); 68d94325d3SShri Abhyankar for (i=0; i < nevents; i++) { 69d94325d3SShri Abhyankar event->direction[i] = direction[i]; 70d94325d3SShri Abhyankar event->terminate[i] = terminate[i]; 71d94325d3SShri Abhyankar } 72854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->events_zero);CHKERRQ(ierr); 732dc7a7e3SShri Abhyankar event->monitor = eventmonitor; 742dc7a7e3SShri Abhyankar event->postevent = postevent; 752dc7a7e3SShri Abhyankar event->monitorcontext = (void*)mectx; 762dc7a7e3SShri Abhyankar event->nevents = nevents; 772dc7a7e3SShri Abhyankar 78f7aea88cSShri Abhyankar /* Initialize the event recorder */ 79f7aea88cSShri Abhyankar event->recorder.ctr = 0; 80f7aea88cSShri Abhyankar for(i=0; i < MAXEVENTRECORDERS; i++) { 81f7aea88cSShri Abhyankar ierr = PetscMalloc1(nevents,&event->recorder.eventidx[i]);CHKERRQ(ierr); 82f7aea88cSShri Abhyankar } 83f7aea88cSShri Abhyankar 842dc7a7e3SShri Abhyankar ierr = TSGetTime(ts,&t);CHKERRQ(ierr); 852dc7a7e3SShri Abhyankar ierr = TSGetTimeStep(ts,&event->initial_timestep);CHKERRQ(ierr); 862dc7a7e3SShri Abhyankar ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 872dc7a7e3SShri Abhyankar event->ptime_prev = t; 88d94325d3SShri Abhyankar ierr = (*event->monitor)(ts,t,U,event->fvalue_prev,mectx);CHKERRQ(ierr); 892dc7a7e3SShri Abhyankar ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"TS Event options","");CHKERRQ(ierr); 902dc7a7e3SShri Abhyankar { 912dc7a7e3SShri Abhyankar event->tol = 1.0e-6; 922dc7a7e3SShri Abhyankar ierr = PetscOptionsReal("-ts_event_tol","","",event->tol,&event->tol,NULL);CHKERRQ(ierr); 932dc7a7e3SShri Abhyankar } 942dc7a7e3SShri Abhyankar ierr = PetscOptionsEnd();CHKERRQ(ierr); 95d94325d3SShri Abhyankar ts->event = event; 962dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 972dc7a7e3SShri Abhyankar } 982dc7a7e3SShri Abhyankar 992dc7a7e3SShri Abhyankar #undef __FUNCT__ 1002dc7a7e3SShri Abhyankar #define __FUNCT__ "TSPostEvent" 101031fbad4SShri Abhyankar /* 102031fbad4SShri Abhyankar TSPostEvent - Does post event processing by calling the user-defined postevent function 103031fbad4SShri Abhyankar 104031fbad4SShri Abhyankar Logically Collective on TS 105031fbad4SShri Abhyankar 106031fbad4SShri Abhyankar Input Parameters: 107031fbad4SShri Abhyankar + ts - the TS context 108031fbad4SShri Abhyankar . nevents_zero - number of local events whose event function is zero 109031fbad4SShri Abhyankar . events_zero - indices of local events which have reached zero 110031fbad4SShri Abhyankar . t - current time 111031fbad4SShri Abhyankar . U - current solution 112031fbad4SShri Abhyankar . forwardsolve - Flag to indicate whether TS is doing a forward solve (1) or adjoint solve (0) 113031fbad4SShri Abhyankar - ctx - the context passed with eventmonitor 114031fbad4SShri Abhyankar 115031fbad4SShri Abhyankar Level: intermediate 116031fbad4SShri Abhyankar 117031fbad4SShri Abhyankar .keywords: TS, event, set, monitor 118031fbad4SShri Abhyankar 119031fbad4SShri Abhyankar .seealso: TSSetEventMonitor(),TSEvent 120031fbad4SShri Abhyankar */ 121031fbad4SShri Abhyankar #undef __FUNCT__ 122031fbad4SShri Abhyankar #define __FUNCT__ "TSPostEvent" 123031fbad4SShri Abhyankar PetscErrorCode TSPostEvent(TS ts,PetscInt nevents_zero,PetscInt events_zero[],PetscReal t,Vec U,PetscBool forwardsolve,void *ctx) 1242dc7a7e3SShri Abhyankar { 1252dc7a7e3SShri Abhyankar PetscErrorCode ierr; 1262dc7a7e3SShri Abhyankar TSEvent event=ts->event; 1272dc7a7e3SShri Abhyankar PetscBool terminate=PETSC_FALSE; 128*d0578d90SShri Abhyankar PetscInt i,ctr,stepnum; 1292dc7a7e3SShri Abhyankar PetscBool ts_terminate; 1302dc7a7e3SShri Abhyankar 1312dc7a7e3SShri Abhyankar PetscFunctionBegin; 1322dc7a7e3SShri Abhyankar if (event->postevent) { 133031fbad4SShri Abhyankar ierr = (*event->postevent)(ts,nevents_zero,events_zero,t,U,forwardsolve,ctx);CHKERRQ(ierr); 1342dc7a7e3SShri Abhyankar } 1352dc7a7e3SShri Abhyankar for(i = 0; i < nevents_zero;i++) { 136e105d053SSatish Balay terminate = (PetscBool)(terminate || event->terminate[events_zero[i]]); 1372dc7a7e3SShri Abhyankar } 138b4549700SJed Brown ierr = MPI_Allreduce(&terminate,&ts_terminate,1,MPIU_BOOL,MPI_LOR,((PetscObject)ts)->comm);CHKERRQ(ierr); 1392dc7a7e3SShri Abhyankar if (terminate) { 1402dc7a7e3SShri Abhyankar ierr = TSSetConvergedReason(ts,TS_CONVERGED_EVENT);CHKERRQ(ierr); 1412dc7a7e3SShri Abhyankar event->status = TSEVENT_NONE; 1422dc7a7e3SShri Abhyankar } else { 1432dc7a7e3SShri Abhyankar event->status = TSEVENT_RESET_NEXTSTEP; 1442dc7a7e3SShri Abhyankar } 145f7aea88cSShri Abhyankar 146*d0578d90SShri Abhyankar /* Record the event in the event recorder */ 147*d0578d90SShri Abhyankar ierr = TSGetTimeStepNumber(ts,&stepnum);CHKERRQ(ierr); 148f7aea88cSShri Abhyankar ctr = event->recorder.ctr; 149f7aea88cSShri Abhyankar if (ctr == MAXEVENTRECORDERS) { 150f7aea88cSShri Abhyankar SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Exceeded limit (=%d) for number of events recorded",MAXEVENTRECORDERS); 151f7aea88cSShri Abhyankar } 152f7aea88cSShri Abhyankar event->recorder.time[ctr] = t; 153*d0578d90SShri Abhyankar event->recorder.stepnum[ctr] = stepnum; 154f7aea88cSShri Abhyankar event->recorder.nevents[ctr] = nevents_zero; 155f7aea88cSShri Abhyankar for(i=0; i < nevents_zero; i++) event->recorder.eventidx[ctr][i] = events_zero[i]; 156f7aea88cSShri Abhyankar event->recorder.ctr++; 157f7aea88cSShri Abhyankar 15873967516SShri Abhyankar /* Reset the event residual functions as states might get changed by the postevent callback */ 15973967516SShri Abhyankar ierr = (*event->monitor)(ts,t,U,event->fvalue_prev,event->monitorcontext);CHKERRQ(ierr); 16073967516SShri Abhyankar event->ptime_prev = t; 16173967516SShri Abhyankar 1622dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 1632dc7a7e3SShri Abhyankar } 1642dc7a7e3SShri Abhyankar 1652dc7a7e3SShri Abhyankar #undef __FUNCT__ 1662dc7a7e3SShri Abhyankar #define __FUNCT__ "TSEventMonitorDestroy" 1672dc7a7e3SShri Abhyankar PetscErrorCode TSEventMonitorDestroy(TSEvent *event) 1682dc7a7e3SShri Abhyankar { 1692dc7a7e3SShri Abhyankar PetscErrorCode ierr; 170f7aea88cSShri Abhyankar PetscInt i; 1712dc7a7e3SShri Abhyankar 1722dc7a7e3SShri Abhyankar PetscFunctionBegin; 1732dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->fvalue);CHKERRQ(ierr); 1742dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->fvalue_prev);CHKERRQ(ierr); 1752dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->direction);CHKERRQ(ierr); 176d94325d3SShri Abhyankar ierr = PetscFree((*event)->terminate);CHKERRQ(ierr); 1772dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->events_zero);CHKERRQ(ierr); 178f7aea88cSShri Abhyankar for(i=0; i < MAXEVENTRECORDERS; i++) { 179f7aea88cSShri Abhyankar ierr = PetscFree((*event)->recorder.eventidx[i]); 180f7aea88cSShri Abhyankar } 1812dc7a7e3SShri Abhyankar ierr = PetscFree(*event);CHKERRQ(ierr); 1822dc7a7e3SShri Abhyankar *event = NULL; 1832dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 1842dc7a7e3SShri Abhyankar } 1852dc7a7e3SShri Abhyankar 1862dc7a7e3SShri Abhyankar #undef __FUNCT__ 1872dc7a7e3SShri Abhyankar #define __FUNCT__ "TSEventMonitor" 1882dc7a7e3SShri Abhyankar PetscErrorCode TSEventMonitor(TS ts) 1892dc7a7e3SShri Abhyankar { 1902dc7a7e3SShri Abhyankar PetscErrorCode ierr; 1912dc7a7e3SShri Abhyankar TSEvent event=ts->event; 1922dc7a7e3SShri Abhyankar PetscReal t; 1932dc7a7e3SShri Abhyankar Vec U; 1942dc7a7e3SShri Abhyankar PetscInt i; 1952dc7a7e3SShri Abhyankar PetscReal dt; 196b4549700SJed Brown TSEventStatus status = event->status; 1972dc7a7e3SShri Abhyankar PetscInt rollback=0,in[2],out[2]; 198031fbad4SShri Abhyankar PetscBool forwardsolve=PETSC_TRUE; /* Flag indicating that TS is doing a forward solve */ 1992dc7a7e3SShri Abhyankar 2002dc7a7e3SShri Abhyankar PetscFunctionBegin; 2012dc7a7e3SShri Abhyankar 2022dc7a7e3SShri Abhyankar ierr = TSGetTime(ts,&t);CHKERRQ(ierr); 2032dc7a7e3SShri Abhyankar ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 2042dc7a7e3SShri Abhyankar 2052dc7a7e3SShri Abhyankar ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr); 2062dc7a7e3SShri Abhyankar if (event->status == TSEVENT_RESET_NEXTSTEP) { 2072dc7a7e3SShri Abhyankar /* Take initial time step */ 2082dc7a7e3SShri Abhyankar dt = event->initial_timestep; 2092dc7a7e3SShri Abhyankar ts->time_step = dt; 2102dc7a7e3SShri Abhyankar event->status = TSEVENT_NONE; 2112dc7a7e3SShri Abhyankar } 2122dc7a7e3SShri Abhyankar 2132dc7a7e3SShri Abhyankar if (event->status == TSEVENT_NONE) { 2142dc7a7e3SShri Abhyankar event->tstepend = t; 2152dc7a7e3SShri Abhyankar } 2162dc7a7e3SShri Abhyankar 2172dc7a7e3SShri Abhyankar event->nevents_zero = 0; 2182dc7a7e3SShri Abhyankar 219d94325d3SShri Abhyankar ierr = (*event->monitor)(ts,t,U,event->fvalue,event->monitorcontext);CHKERRQ(ierr); 2202dc7a7e3SShri Abhyankar if (event->status != TSEVENT_NONE) { 2212dc7a7e3SShri Abhyankar for (i=0; i < event->nevents; i++) { 222e105d053SSatish Balay if (PetscAbsScalar(event->fvalue[i]) < event->tol) { 2232dc7a7e3SShri Abhyankar event->status = TSEVENT_ZERO; 2242dc7a7e3SShri Abhyankar event->events_zero[event->nevents_zero++] = i; 2252dc7a7e3SShri Abhyankar } 2262dc7a7e3SShri Abhyankar } 2272dc7a7e3SShri Abhyankar } 2282dc7a7e3SShri Abhyankar 2292dc7a7e3SShri Abhyankar status = event->status; 230b4549700SJed Brown ierr = MPI_Allreduce((PetscEnum*)&status,(PetscEnum*)&event->status,1,MPIU_ENUM,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr); 2312dc7a7e3SShri Abhyankar 2322dc7a7e3SShri Abhyankar if (event->status == TSEVENT_ZERO) { 233031fbad4SShri Abhyankar ierr = TSPostEvent(ts,event->nevents_zero,event->events_zero,t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr); 234c540466cSShri Abhyankar dt = event->tstepend-t; 235c540466cSShri Abhyankar if(PetscAbsScalar(dt) < PETSC_SMALL) dt += event->initial_timestep; 236c540466cSShri Abhyankar ts->time_step = dt; 2372dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 2382dc7a7e3SShri Abhyankar } 2392dc7a7e3SShri Abhyankar 2402dc7a7e3SShri Abhyankar for (i = 0; i < event->nevents; i++) { 241d94325d3SShri Abhyankar PetscInt fvalue_sign,fvalueprev_sign; 242d94325d3SShri Abhyankar fvalue_sign = PetscSign(PetscRealPart(event->fvalue[i])); 243d94325d3SShri Abhyankar fvalueprev_sign = PetscSign(PetscRealPart(event->fvalue_prev[i])); 2447a728e9fSShri Abhyankar if (fvalueprev_sign != 0 && (fvalue_sign != fvalueprev_sign)) { 245d94325d3SShri Abhyankar switch (event->direction[i]) { 246d94325d3SShri Abhyankar case -1: 247d94325d3SShri Abhyankar if (fvalue_sign < 0) { 2482dc7a7e3SShri Abhyankar rollback = 1; 2492dc7a7e3SShri Abhyankar /* Compute linearly interpolated new time step */ 250e105d053SSatish Balay dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 2512dc7a7e3SShri Abhyankar } 252d94325d3SShri Abhyankar break; 253d94325d3SShri Abhyankar case 1: 254d94325d3SShri Abhyankar if (fvalue_sign > 0) { 255d94325d3SShri Abhyankar rollback = 1; 256d94325d3SShri Abhyankar /* Compute linearly interpolated new time step */ 257d94325d3SShri Abhyankar dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 2582dc7a7e3SShri Abhyankar } 259d94325d3SShri Abhyankar break; 260d94325d3SShri Abhyankar case 0: 261d94325d3SShri Abhyankar rollback = 1; 262d94325d3SShri Abhyankar /* Compute linearly interpolated new time step */ 263d94325d3SShri Abhyankar dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 264d94325d3SShri Abhyankar break; 265d94325d3SShri Abhyankar } 266d94325d3SShri Abhyankar } 267d94325d3SShri Abhyankar } 268d94325d3SShri Abhyankar if (rollback) event->status = TSEVENT_LOCATED_INTERVAL; 269d94325d3SShri Abhyankar 2702dc7a7e3SShri Abhyankar in[0] = event->status; 2712dc7a7e3SShri Abhyankar in[1] = rollback; 2722dc7a7e3SShri Abhyankar ierr = MPI_Allreduce(in,out,2,MPIU_INT,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr); 2732dc7a7e3SShri Abhyankar 2742dc7a7e3SShri Abhyankar rollback = out[1]; 2752dc7a7e3SShri Abhyankar if (rollback) { 2762dc7a7e3SShri Abhyankar event->status = TSEVENT_LOCATED_INTERVAL; 2772dc7a7e3SShri Abhyankar } 2782dc7a7e3SShri Abhyankar 2792dc7a7e3SShri Abhyankar if (event->status == TSEVENT_LOCATED_INTERVAL) { 2802dc7a7e3SShri Abhyankar ierr = TSRollBack(ts);CHKERRQ(ierr); 281c540466cSShri Abhyankar ts->steps--; 282c540466cSShri Abhyankar ts->total_steps--; 2832dc7a7e3SShri Abhyankar event->status = TSEVENT_PROCESSING; 2842dc7a7e3SShri Abhyankar } else { 2852dc7a7e3SShri Abhyankar for (i = 0; i < event->nevents; i++) { 2862dc7a7e3SShri Abhyankar event->fvalue_prev[i] = event->fvalue[i]; 2872dc7a7e3SShri Abhyankar } 2882dc7a7e3SShri Abhyankar event->ptime_prev = t; 2892dc7a7e3SShri Abhyankar if (event->status == TSEVENT_PROCESSING) { 2902dc7a7e3SShri Abhyankar dt = event->tstepend - event->ptime_prev; 2912dc7a7e3SShri Abhyankar } 2922dc7a7e3SShri Abhyankar } 293e6b5be14SSatish Balay ierr = MPI_Allreduce(&dt,&(ts->time_step),1,MPIU_REAL,MPI_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr); 2942dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 2952dc7a7e3SShri Abhyankar } 2962dc7a7e3SShri Abhyankar 297*d0578d90SShri Abhyankar #undef __FUNCT__ 298*d0578d90SShri Abhyankar #define __FUNCT__ "TSAdjointEventMonitor" 299*d0578d90SShri Abhyankar PetscErrorCode TSAdjointEventMonitor(TS ts) 300*d0578d90SShri Abhyankar { 301*d0578d90SShri Abhyankar PetscErrorCode ierr; 302*d0578d90SShri Abhyankar TSEvent event=ts->event; 303*d0578d90SShri Abhyankar PetscReal t; 304*d0578d90SShri Abhyankar Vec U; 305*d0578d90SShri Abhyankar PetscInt ctr; 306*d0578d90SShri Abhyankar PetscBool forwardsolve=PETSC_FALSE; /* Flag indicating that TS is doing an adjoint solve */ 307*d0578d90SShri Abhyankar 308*d0578d90SShri Abhyankar PetscFunctionBegin; 309*d0578d90SShri Abhyankar 310*d0578d90SShri Abhyankar ierr = TSGetTime(ts,&t);CHKERRQ(ierr); 311*d0578d90SShri Abhyankar ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 312*d0578d90SShri Abhyankar 313*d0578d90SShri Abhyankar ctr = event->recorder.ctr-1; 314*d0578d90SShri Abhyankar if(ctr >= 0 && PetscAbsScalar(t - event->recorder.time[ctr]) < PETSC_SMALL) { 315*d0578d90SShri Abhyankar /* Call the user postevent function */ 316*d0578d90SShri Abhyankar if(event->postevent) { 317*d0578d90SShri Abhyankar ierr = (*event->postevent)(ts,event->recorder.nevents[ctr],event->recorder.eventidx[ctr],t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr); 318*d0578d90SShri Abhyankar event->recorder.ctr--; 319*d0578d90SShri Abhyankar } 320*d0578d90SShri Abhyankar } 321*d0578d90SShri Abhyankar 322*d0578d90SShri Abhyankar PetscBarrier((PetscObject)ts); 323*d0578d90SShri Abhyankar PetscFunctionReturn(0); 324*d0578d90SShri Abhyankar } 325*d0578d90SShri Abhyankar 326*d0578d90SShri Abhyankar 327*d0578d90SShri Abhyankar 328