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