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