1af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 22dc7a7e3SShri Abhyankar 32dc7a7e3SShri Abhyankar #undef __FUNCT__ 4*6427ac75SLisandro Dalcin #define __FUNCT__ "TSEventInitialize" 56fea3669SShri Abhyankar /* 6*6427ac75SLisandro Dalcin TSEventInitialize - Initializes TSEvent for TSSolve 76fea3669SShri Abhyankar */ 8*6427ac75SLisandro Dalcin PetscErrorCode TSEventInitialize(TSEvent event,TS ts,PetscReal t,Vec U) 96fea3669SShri Abhyankar { 106fea3669SShri Abhyankar PetscErrorCode ierr; 116fea3669SShri Abhyankar 126fea3669SShri Abhyankar PetscFunctionBegin; 13*6427ac75SLisandro Dalcin if (!event) PetscFunctionReturn(0); 14*6427ac75SLisandro Dalcin PetscValidPointer(event,1); 15*6427ac75SLisandro Dalcin PetscValidHeaderSpecific(ts,TS_CLASSID,2); 16*6427ac75SLisandro Dalcin PetscValidHeaderSpecific(U,VEC_CLASSID,4); 176fea3669SShri Abhyankar 186fea3669SShri Abhyankar ierr = TSGetTimeStep(ts,&event->initial_timestep);CHKERRQ(ierr); 196fea3669SShri Abhyankar event->ptime_prev = t; 20*6427ac75SLisandro Dalcin ierr = (*event->eventhandler)(ts,t,U,event->fvalue_prev,event->ctx);CHKERRQ(ierr); 216fea3669SShri Abhyankar /* Initialize the event recorder */ 226fea3669SShri Abhyankar event->recorder.ctr = 0; 236fea3669SShri Abhyankar PetscFunctionReturn(0); 246fea3669SShri Abhyankar } 256fea3669SShri Abhyankar 266fea3669SShri Abhyankar #undef __FUNCT__ 27e3005195SShri Abhyankar #define __FUNCT__ "TSSetEventTolerances" 28e3005195SShri Abhyankar /*@ 29e3005195SShri Abhyankar TSSetEventTolerances - Set tolerances for event zero crossings when using event handler 30e3005195SShri Abhyankar 31e3005195SShri Abhyankar Logically Collective 32e3005195SShri Abhyankar 33e3005195SShri Abhyankar Input Arguments: 34e3005195SShri Abhyankar + ts - time integration context 35e3005195SShri Abhyankar . tol - scalar tolerance, PETSC_DECIDE to leave current value 36e3005195SShri Abhyankar - vtol - array of tolerances or NULL, used in preference to tol if present 37e3005195SShri Abhyankar 38e3005195SShri Abhyankar - -ts_event_tol <tol> tolerance for event zero crossing 39e3005195SShri Abhyankar 40e3005195SShri Abhyankar Notes: 41e3005195SShri Abhyankar Must call TSSetEventMonitor() before setting the tolerances. 42e3005195SShri Abhyankar 43e3005195SShri Abhyankar The size of vtol is equal to the number of events. 44e3005195SShri Abhyankar 45e3005195SShri Abhyankar Level: beginner 46e3005195SShri Abhyankar 47e3005195SShri Abhyankar .seealso: TS, TSEvent, TSSetEventMonitor() 48e3005195SShri Abhyankar @*/ 49*6427ac75SLisandro Dalcin PetscErrorCode TSSetEventTolerances(TS ts,PetscReal tol,PetscReal vtol[]) 50e3005195SShri Abhyankar { 51*6427ac75SLisandro Dalcin TSEvent event; 52e3005195SShri Abhyankar PetscInt i; 53e3005195SShri Abhyankar 54e3005195SShri Abhyankar PetscFunctionBegin; 55*6427ac75SLisandro Dalcin PetscValidHeaderSpecific(ts,TS_CLASSID,1); 56*6427ac75SLisandro Dalcin if (vtol) PetscValidRealPointer(vtol,3); 57e3005195SShri Abhyankar if(!ts->event) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must set the events first by calling TSSetEventMonitor()"); 58*6427ac75SLisandro Dalcin 59*6427ac75SLisandro Dalcin event = ts->event; 60e3005195SShri Abhyankar if (vtol) { 61e3005195SShri Abhyankar for (i=0; i < event->nevents; i++) event->vtol[i] = vtol[i]; 62e3005195SShri Abhyankar } else { 63e3005195SShri Abhyankar if (tol != PETSC_DECIDE || tol != PETSC_DEFAULT) { 64e3005195SShri Abhyankar for (i=0; i < event->nevents; i++) event->vtol[i] = tol; 65e3005195SShri Abhyankar } 66e3005195SShri Abhyankar } 67e3005195SShri Abhyankar PetscFunctionReturn(0); 68e3005195SShri Abhyankar } 69e3005195SShri Abhyankar 70e3005195SShri 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) 84*6427ac75SLisandro Dalcin . eventhandler - 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 90*6427ac75SLisandro Dalcin Calling sequence of eventhandler: 91*6427ac75SLisandro Dalcin PetscErrorCode EventHandler(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 97*6427ac75SLisandro Dalcin - ctx - [optional] context passed with eventhandler 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) 112*6427ac75SLisandro Dalcin - ctx - the context passed with eventhandler 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 @*/ 120*6427ac75SLisandro Dalcin PetscErrorCode TSSetEventMonitor(TS ts,PetscInt nevents,PetscInt direction[],PetscBool terminate[],PetscErrorCode (*eventhandler)(TS,PetscReal,Vec,PetscScalar*,void*),PetscErrorCode (*postevent)(TS,PetscInt,PetscInt[],PetscReal,Vec,PetscBool,void*),void *ctx) 1212dc7a7e3SShri Abhyankar { 1222dc7a7e3SShri Abhyankar PetscErrorCode ierr; 1232dc7a7e3SShri Abhyankar TSEvent event; 124d94325d3SShri Abhyankar PetscInt i; 125006e6a18SShri Abhyankar PetscBool flg; 126e3005195SShri Abhyankar PetscReal tol=1e-6; 1272dc7a7e3SShri Abhyankar 1282dc7a7e3SShri Abhyankar PetscFunctionBegin; 129*6427ac75SLisandro Dalcin PetscValidHeaderSpecific(ts,TS_CLASSID,1); 130*6427ac75SLisandro Dalcin PetscValidIntPointer(direction,2); 131*6427ac75SLisandro Dalcin PetscValidIntPointer(terminate,3); 132*6427ac75SLisandro Dalcin 133*6427ac75SLisandro Dalcin ierr = PetscNewLog(ts,&event);CHKERRQ(ierr); 134854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->fvalue);CHKERRQ(ierr); 135854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->fvalue_prev);CHKERRQ(ierr); 136854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->direction);CHKERRQ(ierr); 137854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->terminate);CHKERRQ(ierr); 138e3005195SShri Abhyankar ierr = PetscMalloc1(nevents,&event->vtol);CHKERRQ(ierr); 139d94325d3SShri Abhyankar for (i=0; i < nevents; i++) { 140d94325d3SShri Abhyankar event->direction[i] = direction[i]; 141d94325d3SShri Abhyankar event->terminate[i] = terminate[i]; 142d94325d3SShri Abhyankar } 143854ce69bSBarry Smith ierr = PetscMalloc1(nevents,&event->events_zero);CHKERRQ(ierr); 144*6427ac75SLisandro Dalcin event->eventhandler = eventhandler; 1452dc7a7e3SShri Abhyankar event->postevent = postevent; 146*6427ac75SLisandro Dalcin event->ctx = ctx; 1472dc7a7e3SShri Abhyankar event->nevents = nevents; 1482dc7a7e3SShri Abhyankar 149f7aea88cSShri Abhyankar for (i=0; i < MAXEVENTRECORDERS; i++) { 150f7aea88cSShri Abhyankar ierr = PetscMalloc1(nevents,&event->recorder.eventidx[i]);CHKERRQ(ierr); 151f7aea88cSShri Abhyankar } 152f7aea88cSShri Abhyankar 153a9514d71SShri Abhyankar ierr = PetscOptionsBegin(((PetscObject)ts)->comm,"","TS Event options","");CHKERRQ(ierr); 1542dc7a7e3SShri Abhyankar { 155e3005195SShri Abhyankar ierr = PetscOptionsReal("-ts_event_tol","Scalar event tolerance for zero crossing check","",tol,&tol,NULL);CHKERRQ(ierr); 156006e6a18SShri Abhyankar ierr = PetscOptionsName("-ts_event_monitor","Print choices made by event handler","",&flg);CHKERRQ(ierr); 1572dc7a7e3SShri Abhyankar } 1589e12be75SShri Abhyankar PetscOptionsEnd(); 159e3005195SShri Abhyankar for (i=0; i < event->nevents; i++) event->vtol[i] = tol; 160*6427ac75SLisandro Dalcin if (flg) {ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,"stdout",&event->monitor);CHKERRQ(ierr);} 1619e12be75SShri Abhyankar 162*6427ac75SLisandro Dalcin ierr = TSEventDestroy(&ts->event);CHKERRQ(ierr); 163d94325d3SShri Abhyankar ts->event = event; 1642dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 1652dc7a7e3SShri Abhyankar } 1662dc7a7e3SShri Abhyankar 1672dc7a7e3SShri Abhyankar #undef __FUNCT__ 1682dc7a7e3SShri Abhyankar #define __FUNCT__ "TSPostEvent" 169031fbad4SShri Abhyankar /* 170031fbad4SShri Abhyankar TSPostEvent - Does post event processing by calling the user-defined postevent function 171031fbad4SShri Abhyankar 172031fbad4SShri Abhyankar Logically Collective on TS 173031fbad4SShri Abhyankar 174031fbad4SShri Abhyankar Input Parameters: 175031fbad4SShri Abhyankar + ts - the TS context 176031fbad4SShri Abhyankar . nevents_zero - number of local events whose event function is zero 177031fbad4SShri Abhyankar . events_zero - indices of local events which have reached zero 178031fbad4SShri Abhyankar . t - current time 179031fbad4SShri Abhyankar . U - current solution 180*6427ac75SLisandro Dalcin - forwardsolve - Flag to indicate whether TS is doing a forward solve (1) or adjoint solve (0) 181031fbad4SShri Abhyankar 182031fbad4SShri Abhyankar Level: intermediate 183031fbad4SShri Abhyankar 184031fbad4SShri Abhyankar .keywords: TS, event, set, monitor 185031fbad4SShri Abhyankar 186031fbad4SShri Abhyankar .seealso: TSSetEventMonitor(),TSEvent 187031fbad4SShri Abhyankar */ 188031fbad4SShri Abhyankar #undef __FUNCT__ 189031fbad4SShri Abhyankar #define __FUNCT__ "TSPostEvent" 190*6427ac75SLisandro Dalcin PetscErrorCode TSPostEvent(TS ts,PetscInt nevents_zero,PetscInt events_zero[],PetscReal t,Vec U,PetscBool forwardsolve) 1912dc7a7e3SShri Abhyankar { 1922dc7a7e3SShri Abhyankar PetscErrorCode ierr; 1932dc7a7e3SShri Abhyankar TSEvent event=ts->event; 1942dc7a7e3SShri Abhyankar PetscBool terminate=PETSC_FALSE; 195d0578d90SShri Abhyankar PetscInt i,ctr,stepnum; 1962dc7a7e3SShri Abhyankar PetscBool ts_terminate; 1972dc7a7e3SShri Abhyankar 1982dc7a7e3SShri Abhyankar PetscFunctionBegin; 1992dc7a7e3SShri Abhyankar if (event->postevent) { 200*6427ac75SLisandro Dalcin ierr = (*event->postevent)(ts,nevents_zero,events_zero,t,U,forwardsolve,event->ctx);CHKERRQ(ierr); 2012dc7a7e3SShri Abhyankar } 2022dc7a7e3SShri Abhyankar for(i = 0; i < nevents_zero;i++) { 203e105d053SSatish Balay terminate = (PetscBool)(terminate || event->terminate[events_zero[i]]); 2042dc7a7e3SShri Abhyankar } 205b2566f29SBarry Smith ierr = MPIU_Allreduce(&terminate,&ts_terminate,1,MPIU_BOOL,MPI_LOR,((PetscObject)ts)->comm);CHKERRQ(ierr); 2069e12be75SShri Abhyankar if (ts_terminate) { 2072dc7a7e3SShri Abhyankar ierr = TSSetConvergedReason(ts,TS_CONVERGED_EVENT);CHKERRQ(ierr); 2082dc7a7e3SShri Abhyankar event->status = TSEVENT_NONE; 2092dc7a7e3SShri Abhyankar } else { 2102dc7a7e3SShri Abhyankar event->status = TSEVENT_RESET_NEXTSTEP; 2112dc7a7e3SShri Abhyankar } 212f7aea88cSShri Abhyankar 213d0578d90SShri Abhyankar /* Record the event in the event recorder */ 214d0578d90SShri Abhyankar ierr = TSGetTimeStepNumber(ts,&stepnum);CHKERRQ(ierr); 215f7aea88cSShri Abhyankar ctr = event->recorder.ctr; 2166c4ed002SBarry Smith if (ctr == MAXEVENTRECORDERS) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Exceeded limit (=%d) for number of events recorded",MAXEVENTRECORDERS); 217f7aea88cSShri Abhyankar event->recorder.time[ctr] = t; 218d0578d90SShri Abhyankar event->recorder.stepnum[ctr] = stepnum; 219f7aea88cSShri Abhyankar event->recorder.nevents[ctr] = nevents_zero; 220f7aea88cSShri Abhyankar for(i=0; i < nevents_zero; i++) event->recorder.eventidx[ctr][i] = events_zero[i]; 221f7aea88cSShri Abhyankar event->recorder.ctr++; 222f7aea88cSShri Abhyankar 22373967516SShri Abhyankar /* Reset the event residual functions as states might get changed by the postevent callback */ 224*6427ac75SLisandro Dalcin ierr = (*event->eventhandler)(ts,t,U,event->fvalue_prev,event->ctx);CHKERRQ(ierr); 22573967516SShri Abhyankar event->ptime_prev = t; 2262dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 2272dc7a7e3SShri Abhyankar } 2282dc7a7e3SShri Abhyankar 2292dc7a7e3SShri Abhyankar #undef __FUNCT__ 230*6427ac75SLisandro Dalcin #define __FUNCT__ "TSEventDestroy" 231*6427ac75SLisandro Dalcin PetscErrorCode TSEventDestroy(TSEvent *event) 2322dc7a7e3SShri Abhyankar { 2332dc7a7e3SShri Abhyankar PetscErrorCode ierr; 234f7aea88cSShri Abhyankar PetscInt i; 2352dc7a7e3SShri Abhyankar 2362dc7a7e3SShri Abhyankar PetscFunctionBegin; 237*6427ac75SLisandro Dalcin PetscValidPointer(event,1); 238*6427ac75SLisandro Dalcin if (!*event) PetscFunctionReturn(0); 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); 244e3005195SShri 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 } 248*6427ac75SLisandro Dalcin ierr = PetscViewerDestroy(&(*event)->monitor);CHKERRQ(ierr); 2492dc7a7e3SShri Abhyankar ierr = PetscFree(*event);CHKERRQ(ierr); 2502dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 2512dc7a7e3SShri Abhyankar } 2522dc7a7e3SShri Abhyankar 2532dc7a7e3SShri Abhyankar #undef __FUNCT__ 254*6427ac75SLisandro Dalcin #define __FUNCT__ "TSEventHandler" 255*6427ac75SLisandro Dalcin PetscErrorCode TSEventHandler(TS ts) 2562dc7a7e3SShri Abhyankar { 2572dc7a7e3SShri Abhyankar PetscErrorCode ierr; 258*6427ac75SLisandro Dalcin TSEvent event; 2592dc7a7e3SShri Abhyankar PetscReal t; 2602dc7a7e3SShri Abhyankar Vec U; 2612dc7a7e3SShri Abhyankar PetscInt i; 2622dc7a7e3SShri Abhyankar PetscReal dt; 2632dc7a7e3SShri Abhyankar PetscInt rollback=0,in[2],out[2]; 264031fbad4SShri Abhyankar PetscBool forwardsolve=PETSC_TRUE; /* Flag indicating that TS is doing a forward solve */ 2659e12be75SShri Abhyankar PetscInt fvalue_sign,fvalueprev_sign; 2662dc7a7e3SShri Abhyankar 2672dc7a7e3SShri Abhyankar PetscFunctionBegin; 268*6427ac75SLisandro Dalcin PetscValidHeaderSpecific(ts,TS_CLASSID,1); 269*6427ac75SLisandro Dalcin if (!ts->event) PetscFunctionReturn(0); 270*6427ac75SLisandro Dalcin event = ts->event; 2712dc7a7e3SShri Abhyankar 2722dc7a7e3SShri Abhyankar ierr = TSGetTime(ts,&t);CHKERRQ(ierr); 2732dc7a7e3SShri Abhyankar ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 2742dc7a7e3SShri Abhyankar 2752dc7a7e3SShri Abhyankar ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr); 2762dc7a7e3SShri Abhyankar if (event->status == TSEVENT_RESET_NEXTSTEP) { 2772dc7a7e3SShri Abhyankar /* Take initial time step */ 2782dc7a7e3SShri Abhyankar dt = event->initial_timestep; 2792dc7a7e3SShri Abhyankar ts->time_step = dt; 2802dc7a7e3SShri Abhyankar event->status = TSEVENT_NONE; 2812dc7a7e3SShri Abhyankar } 2822dc7a7e3SShri Abhyankar 2832dc7a7e3SShri Abhyankar if (event->status == TSEVENT_NONE) { 2842dc7a7e3SShri Abhyankar event->tstepend = t; 2852dc7a7e3SShri Abhyankar } 2862dc7a7e3SShri Abhyankar 2872dc7a7e3SShri Abhyankar event->nevents_zero = 0; 2882dc7a7e3SShri Abhyankar 289*6427ac75SLisandro Dalcin ierr = (*event->eventhandler)(ts,t,U,event->fvalue,event->ctx);CHKERRQ(ierr); 2909e12be75SShri Abhyankar 2912dc7a7e3SShri Abhyankar for (i = 0; i < event->nevents; i++) { 292e3005195SShri Abhyankar if (PetscAbsScalar(event->fvalue[i]) < event->vtol[i]) { 2932dc7a7e3SShri Abhyankar event->status = TSEVENT_ZERO; 2949e12be75SShri Abhyankar continue; 295006e6a18SShri Abhyankar } 296d94325d3SShri Abhyankar fvalue_sign = PetscSign(PetscRealPart(event->fvalue[i])); 297d94325d3SShri Abhyankar fvalueprev_sign = PetscSign(PetscRealPart(event->fvalue_prev[i])); 298e3005195SShri Abhyankar if (fvalueprev_sign != 0 && (fvalue_sign != fvalueprev_sign) && (PetscAbsScalar(event->fvalue_prev[i]) > event->vtol[i])) { 299d94325d3SShri Abhyankar switch (event->direction[i]) { 300d94325d3SShri Abhyankar case -1: 301d94325d3SShri Abhyankar if (fvalue_sign < 0) { 3022dc7a7e3SShri Abhyankar rollback = 1; 3032dc7a7e3SShri Abhyankar /* Compute linearly interpolated new time step */ 304e105d053SSatish Balay dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 305*6427ac75SLisandro Dalcin if(event->monitor) { 306*6427ac75SLisandro Dalcin ierr = PetscViewerASCIIPrintf(event->monitor,"TSEvent : Event %D interval located [%g - %g]\n",i,(double)event->ptime_prev,(double)t);CHKERRQ(ierr); 307006e6a18SShri Abhyankar } 3082dc7a7e3SShri Abhyankar } 309d94325d3SShri Abhyankar break; 310d94325d3SShri Abhyankar case 1: 311d94325d3SShri Abhyankar if (fvalue_sign > 0) { 312d94325d3SShri Abhyankar rollback = 1; 313d94325d3SShri Abhyankar /* Compute linearly interpolated new time step */ 314d94325d3SShri Abhyankar dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 315*6427ac75SLisandro Dalcin if(event->monitor) { 316*6427ac75SLisandro Dalcin ierr = PetscViewerASCIIPrintf(event->monitor,"TSEvent : Event %D interval located [%g - %g]\n",i,(double)event->ptime_prev,(double)t);CHKERRQ(ierr); 317006e6a18SShri Abhyankar } 3182dc7a7e3SShri Abhyankar } 319d94325d3SShri Abhyankar break; 320d94325d3SShri Abhyankar case 0: 321d94325d3SShri Abhyankar rollback = 1; 322d94325d3SShri Abhyankar /* Compute linearly interpolated new time step */ 323d94325d3SShri Abhyankar dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 324*6427ac75SLisandro Dalcin if(event->monitor) { 325*6427ac75SLisandro Dalcin ierr = PetscViewerASCIIPrintf(event->monitor,"TSEvent : Event %D interval located [%g - %g]\n",i,(double)event->ptime_prev,(double)t);CHKERRQ(ierr); 326006e6a18SShri Abhyankar } 327d94325d3SShri Abhyankar break; 328d94325d3SShri Abhyankar } 329d94325d3SShri Abhyankar } 330d94325d3SShri Abhyankar } 331d94325d3SShri Abhyankar if (rollback) event->status = TSEVENT_LOCATED_INTERVAL; 332d94325d3SShri Abhyankar 3332dc7a7e3SShri Abhyankar in[0] = event->status; 3342dc7a7e3SShri Abhyankar in[1] = rollback; 335b2566f29SBarry Smith ierr = MPIU_Allreduce(in,out,2,MPIU_INT,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr); 3362dc7a7e3SShri Abhyankar 337128a6747SShri Abhyankar event->status = (TSEventStatus)out[0]; 3382dc7a7e3SShri Abhyankar rollback = out[1]; 3392dc7a7e3SShri Abhyankar if (rollback) { 3402dc7a7e3SShri Abhyankar event->status = TSEVENT_LOCATED_INTERVAL; 3412dc7a7e3SShri Abhyankar } 3422dc7a7e3SShri Abhyankar 3439e12be75SShri Abhyankar if (event->status == TSEVENT_ZERO) { 3449e12be75SShri Abhyankar for(i=0; i < event->nevents; i++) { 3459e12be75SShri Abhyankar if (PetscAbsScalar(event->fvalue[i]) < event->vtol[i]) { 3469e12be75SShri Abhyankar event->events_zero[event->nevents_zero++] = i; 347*6427ac75SLisandro Dalcin if(event->monitor) { 348*6427ac75SLisandro Dalcin ierr = PetscViewerASCIIPrintf(event->monitor,"TSEvent : Event %D zero crossing at time %g\n",i,(double)t);CHKERRQ(ierr); 3499e12be75SShri Abhyankar } 3509e12be75SShri Abhyankar } 3519e12be75SShri Abhyankar } 3529e12be75SShri Abhyankar 353*6427ac75SLisandro Dalcin ierr = TSPostEvent(ts,event->nevents_zero,event->events_zero,t,U,forwardsolve);CHKERRQ(ierr); 3549e12be75SShri Abhyankar 3559e12be75SShri Abhyankar dt = event->tstepend-t; 3569e12be75SShri Abhyankar if(PetscAbsReal(dt) < PETSC_SMALL) dt += event->initial_timestep; 3579e12be75SShri Abhyankar ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr); 3589e12be75SShri Abhyankar PetscFunctionReturn(0); 3599e12be75SShri Abhyankar } 3609e12be75SShri Abhyankar 3612dc7a7e3SShri Abhyankar if (event->status == TSEVENT_LOCATED_INTERVAL) { 3622dc7a7e3SShri Abhyankar ierr = TSRollBack(ts);CHKERRQ(ierr); 363c540466cSShri Abhyankar ts->steps--; 364c540466cSShri Abhyankar ts->total_steps--; 365db84a1feSShri Abhyankar ts->reason = TS_CONVERGED_ITERATING; 3662dc7a7e3SShri Abhyankar event->status = TSEVENT_PROCESSING; 3672dc7a7e3SShri Abhyankar } else { 3682dc7a7e3SShri Abhyankar for (i = 0; i < event->nevents; i++) { 3692dc7a7e3SShri Abhyankar event->fvalue_prev[i] = event->fvalue[i]; 3702dc7a7e3SShri Abhyankar } 3712dc7a7e3SShri Abhyankar event->ptime_prev = t; 3722dc7a7e3SShri Abhyankar if (event->status == TSEVENT_PROCESSING) { 3732dc7a7e3SShri Abhyankar dt = event->tstepend - event->ptime_prev; 3742dc7a7e3SShri Abhyankar } 3752dc7a7e3SShri Abhyankar } 3769e12be75SShri Abhyankar 377b2566f29SBarry Smith ierr = MPIU_Allreduce(&dt,&(ts->time_step),1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr); 3782dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 3792dc7a7e3SShri Abhyankar } 3802dc7a7e3SShri Abhyankar 381d0578d90SShri Abhyankar #undef __FUNCT__ 382*6427ac75SLisandro Dalcin #define __FUNCT__ "TSAdjointEventHandler" 383*6427ac75SLisandro Dalcin PetscErrorCode TSAdjointEventHandler(TS ts) 384d0578d90SShri Abhyankar { 385d0578d90SShri Abhyankar PetscErrorCode ierr; 386*6427ac75SLisandro Dalcin TSEvent event; 387d0578d90SShri Abhyankar PetscReal t; 388d0578d90SShri Abhyankar Vec U; 389d0578d90SShri Abhyankar PetscInt ctr; 390d0578d90SShri Abhyankar PetscBool forwardsolve=PETSC_FALSE; /* Flag indicating that TS is doing an adjoint solve */ 391d0578d90SShri Abhyankar 392d0578d90SShri Abhyankar PetscFunctionBegin; 393*6427ac75SLisandro Dalcin PetscValidHeaderSpecific(ts,TS_CLASSID,1); 394*6427ac75SLisandro Dalcin if (!ts->event) PetscFunctionReturn(0); 395*6427ac75SLisandro Dalcin event = ts->event; 396d0578d90SShri Abhyankar 397d0578d90SShri Abhyankar ierr = TSGetTime(ts,&t);CHKERRQ(ierr); 398d0578d90SShri Abhyankar ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 399d0578d90SShri Abhyankar 400d0578d90SShri Abhyankar ctr = event->recorder.ctr-1; 401bcbf8bb3SShri Abhyankar if(ctr >= 0 && PetscAbsReal(t - event->recorder.time[ctr]) < PETSC_SMALL) { 402d0578d90SShri Abhyankar /* Call the user postevent function */ 403d0578d90SShri Abhyankar if(event->postevent) { 404*6427ac75SLisandro Dalcin ierr = (*event->postevent)(ts,event->recorder.nevents[ctr],event->recorder.eventidx[ctr],t,U,forwardsolve,event->ctx);CHKERRQ(ierr); 405d0578d90SShri Abhyankar event->recorder.ctr--; 406d0578d90SShri Abhyankar } 407d0578d90SShri Abhyankar } 408d0578d90SShri Abhyankar 409d0578d90SShri Abhyankar PetscBarrier((PetscObject)ts); 410d0578d90SShri Abhyankar PetscFunctionReturn(0); 411d0578d90SShri Abhyankar } 412