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__ 31*e3005195SShri Abhyankar #define __FUNCT__ "TSSetEventTolerances" 32*e3005195SShri Abhyankar /*@ 33*e3005195SShri Abhyankar TSSetEventTolerances - Set tolerances for event zero crossings when using event handler 34*e3005195SShri Abhyankar 35*e3005195SShri Abhyankar Logically Collective 36*e3005195SShri Abhyankar 37*e3005195SShri Abhyankar Input Arguments: 38*e3005195SShri Abhyankar + ts - time integration context 39*e3005195SShri Abhyankar . tol - scalar tolerance, PETSC_DECIDE to leave current value 40*e3005195SShri Abhyankar - vtol - array of tolerances or NULL, used in preference to tol if present 41*e3005195SShri Abhyankar 42*e3005195SShri Abhyankar - -ts_event_tol <tol> tolerance for event zero crossing 43*e3005195SShri Abhyankar 44*e3005195SShri Abhyankar Notes: 45*e3005195SShri Abhyankar Must call TSSetEventMonitor() before setting the tolerances. 46*e3005195SShri Abhyankar 47*e3005195SShri Abhyankar The size of vtol is equal to the number of events. 48*e3005195SShri Abhyankar 49*e3005195SShri Abhyankar Level: beginner 50*e3005195SShri Abhyankar 51*e3005195SShri Abhyankar .seealso: TS, TSEvent, TSSetEventMonitor() 52*e3005195SShri Abhyankar @*/ 53*e3005195SShri Abhyankar PetscErrorCode TSSetEventTolerances(TS ts,PetscReal tol,PetscReal *vtol) 54*e3005195SShri Abhyankar { 55*e3005195SShri Abhyankar TSEvent event=ts->event; 56*e3005195SShri Abhyankar PetscInt i; 57*e3005195SShri Abhyankar 58*e3005195SShri Abhyankar PetscFunctionBegin; 59*e3005195SShri Abhyankar if(!ts->event) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must set the events first by calling TSSetEventMonitor()"); 60*e3005195SShri Abhyankar if(vtol) { 61*e3005195SShri Abhyankar for(i=0; i < event->nevents; i++) event->vtol[i] = vtol[i]; 62*e3005195SShri Abhyankar } else { 63*e3005195SShri Abhyankar if(tol != PETSC_DECIDE || tol != PETSC_DEFAULT) { 64*e3005195SShri Abhyankar for(i=0; i < event->nevents; i++) event->vtol[i] = tol; 65*e3005195SShri Abhyankar } 66*e3005195SShri Abhyankar } 67*e3005195SShri Abhyankar PetscFunctionReturn(0); 68*e3005195SShri Abhyankar } 69*e3005195SShri Abhyankar 70*e3005195SShri Abhyankar #undef __FUNCT__ 712dc7a7e3SShri Abhyankar #define __FUNCT__ "TSSetEventMonitor" 722dc7a7e3SShri Abhyankar /*@C 732dc7a7e3SShri Abhyankar TSSetEventMonitor - Sets a monitoring function used for detecting events 742dc7a7e3SShri Abhyankar 752dc7a7e3SShri Abhyankar Logically Collective on TS 762dc7a7e3SShri Abhyankar 772dc7a7e3SShri Abhyankar Input Parameters: 782dc7a7e3SShri Abhyankar + ts - the TS context obtained from TSCreate() 792dc7a7e3SShri Abhyankar . nevents - number of local events 80d94325d3SShri Abhyankar . direction - direction of zero crossing to be detected. -1 => Zero crossing in negative direction, 81d94325d3SShri Abhyankar +1 => Zero crossing in positive direction, 0 => both ways (one for each event) 82d94325d3SShri Abhyankar . terminate - flag to indicate whether time stepping should be terminated after 83d94325d3SShri Abhyankar event is detected (one for each event) 842dc7a7e3SShri Abhyankar . eventmonitor - event monitoring routine 852dc7a7e3SShri Abhyankar . postevent - [optional] post-event function 862dc7a7e3SShri Abhyankar - mectx - [optional] user-defined context for private data for the 872dc7a7e3SShri Abhyankar event monitor and post event routine (use NULL if no 882dc7a7e3SShri Abhyankar context is desired) 892dc7a7e3SShri Abhyankar 902dc7a7e3SShri Abhyankar Calling sequence of eventmonitor: 91d94325d3SShri Abhyankar PetscErrorCode EventMonitor(TS ts,PetscReal t,Vec U,PetscScalar *fvalue,void* mectx) 922dc7a7e3SShri Abhyankar 932dc7a7e3SShri Abhyankar Input Parameters: 942dc7a7e3SShri Abhyankar + ts - the TS context 952dc7a7e3SShri Abhyankar . t - current time 962dc7a7e3SShri Abhyankar . U - current iterate 972dc7a7e3SShri Abhyankar - ctx - [optional] context passed with eventmonitor 982dc7a7e3SShri Abhyankar 992dc7a7e3SShri Abhyankar Output parameters: 100d94325d3SShri Abhyankar . fvalue - function value of events at time t 1012dc7a7e3SShri Abhyankar 1022dc7a7e3SShri Abhyankar Calling sequence of postevent: 103031fbad4SShri Abhyankar PetscErrorCode PostEvent(TS ts,PetscInt nevents_zero, PetscInt events_zero, PetscReal t,Vec U,PetscBool forwardsolve,void* ctx) 1042dc7a7e3SShri Abhyankar 1052dc7a7e3SShri Abhyankar Input Parameters: 1062dc7a7e3SShri Abhyankar + ts - the TS context 1072dc7a7e3SShri Abhyankar . nevents_zero - number of local events whose event function is zero 1082dc7a7e3SShri Abhyankar . events_zero - indices of local events which have reached zero 1092dc7a7e3SShri Abhyankar . t - current time 1102dc7a7e3SShri Abhyankar . U - current solution 111031fbad4SShri Abhyankar . forwardsolve - Flag to indicate whether TS is doing a forward solve (1) or adjoint solve (0) 1122dc7a7e3SShri Abhyankar - ctx - the context passed with eventmonitor 1132dc7a7e3SShri Abhyankar 1142dc7a7e3SShri Abhyankar Level: intermediate 1152dc7a7e3SShri Abhyankar 1162dc7a7e3SShri Abhyankar .keywords: TS, event, set, monitor 1172dc7a7e3SShri Abhyankar 1182dc7a7e3SShri Abhyankar .seealso: TSCreate(), TSSetTimeStep(), TSSetConvergedReason() 1192dc7a7e3SShri Abhyankar @*/ 120031fbad4SShri 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) 1212dc7a7e3SShri Abhyankar { 1222dc7a7e3SShri Abhyankar PetscErrorCode ierr; 1232dc7a7e3SShri Abhyankar TSEvent event; 124d94325d3SShri Abhyankar PetscInt i; 125006e6a18SShri Abhyankar PetscBool flg; 126*e3005195SShri Abhyankar PetscReal tol=1e-6; 1272dc7a7e3SShri Abhyankar 1282dc7a7e3SShri Abhyankar PetscFunctionBegin; 12942ea6711SShri ierr = PetscNew(&event);CHKERRQ(ierr); 130854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->fvalue);CHKERRQ(ierr); 131854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->fvalue_prev);CHKERRQ(ierr); 132854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->direction);CHKERRQ(ierr); 133854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->terminate);CHKERRQ(ierr); 134*e3005195SShri Abhyankar ierr = PetscMalloc1(nevents,&event->vtol);CHKERRQ(ierr); 135d94325d3SShri Abhyankar for (i=0; i < nevents; i++) { 136d94325d3SShri Abhyankar event->direction[i] = direction[i]; 137d94325d3SShri Abhyankar event->terminate[i] = terminate[i]; 138d94325d3SShri Abhyankar } 139854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->events_zero);CHKERRQ(ierr); 1402dc7a7e3SShri Abhyankar event->monitor = eventmonitor; 1412dc7a7e3SShri Abhyankar event->postevent = postevent; 1422dc7a7e3SShri Abhyankar event->monitorcontext = (void*)mectx; 1432dc7a7e3SShri Abhyankar event->nevents = nevents; 1442dc7a7e3SShri Abhyankar 145f7aea88cSShri Abhyankar for(i=0; i < MAXEVENTRECORDERS; i++) { 146f7aea88cSShri Abhyankar ierr = PetscMalloc1(nevents,&event->recorder.eventidx[i]);CHKERRQ(ierr); 147f7aea88cSShri Abhyankar } 148f7aea88cSShri Abhyankar 1492dc7a7e3SShri Abhyankar ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"TS Event options","");CHKERRQ(ierr); 1502dc7a7e3SShri Abhyankar { 151*e3005195SShri Abhyankar ierr = PetscOptionsReal("-ts_event_tol","Scalar event tolerance for zero crossing check","",tol,&tol,NULL);CHKERRQ(ierr); 152006e6a18SShri Abhyankar ierr = PetscOptionsName("-ts_event_monitor","Print choices made by event handler","",&flg);CHKERRQ(ierr); 1532dc7a7e3SShri Abhyankar } 154*e3005195SShri Abhyankar 155*e3005195SShri Abhyankar for(i=0; i < event->nevents; i++) event->vtol[i] = tol; 1562dc7a7e3SShri Abhyankar ierr = PetscOptionsEnd();CHKERRQ(ierr); 157006e6a18SShri Abhyankar 158006e6a18SShri Abhyankar if(flg) { 159006e6a18SShri Abhyankar ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ts),"stdout",&event->mon);CHKERRQ(ierr); 160006e6a18SShri Abhyankar } 161d94325d3SShri Abhyankar ts->event = event; 1622dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 1632dc7a7e3SShri Abhyankar } 1642dc7a7e3SShri Abhyankar 1652dc7a7e3SShri Abhyankar #undef __FUNCT__ 1662dc7a7e3SShri Abhyankar #define __FUNCT__ "TSPostEvent" 167031fbad4SShri Abhyankar /* 168031fbad4SShri Abhyankar TSPostEvent - Does post event processing by calling the user-defined postevent function 169031fbad4SShri Abhyankar 170031fbad4SShri Abhyankar Logically Collective on TS 171031fbad4SShri Abhyankar 172031fbad4SShri Abhyankar Input Parameters: 173031fbad4SShri Abhyankar + ts - the TS context 174031fbad4SShri Abhyankar . nevents_zero - number of local events whose event function is zero 175031fbad4SShri Abhyankar . events_zero - indices of local events which have reached zero 176031fbad4SShri Abhyankar . t - current time 177031fbad4SShri Abhyankar . U - current solution 178031fbad4SShri Abhyankar . forwardsolve - Flag to indicate whether TS is doing a forward solve (1) or adjoint solve (0) 179031fbad4SShri Abhyankar - ctx - the context passed with eventmonitor 180031fbad4SShri Abhyankar 181031fbad4SShri Abhyankar Level: intermediate 182031fbad4SShri Abhyankar 183031fbad4SShri Abhyankar .keywords: TS, event, set, monitor 184031fbad4SShri Abhyankar 185031fbad4SShri Abhyankar .seealso: TSSetEventMonitor(),TSEvent 186031fbad4SShri Abhyankar */ 187031fbad4SShri Abhyankar #undef __FUNCT__ 188031fbad4SShri Abhyankar #define __FUNCT__ "TSPostEvent" 189031fbad4SShri Abhyankar PetscErrorCode TSPostEvent(TS ts,PetscInt nevents_zero,PetscInt events_zero[],PetscReal t,Vec U,PetscBool forwardsolve,void *ctx) 1902dc7a7e3SShri Abhyankar { 1912dc7a7e3SShri Abhyankar PetscErrorCode ierr; 1922dc7a7e3SShri Abhyankar TSEvent event=ts->event; 1932dc7a7e3SShri Abhyankar PetscBool terminate=PETSC_FALSE; 194d0578d90SShri Abhyankar PetscInt i,ctr,stepnum; 1952dc7a7e3SShri Abhyankar PetscBool ts_terminate; 1962dc7a7e3SShri Abhyankar 1972dc7a7e3SShri Abhyankar PetscFunctionBegin; 1982dc7a7e3SShri Abhyankar if (event->postevent) { 199031fbad4SShri Abhyankar ierr = (*event->postevent)(ts,nevents_zero,events_zero,t,U,forwardsolve,ctx);CHKERRQ(ierr); 2002dc7a7e3SShri Abhyankar } 2012dc7a7e3SShri Abhyankar for(i = 0; i < nevents_zero;i++) { 202e105d053SSatish Balay terminate = (PetscBool)(terminate || event->terminate[events_zero[i]]); 2032dc7a7e3SShri Abhyankar } 204b4549700SJed Brown ierr = MPI_Allreduce(&terminate,&ts_terminate,1,MPIU_BOOL,MPI_LOR,((PetscObject)ts)->comm);CHKERRQ(ierr); 2052dc7a7e3SShri Abhyankar if (terminate) { 2062dc7a7e3SShri Abhyankar ierr = TSSetConvergedReason(ts,TS_CONVERGED_EVENT);CHKERRQ(ierr); 2072dc7a7e3SShri Abhyankar event->status = TSEVENT_NONE; 2082dc7a7e3SShri Abhyankar } else { 2092dc7a7e3SShri Abhyankar event->status = TSEVENT_RESET_NEXTSTEP; 2102dc7a7e3SShri Abhyankar } 211f7aea88cSShri Abhyankar 212d0578d90SShri Abhyankar /* Record the event in the event recorder */ 213d0578d90SShri Abhyankar ierr = TSGetTimeStepNumber(ts,&stepnum);CHKERRQ(ierr); 214f7aea88cSShri Abhyankar ctr = event->recorder.ctr; 215f7aea88cSShri Abhyankar if (ctr == MAXEVENTRECORDERS) { 216f7aea88cSShri Abhyankar SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Exceeded limit (=%d) for number of events recorded",MAXEVENTRECORDERS); 217f7aea88cSShri Abhyankar } 218f7aea88cSShri Abhyankar event->recorder.time[ctr] = t; 219d0578d90SShri Abhyankar event->recorder.stepnum[ctr] = stepnum; 220f7aea88cSShri Abhyankar event->recorder.nevents[ctr] = nevents_zero; 221f7aea88cSShri Abhyankar for(i=0; i < nevents_zero; i++) event->recorder.eventidx[ctr][i] = events_zero[i]; 222f7aea88cSShri Abhyankar event->recorder.ctr++; 223f7aea88cSShri Abhyankar 22473967516SShri Abhyankar /* Reset the event residual functions as states might get changed by the postevent callback */ 22573967516SShri Abhyankar ierr = (*event->monitor)(ts,t,U,event->fvalue_prev,event->monitorcontext);CHKERRQ(ierr); 22673967516SShri Abhyankar event->ptime_prev = t; 22773967516SShri Abhyankar 2282dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 2292dc7a7e3SShri Abhyankar } 2302dc7a7e3SShri Abhyankar 2312dc7a7e3SShri Abhyankar #undef __FUNCT__ 2322dc7a7e3SShri Abhyankar #define __FUNCT__ "TSEventMonitorDestroy" 2332dc7a7e3SShri Abhyankar PetscErrorCode TSEventMonitorDestroy(TSEvent *event) 2342dc7a7e3SShri Abhyankar { 2352dc7a7e3SShri Abhyankar PetscErrorCode ierr; 236f7aea88cSShri Abhyankar PetscInt i; 2372dc7a7e3SShri Abhyankar 2382dc7a7e3SShri Abhyankar PetscFunctionBegin; 2392dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->fvalue);CHKERRQ(ierr); 2402dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->fvalue_prev);CHKERRQ(ierr); 2412dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->direction);CHKERRQ(ierr); 242d94325d3SShri Abhyankar ierr = PetscFree((*event)->terminate);CHKERRQ(ierr); 2432dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->events_zero);CHKERRQ(ierr); 244*e3005195SShri Abhyankar ierr = PetscFree((*event)->vtol);CHKERRQ(ierr); 245f7aea88cSShri Abhyankar for(i=0; i < MAXEVENTRECORDERS; i++) { 246302440fdSBarry Smith ierr = PetscFree((*event)->recorder.eventidx[i]);CHKERRQ(ierr); 247f7aea88cSShri Abhyankar } 248006e6a18SShri Abhyankar ierr = PetscViewerDestroy(&(*event)->mon);CHKERRQ(ierr); 2492dc7a7e3SShri Abhyankar ierr = PetscFree(*event);CHKERRQ(ierr); 2502dc7a7e3SShri Abhyankar *event = NULL; 2512dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 2522dc7a7e3SShri Abhyankar } 2532dc7a7e3SShri Abhyankar 2542dc7a7e3SShri Abhyankar #undef __FUNCT__ 2552dc7a7e3SShri Abhyankar #define __FUNCT__ "TSEventMonitor" 2562dc7a7e3SShri Abhyankar PetscErrorCode TSEventMonitor(TS ts) 2572dc7a7e3SShri Abhyankar { 2582dc7a7e3SShri Abhyankar PetscErrorCode ierr; 2592dc7a7e3SShri Abhyankar TSEvent event=ts->event; 2602dc7a7e3SShri Abhyankar PetscReal t; 2612dc7a7e3SShri Abhyankar Vec U; 2622dc7a7e3SShri Abhyankar PetscInt i; 2632dc7a7e3SShri Abhyankar PetscReal dt; 264b4549700SJed Brown TSEventStatus status = event->status; 2652dc7a7e3SShri Abhyankar PetscInt rollback=0,in[2],out[2]; 266031fbad4SShri Abhyankar PetscBool forwardsolve=PETSC_TRUE; /* Flag indicating that TS is doing a forward solve */ 2672dc7a7e3SShri Abhyankar 2682dc7a7e3SShri Abhyankar PetscFunctionBegin; 2692dc7a7e3SShri Abhyankar 2702dc7a7e3SShri Abhyankar ierr = TSGetTime(ts,&t);CHKERRQ(ierr); 2712dc7a7e3SShri Abhyankar ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 2722dc7a7e3SShri Abhyankar 2732dc7a7e3SShri Abhyankar ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr); 2742dc7a7e3SShri Abhyankar if (event->status == TSEVENT_RESET_NEXTSTEP) { 2752dc7a7e3SShri Abhyankar /* Take initial time step */ 2762dc7a7e3SShri Abhyankar dt = event->initial_timestep; 2772dc7a7e3SShri Abhyankar ts->time_step = dt; 2782dc7a7e3SShri Abhyankar event->status = TSEVENT_NONE; 2792dc7a7e3SShri Abhyankar } 2802dc7a7e3SShri Abhyankar 2812dc7a7e3SShri Abhyankar if (event->status == TSEVENT_NONE) { 2822dc7a7e3SShri Abhyankar event->tstepend = t; 2832dc7a7e3SShri Abhyankar } 2842dc7a7e3SShri Abhyankar 2852dc7a7e3SShri Abhyankar event->nevents_zero = 0; 2862dc7a7e3SShri Abhyankar 287d94325d3SShri Abhyankar ierr = (*event->monitor)(ts,t,U,event->fvalue,event->monitorcontext);CHKERRQ(ierr); 2882dc7a7e3SShri Abhyankar for (i=0; i < event->nevents; i++) { 289*e3005195SShri Abhyankar if (PetscAbsScalar(event->fvalue[i]) < event->vtol[i]) { 2902dc7a7e3SShri Abhyankar event->status = TSEVENT_ZERO; 2912dc7a7e3SShri Abhyankar event->events_zero[event->nevents_zero++] = i; 292006e6a18SShri Abhyankar if(event->mon) { 293006e6a18SShri Abhyankar ierr = PetscViewerASCIIPrintf(event->mon,"TSEvent : Event %D zero crossing at time %g\n",i,(double)t);CHKERRQ(ierr); 294006e6a18SShri Abhyankar } 2952dc7a7e3SShri Abhyankar } 2962dc7a7e3SShri Abhyankar } 2972dc7a7e3SShri Abhyankar 2982dc7a7e3SShri Abhyankar status = event->status; 299b4549700SJed Brown ierr = MPI_Allreduce((PetscEnum*)&status,(PetscEnum*)&event->status,1,MPIU_ENUM,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr); 3002dc7a7e3SShri Abhyankar 3012dc7a7e3SShri Abhyankar if (event->status == TSEVENT_ZERO) { 302031fbad4SShri Abhyankar ierr = TSPostEvent(ts,event->nevents_zero,event->events_zero,t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr); 303c540466cSShri Abhyankar dt = event->tstepend-t; 304bcbf8bb3SShri Abhyankar if(PetscAbsReal(dt) < PETSC_SMALL) dt += event->initial_timestep; 30593fbeba1SShri Abhyankar ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr); 3062dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 3072dc7a7e3SShri Abhyankar } 3082dc7a7e3SShri Abhyankar 3092dc7a7e3SShri Abhyankar for (i = 0; i < event->nevents; i++) { 310d94325d3SShri Abhyankar PetscInt fvalue_sign,fvalueprev_sign; 311d94325d3SShri Abhyankar fvalue_sign = PetscSign(PetscRealPart(event->fvalue[i])); 312d94325d3SShri Abhyankar fvalueprev_sign = PetscSign(PetscRealPart(event->fvalue_prev[i])); 313*e3005195SShri Abhyankar if (fvalueprev_sign != 0 && (fvalue_sign != fvalueprev_sign) && (PetscAbsScalar(event->fvalue_prev[i]) > event->vtol[i])) { 314d94325d3SShri Abhyankar switch (event->direction[i]) { 315d94325d3SShri Abhyankar case -1: 316d94325d3SShri Abhyankar if (fvalue_sign < 0) { 3172dc7a7e3SShri Abhyankar rollback = 1; 3182dc7a7e3SShri Abhyankar /* Compute linearly interpolated new time step */ 319e105d053SSatish Balay dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 320006e6a18SShri Abhyankar if(event->mon) { 321006e6a18SShri Abhyankar ierr = PetscViewerASCIIPrintf(event->mon,"TSEvent : Event %D interval located [%g - %g]\n",i,(double)event->ptime_prev,(double)t);CHKERRQ(ierr); 322006e6a18SShri Abhyankar } 3232dc7a7e3SShri Abhyankar } 324d94325d3SShri Abhyankar break; 325d94325d3SShri Abhyankar case 1: 326d94325d3SShri Abhyankar if (fvalue_sign > 0) { 327d94325d3SShri Abhyankar rollback = 1; 328d94325d3SShri Abhyankar /* Compute linearly interpolated new time step */ 329d94325d3SShri Abhyankar dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 330006e6a18SShri Abhyankar if(event->mon) { 331006e6a18SShri Abhyankar ierr = PetscViewerASCIIPrintf(event->mon,"TSEvent : Event %D interval located [%g - %g]\n",i,(double)event->ptime_prev,(double)t);CHKERRQ(ierr); 332006e6a18SShri Abhyankar } 3332dc7a7e3SShri Abhyankar } 334d94325d3SShri Abhyankar break; 335d94325d3SShri Abhyankar case 0: 336d94325d3SShri Abhyankar rollback = 1; 337d94325d3SShri Abhyankar /* Compute linearly interpolated new time step */ 338d94325d3SShri Abhyankar dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 339006e6a18SShri Abhyankar if(event->mon) { 340006e6a18SShri Abhyankar ierr = PetscViewerASCIIPrintf(event->mon,"TSEvent : Event %D interval located [%g - %g]\n",i,(double)event->ptime_prev,(double)t);CHKERRQ(ierr); 341006e6a18SShri Abhyankar } 342d94325d3SShri Abhyankar break; 343d94325d3SShri Abhyankar } 344d94325d3SShri Abhyankar } 345d94325d3SShri Abhyankar } 346d94325d3SShri Abhyankar if (rollback) event->status = TSEVENT_LOCATED_INTERVAL; 347d94325d3SShri Abhyankar 3482dc7a7e3SShri Abhyankar in[0] = event->status; 3492dc7a7e3SShri Abhyankar in[1] = rollback; 3502dc7a7e3SShri Abhyankar ierr = MPI_Allreduce(in,out,2,MPIU_INT,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr); 3512dc7a7e3SShri Abhyankar 3522dc7a7e3SShri Abhyankar rollback = out[1]; 3532dc7a7e3SShri Abhyankar if (rollback) { 3542dc7a7e3SShri Abhyankar event->status = TSEVENT_LOCATED_INTERVAL; 3552dc7a7e3SShri Abhyankar } 3562dc7a7e3SShri Abhyankar 3572dc7a7e3SShri Abhyankar if (event->status == TSEVENT_LOCATED_INTERVAL) { 3582dc7a7e3SShri Abhyankar ierr = TSRollBack(ts);CHKERRQ(ierr); 359c540466cSShri Abhyankar ts->steps--; 360c540466cSShri Abhyankar ts->total_steps--; 361db84a1feSShri Abhyankar ts->reason = TS_CONVERGED_ITERATING; 3622dc7a7e3SShri Abhyankar event->status = TSEVENT_PROCESSING; 3632dc7a7e3SShri Abhyankar } else { 3642dc7a7e3SShri Abhyankar for (i = 0; i < event->nevents; i++) { 3652dc7a7e3SShri Abhyankar event->fvalue_prev[i] = event->fvalue[i]; 3662dc7a7e3SShri Abhyankar } 3672dc7a7e3SShri Abhyankar event->ptime_prev = t; 3682dc7a7e3SShri Abhyankar if (event->status == TSEVENT_PROCESSING) { 3692dc7a7e3SShri Abhyankar dt = event->tstepend - event->ptime_prev; 3702dc7a7e3SShri Abhyankar } 3712dc7a7e3SShri Abhyankar } 372a9b180a6SBarry Smith ierr = MPI_Allreduce(&dt,&(ts->time_step),1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr); 3732dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 3742dc7a7e3SShri Abhyankar } 3752dc7a7e3SShri Abhyankar 376d0578d90SShri Abhyankar #undef __FUNCT__ 377d0578d90SShri Abhyankar #define __FUNCT__ "TSAdjointEventMonitor" 378d0578d90SShri Abhyankar PetscErrorCode TSAdjointEventMonitor(TS ts) 379d0578d90SShri Abhyankar { 380d0578d90SShri Abhyankar PetscErrorCode ierr; 381d0578d90SShri Abhyankar TSEvent event=ts->event; 382d0578d90SShri Abhyankar PetscReal t; 383d0578d90SShri Abhyankar Vec U; 384d0578d90SShri Abhyankar PetscInt ctr; 385d0578d90SShri Abhyankar PetscBool forwardsolve=PETSC_FALSE; /* Flag indicating that TS is doing an adjoint solve */ 386d0578d90SShri Abhyankar 387d0578d90SShri Abhyankar PetscFunctionBegin; 388d0578d90SShri Abhyankar 389d0578d90SShri Abhyankar ierr = TSGetTime(ts,&t);CHKERRQ(ierr); 390d0578d90SShri Abhyankar ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 391d0578d90SShri Abhyankar 392d0578d90SShri Abhyankar ctr = event->recorder.ctr-1; 393bcbf8bb3SShri Abhyankar if(ctr >= 0 && PetscAbsReal(t - event->recorder.time[ctr]) < PETSC_SMALL) { 394d0578d90SShri Abhyankar /* Call the user postevent function */ 395d0578d90SShri Abhyankar if(event->postevent) { 396d0578d90SShri Abhyankar ierr = (*event->postevent)(ts,event->recorder.nevents[ctr],event->recorder.eventidx[ctr],t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr); 397d0578d90SShri Abhyankar event->recorder.ctr--; 398d0578d90SShri Abhyankar } 399d0578d90SShri Abhyankar } 400d0578d90SShri Abhyankar 401d0578d90SShri Abhyankar PetscBarrier((PetscObject)ts); 402d0578d90SShri Abhyankar PetscFunctionReturn(0); 403d0578d90SShri Abhyankar } 404d0578d90SShri Abhyankar 405d0578d90SShri Abhyankar 406d0578d90SShri Abhyankar 407