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__ 31e3005195SShri Abhyankar #define __FUNCT__ "TSSetEventTolerances" 32e3005195SShri Abhyankar /*@ 33e3005195SShri Abhyankar TSSetEventTolerances - Set tolerances for event zero crossings when using event handler 34e3005195SShri Abhyankar 35e3005195SShri Abhyankar Logically Collective 36e3005195SShri Abhyankar 37e3005195SShri Abhyankar Input Arguments: 38e3005195SShri Abhyankar + ts - time integration context 39e3005195SShri Abhyankar . tol - scalar tolerance, PETSC_DECIDE to leave current value 40e3005195SShri Abhyankar - vtol - array of tolerances or NULL, used in preference to tol if present 41e3005195SShri Abhyankar 42e3005195SShri Abhyankar - -ts_event_tol <tol> tolerance for event zero crossing 43e3005195SShri Abhyankar 44e3005195SShri Abhyankar Notes: 45e3005195SShri Abhyankar Must call TSSetEventMonitor() before setting the tolerances. 46e3005195SShri Abhyankar 47e3005195SShri Abhyankar The size of vtol is equal to the number of events. 48e3005195SShri Abhyankar 49e3005195SShri Abhyankar Level: beginner 50e3005195SShri Abhyankar 51e3005195SShri Abhyankar .seealso: TS, TSEvent, TSSetEventMonitor() 52e3005195SShri Abhyankar @*/ 53e3005195SShri Abhyankar PetscErrorCode TSSetEventTolerances(TS ts,PetscReal tol,PetscReal *vtol) 54e3005195SShri Abhyankar { 55e3005195SShri Abhyankar TSEvent event=ts->event; 56e3005195SShri Abhyankar PetscInt i; 57e3005195SShri Abhyankar 58e3005195SShri Abhyankar PetscFunctionBegin; 59e3005195SShri Abhyankar if(!ts->event) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must set the events first by calling TSSetEventMonitor()"); 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) 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; 126e3005195SShri 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); 134e3005195SShri 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 149a9514d71SShri Abhyankar ierr = PetscOptionsBegin(((PetscObject)ts)->comm,"","TS Event options","");CHKERRQ(ierr); 1502dc7a7e3SShri Abhyankar { 151e3005195SShri 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 } 1549e12be75SShri Abhyankar PetscOptionsEnd(); 155e3005195SShri Abhyankar 156e3005195SShri Abhyankar for(i=0; i < event->nevents; i++) event->vtol[i] = tol; 1579e12be75SShri Abhyankar 158006e6a18SShri Abhyankar 159006e6a18SShri Abhyankar if(flg) { 1609e12be75SShri Abhyankar ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,"stdout",&event->mon);CHKERRQ(ierr); 161006e6a18SShri Abhyankar } 162d94325d3SShri Abhyankar ts->event = event; 1632dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 1642dc7a7e3SShri Abhyankar } 1652dc7a7e3SShri Abhyankar 1662dc7a7e3SShri Abhyankar #undef __FUNCT__ 1672dc7a7e3SShri Abhyankar #define __FUNCT__ "TSPostEvent" 168031fbad4SShri Abhyankar /* 169031fbad4SShri Abhyankar TSPostEvent - Does post event processing by calling the user-defined postevent function 170031fbad4SShri Abhyankar 171031fbad4SShri Abhyankar Logically Collective on TS 172031fbad4SShri Abhyankar 173031fbad4SShri Abhyankar Input Parameters: 174031fbad4SShri Abhyankar + ts - the TS context 175031fbad4SShri Abhyankar . nevents_zero - number of local events whose event function is zero 176031fbad4SShri Abhyankar . events_zero - indices of local events which have reached zero 177031fbad4SShri Abhyankar . t - current time 178031fbad4SShri Abhyankar . U - current solution 179031fbad4SShri Abhyankar . forwardsolve - Flag to indicate whether TS is doing a forward solve (1) or adjoint solve (0) 180031fbad4SShri Abhyankar - ctx - the context passed with eventmonitor 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" 190031fbad4SShri Abhyankar PetscErrorCode TSPostEvent(TS ts,PetscInt nevents_zero,PetscInt events_zero[],PetscReal t,Vec U,PetscBool forwardsolve,void *ctx) 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) { 200031fbad4SShri Abhyankar ierr = (*event->postevent)(ts,nevents_zero,events_zero,t,U,forwardsolve,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 } 205*b2566f29SBarry 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 */ 22473967516SShri Abhyankar ierr = (*event->monitor)(ts,t,U,event->fvalue_prev,event->monitorcontext);CHKERRQ(ierr); 22573967516SShri Abhyankar event->ptime_prev = t; 22673967516SShri Abhyankar 2272dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 2282dc7a7e3SShri Abhyankar } 2292dc7a7e3SShri Abhyankar 2302dc7a7e3SShri Abhyankar #undef __FUNCT__ 2312dc7a7e3SShri Abhyankar #define __FUNCT__ "TSEventMonitorDestroy" 2322dc7a7e3SShri Abhyankar PetscErrorCode TSEventMonitorDestroy(TSEvent *event) 2332dc7a7e3SShri Abhyankar { 2342dc7a7e3SShri Abhyankar PetscErrorCode ierr; 235f7aea88cSShri Abhyankar PetscInt i; 2362dc7a7e3SShri Abhyankar 2372dc7a7e3SShri Abhyankar PetscFunctionBegin; 2382dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->fvalue);CHKERRQ(ierr); 2392dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->fvalue_prev);CHKERRQ(ierr); 2402dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->direction);CHKERRQ(ierr); 241d94325d3SShri Abhyankar ierr = PetscFree((*event)->terminate);CHKERRQ(ierr); 2422dc7a7e3SShri Abhyankar ierr = PetscFree((*event)->events_zero);CHKERRQ(ierr); 243e3005195SShri Abhyankar ierr = PetscFree((*event)->vtol);CHKERRQ(ierr); 244f7aea88cSShri Abhyankar for(i=0; i < MAXEVENTRECORDERS; i++) { 245302440fdSBarry Smith ierr = PetscFree((*event)->recorder.eventidx[i]);CHKERRQ(ierr); 246f7aea88cSShri Abhyankar } 247006e6a18SShri Abhyankar ierr = PetscViewerDestroy(&(*event)->mon);CHKERRQ(ierr); 2482dc7a7e3SShri Abhyankar ierr = PetscFree(*event);CHKERRQ(ierr); 2492dc7a7e3SShri Abhyankar *event = NULL; 2502dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 2512dc7a7e3SShri Abhyankar } 2522dc7a7e3SShri Abhyankar 2532dc7a7e3SShri Abhyankar #undef __FUNCT__ 2542dc7a7e3SShri Abhyankar #define __FUNCT__ "TSEventMonitor" 2552dc7a7e3SShri Abhyankar PetscErrorCode TSEventMonitor(TS ts) 2562dc7a7e3SShri Abhyankar { 2572dc7a7e3SShri Abhyankar PetscErrorCode ierr; 2582dc7a7e3SShri Abhyankar TSEvent event=ts->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; 2682dc7a7e3SShri Abhyankar 2692dc7a7e3SShri Abhyankar ierr = TSGetTime(ts,&t);CHKERRQ(ierr); 2702dc7a7e3SShri Abhyankar ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 2712dc7a7e3SShri Abhyankar 2722dc7a7e3SShri Abhyankar ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr); 2732dc7a7e3SShri Abhyankar if (event->status == TSEVENT_RESET_NEXTSTEP) { 2742dc7a7e3SShri Abhyankar /* Take initial time step */ 2752dc7a7e3SShri Abhyankar dt = event->initial_timestep; 2762dc7a7e3SShri Abhyankar ts->time_step = dt; 2772dc7a7e3SShri Abhyankar event->status = TSEVENT_NONE; 2782dc7a7e3SShri Abhyankar } 2792dc7a7e3SShri Abhyankar 2802dc7a7e3SShri Abhyankar if (event->status == TSEVENT_NONE) { 2812dc7a7e3SShri Abhyankar event->tstepend = t; 2822dc7a7e3SShri Abhyankar } 2832dc7a7e3SShri Abhyankar 2842dc7a7e3SShri Abhyankar event->nevents_zero = 0; 2852dc7a7e3SShri Abhyankar 286d94325d3SShri Abhyankar ierr = (*event->monitor)(ts,t,U,event->fvalue,event->monitorcontext);CHKERRQ(ierr); 2879e12be75SShri Abhyankar 2882dc7a7e3SShri Abhyankar for (i = 0; i < event->nevents; i++) { 289e3005195SShri Abhyankar if (PetscAbsScalar(event->fvalue[i]) < event->vtol[i]) { 2902dc7a7e3SShri Abhyankar event->status = TSEVENT_ZERO; 2919e12be75SShri Abhyankar continue; 292006e6a18SShri Abhyankar } 293d94325d3SShri Abhyankar fvalue_sign = PetscSign(PetscRealPart(event->fvalue[i])); 294d94325d3SShri Abhyankar fvalueprev_sign = PetscSign(PetscRealPart(event->fvalue_prev[i])); 295e3005195SShri Abhyankar if (fvalueprev_sign != 0 && (fvalue_sign != fvalueprev_sign) && (PetscAbsScalar(event->fvalue_prev[i]) > event->vtol[i])) { 296d94325d3SShri Abhyankar switch (event->direction[i]) { 297d94325d3SShri Abhyankar case -1: 298d94325d3SShri Abhyankar if (fvalue_sign < 0) { 2992dc7a7e3SShri Abhyankar rollback = 1; 3002dc7a7e3SShri Abhyankar /* Compute linearly interpolated new time step */ 301e105d053SSatish Balay dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 302006e6a18SShri Abhyankar if(event->mon) { 303006e6a18SShri Abhyankar ierr = PetscViewerASCIIPrintf(event->mon,"TSEvent : Event %D interval located [%g - %g]\n",i,(double)event->ptime_prev,(double)t);CHKERRQ(ierr); 304006e6a18SShri Abhyankar } 3052dc7a7e3SShri Abhyankar } 306d94325d3SShri Abhyankar break; 307d94325d3SShri Abhyankar case 1: 308d94325d3SShri Abhyankar if (fvalue_sign > 0) { 309d94325d3SShri Abhyankar rollback = 1; 310d94325d3SShri Abhyankar /* Compute linearly interpolated new time step */ 311d94325d3SShri Abhyankar dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 312006e6a18SShri Abhyankar if(event->mon) { 313006e6a18SShri Abhyankar ierr = PetscViewerASCIIPrintf(event->mon,"TSEvent : Event %D interval located [%g - %g]\n",i,(double)event->ptime_prev,(double)t);CHKERRQ(ierr); 314006e6a18SShri Abhyankar } 3152dc7a7e3SShri Abhyankar } 316d94325d3SShri Abhyankar break; 317d94325d3SShri Abhyankar case 0: 318d94325d3SShri Abhyankar rollback = 1; 319d94325d3SShri Abhyankar /* Compute linearly interpolated new time step */ 320d94325d3SShri Abhyankar dt = PetscMin(dt,PetscRealPart(-event->fvalue_prev[i]*(t - event->ptime_prev)/(event->fvalue[i] - event->fvalue_prev[i]))); 321006e6a18SShri Abhyankar if(event->mon) { 322006e6a18SShri Abhyankar ierr = PetscViewerASCIIPrintf(event->mon,"TSEvent : Event %D interval located [%g - %g]\n",i,(double)event->ptime_prev,(double)t);CHKERRQ(ierr); 323006e6a18SShri Abhyankar } 324d94325d3SShri Abhyankar break; 325d94325d3SShri Abhyankar } 326d94325d3SShri Abhyankar } 327d94325d3SShri Abhyankar } 328d94325d3SShri Abhyankar if (rollback) event->status = TSEVENT_LOCATED_INTERVAL; 329d94325d3SShri Abhyankar 3302dc7a7e3SShri Abhyankar in[0] = event->status; 3312dc7a7e3SShri Abhyankar in[1] = rollback; 332*b2566f29SBarry Smith ierr = MPIU_Allreduce(in,out,2,MPIU_INT,MPI_MAX,((PetscObject)ts)->comm);CHKERRQ(ierr); 3332dc7a7e3SShri Abhyankar 334128a6747SShri Abhyankar event->status = (TSEventStatus)out[0]; 3352dc7a7e3SShri Abhyankar rollback = out[1]; 3362dc7a7e3SShri Abhyankar if (rollback) { 3372dc7a7e3SShri Abhyankar event->status = TSEVENT_LOCATED_INTERVAL; 3382dc7a7e3SShri Abhyankar } 3392dc7a7e3SShri Abhyankar 3409e12be75SShri Abhyankar if (event->status == TSEVENT_ZERO) { 3419e12be75SShri Abhyankar for(i=0; i < event->nevents; i++) { 3429e12be75SShri Abhyankar if (PetscAbsScalar(event->fvalue[i]) < event->vtol[i]) { 3439e12be75SShri Abhyankar event->events_zero[event->nevents_zero++] = i; 3449e12be75SShri Abhyankar if(event->mon) { 3459e12be75SShri Abhyankar ierr = PetscViewerASCIIPrintf(event->mon,"TSEvent : Event %D zero crossing at time %g\n",i,(double)t);CHKERRQ(ierr); 3469e12be75SShri Abhyankar } 3479e12be75SShri Abhyankar } 3489e12be75SShri Abhyankar } 3499e12be75SShri Abhyankar 3509e12be75SShri Abhyankar ierr = TSPostEvent(ts,event->nevents_zero,event->events_zero,t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr); 3519e12be75SShri Abhyankar 3529e12be75SShri Abhyankar dt = event->tstepend-t; 3539e12be75SShri Abhyankar if(PetscAbsReal(dt) < PETSC_SMALL) dt += event->initial_timestep; 3549e12be75SShri Abhyankar ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr); 3559e12be75SShri Abhyankar PetscFunctionReturn(0); 3569e12be75SShri Abhyankar } 3579e12be75SShri Abhyankar 3582dc7a7e3SShri Abhyankar if (event->status == TSEVENT_LOCATED_INTERVAL) { 3592dc7a7e3SShri Abhyankar ierr = TSRollBack(ts);CHKERRQ(ierr); 360c540466cSShri Abhyankar ts->steps--; 361c540466cSShri Abhyankar ts->total_steps--; 362db84a1feSShri Abhyankar ts->reason = TS_CONVERGED_ITERATING; 3632dc7a7e3SShri Abhyankar event->status = TSEVENT_PROCESSING; 3642dc7a7e3SShri Abhyankar } else { 3652dc7a7e3SShri Abhyankar for (i = 0; i < event->nevents; i++) { 3662dc7a7e3SShri Abhyankar event->fvalue_prev[i] = event->fvalue[i]; 3672dc7a7e3SShri Abhyankar } 3682dc7a7e3SShri Abhyankar event->ptime_prev = t; 3692dc7a7e3SShri Abhyankar if (event->status == TSEVENT_PROCESSING) { 3702dc7a7e3SShri Abhyankar dt = event->tstepend - event->ptime_prev; 3712dc7a7e3SShri Abhyankar } 3722dc7a7e3SShri Abhyankar } 3739e12be75SShri Abhyankar 374*b2566f29SBarry Smith ierr = MPIU_Allreduce(&dt,&(ts->time_step),1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr); 3752dc7a7e3SShri Abhyankar PetscFunctionReturn(0); 3762dc7a7e3SShri Abhyankar } 3772dc7a7e3SShri Abhyankar 378d0578d90SShri Abhyankar #undef __FUNCT__ 379d0578d90SShri Abhyankar #define __FUNCT__ "TSAdjointEventMonitor" 380d0578d90SShri Abhyankar PetscErrorCode TSAdjointEventMonitor(TS ts) 381d0578d90SShri Abhyankar { 382d0578d90SShri Abhyankar PetscErrorCode ierr; 383d0578d90SShri Abhyankar TSEvent event=ts->event; 384d0578d90SShri Abhyankar PetscReal t; 385d0578d90SShri Abhyankar Vec U; 386d0578d90SShri Abhyankar PetscInt ctr; 387d0578d90SShri Abhyankar PetscBool forwardsolve=PETSC_FALSE; /* Flag indicating that TS is doing an adjoint solve */ 388d0578d90SShri Abhyankar 389d0578d90SShri Abhyankar PetscFunctionBegin; 390d0578d90SShri Abhyankar 391d0578d90SShri Abhyankar ierr = TSGetTime(ts,&t);CHKERRQ(ierr); 392d0578d90SShri Abhyankar ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 393d0578d90SShri Abhyankar 394d0578d90SShri Abhyankar ctr = event->recorder.ctr-1; 395bcbf8bb3SShri Abhyankar if(ctr >= 0 && PetscAbsReal(t - event->recorder.time[ctr]) < PETSC_SMALL) { 396d0578d90SShri Abhyankar /* Call the user postevent function */ 397d0578d90SShri Abhyankar if(event->postevent) { 398d0578d90SShri Abhyankar ierr = (*event->postevent)(ts,event->recorder.nevents[ctr],event->recorder.eventidx[ctr],t,U,forwardsolve,event->monitorcontext);CHKERRQ(ierr); 399d0578d90SShri Abhyankar event->recorder.ctr--; 400d0578d90SShri Abhyankar } 401d0578d90SShri Abhyankar } 402d0578d90SShri Abhyankar 403d0578d90SShri Abhyankar PetscBarrier((PetscObject)ts); 404d0578d90SShri Abhyankar PetscFunctionReturn(0); 405d0578d90SShri Abhyankar } 406d0578d90SShri Abhyankar 407d0578d90SShri Abhyankar 408d0578d90SShri Abhyankar 409