1 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 2 #include <petscdmshell.h> 3 #include <petscdmda.h> 4 #include <petscviewer.h> 5 #include <petscdraw.h> 6 #include <petscconvest.h> 7 8 #define SkipSmallValue(a,b,tol) if (PetscAbsScalar(a)< tol || PetscAbsScalar(b)< tol) continue; 9 10 /* Logging support */ 11 PetscClassId TS_CLASSID, DMTS_CLASSID; 12 PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 13 14 const char *const TSExactFinalTimeOptions[] = {"UNSPECIFIED","STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",NULL}; 15 16 17 /*@C 18 TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 19 20 Collective on TS 21 22 Input Parameters: 23 + ts - TS object you wish to monitor 24 . name - the monitor type one is seeking 25 . help - message indicating what monitoring is done 26 . manual - manual page for the monitor 27 . monitor - the monitor function 28 - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the TS or PetscViewer objects 29 30 Level: developer 31 32 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 33 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 34 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 35 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 36 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 37 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 38 PetscOptionsFList(), PetscOptionsEList() 39 @*/ 40 PetscErrorCode TSMonitorSetFromOptions(TS ts,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(TS,PetscViewerAndFormat*)) 41 { 42 PetscErrorCode ierr; 43 PetscViewer viewer; 44 PetscViewerFormat format; 45 PetscBool flg; 46 47 PetscFunctionBegin; 48 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject) ts)->options,((PetscObject)ts)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 49 if (flg) { 50 PetscViewerAndFormat *vf; 51 ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 52 ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 53 if (monitorsetup) { 54 ierr = (*monitorsetup)(ts,vf);CHKERRQ(ierr); 55 } 56 ierr = TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 57 } 58 PetscFunctionReturn(0); 59 } 60 61 static PetscErrorCode TSAdaptSetDefaultType(TSAdapt adapt,TSAdaptType default_type) 62 { 63 PetscErrorCode ierr; 64 65 PetscFunctionBegin; 66 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 67 PetscValidCharPointer(default_type,2); 68 if (!((PetscObject)adapt)->type_name) { 69 ierr = TSAdaptSetType(adapt,default_type);CHKERRQ(ierr); 70 } 71 PetscFunctionReturn(0); 72 } 73 74 /*@ 75 TSSetFromOptions - Sets various TS parameters from user options. 76 77 Collective on TS 78 79 Input Parameter: 80 . ts - the TS context obtained from TSCreate() 81 82 Options Database Keys: 83 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSALPHA, TSGLLE, TSSSP, TSGLEE, TSBSYMP 84 . -ts_save_trajectory - checkpoint the solution at each time-step 85 . -ts_max_time <time> - maximum time to compute to 86 . -ts_max_steps <steps> - maximum number of time-steps to take 87 . -ts_init_time <time> - initial time to start computation 88 . -ts_final_time <time> - final time to compute to (deprecated: use -ts_max_time) 89 . -ts_dt <dt> - initial time step 90 . -ts_exact_final_time <stepover,interpolate,matchstep> - whether to stop at the exact given final time and how to compute the solution at that ti,e 91 . -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed 92 . -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails 93 . -ts_error_if_step_fails <true,false> - Error if no step succeeds 94 . -ts_rtol <rtol> - relative tolerance for local truncation error 95 . -ts_atol <atol> Absolute tolerance for local truncation error 96 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - test the Jacobian at each iteration against finite difference with RHS function 97 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - test the Jacobian at each iteration against finite difference with RHS function 98 . -ts_adjoint_solve <yes,no> After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory) 99 . -ts_fd_color - Use finite differences with coloring to compute IJacobian 100 . -ts_monitor - print information at each timestep 101 . -ts_monitor_lg_solution - Monitor solution graphically 102 . -ts_monitor_lg_error - Monitor error graphically 103 . -ts_monitor_error - Monitors norm of error 104 . -ts_monitor_lg_timestep - Monitor timestep size graphically 105 . -ts_monitor_lg_timestep_log - Monitor log timestep size graphically 106 . -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically 107 . -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically 108 . -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically 109 . -ts_monitor_draw_solution - Monitor solution graphically 110 . -ts_monitor_draw_solution_phase <xleft,yleft,xright,yright> - Monitor solution graphically with phase diagram, requires problem with exactly 2 degrees of freedom 111 . -ts_monitor_draw_error - Monitor error graphically, requires use to have provided TSSetSolutionFunction() 112 . -ts_monitor_solution [ascii binary draw][:filename][:viewerformat] - monitors the solution at each timestep 113 . -ts_monitor_solution_vtk <filename.vts,filename.vtu> - Save each time step to a binary file, use filename-%%03D.vts (filename-%%03D.vtu) 114 - -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time 115 116 Developer Note: 117 We should unify all the -ts_monitor options in the way that -xxx_view has been unified 118 119 Level: beginner 120 121 .seealso: TSGetType() 122 @*/ 123 PetscErrorCode TSSetFromOptions(TS ts) 124 { 125 PetscBool opt,flg,tflg; 126 PetscErrorCode ierr; 127 char monfilename[PETSC_MAX_PATH_LEN]; 128 PetscReal time_step; 129 TSExactFinalTimeOption eftopt; 130 char dir[16]; 131 TSIFunction ifun; 132 const char *defaultType; 133 char typeName[256]; 134 135 PetscFunctionBegin; 136 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 137 138 ierr = TSRegisterAll();CHKERRQ(ierr); 139 ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr); 140 141 ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr); 142 if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name; 143 else defaultType = ifun ? TSBEULER : TSEULER; 144 ierr = PetscOptionsFList("-ts_type","TS method","TSSetType",TSList,defaultType,typeName,256,&opt);CHKERRQ(ierr); 145 if (opt) { 146 ierr = TSSetType(ts,typeName);CHKERRQ(ierr); 147 } else { 148 ierr = TSSetType(ts,defaultType);CHKERRQ(ierr); 149 } 150 151 /* Handle generic TS options */ 152 ierr = PetscOptionsDeprecated("-ts_final_time","-ts_max_time","3.10",NULL);CHKERRQ(ierr); 153 ierr = PetscOptionsReal("-ts_max_time","Maximum time to run to","TSSetMaxTime",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr); 154 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetMaxSteps",ts->max_steps,&ts->max_steps,NULL);CHKERRQ(ierr); 155 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);CHKERRQ(ierr); 156 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr); 157 if (flg) {ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);} 158 ierr = PetscOptionsEnum("-ts_exact_final_time","Option for handling of final time step","TSSetExactFinalTime",TSExactFinalTimeOptions,(PetscEnum)ts->exact_final_time,(PetscEnum*)&eftopt,&flg);CHKERRQ(ierr); 159 if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);} 160 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);CHKERRQ(ierr); 161 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);CHKERRQ(ierr); 162 ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);CHKERRQ(ierr); 163 ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);CHKERRQ(ierr); 164 ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);CHKERRQ(ierr); 165 166 ierr = PetscOptionsBool("-ts_rhs_jacobian_test_mult","Test the RHS Jacobian for consistency with RHS at each solve ","None",ts->testjacobian,&ts->testjacobian,NULL);CHKERRQ(ierr); 167 ierr = PetscOptionsBool("-ts_rhs_jacobian_test_mult_transpose","Test the RHS Jacobian transpose for consistency with RHS at each solve ","None",ts->testjacobiantranspose,&ts->testjacobiantranspose,NULL);CHKERRQ(ierr); 168 ierr = PetscOptionsBool("-ts_use_splitrhsfunction","Use the split RHS function for multirate solvers ","TSSetUseSplitRHSFunction",ts->use_splitrhsfunction,&ts->use_splitrhsfunction,NULL);CHKERRQ(ierr); 169 #if defined(PETSC_HAVE_SAWS) 170 { 171 PetscBool set; 172 flg = PETSC_FALSE; 173 ierr = PetscOptionsBool("-ts_saws_block","Block for SAWs memory snooper at end of TSSolve","PetscObjectSAWsBlock",((PetscObject)ts)->amspublishblock,&flg,&set);CHKERRQ(ierr); 174 if (set) { 175 ierr = PetscObjectSAWsSetBlock((PetscObject)ts,flg);CHKERRQ(ierr); 176 } 177 } 178 #endif 179 180 /* Monitor options */ 181 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor","Monitor time and timestep size","TSMonitorDefault",TSMonitorDefault,NULL);CHKERRQ(ierr); 182 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor_extreme","Monitor extreme values of the solution","TSMonitorExtreme",TSMonitorExtreme,NULL);CHKERRQ(ierr); 183 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor_solution","View the solution at each timestep","TSMonitorSolution",TSMonitorSolution,NULL);CHKERRQ(ierr); 184 185 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr); 186 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 187 188 ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr); 189 if (opt) { 190 TSMonitorLGCtx ctx; 191 PetscInt howoften = 1; 192 193 ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 194 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 195 ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 196 } 197 198 ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr); 199 if (opt) { 200 TSMonitorLGCtx ctx; 201 PetscInt howoften = 1; 202 203 ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);CHKERRQ(ierr); 204 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 205 ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 206 } 207 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor_error","View the error at each timestep","TSMonitorError",TSMonitorError,NULL);CHKERRQ(ierr); 208 209 ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 210 if (opt) { 211 TSMonitorLGCtx ctx; 212 PetscInt howoften = 1; 213 214 ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 215 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 216 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 217 } 218 ierr = PetscOptionsName("-ts_monitor_lg_timestep_log","Monitor log timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 219 if (opt) { 220 TSMonitorLGCtx ctx; 221 PetscInt howoften = 1; 222 223 ierr = PetscOptionsInt("-ts_monitor_lg_timestep_log","Monitor log timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 224 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 225 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 226 ctx->semilogy = PETSC_TRUE; 227 } 228 229 ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr); 230 if (opt) { 231 TSMonitorLGCtx ctx; 232 PetscInt howoften = 1; 233 234 ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 235 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 236 ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 237 } 238 ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr); 239 if (opt) { 240 TSMonitorLGCtx ctx; 241 PetscInt howoften = 1; 242 243 ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 244 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 245 ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 246 } 247 ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr); 248 if (opt) { 249 TSMonitorSPEigCtx ctx; 250 PetscInt howoften = 1; 251 252 ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);CHKERRQ(ierr); 253 ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 254 ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr); 255 } 256 ierr = PetscOptionsName("-ts_monitor_sp_swarm","Display particle phase from the DMSwarm","TSMonitorSPSwarm",&opt);CHKERRQ(ierr); 257 if (opt) { 258 TSMonitorSPCtx ctx; 259 PetscInt howoften = 1; 260 ierr = PetscOptionsInt("-ts_monitor_sp_swarm","Display particles phase from the DMSwarm","TSMonitorSPSwarm",howoften,&howoften,NULL);CHKERRQ(ierr); 261 ierr = TSMonitorSPCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx);CHKERRQ(ierr); 262 ierr = TSMonitorSet(ts, TSMonitorSPSwarmSolution, ctx, (PetscErrorCode (*)(void**))TSMonitorSPCtxDestroy);CHKERRQ(ierr); 263 } 264 opt = PETSC_FALSE; 265 ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr); 266 if (opt) { 267 TSMonitorDrawCtx ctx; 268 PetscInt howoften = 1; 269 270 ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 271 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,"Computed Solution",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 272 ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 273 } 274 opt = PETSC_FALSE; 275 ierr = PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);CHKERRQ(ierr); 276 if (opt) { 277 TSMonitorDrawCtx ctx; 278 PetscReal bounds[4]; 279 PetscInt n = 4; 280 PetscDraw draw; 281 PetscDrawAxis axis; 282 283 ierr = PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);CHKERRQ(ierr); 284 if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field"); 285 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,1,&ctx);CHKERRQ(ierr); 286 ierr = PetscViewerDrawGetDraw(ctx->viewer,0,&draw);CHKERRQ(ierr); 287 ierr = PetscViewerDrawGetDrawAxis(ctx->viewer,0,&axis);CHKERRQ(ierr); 288 ierr = PetscDrawAxisSetLimits(axis,bounds[0],bounds[2],bounds[1],bounds[3]);CHKERRQ(ierr); 289 ierr = PetscDrawAxisSetLabels(axis,"Phase Diagram","Variable 1","Variable 2");CHKERRQ(ierr); 290 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 291 } 292 opt = PETSC_FALSE; 293 ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr); 294 if (opt) { 295 TSMonitorDrawCtx ctx; 296 PetscInt howoften = 1; 297 298 ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);CHKERRQ(ierr); 299 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,"Error",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 300 ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 301 } 302 opt = PETSC_FALSE; 303 ierr = PetscOptionsName("-ts_monitor_draw_solution_function","Monitor solution provided by TSMonitorSetSolutionFunction() graphically","TSMonitorDrawSolutionFunction",&opt);CHKERRQ(ierr); 304 if (opt) { 305 TSMonitorDrawCtx ctx; 306 PetscInt howoften = 1; 307 308 ierr = PetscOptionsInt("-ts_monitor_draw_solution_function","Monitor solution provided by TSMonitorSetSolutionFunction() graphically","TSMonitorDrawSolutionFunction",howoften,&howoften,NULL);CHKERRQ(ierr); 309 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,"Solution provided by user function",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 310 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionFunction,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 311 } 312 313 opt = PETSC_FALSE; 314 ierr = PetscOptionsString("-ts_monitor_solution_vtk","Save each time step to a binary file, use filename-%%03D.vts","TSMonitorSolutionVTK",NULL,monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr); 315 if (flg) { 316 const char *ptr,*ptr2; 317 char *filetemplate; 318 if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 319 /* Do some cursory validation of the input. */ 320 ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr); 321 if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 322 for (ptr++; ptr && *ptr; ptr++) { 323 ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr); 324 if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03D.vts"); 325 if (ptr2) break; 326 } 327 ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr); 328 ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr); 329 } 330 331 ierr = PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,sizeof(dir),&flg);CHKERRQ(ierr); 332 if (flg) { 333 TSMonitorDMDARayCtx *rayctx; 334 int ray = 0; 335 DMDirection ddir; 336 DM da; 337 PetscMPIInt rank; 338 339 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 340 if (dir[0] == 'x') ddir = DM_X; 341 else if (dir[0] == 'y') ddir = DM_Y; 342 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 343 sscanf(dir+2,"%d",&ray); 344 345 ierr = PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %d\n",dir[0],ray);CHKERRQ(ierr); 346 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 347 ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 348 ierr = DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);CHKERRQ(ierr); 349 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr); 350 if (!rank) { 351 ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,NULL,NULL,0,0,600,300,&rayctx->viewer);CHKERRQ(ierr); 352 } 353 rayctx->lgctx = NULL; 354 ierr = TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);CHKERRQ(ierr); 355 } 356 ierr = PetscOptionsString("-ts_monitor_lg_dmda_ray","Display a ray of the solution","None","x=0",dir,sizeof(dir),&flg);CHKERRQ(ierr); 357 if (flg) { 358 TSMonitorDMDARayCtx *rayctx; 359 int ray = 0; 360 DMDirection ddir; 361 DM da; 362 PetscInt howoften = 1; 363 364 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir); 365 if (dir[0] == 'x') ddir = DM_X; 366 else if (dir[0] == 'y') ddir = DM_Y; 367 else SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir); 368 sscanf(dir+2, "%d", &ray); 369 370 ierr = PetscInfo2(((PetscObject) ts),"Displaying LG DMDA ray %c = %d\n", dir[0], ray);CHKERRQ(ierr); 371 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 372 ierr = TSGetDM(ts, &da);CHKERRQ(ierr); 373 ierr = DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter);CHKERRQ(ierr); 374 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&rayctx->lgctx);CHKERRQ(ierr); 375 ierr = TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy);CHKERRQ(ierr); 376 } 377 378 ierr = PetscOptionsName("-ts_monitor_envelope","Monitor maximum and minimum value of each component of the solution","TSMonitorEnvelope",&opt);CHKERRQ(ierr); 379 if (opt) { 380 TSMonitorEnvelopeCtx ctx; 381 382 ierr = TSMonitorEnvelopeCtxCreate(ts,&ctx);CHKERRQ(ierr); 383 ierr = TSMonitorSet(ts,TSMonitorEnvelope,ctx,(PetscErrorCode (*)(void**))TSMonitorEnvelopeCtxDestroy);CHKERRQ(ierr); 384 } 385 386 flg = PETSC_FALSE; 387 ierr = PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeJacobianDefaultColor", flg, &flg, NULL);CHKERRQ(ierr); 388 if (flg) { 389 DM dm; 390 DMTS tdm; 391 392 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 393 ierr = DMGetDMTS(dm, &tdm);CHKERRQ(ierr); 394 tdm->ijacobianctx = NULL; 395 ierr = TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, NULL);CHKERRQ(ierr); 396 ierr = PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 397 } 398 399 /* Handle specific TS options */ 400 if (ts->ops->setfromoptions) { 401 ierr = (*ts->ops->setfromoptions)(PetscOptionsObject,ts);CHKERRQ(ierr); 402 } 403 404 /* Handle TSAdapt options */ 405 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 406 ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr); 407 ierr = TSAdaptSetFromOptions(PetscOptionsObject,ts->adapt);CHKERRQ(ierr); 408 409 /* TS trajectory must be set after TS, since it may use some TS options above */ 410 tflg = ts->trajectory ? PETSC_TRUE : PETSC_FALSE; 411 ierr = PetscOptionsBool("-ts_save_trajectory","Save the solution at each timestep","TSSetSaveTrajectory",tflg,&tflg,NULL);CHKERRQ(ierr); 412 if (tflg) { 413 ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); 414 } 415 416 ierr = TSAdjointSetFromOptions(PetscOptionsObject,ts);CHKERRQ(ierr); 417 418 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 419 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ts);CHKERRQ(ierr); 420 ierr = PetscOptionsEnd();CHKERRQ(ierr); 421 422 if (ts->trajectory) { 423 ierr = TSTrajectorySetFromOptions(ts->trajectory,ts);CHKERRQ(ierr); 424 } 425 426 /* why do we have to do this here and not during TSSetUp? */ 427 ierr = TSGetSNES(ts,&ts->snes);CHKERRQ(ierr); 428 if (ts->problem_type == TS_LINEAR) { 429 ierr = PetscObjectTypeCompareAny((PetscObject)ts->snes,&flg,SNESKSPONLY,SNESKSPTRANSPOSEONLY,"");CHKERRQ(ierr); 430 if (!flg) { ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); } 431 } 432 ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr); 433 PetscFunctionReturn(0); 434 } 435 436 /*@ 437 TSGetTrajectory - Gets the trajectory from a TS if it exists 438 439 Collective on TS 440 441 Input Parameters: 442 . ts - the TS context obtained from TSCreate() 443 444 Output Parameters: 445 . tr - the TSTrajectory object, if it exists 446 447 Note: This routine should be called after all TS options have been set 448 449 Level: advanced 450 451 .seealso: TSGetTrajectory(), TSAdjointSolve(), TSTrajectory, TSTrajectoryCreate() 452 453 @*/ 454 PetscErrorCode TSGetTrajectory(TS ts,TSTrajectory *tr) 455 { 456 PetscFunctionBegin; 457 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 458 *tr = ts->trajectory; 459 PetscFunctionReturn(0); 460 } 461 462 /*@ 463 TSSetSaveTrajectory - Causes the TS to save its solutions as it iterates forward in time in a TSTrajectory object 464 465 Collective on TS 466 467 Input Parameters: 468 . ts - the TS context obtained from TSCreate() 469 470 Options Database: 471 + -ts_save_trajectory - saves the trajectory to a file 472 - -ts_trajectory_type type 473 474 Note: This routine should be called after all TS options have been set 475 476 The TSTRAJECTORYVISUALIZATION files can be loaded into Python with $PETSC_DIR/lib/petsc/bin/PetscBinaryIOTrajectory.py and 477 MATLAB with $PETSC_DIR/share/petsc/matlab/PetscReadBinaryTrajectory.m 478 479 Level: intermediate 480 481 .seealso: TSGetTrajectory(), TSAdjointSolve() 482 483 @*/ 484 PetscErrorCode TSSetSaveTrajectory(TS ts) 485 { 486 PetscErrorCode ierr; 487 488 PetscFunctionBegin; 489 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 490 if (!ts->trajectory) { 491 ierr = TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory);CHKERRQ(ierr); 492 } 493 PetscFunctionReturn(0); 494 } 495 496 /*@ 497 TSResetTrajectory - Destroys and recreates the internal TSTrajectory object 498 499 Collective on TS 500 501 Input Parameters: 502 . ts - the TS context obtained from TSCreate() 503 504 Level: intermediate 505 506 .seealso: TSGetTrajectory(), TSAdjointSolve() 507 508 @*/ 509 PetscErrorCode TSResetTrajectory(TS ts) 510 { 511 PetscErrorCode ierr; 512 513 PetscFunctionBegin; 514 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 515 if (ts->trajectory) { 516 ierr = TSTrajectoryDestroy(&ts->trajectory);CHKERRQ(ierr); 517 ierr = TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory);CHKERRQ(ierr); 518 } 519 PetscFunctionReturn(0); 520 } 521 522 /*@ 523 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 524 set with TSSetRHSJacobian(). 525 526 Collective on TS 527 528 Input Parameters: 529 + ts - the TS context 530 . t - current timestep 531 - U - input vector 532 533 Output Parameters: 534 + A - Jacobian matrix 535 . B - optional preconditioning matrix 536 - flag - flag indicating matrix structure 537 538 Notes: 539 Most users should not need to explicitly call this routine, as it 540 is used internally within the nonlinear solvers. 541 542 See KSPSetOperators() for important information about setting the 543 flag parameter. 544 545 Level: developer 546 547 .seealso: TSSetRHSJacobian(), KSPSetOperators() 548 @*/ 549 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat B) 550 { 551 PetscErrorCode ierr; 552 PetscObjectState Ustate; 553 PetscObjectId Uid; 554 DM dm; 555 DMTS tsdm; 556 TSRHSJacobian rhsjacobianfunc; 557 void *ctx; 558 TSIJacobian ijacobianfunc; 559 TSRHSFunction rhsfunction; 560 561 PetscFunctionBegin; 562 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 563 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 564 PetscCheckSameComm(ts,1,U,3); 565 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 566 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 567 ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr); 568 ierr = DMTSGetIJacobian(dm,&ijacobianfunc,NULL);CHKERRQ(ierr); 569 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 570 ierr = PetscObjectStateGet((PetscObject)U,&Ustate);CHKERRQ(ierr); 571 ierr = PetscObjectGetId((PetscObject)U,&Uid);CHKERRQ(ierr); 572 573 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && (rhsfunction != TSComputeRHSFunctionLinear)) { 574 /* restore back RHS Jacobian matrices if they have been shifted/scaled */ 575 if (A == ts->Arhs) { 576 if (ts->rhsjacobian.shift != 0) { 577 ierr = MatShift(A,-ts->rhsjacobian.shift);CHKERRQ(ierr); 578 } 579 if (ts->rhsjacobian.scale != 1.) { 580 ierr = MatScale(A,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 581 } 582 } 583 if (B && B == ts->Brhs && A != B) { 584 if (ts->rhsjacobian.shift != 0) { 585 ierr = MatShift(B,-ts->rhsjacobian.shift);CHKERRQ(ierr); 586 } 587 if (ts->rhsjacobian.scale != 1.) { 588 ierr = MatScale(B,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 589 } 590 } 591 ts->rhsjacobian.shift = 0; 592 ts->rhsjacobian.scale = 1.; 593 PetscFunctionReturn(0); 594 } 595 596 if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 597 598 if (ts->rhsjacobian.reuse) { 599 if (A == ts->Arhs) { 600 /* MatScale has a short path for this case. 601 However, this code path is taken the first time TSComputeRHSJacobian is called 602 and the matrices have not assembled yet */ 603 if (ts->rhsjacobian.shift != 0) { 604 ierr = MatShift(A,-ts->rhsjacobian.shift);CHKERRQ(ierr); 605 } 606 if (ts->rhsjacobian.scale != 1.) { 607 ierr = MatScale(A,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 608 } 609 } 610 if (B && B == ts->Brhs && A != B) { 611 if (ts->rhsjacobian.shift != 0) { 612 ierr = MatShift(B,-ts->rhsjacobian.shift);CHKERRQ(ierr); 613 } 614 if (ts->rhsjacobian.scale != 1.) { 615 ierr = MatScale(B,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 616 } 617 } 618 } 619 620 if (rhsjacobianfunc) { 621 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 622 PetscStackPush("TS user Jacobian function"); 623 ierr = (*rhsjacobianfunc)(ts,t,U,A,B,ctx);CHKERRQ(ierr); 624 PetscStackPop; 625 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 626 } else { 627 ierr = MatZeroEntries(A);CHKERRQ(ierr); 628 if (B && A != B) {ierr = MatZeroEntries(B);CHKERRQ(ierr);} 629 } 630 ts->rhsjacobian.time = t; 631 ts->rhsjacobian.shift = 0; 632 ts->rhsjacobian.scale = 1.; 633 ierr = PetscObjectGetId((PetscObject)U,&ts->rhsjacobian.Xid);CHKERRQ(ierr); 634 ierr = PetscObjectStateGet((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 635 PetscFunctionReturn(0); 636 } 637 638 /*@ 639 TSComputeRHSFunction - Evaluates the right-hand-side function. 640 641 Collective on TS 642 643 Input Parameters: 644 + ts - the TS context 645 . t - current time 646 - U - state vector 647 648 Output Parameter: 649 . y - right hand side 650 651 Note: 652 Most users should not need to explicitly call this routine, as it 653 is used internally within the nonlinear solvers. 654 655 Level: developer 656 657 .seealso: TSSetRHSFunction(), TSComputeIFunction() 658 @*/ 659 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y) 660 { 661 PetscErrorCode ierr; 662 TSRHSFunction rhsfunction; 663 TSIFunction ifunction; 664 void *ctx; 665 DM dm; 666 667 PetscFunctionBegin; 668 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 669 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 670 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 671 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 672 ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr); 673 ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr); 674 675 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 676 677 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 678 if (rhsfunction) { 679 ierr = VecLockReadPush(U);CHKERRQ(ierr); 680 PetscStackPush("TS user right-hand-side function"); 681 ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr); 682 PetscStackPop; 683 ierr = VecLockReadPop(U);CHKERRQ(ierr); 684 } else { 685 ierr = VecZeroEntries(y);CHKERRQ(ierr); 686 } 687 688 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 689 PetscFunctionReturn(0); 690 } 691 692 /*@ 693 TSComputeSolutionFunction - Evaluates the solution function. 694 695 Collective on TS 696 697 Input Parameters: 698 + ts - the TS context 699 - t - current time 700 701 Output Parameter: 702 . U - the solution 703 704 Note: 705 Most users should not need to explicitly call this routine, as it 706 is used internally within the nonlinear solvers. 707 708 Level: developer 709 710 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 711 @*/ 712 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U) 713 { 714 PetscErrorCode ierr; 715 TSSolutionFunction solutionfunction; 716 void *ctx; 717 DM dm; 718 719 PetscFunctionBegin; 720 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 721 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 722 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 723 ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr); 724 725 if (solutionfunction) { 726 PetscStackPush("TS user solution function"); 727 ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr); 728 PetscStackPop; 729 } 730 PetscFunctionReturn(0); 731 } 732 /*@ 733 TSComputeForcingFunction - Evaluates the forcing function. 734 735 Collective on TS 736 737 Input Parameters: 738 + ts - the TS context 739 - t - current time 740 741 Output Parameter: 742 . U - the function value 743 744 Note: 745 Most users should not need to explicitly call this routine, as it 746 is used internally within the nonlinear solvers. 747 748 Level: developer 749 750 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 751 @*/ 752 PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U) 753 { 754 PetscErrorCode ierr, (*forcing)(TS,PetscReal,Vec,void*); 755 void *ctx; 756 DM dm; 757 758 PetscFunctionBegin; 759 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 760 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 761 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 762 ierr = DMTSGetForcingFunction(dm,&forcing,&ctx);CHKERRQ(ierr); 763 764 if (forcing) { 765 PetscStackPush("TS user forcing function"); 766 ierr = (*forcing)(ts,t,U,ctx);CHKERRQ(ierr); 767 PetscStackPop; 768 } 769 PetscFunctionReturn(0); 770 } 771 772 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 773 { 774 Vec F; 775 PetscErrorCode ierr; 776 777 PetscFunctionBegin; 778 *Frhs = NULL; 779 ierr = TSGetIFunction(ts,&F,NULL,NULL);CHKERRQ(ierr); 780 if (!ts->Frhs) { 781 ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr); 782 } 783 *Frhs = ts->Frhs; 784 PetscFunctionReturn(0); 785 } 786 787 PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 788 { 789 Mat A,B; 790 PetscErrorCode ierr; 791 TSIJacobian ijacobian; 792 793 PetscFunctionBegin; 794 if (Arhs) *Arhs = NULL; 795 if (Brhs) *Brhs = NULL; 796 ierr = TSGetIJacobian(ts,&A,&B,&ijacobian,NULL);CHKERRQ(ierr); 797 if (Arhs) { 798 if (!ts->Arhs) { 799 if (ijacobian) { 800 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 801 } else { 802 ts->Arhs = A; 803 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 804 } 805 } else { 806 PetscBool flg; 807 ierr = SNESGetUseMatrixFree(ts->snes,NULL,&flg);CHKERRQ(ierr); 808 /* Handle case where user provided only RHSJacobian and used -snes_mf_operator */ 809 if (flg && !ijacobian && ts->Arhs == ts->Brhs){ 810 ierr = PetscObjectDereference((PetscObject)ts->Arhs);CHKERRQ(ierr); 811 ts->Arhs = A; 812 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 813 } 814 } 815 *Arhs = ts->Arhs; 816 } 817 if (Brhs) { 818 if (!ts->Brhs) { 819 if (A != B) { 820 if (ijacobian) { 821 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 822 } else { 823 ts->Brhs = B; 824 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 825 } 826 } else { 827 ierr = PetscObjectReference((PetscObject)ts->Arhs);CHKERRQ(ierr); 828 ts->Brhs = ts->Arhs; 829 } 830 } 831 *Brhs = ts->Brhs; 832 } 833 PetscFunctionReturn(0); 834 } 835 836 /*@ 837 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0 838 839 Collective on TS 840 841 Input Parameters: 842 + ts - the TS context 843 . t - current time 844 . U - state vector 845 . Udot - time derivative of state vector 846 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 847 848 Output Parameter: 849 . Y - right hand side 850 851 Note: 852 Most users should not need to explicitly call this routine, as it 853 is used internally within the nonlinear solvers. 854 855 If the user did did not write their equations in implicit form, this 856 function recasts them in implicit form. 857 858 Level: developer 859 860 .seealso: TSSetIFunction(), TSComputeRHSFunction() 861 @*/ 862 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex) 863 { 864 PetscErrorCode ierr; 865 TSIFunction ifunction; 866 TSRHSFunction rhsfunction; 867 void *ctx; 868 DM dm; 869 870 PetscFunctionBegin; 871 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 872 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 873 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 874 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 875 876 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 877 ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr); 878 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 879 880 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 881 882 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 883 if (ifunction) { 884 PetscStackPush("TS user implicit function"); 885 ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr); 886 PetscStackPop; 887 } 888 if (imex) { 889 if (!ifunction) { 890 ierr = VecCopy(Udot,Y);CHKERRQ(ierr); 891 } 892 } else if (rhsfunction) { 893 if (ifunction) { 894 Vec Frhs; 895 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 896 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 897 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 898 } else { 899 ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr); 900 ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr); 901 } 902 } 903 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 904 PetscFunctionReturn(0); 905 } 906 907 /*@ 908 TSComputeIJacobian - Evaluates the Jacobian of the DAE 909 910 Collective on TS 911 912 Input 913 Input Parameters: 914 + ts - the TS context 915 . t - current timestep 916 . U - state vector 917 . Udot - time derivative of state vector 918 . shift - shift to apply, see note below 919 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 920 921 Output Parameters: 922 + A - Jacobian matrix 923 - B - matrix from which the preconditioner is constructed; often the same as A 924 925 Notes: 926 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 927 928 dF/dU + shift*dF/dUdot 929 930 Most users should not need to explicitly call this routine, as it 931 is used internally within the nonlinear solvers. 932 933 Level: developer 934 935 .seealso: TSSetIJacobian() 936 @*/ 937 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,PetscBool imex) 938 { 939 PetscErrorCode ierr; 940 TSIJacobian ijacobian; 941 TSRHSJacobian rhsjacobian; 942 DM dm; 943 void *ctx; 944 945 PetscFunctionBegin; 946 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 947 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 948 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 949 PetscValidPointer(A,6); 950 PetscValidHeaderSpecific(A,MAT_CLASSID,6); 951 PetscValidPointer(B,7); 952 PetscValidHeaderSpecific(B,MAT_CLASSID,7); 953 954 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 955 ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr); 956 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 957 958 if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 959 960 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 961 if (ijacobian) { 962 PetscStackPush("TS user implicit Jacobian"); 963 ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,ctx);CHKERRQ(ierr); 964 PetscStackPop; 965 } 966 if (imex) { 967 if (!ijacobian) { /* system was written as Udot = G(t,U) */ 968 PetscBool assembled; 969 if (rhsjacobian) { 970 Mat Arhs = NULL; 971 ierr = TSGetRHSMats_Private(ts,&Arhs,NULL);CHKERRQ(ierr); 972 if (A == Arhs) { 973 if (rhsjacobian == TSComputeRHSJacobianConstant) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Unsupported operation! cannot use TSComputeRHSJacobianConstant"); 974 ts->rhsjacobian.time = PETSC_MIN_REAL; 975 } 976 } 977 ierr = MatZeroEntries(A);CHKERRQ(ierr); 978 ierr = MatAssembled(A,&assembled);CHKERRQ(ierr); 979 if (!assembled) { 980 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 981 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 982 } 983 ierr = MatShift(A,shift);CHKERRQ(ierr); 984 if (A != B) { 985 ierr = MatZeroEntries(B);CHKERRQ(ierr); 986 ierr = MatAssembled(B,&assembled);CHKERRQ(ierr); 987 if (!assembled) { 988 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 989 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 990 } 991 ierr = MatShift(B,shift);CHKERRQ(ierr); 992 } 993 } 994 } else { 995 Mat Arhs = NULL,Brhs = NULL; 996 if (rhsjacobian) { 997 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 998 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 999 } 1000 if (Arhs == A) { /* No IJacobian, so we only have the RHS matrix */ 1001 PetscBool flg; 1002 ts->rhsjacobian.scale = -1; 1003 ts->rhsjacobian.shift = shift; 1004 ierr = SNESGetUseMatrixFree(ts->snes,NULL,&flg);CHKERRQ(ierr); 1005 /* since -snes_mf_operator uses the full SNES function it does not need to be shifted or scaled here */ 1006 if (!flg) { 1007 ierr = MatScale(A,-1);CHKERRQ(ierr); 1008 ierr = MatShift(A,shift);CHKERRQ(ierr); 1009 } 1010 if (A != B) { 1011 ierr = MatScale(B,-1);CHKERRQ(ierr); 1012 ierr = MatShift(B,shift);CHKERRQ(ierr); 1013 } 1014 } else if (Arhs) { /* Both IJacobian and RHSJacobian */ 1015 MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 1016 if (!ijacobian) { /* No IJacobian provided, but we have a separate RHS matrix */ 1017 ierr = MatZeroEntries(A);CHKERRQ(ierr); 1018 ierr = MatShift(A,shift);CHKERRQ(ierr); 1019 if (A != B) { 1020 ierr = MatZeroEntries(B);CHKERRQ(ierr); 1021 ierr = MatShift(B,shift);CHKERRQ(ierr); 1022 } 1023 } 1024 ierr = MatAXPY(A,-1,Arhs,axpy);CHKERRQ(ierr); 1025 if (A != B) { 1026 ierr = MatAXPY(B,-1,Brhs,axpy);CHKERRQ(ierr); 1027 } 1028 } 1029 } 1030 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 1031 PetscFunctionReturn(0); 1032 } 1033 1034 /*@C 1035 TSSetRHSFunction - Sets the routine for evaluating the function, 1036 where U_t = G(t,u). 1037 1038 Logically Collective on TS 1039 1040 Input Parameters: 1041 + ts - the TS context obtained from TSCreate() 1042 . r - vector to put the computed right hand side (or NULL to have it created) 1043 . f - routine for evaluating the right-hand-side function 1044 - ctx - [optional] user-defined context for private data for the 1045 function evaluation routine (may be NULL) 1046 1047 Calling sequence of f: 1048 $ PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec F,void *ctx); 1049 1050 + ts - timestep context 1051 . t - current timestep 1052 . u - input vector 1053 . F - function vector 1054 - ctx - [optional] user-defined function context 1055 1056 Level: beginner 1057 1058 Notes: 1059 You must call this function or TSSetIFunction() to define your ODE. You cannot use this function when solving a DAE. 1060 1061 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSSetIFunction() 1062 @*/ 1063 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 1064 { 1065 PetscErrorCode ierr; 1066 SNES snes; 1067 Vec ralloc = NULL; 1068 DM dm; 1069 1070 PetscFunctionBegin; 1071 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1072 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1073 1074 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1075 ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr); 1076 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1077 if (!r && !ts->dm && ts->vec_sol) { 1078 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 1079 r = ralloc; 1080 } 1081 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 1082 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 1083 PetscFunctionReturn(0); 1084 } 1085 1086 /*@C 1087 TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE 1088 1089 Logically Collective on TS 1090 1091 Input Parameters: 1092 + ts - the TS context obtained from TSCreate() 1093 . f - routine for evaluating the solution 1094 - ctx - [optional] user-defined context for private data for the 1095 function evaluation routine (may be NULL) 1096 1097 Calling sequence of f: 1098 $ PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx); 1099 1100 + t - current timestep 1101 . u - output vector 1102 - ctx - [optional] user-defined function context 1103 1104 Options Database: 1105 + -ts_monitor_lg_error - create a graphical monitor of error history, requires user to have provided TSSetSolutionFunction() 1106 - -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 1107 1108 Notes: 1109 This routine is used for testing accuracy of time integration schemes when you already know the solution. 1110 If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to 1111 create closed-form solutions with non-physical forcing terms. 1112 1113 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 1114 1115 Level: beginner 1116 1117 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction(), TSSetSolution(), TSGetSolution(), TSMonitorLGError(), TSMonitorDrawError() 1118 @*/ 1119 PetscErrorCode TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 1120 { 1121 PetscErrorCode ierr; 1122 DM dm; 1123 1124 PetscFunctionBegin; 1125 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1126 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1127 ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr); 1128 PetscFunctionReturn(0); 1129 } 1130 1131 /*@C 1132 TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE 1133 1134 Logically Collective on TS 1135 1136 Input Parameters: 1137 + ts - the TS context obtained from TSCreate() 1138 . func - routine for evaluating the forcing function 1139 - ctx - [optional] user-defined context for private data for the 1140 function evaluation routine (may be NULL) 1141 1142 Calling sequence of func: 1143 $ PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx); 1144 1145 + t - current timestep 1146 . f - output vector 1147 - ctx - [optional] user-defined function context 1148 1149 Notes: 1150 This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to 1151 create closed-form solutions with a non-physical forcing term. It allows you to use the Method of Manufactored Solution without directly editing the 1152 definition of the problem you are solving and hence possibly introducing bugs. 1153 1154 This replaces the ODE F(u,u_t,t) = 0 the TS is solving with F(u,u_t,t) - func(t) = 0 1155 1156 This forcing function does not depend on the solution to the equations, it can only depend on spatial location, time, and possibly parameters, the 1157 parameters can be passed in the ctx variable. 1158 1159 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 1160 1161 Level: beginner 1162 1163 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction() 1164 @*/ 1165 PetscErrorCode TSSetForcingFunction(TS ts,TSForcingFunction func,void *ctx) 1166 { 1167 PetscErrorCode ierr; 1168 DM dm; 1169 1170 PetscFunctionBegin; 1171 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1172 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1173 ierr = DMTSSetForcingFunction(dm,func,ctx);CHKERRQ(ierr); 1174 PetscFunctionReturn(0); 1175 } 1176 1177 /*@C 1178 TSSetRHSJacobian - Sets the function to compute the Jacobian of G, 1179 where U_t = G(U,t), as well as the location to store the matrix. 1180 1181 Logically Collective on TS 1182 1183 Input Parameters: 1184 + ts - the TS context obtained from TSCreate() 1185 . Amat - (approximate) Jacobian matrix 1186 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1187 . f - the Jacobian evaluation routine 1188 - ctx - [optional] user-defined context for private data for the 1189 Jacobian evaluation routine (may be NULL) 1190 1191 Calling sequence of f: 1192 $ PetscErrorCode f(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx); 1193 1194 + t - current timestep 1195 . u - input vector 1196 . Amat - (approximate) Jacobian matrix 1197 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1198 - ctx - [optional] user-defined context for matrix evaluation routine 1199 1200 Notes: 1201 You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value 1202 1203 The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f() 1204 You should not assume the values are the same in the next call to f() as you set them in the previous call. 1205 1206 Level: beginner 1207 1208 .seealso: SNESComputeJacobianDefaultColor(), TSSetRHSFunction(), TSRHSJacobianSetReuse(), TSSetIJacobian() 1209 1210 @*/ 1211 PetscErrorCode TSSetRHSJacobian(TS ts,Mat Amat,Mat Pmat,TSRHSJacobian f,void *ctx) 1212 { 1213 PetscErrorCode ierr; 1214 SNES snes; 1215 DM dm; 1216 TSIJacobian ijacobian; 1217 1218 PetscFunctionBegin; 1219 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1220 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1221 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1222 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1223 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1224 1225 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1226 ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr); 1227 if (f == TSComputeRHSJacobianConstant) { 1228 /* Handle this case automatically for the user; otherwise user should call themselves. */ 1229 ierr = TSRHSJacobianSetReuse(ts,PETSC_TRUE);CHKERRQ(ierr); 1230 } 1231 ierr = DMTSGetIJacobian(dm,&ijacobian,NULL);CHKERRQ(ierr); 1232 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1233 if (!ijacobian) { 1234 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1235 } 1236 if (Amat) { 1237 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 1238 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1239 ts->Arhs = Amat; 1240 } 1241 if (Pmat) { 1242 ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 1243 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1244 ts->Brhs = Pmat; 1245 } 1246 PetscFunctionReturn(0); 1247 } 1248 1249 /*@C 1250 TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved. 1251 1252 Logically Collective on TS 1253 1254 Input Parameters: 1255 + ts - the TS context obtained from TSCreate() 1256 . r - vector to hold the residual (or NULL to have it created internally) 1257 . f - the function evaluation routine 1258 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1259 1260 Calling sequence of f: 1261 $ PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 1262 1263 + t - time at step/stage being solved 1264 . u - state vector 1265 . u_t - time derivative of state vector 1266 . F - function vector 1267 - ctx - [optional] user-defined context for matrix evaluation routine 1268 1269 Important: 1270 The user MUST call either this routine or TSSetRHSFunction() to define the ODE. When solving DAEs you must use this function. 1271 1272 Level: beginner 1273 1274 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian() 1275 @*/ 1276 PetscErrorCode TSSetIFunction(TS ts,Vec r,TSIFunction f,void *ctx) 1277 { 1278 PetscErrorCode ierr; 1279 SNES snes; 1280 Vec ralloc = NULL; 1281 DM dm; 1282 1283 PetscFunctionBegin; 1284 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1285 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1286 1287 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1288 ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr); 1289 1290 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1291 if (!r && !ts->dm && ts->vec_sol) { 1292 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 1293 r = ralloc; 1294 } 1295 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 1296 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 1297 PetscFunctionReturn(0); 1298 } 1299 1300 /*@C 1301 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1302 1303 Not Collective 1304 1305 Input Parameter: 1306 . ts - the TS context 1307 1308 Output Parameter: 1309 + r - vector to hold residual (or NULL) 1310 . func - the function to compute residual (or NULL) 1311 - ctx - the function context (or NULL) 1312 1313 Level: advanced 1314 1315 .seealso: TSSetIFunction(), SNESGetFunction() 1316 @*/ 1317 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 1318 { 1319 PetscErrorCode ierr; 1320 SNES snes; 1321 DM dm; 1322 1323 PetscFunctionBegin; 1324 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1325 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1326 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1327 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1328 ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr); 1329 PetscFunctionReturn(0); 1330 } 1331 1332 /*@C 1333 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 1334 1335 Not Collective 1336 1337 Input Parameter: 1338 . ts - the TS context 1339 1340 Output Parameter: 1341 + r - vector to hold computed right hand side (or NULL) 1342 . func - the function to compute right hand side (or NULL) 1343 - ctx - the function context (or NULL) 1344 1345 Level: advanced 1346 1347 .seealso: TSSetRHSFunction(), SNESGetFunction() 1348 @*/ 1349 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 1350 { 1351 PetscErrorCode ierr; 1352 SNES snes; 1353 DM dm; 1354 1355 PetscFunctionBegin; 1356 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1357 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1358 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1359 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1360 ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr); 1361 PetscFunctionReturn(0); 1362 } 1363 1364 /*@C 1365 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 1366 provided with TSSetIFunction(). 1367 1368 Logically Collective on TS 1369 1370 Input Parameters: 1371 + ts - the TS context obtained from TSCreate() 1372 . Amat - (approximate) Jacobian matrix 1373 . Pmat - matrix used to compute preconditioner (usually the same as Amat) 1374 . f - the Jacobian evaluation routine 1375 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1376 1377 Calling sequence of f: 1378 $ PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx); 1379 1380 + t - time at step/stage being solved 1381 . U - state vector 1382 . U_t - time derivative of state vector 1383 . a - shift 1384 . Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 1385 . Pmat - matrix used for constructing preconditioner, usually the same as Amat 1386 - ctx - [optional] user-defined context for matrix evaluation routine 1387 1388 Notes: 1389 The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve. 1390 1391 If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 1392 space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 1393 1394 The matrix dF/dU + a*dF/dU_t you provide turns out to be 1395 the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 1396 The time integrator internally approximates U_t by W+a*U where the positive "shift" 1397 a and vector W depend on the integration method, step size, and past states. For example with 1398 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 1399 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 1400 1401 You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value 1402 1403 The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f() 1404 You should not assume the values are the same in the next call to f() as you set them in the previous call. 1405 1406 Level: beginner 1407 1408 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESComputeJacobianDefaultColor(), SNESComputeJacobianDefault(), TSSetRHSFunction() 1409 1410 @*/ 1411 PetscErrorCode TSSetIJacobian(TS ts,Mat Amat,Mat Pmat,TSIJacobian f,void *ctx) 1412 { 1413 PetscErrorCode ierr; 1414 SNES snes; 1415 DM dm; 1416 1417 PetscFunctionBegin; 1418 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1419 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1420 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1421 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1422 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1423 1424 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1425 ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr); 1426 1427 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1428 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1429 PetscFunctionReturn(0); 1430 } 1431 1432 /*@ 1433 TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating. Without this flag, TS will change the sign and 1434 shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute 1435 the entire Jacobian. The reuse flag must be set if the evaluation function will assume that the matrix entries have 1436 not been changed by the TS. 1437 1438 Logically Collective 1439 1440 Input Arguments: 1441 + ts - TS context obtained from TSCreate() 1442 - reuse - PETSC_TRUE if the RHS Jacobian 1443 1444 Level: intermediate 1445 1446 .seealso: TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 1447 @*/ 1448 PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse) 1449 { 1450 PetscFunctionBegin; 1451 ts->rhsjacobian.reuse = reuse; 1452 PetscFunctionReturn(0); 1453 } 1454 1455 /*@C 1456 TSSetI2Function - Set the function to compute F(t,U,U_t,U_tt) where F = 0 is the DAE to be solved. 1457 1458 Logically Collective on TS 1459 1460 Input Parameters: 1461 + ts - the TS context obtained from TSCreate() 1462 . F - vector to hold the residual (or NULL to have it created internally) 1463 . fun - the function evaluation routine 1464 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1465 1466 Calling sequence of fun: 1467 $ PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx); 1468 1469 + t - time at step/stage being solved 1470 . U - state vector 1471 . U_t - time derivative of state vector 1472 . U_tt - second time derivative of state vector 1473 . F - function vector 1474 - ctx - [optional] user-defined context for matrix evaluation routine (may be NULL) 1475 1476 Level: beginner 1477 1478 .seealso: TSSetI2Jacobian(), TSSetIFunction(), TSCreate(), TSSetRHSFunction() 1479 @*/ 1480 PetscErrorCode TSSetI2Function(TS ts,Vec F,TSI2Function fun,void *ctx) 1481 { 1482 DM dm; 1483 PetscErrorCode ierr; 1484 1485 PetscFunctionBegin; 1486 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1487 if (F) PetscValidHeaderSpecific(F,VEC_CLASSID,2); 1488 ierr = TSSetIFunction(ts,F,NULL,NULL);CHKERRQ(ierr); 1489 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1490 ierr = DMTSSetI2Function(dm,fun,ctx);CHKERRQ(ierr); 1491 PetscFunctionReturn(0); 1492 } 1493 1494 /*@C 1495 TSGetI2Function - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1496 1497 Not Collective 1498 1499 Input Parameter: 1500 . ts - the TS context 1501 1502 Output Parameter: 1503 + r - vector to hold residual (or NULL) 1504 . fun - the function to compute residual (or NULL) 1505 - ctx - the function context (or NULL) 1506 1507 Level: advanced 1508 1509 .seealso: TSSetIFunction(), SNESGetFunction(), TSCreate() 1510 @*/ 1511 PetscErrorCode TSGetI2Function(TS ts,Vec *r,TSI2Function *fun,void **ctx) 1512 { 1513 PetscErrorCode ierr; 1514 SNES snes; 1515 DM dm; 1516 1517 PetscFunctionBegin; 1518 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1519 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1520 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1521 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1522 ierr = DMTSGetI2Function(dm,fun,ctx);CHKERRQ(ierr); 1523 PetscFunctionReturn(0); 1524 } 1525 1526 /*@C 1527 TSSetI2Jacobian - Set the function to compute the matrix dF/dU + v*dF/dU_t + a*dF/dU_tt 1528 where F(t,U,U_t,U_tt) is the function you provided with TSSetI2Function(). 1529 1530 Logically Collective on TS 1531 1532 Input Parameters: 1533 + ts - the TS context obtained from TSCreate() 1534 . J - Jacobian matrix 1535 . P - preconditioning matrix for J (may be same as J) 1536 . jac - the Jacobian evaluation routine 1537 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1538 1539 Calling sequence of jac: 1540 $ PetscErrorCode jac(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,PetscReal v,PetscReal a,Mat J,Mat P,void *ctx); 1541 1542 + t - time at step/stage being solved 1543 . U - state vector 1544 . U_t - time derivative of state vector 1545 . U_tt - second time derivative of state vector 1546 . v - shift for U_t 1547 . a - shift for U_tt 1548 . J - Jacobian of G(U) = F(t,U,W+v*U,W'+a*U), equivalent to dF/dU + v*dF/dU_t + a*dF/dU_tt 1549 . P - preconditioning matrix for J, may be same as J 1550 - ctx - [optional] user-defined context for matrix evaluation routine 1551 1552 Notes: 1553 The matrices J and P are exactly the matrices that are used by SNES for the nonlinear solve. 1554 1555 The matrix dF/dU + v*dF/dU_t + a*dF/dU_tt you provide turns out to be 1556 the Jacobian of G(U) = F(t,U,W+v*U,W'+a*U) where F(t,U,U_t,U_tt) = 0 is the DAE to be solved. 1557 The time integrator internally approximates U_t by W+v*U and U_tt by W'+a*U where the positive "shift" 1558 parameters 'v' and 'a' and vectors W, W' depend on the integration method, step size, and past states. 1559 1560 Level: beginner 1561 1562 .seealso: TSSetI2Function(), TSGetI2Jacobian() 1563 @*/ 1564 PetscErrorCode TSSetI2Jacobian(TS ts,Mat J,Mat P,TSI2Jacobian jac,void *ctx) 1565 { 1566 DM dm; 1567 PetscErrorCode ierr; 1568 1569 PetscFunctionBegin; 1570 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1571 if (J) PetscValidHeaderSpecific(J,MAT_CLASSID,2); 1572 if (P) PetscValidHeaderSpecific(P,MAT_CLASSID,3); 1573 ierr = TSSetIJacobian(ts,J,P,NULL,NULL);CHKERRQ(ierr); 1574 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1575 ierr = DMTSSetI2Jacobian(dm,jac,ctx);CHKERRQ(ierr); 1576 PetscFunctionReturn(0); 1577 } 1578 1579 /*@C 1580 TSGetI2Jacobian - Returns the implicit Jacobian at the present timestep. 1581 1582 Not Collective, but parallel objects are returned if TS is parallel 1583 1584 Input Parameter: 1585 . ts - The TS context obtained from TSCreate() 1586 1587 Output Parameters: 1588 + J - The (approximate) Jacobian of F(t,U,U_t,U_tt) 1589 . P - The matrix from which the preconditioner is constructed, often the same as J 1590 . jac - The function to compute the Jacobian matrices 1591 - ctx - User-defined context for Jacobian evaluation routine 1592 1593 Notes: 1594 You can pass in NULL for any return argument you do not need. 1595 1596 Level: advanced 1597 1598 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber(), TSSetI2Jacobian(), TSGetI2Function(), TSCreate() 1599 1600 @*/ 1601 PetscErrorCode TSGetI2Jacobian(TS ts,Mat *J,Mat *P,TSI2Jacobian *jac,void **ctx) 1602 { 1603 PetscErrorCode ierr; 1604 SNES snes; 1605 DM dm; 1606 1607 PetscFunctionBegin; 1608 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1609 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 1610 ierr = SNESGetJacobian(snes,J,P,NULL,NULL);CHKERRQ(ierr); 1611 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1612 ierr = DMTSGetI2Jacobian(dm,jac,ctx);CHKERRQ(ierr); 1613 PetscFunctionReturn(0); 1614 } 1615 1616 /*@ 1617 TSComputeI2Function - Evaluates the DAE residual written in implicit form F(t,U,U_t,U_tt) = 0 1618 1619 Collective on TS 1620 1621 Input Parameters: 1622 + ts - the TS context 1623 . t - current time 1624 . U - state vector 1625 . V - time derivative of state vector (U_t) 1626 - A - second time derivative of state vector (U_tt) 1627 1628 Output Parameter: 1629 . F - the residual vector 1630 1631 Note: 1632 Most users should not need to explicitly call this routine, as it 1633 is used internally within the nonlinear solvers. 1634 1635 Level: developer 1636 1637 .seealso: TSSetI2Function(), TSGetI2Function() 1638 @*/ 1639 PetscErrorCode TSComputeI2Function(TS ts,PetscReal t,Vec U,Vec V,Vec A,Vec F) 1640 { 1641 DM dm; 1642 TSI2Function I2Function; 1643 void *ctx; 1644 TSRHSFunction rhsfunction; 1645 PetscErrorCode ierr; 1646 1647 PetscFunctionBegin; 1648 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1649 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 1650 PetscValidHeaderSpecific(V,VEC_CLASSID,4); 1651 PetscValidHeaderSpecific(A,VEC_CLASSID,5); 1652 PetscValidHeaderSpecific(F,VEC_CLASSID,6); 1653 1654 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1655 ierr = DMTSGetI2Function(dm,&I2Function,&ctx);CHKERRQ(ierr); 1656 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 1657 1658 if (!I2Function) { 1659 ierr = TSComputeIFunction(ts,t,U,A,F,PETSC_FALSE);CHKERRQ(ierr); 1660 PetscFunctionReturn(0); 1661 } 1662 1663 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,V,F);CHKERRQ(ierr); 1664 1665 PetscStackPush("TS user implicit function"); 1666 ierr = I2Function(ts,t,U,V,A,F,ctx);CHKERRQ(ierr); 1667 PetscStackPop; 1668 1669 if (rhsfunction) { 1670 Vec Frhs; 1671 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 1672 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 1673 ierr = VecAXPY(F,-1,Frhs);CHKERRQ(ierr); 1674 } 1675 1676 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,V,F);CHKERRQ(ierr); 1677 PetscFunctionReturn(0); 1678 } 1679 1680 /*@ 1681 TSComputeI2Jacobian - Evaluates the Jacobian of the DAE 1682 1683 Collective on TS 1684 1685 Input Parameters: 1686 + ts - the TS context 1687 . t - current timestep 1688 . U - state vector 1689 . V - time derivative of state vector 1690 . A - second time derivative of state vector 1691 . shiftV - shift to apply, see note below 1692 - shiftA - shift to apply, see note below 1693 1694 Output Parameters: 1695 + J - Jacobian matrix 1696 - P - optional preconditioning matrix 1697 1698 Notes: 1699 If F(t,U,V,A)=0 is the DAE, the required Jacobian is 1700 1701 dF/dU + shiftV*dF/dV + shiftA*dF/dA 1702 1703 Most users should not need to explicitly call this routine, as it 1704 is used internally within the nonlinear solvers. 1705 1706 Level: developer 1707 1708 .seealso: TSSetI2Jacobian() 1709 @*/ 1710 PetscErrorCode TSComputeI2Jacobian(TS ts,PetscReal t,Vec U,Vec V,Vec A,PetscReal shiftV,PetscReal shiftA,Mat J,Mat P) 1711 { 1712 DM dm; 1713 TSI2Jacobian I2Jacobian; 1714 void *ctx; 1715 TSRHSJacobian rhsjacobian; 1716 PetscErrorCode ierr; 1717 1718 PetscFunctionBegin; 1719 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1720 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 1721 PetscValidHeaderSpecific(V,VEC_CLASSID,4); 1722 PetscValidHeaderSpecific(A,VEC_CLASSID,5); 1723 PetscValidHeaderSpecific(J,MAT_CLASSID,8); 1724 PetscValidHeaderSpecific(P,MAT_CLASSID,9); 1725 1726 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1727 ierr = DMTSGetI2Jacobian(dm,&I2Jacobian,&ctx);CHKERRQ(ierr); 1728 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 1729 1730 if (!I2Jacobian) { 1731 ierr = TSComputeIJacobian(ts,t,U,A,shiftA,J,P,PETSC_FALSE);CHKERRQ(ierr); 1732 PetscFunctionReturn(0); 1733 } 1734 1735 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,J,P);CHKERRQ(ierr); 1736 1737 PetscStackPush("TS user implicit Jacobian"); 1738 ierr = I2Jacobian(ts,t,U,V,A,shiftV,shiftA,J,P,ctx);CHKERRQ(ierr); 1739 PetscStackPop; 1740 1741 if (rhsjacobian) { 1742 Mat Jrhs,Prhs; MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 1743 ierr = TSGetRHSMats_Private(ts,&Jrhs,&Prhs);CHKERRQ(ierr); 1744 ierr = TSComputeRHSJacobian(ts,t,U,Jrhs,Prhs);CHKERRQ(ierr); 1745 ierr = MatAXPY(J,-1,Jrhs,axpy);CHKERRQ(ierr); 1746 if (P != J) {ierr = MatAXPY(P,-1,Prhs,axpy);CHKERRQ(ierr);} 1747 } 1748 1749 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,J,P);CHKERRQ(ierr); 1750 PetscFunctionReturn(0); 1751 } 1752 1753 /*@C 1754 TSSetTransientVariable - sets function to transform from state to transient variables 1755 1756 Logically Collective 1757 1758 Input Arguments: 1759 + ts - time stepping context on which to change the transient variable 1760 . tvar - a function that transforms to transient variables 1761 - ctx - a context for tvar 1762 1763 Calling sequence of tvar: 1764 $ PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx); 1765 1766 + ts - timestep context 1767 . p - input vector (primative form) 1768 . c - output vector, transient variables (conservative form) 1769 - ctx - [optional] user-defined function context 1770 1771 Level: advanced 1772 1773 Notes: 1774 This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., TSBDF) 1775 can be conservative. In this context, primitive variables P are used to model the state (e.g., because they lead to 1776 well-conditioned formulations even in limiting cases such as low-Mach or zero porosity). The transient variable is 1777 C(P), specified by calling this function. An IFunction thus receives arguments (P, Cdot) and the IJacobian must be 1778 evaluated via the chain rule, as in 1779 1780 dF/dP + shift * dF/dCdot dC/dP. 1781 1782 .seealso: DMTSSetTransientVariable(), DMTSGetTransientVariable(), TSSetIFunction(), TSSetIJacobian() 1783 @*/ 1784 PetscErrorCode TSSetTransientVariable(TS ts,TSTransientVariable tvar,void *ctx) 1785 { 1786 PetscErrorCode ierr; 1787 DM dm; 1788 1789 PetscFunctionBegin; 1790 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1791 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1792 ierr = DMTSSetTransientVariable(dm,tvar,ctx);CHKERRQ(ierr); 1793 PetscFunctionReturn(0); 1794 } 1795 1796 /*@ 1797 TSComputeTransientVariable - transforms state (primitive) variables to transient (conservative) variables 1798 1799 Logically Collective 1800 1801 Input Parameters: 1802 + ts - TS on which to compute 1803 - U - state vector to be transformed to transient variables 1804 1805 Output Parameters: 1806 . C - transient (conservative) variable 1807 1808 Developer Notes: 1809 If DMTSSetTransientVariable() has not been called, then C is not modified in this routine and C=NULL is allowed. 1810 This makes it safe to call without a guard. One can use TSHasTransientVariable() to check if transient variables are 1811 being used. 1812 1813 Level: developer 1814 1815 .seealso: DMTSSetTransientVariable(), TSComputeIFunction(), TSComputeIJacobian() 1816 @*/ 1817 PetscErrorCode TSComputeTransientVariable(TS ts,Vec U,Vec C) 1818 { 1819 PetscErrorCode ierr; 1820 DM dm; 1821 DMTS dmts; 1822 1823 PetscFunctionBegin; 1824 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1825 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 1826 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1827 ierr = DMGetDMTS(dm,&dmts);CHKERRQ(ierr); 1828 if (dmts->ops->transientvar) { 1829 PetscValidHeaderSpecific(C,VEC_CLASSID,3); 1830 ierr = (*dmts->ops->transientvar)(ts,U,C,dmts->transientvarctx);CHKERRQ(ierr); 1831 } 1832 PetscFunctionReturn(0); 1833 } 1834 1835 /*@ 1836 TSHasTransientVariable - determine whether transient variables have been set 1837 1838 Logically Collective 1839 1840 Input Parameters: 1841 . ts - TS on which to compute 1842 1843 Output Parameters: 1844 . has - PETSC_TRUE if transient variables have been set 1845 1846 Level: developer 1847 1848 .seealso: DMTSSetTransientVariable(), TSComputeTransientVariable() 1849 @*/ 1850 PetscErrorCode TSHasTransientVariable(TS ts,PetscBool *has) 1851 { 1852 PetscErrorCode ierr; 1853 DM dm; 1854 DMTS dmts; 1855 1856 PetscFunctionBegin; 1857 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1858 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1859 ierr = DMGetDMTS(dm,&dmts);CHKERRQ(ierr); 1860 *has = dmts->ops->transientvar ? PETSC_TRUE : PETSC_FALSE; 1861 PetscFunctionReturn(0); 1862 } 1863 1864 /*@ 1865 TS2SetSolution - Sets the initial solution and time derivative vectors 1866 for use by the TS routines handling second order equations. 1867 1868 Logically Collective on TS 1869 1870 Input Parameters: 1871 + ts - the TS context obtained from TSCreate() 1872 . u - the solution vector 1873 - v - the time derivative vector 1874 1875 Level: beginner 1876 1877 @*/ 1878 PetscErrorCode TS2SetSolution(TS ts,Vec u,Vec v) 1879 { 1880 PetscErrorCode ierr; 1881 1882 PetscFunctionBegin; 1883 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1884 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 1885 PetscValidHeaderSpecific(v,VEC_CLASSID,3); 1886 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 1887 ierr = PetscObjectReference((PetscObject)v);CHKERRQ(ierr); 1888 ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr); 1889 ts->vec_dot = v; 1890 PetscFunctionReturn(0); 1891 } 1892 1893 /*@ 1894 TS2GetSolution - Returns the solution and time derivative at the present timestep 1895 for second order equations. It is valid to call this routine inside the function 1896 that you are evaluating in order to move to the new timestep. This vector not 1897 changed until the solution at the next timestep has been calculated. 1898 1899 Not Collective, but Vec returned is parallel if TS is parallel 1900 1901 Input Parameter: 1902 . ts - the TS context obtained from TSCreate() 1903 1904 Output Parameter: 1905 + u - the vector containing the solution 1906 - v - the vector containing the time derivative 1907 1908 Level: intermediate 1909 1910 .seealso: TS2SetSolution(), TSGetTimeStep(), TSGetTime() 1911 1912 @*/ 1913 PetscErrorCode TS2GetSolution(TS ts,Vec *u,Vec *v) 1914 { 1915 PetscFunctionBegin; 1916 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1917 if (u) PetscValidPointer(u,2); 1918 if (v) PetscValidPointer(v,3); 1919 if (u) *u = ts->vec_sol; 1920 if (v) *v = ts->vec_dot; 1921 PetscFunctionReturn(0); 1922 } 1923 1924 /*@C 1925 TSLoad - Loads a KSP that has been stored in binary with KSPView(). 1926 1927 Collective on PetscViewer 1928 1929 Input Parameters: 1930 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or 1931 some related function before a call to TSLoad(). 1932 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 1933 1934 Level: intermediate 1935 1936 Notes: 1937 The type is determined by the data in the file, any type set into the TS before this call is ignored. 1938 1939 Notes for advanced users: 1940 Most users should not need to know the details of the binary storage 1941 format, since TSLoad() and TSView() completely hide these details. 1942 But for anyone who's interested, the standard binary matrix storage 1943 format is 1944 .vb 1945 has not yet been determined 1946 .ve 1947 1948 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad() 1949 @*/ 1950 PetscErrorCode TSLoad(TS ts, PetscViewer viewer) 1951 { 1952 PetscErrorCode ierr; 1953 PetscBool isbinary; 1954 PetscInt classid; 1955 char type[256]; 1956 DMTS sdm; 1957 DM dm; 1958 1959 PetscFunctionBegin; 1960 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1961 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1962 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1963 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 1964 1965 ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 1966 if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file"); 1967 ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 1968 ierr = TSSetType(ts, type);CHKERRQ(ierr); 1969 if (ts->ops->load) { 1970 ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr); 1971 } 1972 ierr = DMCreate(PetscObjectComm((PetscObject)ts),&dm);CHKERRQ(ierr); 1973 ierr = DMLoad(dm,viewer);CHKERRQ(ierr); 1974 ierr = TSSetDM(ts,dm);CHKERRQ(ierr); 1975 ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr); 1976 ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr); 1977 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1978 ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr); 1979 PetscFunctionReturn(0); 1980 } 1981 1982 #include <petscdraw.h> 1983 #if defined(PETSC_HAVE_SAWS) 1984 #include <petscviewersaws.h> 1985 #endif 1986 1987 /*@C 1988 TSViewFromOptions - View from Options 1989 1990 Collective on TS 1991 1992 Input Parameters: 1993 + A - the application ordering context 1994 . obj - Optional object 1995 - name - command line option 1996 1997 Level: intermediate 1998 .seealso: TS, TSView, PetscObjectViewFromOptions(), TSCreate() 1999 @*/ 2000 PetscErrorCode TSViewFromOptions(TS A,PetscObject obj,const char name[]) 2001 { 2002 PetscErrorCode ierr; 2003 2004 PetscFunctionBegin; 2005 PetscValidHeaderSpecific(A,TS_CLASSID,1); 2006 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 2007 PetscFunctionReturn(0); 2008 } 2009 2010 /*@C 2011 TSView - Prints the TS data structure. 2012 2013 Collective on TS 2014 2015 Input Parameters: 2016 + ts - the TS context obtained from TSCreate() 2017 - viewer - visualization context 2018 2019 Options Database Key: 2020 . -ts_view - calls TSView() at end of TSStep() 2021 2022 Notes: 2023 The available visualization contexts include 2024 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 2025 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 2026 output where only the first processor opens 2027 the file. All other processors send their 2028 data to the first processor to print. 2029 2030 The user can open an alternative visualization context with 2031 PetscViewerASCIIOpen() - output to a specified file. 2032 2033 Level: beginner 2034 2035 .seealso: PetscViewerASCIIOpen() 2036 @*/ 2037 PetscErrorCode TSView(TS ts,PetscViewer viewer) 2038 { 2039 PetscErrorCode ierr; 2040 TSType type; 2041 PetscBool iascii,isstring,isundials,isbinary,isdraw; 2042 DMTS sdm; 2043 #if defined(PETSC_HAVE_SAWS) 2044 PetscBool issaws; 2045 #endif 2046 2047 PetscFunctionBegin; 2048 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2049 if (!viewer) { 2050 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr); 2051 } 2052 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 2053 PetscCheckSameComm(ts,1,viewer,2); 2054 2055 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2056 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 2057 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 2058 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 2059 #if defined(PETSC_HAVE_SAWS) 2060 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 2061 #endif 2062 if (iascii) { 2063 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer);CHKERRQ(ierr); 2064 if (ts->ops->view) { 2065 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2066 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 2067 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2068 } 2069 if (ts->max_steps < PETSC_MAX_INT) { 2070 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 2071 } 2072 if (ts->max_time < PETSC_MAX_REAL) { 2073 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%g\n",(double)ts->max_time);CHKERRQ(ierr); 2074 } 2075 if (ts->usessnes) { 2076 PetscBool lin; 2077 if (ts->problem_type == TS_NONLINEAR) { 2078 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr); 2079 } 2080 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr); 2081 ierr = PetscObjectTypeCompareAny((PetscObject)ts->snes,&lin,SNESKSPONLY,SNESKSPTRANSPOSEONLY,"");CHKERRQ(ierr); 2082 ierr = PetscViewerASCIIPrintf(viewer," total number of %slinear solve failures=%D\n",lin ? "" : "non",ts->num_snes_failures);CHKERRQ(ierr); 2083 } 2084 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 2085 if (ts->vrtol) { 2086 ierr = PetscViewerASCIIPrintf(viewer," using vector of relative error tolerances, ");CHKERRQ(ierr); 2087 } else { 2088 ierr = PetscViewerASCIIPrintf(viewer," using relative error tolerance of %g, ",(double)ts->rtol);CHKERRQ(ierr); 2089 } 2090 if (ts->vatol) { 2091 ierr = PetscViewerASCIIPrintf(viewer," using vector of absolute error tolerances\n");CHKERRQ(ierr); 2092 } else { 2093 ierr = PetscViewerASCIIPrintf(viewer," using absolute error tolerance of %g\n",(double)ts->atol);CHKERRQ(ierr); 2094 } 2095 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2096 ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr); 2097 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2098 } else if (isstring) { 2099 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 2100 ierr = PetscViewerStringSPrintf(viewer," TSType: %-7.7s",type);CHKERRQ(ierr); 2101 if (ts->ops->view) {ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);} 2102 } else if (isbinary) { 2103 PetscInt classid = TS_FILE_CLASSID; 2104 MPI_Comm comm; 2105 PetscMPIInt rank; 2106 char type[256]; 2107 2108 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 2109 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 2110 if (!rank) { 2111 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 2112 ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr); 2113 ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr); 2114 } 2115 if (ts->ops->view) { 2116 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 2117 } 2118 if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);} 2119 ierr = DMView(ts->dm,viewer);CHKERRQ(ierr); 2120 ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr); 2121 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 2122 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 2123 } else if (isdraw) { 2124 PetscDraw draw; 2125 char str[36]; 2126 PetscReal x,y,bottom,h; 2127 2128 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 2129 ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 2130 ierr = PetscStrcpy(str,"TS: ");CHKERRQ(ierr); 2131 ierr = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr); 2132 ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 2133 bottom = y - h; 2134 ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 2135 if (ts->ops->view) { 2136 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 2137 } 2138 if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);} 2139 if (ts->snes) {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);} 2140 ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 2141 #if defined(PETSC_HAVE_SAWS) 2142 } else if (issaws) { 2143 PetscMPIInt rank; 2144 const char *name; 2145 2146 ierr = PetscObjectGetName((PetscObject)ts,&name);CHKERRQ(ierr); 2147 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 2148 if (!((PetscObject)ts)->amsmem && !rank) { 2149 char dir[1024]; 2150 2151 ierr = PetscObjectViewSAWs((PetscObject)ts,viewer);CHKERRQ(ierr); 2152 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);CHKERRQ(ierr); 2153 PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT)); 2154 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);CHKERRQ(ierr); 2155 PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE)); 2156 } 2157 if (ts->ops->view) { 2158 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 2159 } 2160 #endif 2161 } 2162 if (ts->snes && ts->usessnes) { 2163 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2164 ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr); 2165 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2166 } 2167 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 2168 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 2169 2170 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2171 ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 2172 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2173 PetscFunctionReturn(0); 2174 } 2175 2176 /*@ 2177 TSSetApplicationContext - Sets an optional user-defined context for 2178 the timesteppers. 2179 2180 Logically Collective on TS 2181 2182 Input Parameters: 2183 + ts - the TS context obtained from TSCreate() 2184 - usrP - optional user context 2185 2186 Fortran Notes: 2187 To use this from Fortran you must write a Fortran interface definition for this 2188 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 2189 2190 Level: intermediate 2191 2192 .seealso: TSGetApplicationContext() 2193 @*/ 2194 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 2195 { 2196 PetscFunctionBegin; 2197 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2198 ts->user = usrP; 2199 PetscFunctionReturn(0); 2200 } 2201 2202 /*@ 2203 TSGetApplicationContext - Gets the user-defined context for the 2204 timestepper. 2205 2206 Not Collective 2207 2208 Input Parameter: 2209 . ts - the TS context obtained from TSCreate() 2210 2211 Output Parameter: 2212 . usrP - user context 2213 2214 Fortran Notes: 2215 To use this from Fortran you must write a Fortran interface definition for this 2216 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 2217 2218 Level: intermediate 2219 2220 .seealso: TSSetApplicationContext() 2221 @*/ 2222 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 2223 { 2224 PetscFunctionBegin; 2225 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2226 *(void**)usrP = ts->user; 2227 PetscFunctionReturn(0); 2228 } 2229 2230 /*@ 2231 TSGetStepNumber - Gets the number of steps completed. 2232 2233 Not Collective 2234 2235 Input Parameter: 2236 . ts - the TS context obtained from TSCreate() 2237 2238 Output Parameter: 2239 . steps - number of steps completed so far 2240 2241 Level: intermediate 2242 2243 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep() 2244 @*/ 2245 PetscErrorCode TSGetStepNumber(TS ts,PetscInt *steps) 2246 { 2247 PetscFunctionBegin; 2248 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2249 PetscValidIntPointer(steps,2); 2250 *steps = ts->steps; 2251 PetscFunctionReturn(0); 2252 } 2253 2254 /*@ 2255 TSSetStepNumber - Sets the number of steps completed. 2256 2257 Logically Collective on TS 2258 2259 Input Parameters: 2260 + ts - the TS context 2261 - steps - number of steps completed so far 2262 2263 Notes: 2264 For most uses of the TS solvers the user need not explicitly call 2265 TSSetStepNumber(), as the step counter is appropriately updated in 2266 TSSolve()/TSStep()/TSRollBack(). Power users may call this routine to 2267 reinitialize timestepping by setting the step counter to zero (and time 2268 to the initial time) to solve a similar problem with different initial 2269 conditions or parameters. Other possible use case is to continue 2270 timestepping from a previously interrupted run in such a way that TS 2271 monitors will be called with a initial nonzero step counter. 2272 2273 Level: advanced 2274 2275 .seealso: TSGetStepNumber(), TSSetTime(), TSSetTimeStep(), TSSetSolution() 2276 @*/ 2277 PetscErrorCode TSSetStepNumber(TS ts,PetscInt steps) 2278 { 2279 PetscFunctionBegin; 2280 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2281 PetscValidLogicalCollectiveInt(ts,steps,2); 2282 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Step number must be non-negative"); 2283 ts->steps = steps; 2284 PetscFunctionReturn(0); 2285 } 2286 2287 /*@ 2288 TSSetTimeStep - Allows one to reset the timestep at any time, 2289 useful for simple pseudo-timestepping codes. 2290 2291 Logically Collective on TS 2292 2293 Input Parameters: 2294 + ts - the TS context obtained from TSCreate() 2295 - time_step - the size of the timestep 2296 2297 Level: intermediate 2298 2299 .seealso: TSGetTimeStep(), TSSetTime() 2300 2301 @*/ 2302 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 2303 { 2304 PetscFunctionBegin; 2305 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2306 PetscValidLogicalCollectiveReal(ts,time_step,2); 2307 ts->time_step = time_step; 2308 PetscFunctionReturn(0); 2309 } 2310 2311 /*@ 2312 TSSetExactFinalTime - Determines whether to adapt the final time step to 2313 match the exact final time, interpolate solution to the exact final time, 2314 or just return at the final time TS computed. 2315 2316 Logically Collective on TS 2317 2318 Input Parameter: 2319 + ts - the time-step context 2320 - eftopt - exact final time option 2321 2322 $ TS_EXACTFINALTIME_STEPOVER - Don't do anything if final time is exceeded 2323 $ TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time 2324 $ TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time 2325 2326 Options Database: 2327 . -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step at runtime 2328 2329 Warning: If you use the option TS_EXACTFINALTIME_STEPOVER the solution may be at a very different time 2330 then the final time you selected. 2331 2332 Level: beginner 2333 2334 .seealso: TSExactFinalTimeOption, TSGetExactFinalTime() 2335 @*/ 2336 PetscErrorCode TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt) 2337 { 2338 PetscFunctionBegin; 2339 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2340 PetscValidLogicalCollectiveEnum(ts,eftopt,2); 2341 ts->exact_final_time = eftopt; 2342 PetscFunctionReturn(0); 2343 } 2344 2345 /*@ 2346 TSGetExactFinalTime - Gets the exact final time option. 2347 2348 Not Collective 2349 2350 Input Parameter: 2351 . ts - the TS context 2352 2353 Output Parameter: 2354 . eftopt - exact final time option 2355 2356 Level: beginner 2357 2358 .seealso: TSExactFinalTimeOption, TSSetExactFinalTime() 2359 @*/ 2360 PetscErrorCode TSGetExactFinalTime(TS ts,TSExactFinalTimeOption *eftopt) 2361 { 2362 PetscFunctionBegin; 2363 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2364 PetscValidPointer(eftopt,2); 2365 *eftopt = ts->exact_final_time; 2366 PetscFunctionReturn(0); 2367 } 2368 2369 /*@ 2370 TSGetTimeStep - Gets the current timestep size. 2371 2372 Not Collective 2373 2374 Input Parameter: 2375 . ts - the TS context obtained from TSCreate() 2376 2377 Output Parameter: 2378 . dt - the current timestep size 2379 2380 Level: intermediate 2381 2382 .seealso: TSSetTimeStep(), TSGetTime() 2383 2384 @*/ 2385 PetscErrorCode TSGetTimeStep(TS ts,PetscReal *dt) 2386 { 2387 PetscFunctionBegin; 2388 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2389 PetscValidRealPointer(dt,2); 2390 *dt = ts->time_step; 2391 PetscFunctionReturn(0); 2392 } 2393 2394 /*@ 2395 TSGetSolution - Returns the solution at the present timestep. It 2396 is valid to call this routine inside the function that you are evaluating 2397 in order to move to the new timestep. This vector not changed until 2398 the solution at the next timestep has been calculated. 2399 2400 Not Collective, but Vec returned is parallel if TS is parallel 2401 2402 Input Parameter: 2403 . ts - the TS context obtained from TSCreate() 2404 2405 Output Parameter: 2406 . v - the vector containing the solution 2407 2408 Note: If you used TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP); this does not return the solution at the requested 2409 final time. It returns the solution at the next timestep. 2410 2411 Level: intermediate 2412 2413 .seealso: TSGetTimeStep(), TSGetTime(), TSGetSolveTime(), TSGetSolutionComponents(), TSSetSolutionFunction() 2414 2415 @*/ 2416 PetscErrorCode TSGetSolution(TS ts,Vec *v) 2417 { 2418 PetscFunctionBegin; 2419 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2420 PetscValidPointer(v,2); 2421 *v = ts->vec_sol; 2422 PetscFunctionReturn(0); 2423 } 2424 2425 /*@ 2426 TSGetSolutionComponents - Returns any solution components at the present 2427 timestep, if available for the time integration method being used. 2428 Solution components are quantities that share the same size and 2429 structure as the solution vector. 2430 2431 Not Collective, but Vec returned is parallel if TS is parallel 2432 2433 Parameters : 2434 + ts - the TS context obtained from TSCreate() (input parameter). 2435 . n - If v is PETSC_NULL, then the number of solution components is 2436 returned through n, else the n-th solution component is 2437 returned in v. 2438 - v - the vector containing the n-th solution component 2439 (may be PETSC_NULL to use this function to find out 2440 the number of solutions components). 2441 2442 Level: advanced 2443 2444 .seealso: TSGetSolution() 2445 2446 @*/ 2447 PetscErrorCode TSGetSolutionComponents(TS ts,PetscInt *n,Vec *v) 2448 { 2449 PetscErrorCode ierr; 2450 2451 PetscFunctionBegin; 2452 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2453 if (!ts->ops->getsolutioncomponents) *n = 0; 2454 else { 2455 ierr = (*ts->ops->getsolutioncomponents)(ts,n,v);CHKERRQ(ierr); 2456 } 2457 PetscFunctionReturn(0); 2458 } 2459 2460 /*@ 2461 TSGetAuxSolution - Returns an auxiliary solution at the present 2462 timestep, if available for the time integration method being used. 2463 2464 Not Collective, but Vec returned is parallel if TS is parallel 2465 2466 Parameters : 2467 + ts - the TS context obtained from TSCreate() (input parameter). 2468 - v - the vector containing the auxiliary solution 2469 2470 Level: intermediate 2471 2472 .seealso: TSGetSolution() 2473 2474 @*/ 2475 PetscErrorCode TSGetAuxSolution(TS ts,Vec *v) 2476 { 2477 PetscErrorCode ierr; 2478 2479 PetscFunctionBegin; 2480 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2481 if (ts->ops->getauxsolution) { 2482 ierr = (*ts->ops->getauxsolution)(ts,v);CHKERRQ(ierr); 2483 } else { 2484 ierr = VecZeroEntries(*v);CHKERRQ(ierr); 2485 } 2486 PetscFunctionReturn(0); 2487 } 2488 2489 /*@ 2490 TSGetTimeError - Returns the estimated error vector, if the chosen 2491 TSType has an error estimation functionality. 2492 2493 Not Collective, but Vec returned is parallel if TS is parallel 2494 2495 Note: MUST call after TSSetUp() 2496 2497 Parameters : 2498 + ts - the TS context obtained from TSCreate() (input parameter). 2499 . n - current estimate (n=0) or previous one (n=-1) 2500 - v - the vector containing the error (same size as the solution). 2501 2502 Level: intermediate 2503 2504 .seealso: TSGetSolution(), TSSetTimeError() 2505 2506 @*/ 2507 PetscErrorCode TSGetTimeError(TS ts,PetscInt n,Vec *v) 2508 { 2509 PetscErrorCode ierr; 2510 2511 PetscFunctionBegin; 2512 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2513 if (ts->ops->gettimeerror) { 2514 ierr = (*ts->ops->gettimeerror)(ts,n,v);CHKERRQ(ierr); 2515 } else { 2516 ierr = VecZeroEntries(*v);CHKERRQ(ierr); 2517 } 2518 PetscFunctionReturn(0); 2519 } 2520 2521 /*@ 2522 TSSetTimeError - Sets the estimated error vector, if the chosen 2523 TSType has an error estimation functionality. This can be used 2524 to restart such a time integrator with a given error vector. 2525 2526 Not Collective, but Vec returned is parallel if TS is parallel 2527 2528 Parameters : 2529 + ts - the TS context obtained from TSCreate() (input parameter). 2530 - v - the vector containing the error (same size as the solution). 2531 2532 Level: intermediate 2533 2534 .seealso: TSSetSolution(), TSGetTimeError) 2535 2536 @*/ 2537 PetscErrorCode TSSetTimeError(TS ts,Vec v) 2538 { 2539 PetscErrorCode ierr; 2540 2541 PetscFunctionBegin; 2542 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2543 if (!ts->setupcalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetUp() first"); 2544 if (ts->ops->settimeerror) { 2545 ierr = (*ts->ops->settimeerror)(ts,v);CHKERRQ(ierr); 2546 } 2547 PetscFunctionReturn(0); 2548 } 2549 2550 /* ----- Routines to initialize and destroy a timestepper ---- */ 2551 /*@ 2552 TSSetProblemType - Sets the type of problem to be solved. 2553 2554 Not collective 2555 2556 Input Parameters: 2557 + ts - The TS 2558 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2559 .vb 2560 U_t - A U = 0 (linear) 2561 U_t - A(t) U = 0 (linear) 2562 F(t,U,U_t) = 0 (nonlinear) 2563 .ve 2564 2565 Level: beginner 2566 2567 .seealso: TSSetUp(), TSProblemType, TS 2568 @*/ 2569 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 2570 { 2571 PetscErrorCode ierr; 2572 2573 PetscFunctionBegin; 2574 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2575 ts->problem_type = type; 2576 if (type == TS_LINEAR) { 2577 SNES snes; 2578 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2579 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 2580 } 2581 PetscFunctionReturn(0); 2582 } 2583 2584 /*@C 2585 TSGetProblemType - Gets the type of problem to be solved. 2586 2587 Not collective 2588 2589 Input Parameter: 2590 . ts - The TS 2591 2592 Output Parameter: 2593 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2594 .vb 2595 M U_t = A U 2596 M(t) U_t = A(t) U 2597 F(t,U,U_t) 2598 .ve 2599 2600 Level: beginner 2601 2602 .seealso: TSSetUp(), TSProblemType, TS 2603 @*/ 2604 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 2605 { 2606 PetscFunctionBegin; 2607 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2608 PetscValidIntPointer(type,2); 2609 *type = ts->problem_type; 2610 PetscFunctionReturn(0); 2611 } 2612 2613 /* 2614 Attempt to check/preset a default value for the exact final time option. This is needed at the beginning of TSSolve() and in TSSetUp() 2615 */ 2616 static PetscErrorCode TSSetExactFinalTimeDefault(TS ts) 2617 { 2618 PetscErrorCode ierr; 2619 PetscBool isnone; 2620 2621 PetscFunctionBegin; 2622 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 2623 ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr); 2624 2625 ierr = PetscObjectTypeCompare((PetscObject)ts->adapt,TSADAPTNONE,&isnone);CHKERRQ(ierr); 2626 if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) { 2627 ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP; 2628 } else if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) { 2629 ts->exact_final_time = TS_EXACTFINALTIME_INTERPOLATE; 2630 } 2631 PetscFunctionReturn(0); 2632 } 2633 2634 2635 /*@ 2636 TSSetUp - Sets up the internal data structures for the later use of a timestepper. 2637 2638 Collective on TS 2639 2640 Input Parameter: 2641 . ts - the TS context obtained from TSCreate() 2642 2643 Notes: 2644 For basic use of the TS solvers the user need not explicitly call 2645 TSSetUp(), since these actions will automatically occur during 2646 the call to TSStep() or TSSolve(). However, if one wishes to control this 2647 phase separately, TSSetUp() should be called after TSCreate() 2648 and optional routines of the form TSSetXXX(), but before TSStep() and TSSolve(). 2649 2650 Level: advanced 2651 2652 .seealso: TSCreate(), TSStep(), TSDestroy(), TSSolve() 2653 @*/ 2654 PetscErrorCode TSSetUp(TS ts) 2655 { 2656 PetscErrorCode ierr; 2657 DM dm; 2658 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2659 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 2660 TSIFunction ifun; 2661 TSIJacobian ijac; 2662 TSI2Jacobian i2jac; 2663 TSRHSJacobian rhsjac; 2664 2665 PetscFunctionBegin; 2666 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2667 if (ts->setupcalled) PetscFunctionReturn(0); 2668 2669 if (!((PetscObject)ts)->type_name) { 2670 ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr); 2671 ierr = TSSetType(ts,ifun ? TSBEULER : TSEULER);CHKERRQ(ierr); 2672 } 2673 2674 if (!ts->vec_sol) { 2675 if (ts->dm) { 2676 ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr); 2677 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 2678 } 2679 2680 if (!ts->Jacp && ts->Jacprhs) { /* IJacobianP shares the same matrix with RHSJacobianP if only RHSJacobianP is provided */ 2681 ierr = PetscObjectReference((PetscObject)ts->Jacprhs);CHKERRQ(ierr); 2682 ts->Jacp = ts->Jacprhs; 2683 } 2684 2685 if (ts->quadraturets) { 2686 ierr = TSSetUp(ts->quadraturets);CHKERRQ(ierr); 2687 ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr); 2688 ierr = VecDuplicate(ts->quadraturets->vec_sol,&ts->vec_costintegrand);CHKERRQ(ierr); 2689 } 2690 2691 ierr = TSGetRHSJacobian(ts,NULL,NULL,&rhsjac,NULL);CHKERRQ(ierr); 2692 if (ts->rhsjacobian.reuse && rhsjac == TSComputeRHSJacobianConstant) { 2693 Mat Amat,Pmat; 2694 SNES snes; 2695 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2696 ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr); 2697 /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would 2698 * have displaced the RHS matrix */ 2699 if (Amat && Amat == ts->Arhs) { 2700 /* we need to copy the values of the matrix because for the constant Jacobian case the user will never set the numerical values in this new location */ 2701 ierr = MatDuplicate(ts->Arhs,MAT_COPY_VALUES,&Amat);CHKERRQ(ierr); 2702 ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr); 2703 ierr = MatDestroy(&Amat);CHKERRQ(ierr); 2704 } 2705 if (Pmat && Pmat == ts->Brhs) { 2706 ierr = MatDuplicate(ts->Brhs,MAT_COPY_VALUES,&Pmat);CHKERRQ(ierr); 2707 ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr); 2708 ierr = MatDestroy(&Pmat);CHKERRQ(ierr); 2709 } 2710 } 2711 2712 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 2713 ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr); 2714 2715 if (ts->ops->setup) { 2716 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 2717 } 2718 2719 ierr = TSSetExactFinalTimeDefault(ts);CHKERRQ(ierr); 2720 2721 /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction 2722 to be set right but can't do it elsewhere due to the overreliance on ctx=ts. 2723 */ 2724 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2725 ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr); 2726 if (!func) { 2727 ierr = DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr); 2728 } 2729 /* If the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it. 2730 Otherwise, the SNES will use coloring internally to form the Jacobian. 2731 */ 2732 ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr); 2733 ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr); 2734 ierr = DMTSGetI2Jacobian(dm,&i2jac,NULL);CHKERRQ(ierr); 2735 ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr); 2736 if (!jac && (ijac || i2jac || rhsjac)) { 2737 ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2738 } 2739 2740 /* if time integration scheme has a starting method, call it */ 2741 if (ts->ops->startingmethod) { 2742 ierr = (*ts->ops->startingmethod)(ts);CHKERRQ(ierr); 2743 } 2744 2745 ts->setupcalled = PETSC_TRUE; 2746 PetscFunctionReturn(0); 2747 } 2748 2749 /*@ 2750 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 2751 2752 Collective on TS 2753 2754 Input Parameter: 2755 . ts - the TS context obtained from TSCreate() 2756 2757 Level: beginner 2758 2759 .seealso: TSCreate(), TSSetup(), TSDestroy() 2760 @*/ 2761 PetscErrorCode TSReset(TS ts) 2762 { 2763 TS_RHSSplitLink ilink = ts->tsrhssplit,next; 2764 PetscErrorCode ierr; 2765 2766 PetscFunctionBegin; 2767 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2768 2769 if (ts->ops->reset) { 2770 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 2771 } 2772 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 2773 if (ts->adapt) {ierr = TSAdaptReset(ts->adapt);CHKERRQ(ierr);} 2774 2775 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 2776 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 2777 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 2778 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2779 ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr); 2780 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 2781 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 2782 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 2783 2784 ierr = MatDestroy(&ts->Jacprhs);CHKERRQ(ierr); 2785 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 2786 if (ts->forward_solve) { 2787 ierr = TSForwardReset(ts);CHKERRQ(ierr); 2788 } 2789 if (ts->quadraturets) { 2790 ierr = TSReset(ts->quadraturets);CHKERRQ(ierr); 2791 ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr); 2792 } 2793 while (ilink) { 2794 next = ilink->next; 2795 ierr = TSDestroy(&ilink->ts);CHKERRQ(ierr); 2796 ierr = PetscFree(ilink->splitname);CHKERRQ(ierr); 2797 ierr = ISDestroy(&ilink->is);CHKERRQ(ierr); 2798 ierr = PetscFree(ilink);CHKERRQ(ierr); 2799 ilink = next; 2800 } 2801 ts->num_rhs_splits = 0; 2802 ts->setupcalled = PETSC_FALSE; 2803 PetscFunctionReturn(0); 2804 } 2805 2806 /*@ 2807 TSDestroy - Destroys the timestepper context that was created 2808 with TSCreate(). 2809 2810 Collective on TS 2811 2812 Input Parameter: 2813 . ts - the TS context obtained from TSCreate() 2814 2815 Level: beginner 2816 2817 .seealso: TSCreate(), TSSetUp(), TSSolve() 2818 @*/ 2819 PetscErrorCode TSDestroy(TS *ts) 2820 { 2821 PetscErrorCode ierr; 2822 2823 PetscFunctionBegin; 2824 if (!*ts) PetscFunctionReturn(0); 2825 PetscValidHeaderSpecific(*ts,TS_CLASSID,1); 2826 if (--((PetscObject)(*ts))->refct > 0) {*ts = NULL; PetscFunctionReturn(0);} 2827 2828 ierr = TSReset(*ts);CHKERRQ(ierr); 2829 ierr = TSAdjointReset(*ts);CHKERRQ(ierr); 2830 if ((*ts)->forward_solve) { 2831 ierr = TSForwardReset(*ts);CHKERRQ(ierr); 2832 } 2833 /* if memory was published with SAWs then destroy it */ 2834 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 2835 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 2836 2837 ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr); 2838 2839 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 2840 ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr); 2841 2842 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 2843 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 2844 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 2845 ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr); 2846 2847 ierr = TSDestroy(&(*ts)->quadraturets);CHKERRQ(ierr); 2848 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 2849 PetscFunctionReturn(0); 2850 } 2851 2852 /*@ 2853 TSGetSNES - Returns the SNES (nonlinear solver) associated with 2854 a TS (timestepper) context. Valid only for nonlinear problems. 2855 2856 Not Collective, but SNES is parallel if TS is parallel 2857 2858 Input Parameter: 2859 . ts - the TS context obtained from TSCreate() 2860 2861 Output Parameter: 2862 . snes - the nonlinear solver context 2863 2864 Notes: 2865 The user can then directly manipulate the SNES context to set various 2866 options, etc. Likewise, the user can then extract and manipulate the 2867 KSP, KSP, and PC contexts as well. 2868 2869 TSGetSNES() does not work for integrators that do not use SNES; in 2870 this case TSGetSNES() returns NULL in snes. 2871 2872 Level: beginner 2873 2874 @*/ 2875 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 2876 { 2877 PetscErrorCode ierr; 2878 2879 PetscFunctionBegin; 2880 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2881 PetscValidPointer(snes,2); 2882 if (!ts->snes) { 2883 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 2884 ierr = PetscObjectSetOptions((PetscObject)ts->snes,((PetscObject)ts)->options);CHKERRQ(ierr); 2885 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2886 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 2887 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 2888 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2889 if (ts->problem_type == TS_LINEAR) { 2890 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 2891 } 2892 } 2893 *snes = ts->snes; 2894 PetscFunctionReturn(0); 2895 } 2896 2897 /*@ 2898 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 2899 2900 Collective 2901 2902 Input Parameter: 2903 + ts - the TS context obtained from TSCreate() 2904 - snes - the nonlinear solver context 2905 2906 Notes: 2907 Most users should have the TS created by calling TSGetSNES() 2908 2909 Level: developer 2910 2911 @*/ 2912 PetscErrorCode TSSetSNES(TS ts,SNES snes) 2913 { 2914 PetscErrorCode ierr; 2915 PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 2916 2917 PetscFunctionBegin; 2918 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2919 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 2920 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 2921 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 2922 2923 ts->snes = snes; 2924 2925 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2926 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 2927 if (func == SNESTSFormJacobian) { 2928 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2929 } 2930 PetscFunctionReturn(0); 2931 } 2932 2933 /*@ 2934 TSGetKSP - Returns the KSP (linear solver) associated with 2935 a TS (timestepper) context. 2936 2937 Not Collective, but KSP is parallel if TS is parallel 2938 2939 Input Parameter: 2940 . ts - the TS context obtained from TSCreate() 2941 2942 Output Parameter: 2943 . ksp - the nonlinear solver context 2944 2945 Notes: 2946 The user can then directly manipulate the KSP context to set various 2947 options, etc. Likewise, the user can then extract and manipulate the 2948 KSP and PC contexts as well. 2949 2950 TSGetKSP() does not work for integrators that do not use KSP; 2951 in this case TSGetKSP() returns NULL in ksp. 2952 2953 Level: beginner 2954 2955 @*/ 2956 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2957 { 2958 PetscErrorCode ierr; 2959 SNES snes; 2960 2961 PetscFunctionBegin; 2962 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2963 PetscValidPointer(ksp,2); 2964 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2965 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2966 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2967 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2968 PetscFunctionReturn(0); 2969 } 2970 2971 /* ----------- Routines to set solver parameters ---------- */ 2972 2973 /*@ 2974 TSSetMaxSteps - Sets the maximum number of steps to use. 2975 2976 Logically Collective on TS 2977 2978 Input Parameters: 2979 + ts - the TS context obtained from TSCreate() 2980 - maxsteps - maximum number of steps to use 2981 2982 Options Database Keys: 2983 . -ts_max_steps <maxsteps> - Sets maxsteps 2984 2985 Notes: 2986 The default maximum number of steps is 5000 2987 2988 Level: intermediate 2989 2990 .seealso: TSGetMaxSteps(), TSSetMaxTime(), TSSetExactFinalTime() 2991 @*/ 2992 PetscErrorCode TSSetMaxSteps(TS ts,PetscInt maxsteps) 2993 { 2994 PetscFunctionBegin; 2995 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2996 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2997 if (maxsteps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of steps must be non-negative"); 2998 ts->max_steps = maxsteps; 2999 PetscFunctionReturn(0); 3000 } 3001 3002 /*@ 3003 TSGetMaxSteps - Gets the maximum number of steps to use. 3004 3005 Not Collective 3006 3007 Input Parameters: 3008 . ts - the TS context obtained from TSCreate() 3009 3010 Output Parameter: 3011 . maxsteps - maximum number of steps to use 3012 3013 Level: advanced 3014 3015 .seealso: TSSetMaxSteps(), TSGetMaxTime(), TSSetMaxTime() 3016 @*/ 3017 PetscErrorCode TSGetMaxSteps(TS ts,PetscInt *maxsteps) 3018 { 3019 PetscFunctionBegin; 3020 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3021 PetscValidIntPointer(maxsteps,2); 3022 *maxsteps = ts->max_steps; 3023 PetscFunctionReturn(0); 3024 } 3025 3026 /*@ 3027 TSSetMaxTime - Sets the maximum (or final) time for timestepping. 3028 3029 Logically Collective on TS 3030 3031 Input Parameters: 3032 + ts - the TS context obtained from TSCreate() 3033 - maxtime - final time to step to 3034 3035 Options Database Keys: 3036 . -ts_max_time <maxtime> - Sets maxtime 3037 3038 Notes: 3039 The default maximum time is 5.0 3040 3041 Level: intermediate 3042 3043 .seealso: TSGetMaxTime(), TSSetMaxSteps(), TSSetExactFinalTime() 3044 @*/ 3045 PetscErrorCode TSSetMaxTime(TS ts,PetscReal maxtime) 3046 { 3047 PetscFunctionBegin; 3048 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3049 PetscValidLogicalCollectiveReal(ts,maxtime,2); 3050 ts->max_time = maxtime; 3051 PetscFunctionReturn(0); 3052 } 3053 3054 /*@ 3055 TSGetMaxTime - Gets the maximum (or final) time for timestepping. 3056 3057 Not Collective 3058 3059 Input Parameters: 3060 . ts - the TS context obtained from TSCreate() 3061 3062 Output Parameter: 3063 . maxtime - final time to step to 3064 3065 Level: advanced 3066 3067 .seealso: TSSetMaxTime(), TSGetMaxSteps(), TSSetMaxSteps() 3068 @*/ 3069 PetscErrorCode TSGetMaxTime(TS ts,PetscReal *maxtime) 3070 { 3071 PetscFunctionBegin; 3072 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3073 PetscValidRealPointer(maxtime,2); 3074 *maxtime = ts->max_time; 3075 PetscFunctionReturn(0); 3076 } 3077 3078 /*@ 3079 TSSetInitialTimeStep - Deprecated, use TSSetTime() and TSSetTimeStep(). 3080 3081 Level: deprecated 3082 3083 @*/ 3084 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 3085 { 3086 PetscErrorCode ierr; 3087 PetscFunctionBegin; 3088 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3089 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 3090 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 3091 PetscFunctionReturn(0); 3092 } 3093 3094 /*@ 3095 TSGetDuration - Deprecated, use TSGetMaxSteps() and TSGetMaxTime(). 3096 3097 Level: deprecated 3098 3099 @*/ 3100 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 3101 { 3102 PetscFunctionBegin; 3103 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3104 if (maxsteps) { 3105 PetscValidIntPointer(maxsteps,2); 3106 *maxsteps = ts->max_steps; 3107 } 3108 if (maxtime) { 3109 PetscValidScalarPointer(maxtime,3); 3110 *maxtime = ts->max_time; 3111 } 3112 PetscFunctionReturn(0); 3113 } 3114 3115 /*@ 3116 TSSetDuration - Deprecated, use TSSetMaxSteps() and TSSetMaxTime(). 3117 3118 Level: deprecated 3119 3120 @*/ 3121 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 3122 { 3123 PetscFunctionBegin; 3124 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3125 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 3126 PetscValidLogicalCollectiveReal(ts,maxtime,2); 3127 if (maxsteps >= 0) ts->max_steps = maxsteps; 3128 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 3129 PetscFunctionReturn(0); 3130 } 3131 3132 /*@ 3133 TSGetTimeStepNumber - Deprecated, use TSGetStepNumber(). 3134 3135 Level: deprecated 3136 3137 @*/ 3138 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 3139 3140 /*@ 3141 TSGetTotalSteps - Deprecated, use TSGetStepNumber(). 3142 3143 Level: deprecated 3144 3145 @*/ 3146 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 3147 3148 /*@ 3149 TSSetSolution - Sets the initial solution vector 3150 for use by the TS routines. 3151 3152 Logically Collective on TS 3153 3154 Input Parameters: 3155 + ts - the TS context obtained from TSCreate() 3156 - u - the solution vector 3157 3158 Level: beginner 3159 3160 .seealso: TSSetSolutionFunction(), TSGetSolution(), TSCreate() 3161 @*/ 3162 PetscErrorCode TSSetSolution(TS ts,Vec u) 3163 { 3164 PetscErrorCode ierr; 3165 DM dm; 3166 3167 PetscFunctionBegin; 3168 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3169 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3170 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 3171 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 3172 ts->vec_sol = u; 3173 3174 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3175 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 3176 PetscFunctionReturn(0); 3177 } 3178 3179 /*@C 3180 TSSetPreStep - Sets the general-purpose function 3181 called once at the beginning of each time step. 3182 3183 Logically Collective on TS 3184 3185 Input Parameters: 3186 + ts - The TS context obtained from TSCreate() 3187 - func - The function 3188 3189 Calling sequence of func: 3190 . PetscErrorCode func (TS ts); 3191 3192 Level: intermediate 3193 3194 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep(), TSRestartStep() 3195 @*/ 3196 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 3197 { 3198 PetscFunctionBegin; 3199 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3200 ts->prestep = func; 3201 PetscFunctionReturn(0); 3202 } 3203 3204 /*@ 3205 TSPreStep - Runs the user-defined pre-step function. 3206 3207 Collective on TS 3208 3209 Input Parameters: 3210 . ts - The TS context obtained from TSCreate() 3211 3212 Notes: 3213 TSPreStep() is typically used within time stepping implementations, 3214 so most users would not generally call this routine themselves. 3215 3216 Level: developer 3217 3218 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 3219 @*/ 3220 PetscErrorCode TSPreStep(TS ts) 3221 { 3222 PetscErrorCode ierr; 3223 3224 PetscFunctionBegin; 3225 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3226 if (ts->prestep) { 3227 Vec U; 3228 PetscObjectState sprev,spost; 3229 3230 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3231 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3232 PetscStackCallStandard((*ts->prestep),(ts)); 3233 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3234 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3235 } 3236 PetscFunctionReturn(0); 3237 } 3238 3239 /*@C 3240 TSSetPreStage - Sets the general-purpose function 3241 called once at the beginning of each stage. 3242 3243 Logically Collective on TS 3244 3245 Input Parameters: 3246 + ts - The TS context obtained from TSCreate() 3247 - func - The function 3248 3249 Calling sequence of func: 3250 . PetscErrorCode func(TS ts, PetscReal stagetime); 3251 3252 Level: intermediate 3253 3254 Note: 3255 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3256 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3257 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3258 3259 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3260 @*/ 3261 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 3262 { 3263 PetscFunctionBegin; 3264 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3265 ts->prestage = func; 3266 PetscFunctionReturn(0); 3267 } 3268 3269 /*@C 3270 TSSetPostStage - Sets the general-purpose function 3271 called once at the end of each stage. 3272 3273 Logically Collective on TS 3274 3275 Input Parameters: 3276 + ts - The TS context obtained from TSCreate() 3277 - func - The function 3278 3279 Calling sequence of func: 3280 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 3281 3282 Level: intermediate 3283 3284 Note: 3285 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3286 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3287 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3288 3289 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3290 @*/ 3291 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 3292 { 3293 PetscFunctionBegin; 3294 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3295 ts->poststage = func; 3296 PetscFunctionReturn(0); 3297 } 3298 3299 /*@C 3300 TSSetPostEvaluate - Sets the general-purpose function 3301 called once at the end of each step evaluation. 3302 3303 Logically Collective on TS 3304 3305 Input Parameters: 3306 + ts - The TS context obtained from TSCreate() 3307 - func - The function 3308 3309 Calling sequence of func: 3310 . PetscErrorCode func(TS ts); 3311 3312 Level: intermediate 3313 3314 Note: 3315 Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling 3316 thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep() 3317 may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step 3318 solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step 3319 with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime() 3320 3321 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3322 @*/ 3323 PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS)) 3324 { 3325 PetscFunctionBegin; 3326 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3327 ts->postevaluate = func; 3328 PetscFunctionReturn(0); 3329 } 3330 3331 /*@ 3332 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 3333 3334 Collective on TS 3335 3336 Input Parameters: 3337 . ts - The TS context obtained from TSCreate() 3338 stagetime - The absolute time of the current stage 3339 3340 Notes: 3341 TSPreStage() is typically used within time stepping implementations, 3342 most users would not generally call this routine themselves. 3343 3344 Level: developer 3345 3346 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3347 @*/ 3348 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 3349 { 3350 PetscFunctionBegin; 3351 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3352 if (ts->prestage) { 3353 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 3354 } 3355 PetscFunctionReturn(0); 3356 } 3357 3358 /*@ 3359 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 3360 3361 Collective on TS 3362 3363 Input Parameters: 3364 . ts - The TS context obtained from TSCreate() 3365 stagetime - The absolute time of the current stage 3366 stageindex - Stage number 3367 Y - Array of vectors (of size = total number 3368 of stages) with the stage solutions 3369 3370 Notes: 3371 TSPostStage() is typically used within time stepping implementations, 3372 most users would not generally call this routine themselves. 3373 3374 Level: developer 3375 3376 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3377 @*/ 3378 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 3379 { 3380 PetscFunctionBegin; 3381 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3382 if (ts->poststage) { 3383 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 3384 } 3385 PetscFunctionReturn(0); 3386 } 3387 3388 /*@ 3389 TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate() 3390 3391 Collective on TS 3392 3393 Input Parameters: 3394 . ts - The TS context obtained from TSCreate() 3395 3396 Notes: 3397 TSPostEvaluate() is typically used within time stepping implementations, 3398 most users would not generally call this routine themselves. 3399 3400 Level: developer 3401 3402 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep() 3403 @*/ 3404 PetscErrorCode TSPostEvaluate(TS ts) 3405 { 3406 PetscErrorCode ierr; 3407 3408 PetscFunctionBegin; 3409 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3410 if (ts->postevaluate) { 3411 Vec U; 3412 PetscObjectState sprev,spost; 3413 3414 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3415 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3416 PetscStackCallStandard((*ts->postevaluate),(ts)); 3417 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3418 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3419 } 3420 PetscFunctionReturn(0); 3421 } 3422 3423 /*@C 3424 TSSetPostStep - Sets the general-purpose function 3425 called once at the end of each time step. 3426 3427 Logically Collective on TS 3428 3429 Input Parameters: 3430 + ts - The TS context obtained from TSCreate() 3431 - func - The function 3432 3433 Calling sequence of func: 3434 $ func (TS ts); 3435 3436 Notes: 3437 The function set by TSSetPostStep() is called after each successful step. The solution vector X 3438 obtained by TSGetSolution() may be different than that computed at the step end if the event handler 3439 locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead. 3440 3441 Level: intermediate 3442 3443 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetStepNumber(), TSGetTime(), TSRestartStep() 3444 @*/ 3445 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 3446 { 3447 PetscFunctionBegin; 3448 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3449 ts->poststep = func; 3450 PetscFunctionReturn(0); 3451 } 3452 3453 /*@ 3454 TSPostStep - Runs the user-defined post-step function. 3455 3456 Collective on TS 3457 3458 Input Parameters: 3459 . ts - The TS context obtained from TSCreate() 3460 3461 Notes: 3462 TSPostStep() is typically used within time stepping implementations, 3463 so most users would not generally call this routine themselves. 3464 3465 Level: developer 3466 3467 @*/ 3468 PetscErrorCode TSPostStep(TS ts) 3469 { 3470 PetscErrorCode ierr; 3471 3472 PetscFunctionBegin; 3473 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3474 if (ts->poststep) { 3475 Vec U; 3476 PetscObjectState sprev,spost; 3477 3478 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3479 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3480 PetscStackCallStandard((*ts->poststep),(ts)); 3481 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3482 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3483 } 3484 PetscFunctionReturn(0); 3485 } 3486 3487 /* ------------ Routines to set performance monitoring options ----------- */ 3488 3489 /*@C 3490 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 3491 timestep to display the iteration's progress. 3492 3493 Logically Collective on TS 3494 3495 Input Parameters: 3496 + ts - the TS context obtained from TSCreate() 3497 . monitor - monitoring routine 3498 . mctx - [optional] user-defined context for private data for the 3499 monitor routine (use NULL if no context is desired) 3500 - monitordestroy - [optional] routine that frees monitor context 3501 (may be NULL) 3502 3503 Calling sequence of monitor: 3504 $ PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 3505 3506 + ts - the TS context 3507 . steps - iteration number (after the final time step the monitor routine may be called with a step of -1, this indicates the solution has been interpolated to this time) 3508 . time - current time 3509 . u - current iterate 3510 - mctx - [optional] monitoring context 3511 3512 Notes: 3513 This routine adds an additional monitor to the list of monitors that 3514 already has been loaded. 3515 3516 Fortran Notes: 3517 Only a single monitor function can be set for each TS object 3518 3519 Level: intermediate 3520 3521 .seealso: TSMonitorDefault(), TSMonitorCancel() 3522 @*/ 3523 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 3524 { 3525 PetscErrorCode ierr; 3526 PetscInt i; 3527 PetscBool identical; 3528 3529 PetscFunctionBegin; 3530 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3531 for (i=0; i<ts->numbermonitors;i++) { 3532 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr); 3533 if (identical) PetscFunctionReturn(0); 3534 } 3535 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3536 ts->monitor[ts->numbermonitors] = monitor; 3537 ts->monitordestroy[ts->numbermonitors] = mdestroy; 3538 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 3539 PetscFunctionReturn(0); 3540 } 3541 3542 /*@C 3543 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 3544 3545 Logically Collective on TS 3546 3547 Input Parameters: 3548 . ts - the TS context obtained from TSCreate() 3549 3550 Notes: 3551 There is no way to remove a single, specific monitor. 3552 3553 Level: intermediate 3554 3555 .seealso: TSMonitorDefault(), TSMonitorSet() 3556 @*/ 3557 PetscErrorCode TSMonitorCancel(TS ts) 3558 { 3559 PetscErrorCode ierr; 3560 PetscInt i; 3561 3562 PetscFunctionBegin; 3563 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3564 for (i=0; i<ts->numbermonitors; i++) { 3565 if (ts->monitordestroy[i]) { 3566 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 3567 } 3568 } 3569 ts->numbermonitors = 0; 3570 PetscFunctionReturn(0); 3571 } 3572 3573 /*@C 3574 TSMonitorDefault - The Default monitor, prints the timestep and time for each step 3575 3576 Level: intermediate 3577 3578 .seealso: TSMonitorSet() 3579 @*/ 3580 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3581 { 3582 PetscErrorCode ierr; 3583 PetscViewer viewer = vf->viewer; 3584 PetscBool iascii,ibinary; 3585 3586 PetscFunctionBegin; 3587 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3588 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3589 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 3590 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3591 if (iascii) { 3592 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3593 if (step == -1){ /* this indicates it is an interpolated solution */ 3594 ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr); 3595 } else { 3596 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3597 } 3598 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3599 } else if (ibinary) { 3600 PetscMPIInt rank; 3601 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 3602 if (!rank) { 3603 PetscBool skipHeader; 3604 PetscInt classid = REAL_FILE_CLASSID; 3605 3606 ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 3607 if (!skipHeader) { 3608 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 3609 } 3610 ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr); 3611 } else { 3612 ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr); 3613 } 3614 } 3615 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3616 PetscFunctionReturn(0); 3617 } 3618 3619 /*@C 3620 TSMonitorExtreme - Prints the extreme values of the solution at each timestep 3621 3622 Level: intermediate 3623 3624 .seealso: TSMonitorSet() 3625 @*/ 3626 PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3627 { 3628 PetscErrorCode ierr; 3629 PetscViewer viewer = vf->viewer; 3630 PetscBool iascii; 3631 PetscReal max,min; 3632 3633 3634 PetscFunctionBegin; 3635 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3636 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3637 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3638 if (iascii) { 3639 ierr = VecMax(v,NULL,&max);CHKERRQ(ierr); 3640 ierr = VecMin(v,NULL,&min);CHKERRQ(ierr); 3641 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3642 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s max %g min %g\n",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)" : "",(double)max,(double)min);CHKERRQ(ierr); 3643 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3644 } 3645 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3646 PetscFunctionReturn(0); 3647 } 3648 3649 /*@ 3650 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 3651 3652 Collective on TS 3653 3654 Input Argument: 3655 + ts - time stepping context 3656 - t - time to interpolate to 3657 3658 Output Argument: 3659 . U - state at given time 3660 3661 Level: intermediate 3662 3663 Developer Notes: 3664 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3665 3666 .seealso: TSSetExactFinalTime(), TSSolve() 3667 @*/ 3668 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3669 { 3670 PetscErrorCode ierr; 3671 3672 PetscFunctionBegin; 3673 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3674 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3675 if (t < ts->ptime_prev || t > ts->ptime) SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Requested time %g not in last time steps [%g,%g]",t,(double)ts->ptime_prev,(double)ts->ptime); 3676 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3677 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3678 PetscFunctionReturn(0); 3679 } 3680 3681 /*@ 3682 TSStep - Steps one time step 3683 3684 Collective on TS 3685 3686 Input Parameter: 3687 . ts - the TS context obtained from TSCreate() 3688 3689 Level: developer 3690 3691 Notes: 3692 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3693 3694 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3695 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3696 3697 This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the 3698 time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3699 3700 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3701 @*/ 3702 PetscErrorCode TSStep(TS ts) 3703 { 3704 PetscErrorCode ierr; 3705 static PetscBool cite = PETSC_FALSE; 3706 PetscReal ptime; 3707 3708 PetscFunctionBegin; 3709 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3710 ierr = PetscCitationsRegister("@article{tspaper,\n" 3711 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3712 " author = {Abhyankar, Shrirang and Brown, Jed and Constantinescu, Emil and Ghosh, Debojyoti and Smith, Barry F. and Zhang, Hong},\n" 3713 " journal = {arXiv e-preprints},\n" 3714 " eprint = {1806.01437},\n" 3715 " archivePrefix = {arXiv},\n" 3716 " year = {2018}\n}\n",&cite);CHKERRQ(ierr); 3717 3718 ierr = TSSetUp(ts);CHKERRQ(ierr); 3719 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3720 3721 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3722 if (ts->max_time >= PETSC_MAX_REAL && ts->max_steps == PETSC_MAX_INT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>"); 3723 if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSStep()"); 3724 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && !ts->adapt) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE"); 3725 3726 if (!ts->steps) ts->ptime_prev = ts->ptime; 3727 ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev; 3728 ts->reason = TS_CONVERGED_ITERATING; 3729 3730 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3731 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3732 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3733 3734 if (ts->reason >= 0) { 3735 ts->ptime_prev = ptime; 3736 ts->steps++; 3737 ts->steprollback = PETSC_FALSE; 3738 ts->steprestart = PETSC_FALSE; 3739 } 3740 3741 if (!ts->reason) { 3742 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3743 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3744 } 3745 3746 if (ts->reason < 0 && ts->errorifstepfailed && ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 3747 if (ts->reason < 0 && ts->errorifstepfailed) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3748 PetscFunctionReturn(0); 3749 } 3750 3751 /*@ 3752 TSEvaluateWLTE - Evaluate the weighted local truncation error norm 3753 at the end of a time step with a given order of accuracy. 3754 3755 Collective on TS 3756 3757 Input Arguments: 3758 + ts - time stepping context 3759 . wnormtype - norm type, either NORM_2 or NORM_INFINITY 3760 - order - optional, desired order for the error evaluation or PETSC_DECIDE 3761 3762 Output Arguments: 3763 + order - optional, the actual order of the error evaluation 3764 - wlte - the weighted local truncation error norm 3765 3766 Level: advanced 3767 3768 Notes: 3769 If the timestepper cannot evaluate the error in a particular step 3770 (eg. in the first step or restart steps after event handling), 3771 this routine returns wlte=-1.0 . 3772 3773 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm() 3774 @*/ 3775 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte) 3776 { 3777 PetscErrorCode ierr; 3778 3779 PetscFunctionBegin; 3780 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3781 PetscValidType(ts,1); 3782 PetscValidLogicalCollectiveEnum(ts,wnormtype,4); 3783 if (order) PetscValidIntPointer(order,3); 3784 if (order) PetscValidLogicalCollectiveInt(ts,*order,3); 3785 PetscValidRealPointer(wlte,4); 3786 if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 3787 if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name); 3788 ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr); 3789 PetscFunctionReturn(0); 3790 } 3791 3792 /*@ 3793 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 3794 3795 Collective on TS 3796 3797 Input Arguments: 3798 + ts - time stepping context 3799 . order - desired order of accuracy 3800 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 3801 3802 Output Arguments: 3803 . U - state at the end of the current step 3804 3805 Level: advanced 3806 3807 Notes: 3808 This function cannot be called until all stages have been evaluated. 3809 It is normally called by adaptive controllers before a step has been accepted and may also be called by the user after TSStep() has returned. 3810 3811 .seealso: TSStep(), TSAdapt 3812 @*/ 3813 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 3814 { 3815 PetscErrorCode ierr; 3816 3817 PetscFunctionBegin; 3818 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3819 PetscValidType(ts,1); 3820 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3821 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3822 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 3823 PetscFunctionReturn(0); 3824 } 3825 3826 /*@C 3827 TSGetComputeInitialCondition - Get the function used to automatically compute an initial condition for the timestepping. 3828 3829 Not collective 3830 3831 Input Argument: 3832 . ts - time stepping context 3833 3834 Output Argument: 3835 . initConditions - The function which computes an initial condition 3836 3837 Level: advanced 3838 3839 Notes: 3840 The calling sequence for the function is 3841 $ initCondition(TS ts, Vec u) 3842 $ ts - The timestepping context 3843 $ u - The input vector in which the initial condition is stored 3844 3845 .seealso: TSSetComputeInitialCondition(), TSComputeInitialCondition() 3846 @*/ 3847 PetscErrorCode TSGetComputeInitialCondition(TS ts, PetscErrorCode (**initCondition)(TS, Vec)) 3848 { 3849 PetscFunctionBegin; 3850 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3851 PetscValidPointer(initCondition, 2); 3852 *initCondition = ts->ops->initcondition; 3853 PetscFunctionReturn(0); 3854 } 3855 3856 /*@C 3857 TSSetComputeInitialCondition - Set the function used to automatically compute an initial condition for the timestepping. 3858 3859 Logically collective on ts 3860 3861 Input Arguments: 3862 + ts - time stepping context 3863 - initCondition - The function which computes an initial condition 3864 3865 Level: advanced 3866 3867 Calling sequence for initCondition: 3868 $ PetscErrorCode initCondition(TS ts, Vec u) 3869 3870 + ts - The timestepping context 3871 - u - The input vector in which the initial condition is to be stored 3872 3873 .seealso: TSGetComputeInitialCondition(), TSComputeInitialCondition() 3874 @*/ 3875 PetscErrorCode TSSetComputeInitialCondition(TS ts, PetscErrorCode (*initCondition)(TS, Vec)) 3876 { 3877 PetscFunctionBegin; 3878 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3879 PetscValidFunction(initCondition, 2); 3880 ts->ops->initcondition = initCondition; 3881 PetscFunctionReturn(0); 3882 } 3883 3884 /*@ 3885 TSComputeInitialCondition - Compute an initial condition for the timestepping using the function previously set. 3886 3887 Collective on ts 3888 3889 Input Arguments: 3890 + ts - time stepping context 3891 - u - The Vec to store the condition in which will be used in TSSolve() 3892 3893 Level: advanced 3894 3895 .seealso: TSGetComputeInitialCondition(), TSSetComputeInitialCondition(), TSSolve() 3896 @*/ 3897 PetscErrorCode TSComputeInitialCondition(TS ts, Vec u) 3898 { 3899 PetscErrorCode ierr; 3900 3901 PetscFunctionBegin; 3902 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3903 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 3904 if (ts->ops->initcondition) {ierr = (*ts->ops->initcondition)(ts, u);CHKERRQ(ierr);} 3905 PetscFunctionReturn(0); 3906 } 3907 3908 /*@C 3909 TSGetComputeExactError - Get the function used to automatically compute the exact error for the timestepping. 3910 3911 Not collective 3912 3913 Input Argument: 3914 . ts - time stepping context 3915 3916 Output Argument: 3917 . exactError - The function which computes the solution error 3918 3919 Level: advanced 3920 3921 Calling sequence for exactError: 3922 $ PetscErrorCode exactError(TS ts, Vec u) 3923 3924 + ts - The timestepping context 3925 . u - The approximate solution vector 3926 - e - The input vector in which the error is stored 3927 3928 .seealso: TSGetComputeExactError(), TSComputeExactError() 3929 @*/ 3930 PetscErrorCode TSGetComputeExactError(TS ts, PetscErrorCode (**exactError)(TS, Vec, Vec)) 3931 { 3932 PetscFunctionBegin; 3933 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3934 PetscValidPointer(exactError, 2); 3935 *exactError = ts->ops->exacterror; 3936 PetscFunctionReturn(0); 3937 } 3938 3939 /*@C 3940 TSSetComputeExactError - Set the function used to automatically compute the exact error for the timestepping. 3941 3942 Logically collective on ts 3943 3944 Input Arguments: 3945 + ts - time stepping context 3946 - exactError - The function which computes the solution error 3947 3948 Level: advanced 3949 3950 Calling sequence for exactError: 3951 $ PetscErrorCode exactError(TS ts, Vec u) 3952 3953 + ts - The timestepping context 3954 . u - The approximate solution vector 3955 - e - The input vector in which the error is stored 3956 3957 .seealso: TSGetComputeExactError(), TSComputeExactError() 3958 @*/ 3959 PetscErrorCode TSSetComputeExactError(TS ts, PetscErrorCode (*exactError)(TS, Vec, Vec)) 3960 { 3961 PetscFunctionBegin; 3962 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3963 PetscValidFunction(exactError, 2); 3964 ts->ops->exacterror = exactError; 3965 PetscFunctionReturn(0); 3966 } 3967 3968 /*@ 3969 TSComputeExactError - Compute the solution error for the timestepping using the function previously set. 3970 3971 Collective on ts 3972 3973 Input Arguments: 3974 + ts - time stepping context 3975 . u - The approximate solution 3976 - e - The Vec used to store the error 3977 3978 Level: advanced 3979 3980 .seealso: TSGetComputeInitialCondition(), TSSetComputeInitialCondition(), TSSolve() 3981 @*/ 3982 PetscErrorCode TSComputeExactError(TS ts, Vec u, Vec e) 3983 { 3984 PetscErrorCode ierr; 3985 3986 PetscFunctionBegin; 3987 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3988 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 3989 PetscValidHeaderSpecific(e, VEC_CLASSID, 3); 3990 if (ts->ops->exacterror) {ierr = (*ts->ops->exacterror)(ts, u, e);CHKERRQ(ierr);} 3991 PetscFunctionReturn(0); 3992 } 3993 3994 /*@ 3995 TSSolve - Steps the requested number of timesteps. 3996 3997 Collective on TS 3998 3999 Input Parameter: 4000 + ts - the TS context obtained from TSCreate() 4001 - u - the solution vector (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used, 4002 otherwise must contain the initial conditions and will contain the solution at the final requested time 4003 4004 Level: beginner 4005 4006 Notes: 4007 The final time returned by this function may be different from the time of the internally 4008 held state accessible by TSGetSolution() and TSGetTime() because the method may have 4009 stepped over the final time. 4010 4011 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime() 4012 @*/ 4013 PetscErrorCode TSSolve(TS ts,Vec u) 4014 { 4015 Vec solution; 4016 PetscErrorCode ierr; 4017 4018 PetscFunctionBegin; 4019 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4020 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 4021 4022 ierr = TSSetExactFinalTimeDefault(ts);CHKERRQ(ierr); 4023 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && u) { /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */ 4024 if (!ts->vec_sol || u == ts->vec_sol) { 4025 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 4026 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 4027 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 4028 } 4029 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 4030 if (ts->forward_solve) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE"); 4031 } else if (u) { 4032 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 4033 } 4034 ierr = TSSetUp(ts);CHKERRQ(ierr); 4035 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 4036 4037 if (ts->max_time >= PETSC_MAX_REAL && ts->max_steps == PETSC_MAX_INT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>"); 4038 if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSSolve()"); 4039 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && !ts->adapt) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE"); 4040 4041 if (ts->forward_solve) { 4042 ierr = TSForwardSetUp(ts);CHKERRQ(ierr); 4043 } 4044 4045 /* reset number of steps only when the step is not restarted. ARKIMEX 4046 restarts the step after an event. Resetting these counters in such case causes 4047 TSTrajectory to incorrectly save the output files 4048 */ 4049 /* reset time step and iteration counters */ 4050 if (!ts->steps) { 4051 ts->ksp_its = 0; 4052 ts->snes_its = 0; 4053 ts->num_snes_failures = 0; 4054 ts->reject = 0; 4055 ts->steprestart = PETSC_TRUE; 4056 ts->steprollback = PETSC_FALSE; 4057 ts->rhsjacobian.time = PETSC_MIN_REAL; 4058 } 4059 4060 /* make sure initial time step does not overshoot final time */ 4061 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) { 4062 PetscReal maxdt = ts->max_time-ts->ptime; 4063 PetscReal dt = ts->time_step; 4064 4065 ts->time_step = dt >= maxdt ? maxdt : (PetscIsCloseAtTol(dt,maxdt,10*PETSC_MACHINE_EPSILON,0) ? maxdt : dt); 4066 } 4067 ts->reason = TS_CONVERGED_ITERATING; 4068 4069 { 4070 PetscViewer viewer; 4071 PetscViewerFormat format; 4072 PetscBool flg; 4073 static PetscBool incall = PETSC_FALSE; 4074 4075 if (!incall) { 4076 /* Estimate the convergence rate of the time discretization */ 4077 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) ts),((PetscObject)ts)->options, ((PetscObject) ts)->prefix, "-ts_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 4078 if (flg) { 4079 PetscConvEst conv; 4080 DM dm; 4081 PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 4082 PetscInt Nf; 4083 PetscBool checkTemporal = PETSC_TRUE; 4084 4085 incall = PETSC_TRUE; 4086 ierr = PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject) ts)->prefix, "-ts_convergence_temporal", &checkTemporal, &flg);CHKERRQ(ierr); 4087 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 4088 ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4089 ierr = PetscCalloc1(PetscMax(Nf, 1), &alpha);CHKERRQ(ierr); 4090 ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) ts), &conv);CHKERRQ(ierr); 4091 ierr = PetscConvEstUseTS(conv, checkTemporal);CHKERRQ(ierr); 4092 ierr = PetscConvEstSetSolver(conv, (PetscObject) ts);CHKERRQ(ierr); 4093 ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 4094 ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 4095 ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr); 4096 ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 4097 ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 4098 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4099 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4100 ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 4101 ierr = PetscFree(alpha);CHKERRQ(ierr); 4102 incall = PETSC_FALSE; 4103 } 4104 } 4105 } 4106 4107 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 4108 4109 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 4110 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 4111 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4112 ts->solvetime = ts->ptime; 4113 solution = ts->vec_sol; 4114 } else { /* Step the requested number of timesteps. */ 4115 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 4116 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 4117 4118 if (!ts->steps) { 4119 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4120 ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4121 } 4122 4123 while (!ts->reason) { 4124 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4125 if (!ts->steprollback) { 4126 ierr = TSPreStep(ts);CHKERRQ(ierr); 4127 } 4128 ierr = TSStep(ts);CHKERRQ(ierr); 4129 if (ts->testjacobian) { 4130 ierr = TSRHSJacobianTest(ts,NULL);CHKERRQ(ierr); 4131 } 4132 if (ts->testjacobiantranspose) { 4133 ierr = TSRHSJacobianTestTranspose(ts,NULL);CHKERRQ(ierr); 4134 } 4135 if (ts->quadraturets && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */ 4136 if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */ 4137 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 4138 if (ts->reason >= 0) ts->steps++; 4139 } 4140 if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */ 4141 if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */ 4142 ierr = TSForwardStep(ts);CHKERRQ(ierr); 4143 if (ts->reason >= 0) ts->steps++; 4144 } 4145 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4146 ierr = TSEventHandler(ts);CHKERRQ(ierr); /* The right-hand side may be changed due to event. Be careful with Any computation using the RHS information after this point. */ 4147 if (ts->steprollback) { 4148 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4149 } 4150 if (!ts->steprollback) { 4151 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4152 ierr = TSPostStep(ts);CHKERRQ(ierr); 4153 } 4154 } 4155 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4156 4157 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 4158 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 4159 ts->solvetime = ts->max_time; 4160 solution = u; 4161 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 4162 } else { 4163 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4164 ts->solvetime = ts->ptime; 4165 solution = ts->vec_sol; 4166 } 4167 } 4168 4169 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 4170 ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr); 4171 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 4172 if (ts->adjoint_solve) { 4173 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 4174 } 4175 PetscFunctionReturn(0); 4176 } 4177 4178 /*@C 4179 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 4180 4181 Collective on TS 4182 4183 Input Parameters: 4184 + ts - time stepping context obtained from TSCreate() 4185 . step - step number that has just completed 4186 . ptime - model time of the state 4187 - u - state at the current model time 4188 4189 Notes: 4190 TSMonitor() is typically used automatically within the time stepping implementations. 4191 Users would almost never call this routine directly. 4192 4193 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 4194 4195 Level: developer 4196 4197 @*/ 4198 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 4199 { 4200 DM dm; 4201 PetscInt i,n = ts->numbermonitors; 4202 PetscErrorCode ierr; 4203 4204 PetscFunctionBegin; 4205 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4206 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4207 4208 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4209 ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr); 4210 4211 ierr = VecLockReadPush(u);CHKERRQ(ierr); 4212 for (i=0; i<n; i++) { 4213 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 4214 } 4215 ierr = VecLockReadPop(u);CHKERRQ(ierr); 4216 PetscFunctionReturn(0); 4217 } 4218 4219 /* ------------------------------------------------------------------------*/ 4220 /*@C 4221 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 4222 TS to monitor the solution process graphically in various ways 4223 4224 Collective on TS 4225 4226 Input Parameters: 4227 + host - the X display to open, or null for the local machine 4228 . label - the title to put in the title bar 4229 . x, y - the screen coordinates of the upper left coordinate of the window 4230 . m, n - the screen width and height in pixels 4231 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 4232 4233 Output Parameter: 4234 . ctx - the context 4235 4236 Options Database Key: 4237 + -ts_monitor_lg_timestep - automatically sets line graph monitor 4238 + -ts_monitor_lg_timestep_log - automatically sets line graph monitor 4239 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 4240 . -ts_monitor_lg_error - monitor the error 4241 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 4242 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 4243 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 4244 4245 Notes: 4246 Use TSMonitorLGCtxDestroy() to destroy. 4247 4248 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 4249 4250 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 4251 first argument (if that TS object does not have a TSMonitorLGCtx associated with it the function call is ignored) and the second takes a TSMonitorLGCtx object 4252 as the first argument. 4253 4254 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 4255 4256 Level: intermediate 4257 4258 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 4259 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 4260 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 4261 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 4262 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 4263 4264 @*/ 4265 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 4266 { 4267 PetscDraw draw; 4268 PetscErrorCode ierr; 4269 4270 PetscFunctionBegin; 4271 ierr = PetscNew(ctx);CHKERRQ(ierr); 4272 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 4273 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 4274 ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr); 4275 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 4276 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4277 (*ctx)->howoften = howoften; 4278 PetscFunctionReturn(0); 4279 } 4280 4281 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 4282 { 4283 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4284 PetscReal x = ptime,y; 4285 PetscErrorCode ierr; 4286 4287 PetscFunctionBegin; 4288 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 4289 if (!step) { 4290 PetscDrawAxis axis; 4291 const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step"; 4292 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4293 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr); 4294 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4295 } 4296 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 4297 if (ctx->semilogy) y = PetscLog10Real(y); 4298 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4299 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4300 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4301 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 4302 } 4303 PetscFunctionReturn(0); 4304 } 4305 4306 /*@C 4307 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 4308 with TSMonitorLGCtxCreate(). 4309 4310 Collective on TSMonitorLGCtx 4311 4312 Input Parameter: 4313 . ctx - the monitor context 4314 4315 Level: intermediate 4316 4317 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 4318 @*/ 4319 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 4320 { 4321 PetscErrorCode ierr; 4322 4323 PetscFunctionBegin; 4324 if ((*ctx)->transformdestroy) { 4325 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 4326 } 4327 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 4328 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 4329 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 4330 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 4331 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 4332 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4333 PetscFunctionReturn(0); 4334 } 4335 4336 /* 4337 4338 Creates a TS Monitor SPCtx for use with DM Swarm particle visualizations 4339 4340 */ 4341 PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorSPCtx *ctx) 4342 { 4343 PetscDraw draw; 4344 PetscErrorCode ierr; 4345 4346 PetscFunctionBegin; 4347 ierr = PetscNew(ctx);CHKERRQ(ierr); 4348 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 4349 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 4350 ierr = PetscDrawSPCreate(draw,1,&(*ctx)->sp);CHKERRQ(ierr); 4351 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4352 (*ctx)->howoften = howoften; 4353 PetscFunctionReturn(0); 4354 4355 } 4356 4357 /* 4358 Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate 4359 */ 4360 PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx) 4361 { 4362 PetscErrorCode ierr; 4363 4364 PetscFunctionBegin; 4365 4366 ierr = PetscDrawSPDestroy(&(*ctx)->sp);CHKERRQ(ierr); 4367 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4368 4369 PetscFunctionReturn(0); 4370 4371 } 4372 4373 /*@ 4374 TSGetTime - Gets the time of the most recently completed step. 4375 4376 Not Collective 4377 4378 Input Parameter: 4379 . ts - the TS context obtained from TSCreate() 4380 4381 Output Parameter: 4382 . t - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime(). 4383 4384 Level: beginner 4385 4386 Note: 4387 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 4388 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 4389 4390 .seealso: TSGetSolveTime(), TSSetTime(), TSGetTimeStep(), TSGetStepNumber() 4391 4392 @*/ 4393 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 4394 { 4395 PetscFunctionBegin; 4396 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4397 PetscValidRealPointer(t,2); 4398 *t = ts->ptime; 4399 PetscFunctionReturn(0); 4400 } 4401 4402 /*@ 4403 TSGetPrevTime - Gets the starting time of the previously completed step. 4404 4405 Not Collective 4406 4407 Input Parameter: 4408 . ts - the TS context obtained from TSCreate() 4409 4410 Output Parameter: 4411 . t - the previous time 4412 4413 Level: beginner 4414 4415 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep() 4416 4417 @*/ 4418 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 4419 { 4420 PetscFunctionBegin; 4421 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4422 PetscValidRealPointer(t,2); 4423 *t = ts->ptime_prev; 4424 PetscFunctionReturn(0); 4425 } 4426 4427 /*@ 4428 TSSetTime - Allows one to reset the time. 4429 4430 Logically Collective on TS 4431 4432 Input Parameters: 4433 + ts - the TS context obtained from TSCreate() 4434 - time - the time 4435 4436 Level: intermediate 4437 4438 .seealso: TSGetTime(), TSSetMaxSteps() 4439 4440 @*/ 4441 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4442 { 4443 PetscFunctionBegin; 4444 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4445 PetscValidLogicalCollectiveReal(ts,t,2); 4446 ts->ptime = t; 4447 PetscFunctionReturn(0); 4448 } 4449 4450 /*@C 4451 TSSetOptionsPrefix - Sets the prefix used for searching for all 4452 TS options in the database. 4453 4454 Logically Collective on TS 4455 4456 Input Parameter: 4457 + ts - The TS context 4458 - prefix - The prefix to prepend to all option names 4459 4460 Notes: 4461 A hyphen (-) must NOT be given at the beginning of the prefix name. 4462 The first character of all runtime options is AUTOMATICALLY the 4463 hyphen. 4464 4465 Level: advanced 4466 4467 .seealso: TSSetFromOptions() 4468 4469 @*/ 4470 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4471 { 4472 PetscErrorCode ierr; 4473 SNES snes; 4474 4475 PetscFunctionBegin; 4476 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4477 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4478 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4479 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4480 PetscFunctionReturn(0); 4481 } 4482 4483 /*@C 4484 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4485 TS options in the database. 4486 4487 Logically Collective on TS 4488 4489 Input Parameter: 4490 + ts - The TS context 4491 - prefix - The prefix to prepend to all option names 4492 4493 Notes: 4494 A hyphen (-) must NOT be given at the beginning of the prefix name. 4495 The first character of all runtime options is AUTOMATICALLY the 4496 hyphen. 4497 4498 Level: advanced 4499 4500 .seealso: TSGetOptionsPrefix() 4501 4502 @*/ 4503 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4504 { 4505 PetscErrorCode ierr; 4506 SNES snes; 4507 4508 PetscFunctionBegin; 4509 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4510 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4511 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4512 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4513 PetscFunctionReturn(0); 4514 } 4515 4516 /*@C 4517 TSGetOptionsPrefix - Sets the prefix used for searching for all 4518 TS options in the database. 4519 4520 Not Collective 4521 4522 Input Parameter: 4523 . ts - The TS context 4524 4525 Output Parameter: 4526 . prefix - A pointer to the prefix string used 4527 4528 Notes: 4529 On the fortran side, the user should pass in a string 'prifix' of 4530 sufficient length to hold the prefix. 4531 4532 Level: intermediate 4533 4534 .seealso: TSAppendOptionsPrefix() 4535 @*/ 4536 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4537 { 4538 PetscErrorCode ierr; 4539 4540 PetscFunctionBegin; 4541 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4542 PetscValidPointer(prefix,2); 4543 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4544 PetscFunctionReturn(0); 4545 } 4546 4547 /*@C 4548 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4549 4550 Not Collective, but parallel objects are returned if TS is parallel 4551 4552 Input Parameter: 4553 . ts - The TS context obtained from TSCreate() 4554 4555 Output Parameters: 4556 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4557 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4558 . func - Function to compute the Jacobian of the RHS (or NULL) 4559 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4560 4561 Notes: 4562 You can pass in NULL for any return argument you do not need. 4563 4564 Level: intermediate 4565 4566 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4567 4568 @*/ 4569 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4570 { 4571 PetscErrorCode ierr; 4572 DM dm; 4573 4574 PetscFunctionBegin; 4575 if (Amat || Pmat) { 4576 SNES snes; 4577 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4578 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4579 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4580 } 4581 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4582 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4583 PetscFunctionReturn(0); 4584 } 4585 4586 /*@C 4587 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4588 4589 Not Collective, but parallel objects are returned if TS is parallel 4590 4591 Input Parameter: 4592 . ts - The TS context obtained from TSCreate() 4593 4594 Output Parameters: 4595 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4596 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4597 . f - The function to compute the matrices 4598 - ctx - User-defined context for Jacobian evaluation routine 4599 4600 Notes: 4601 You can pass in NULL for any return argument you do not need. 4602 4603 Level: advanced 4604 4605 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4606 4607 @*/ 4608 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4609 { 4610 PetscErrorCode ierr; 4611 DM dm; 4612 4613 PetscFunctionBegin; 4614 if (Amat || Pmat) { 4615 SNES snes; 4616 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4617 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4618 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4619 } 4620 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4621 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4622 PetscFunctionReturn(0); 4623 } 4624 4625 /*@C 4626 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4627 VecView() for the solution at each timestep 4628 4629 Collective on TS 4630 4631 Input Parameters: 4632 + ts - the TS context 4633 . step - current time-step 4634 . ptime - current time 4635 - dummy - either a viewer or NULL 4636 4637 Options Database: 4638 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4639 4640 Notes: 4641 the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4642 will look bad 4643 4644 Level: intermediate 4645 4646 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4647 @*/ 4648 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4649 { 4650 PetscErrorCode ierr; 4651 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4652 PetscDraw draw; 4653 4654 PetscFunctionBegin; 4655 if (!step && ictx->showinitial) { 4656 if (!ictx->initialsolution) { 4657 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 4658 } 4659 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 4660 } 4661 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4662 4663 if (ictx->showinitial) { 4664 PetscReal pause; 4665 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 4666 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 4667 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 4668 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 4669 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 4670 } 4671 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 4672 if (ictx->showtimestepandtime) { 4673 PetscReal xl,yl,xr,yr,h; 4674 char time[32]; 4675 4676 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4677 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4678 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4679 h = yl + .95*(yr - yl); 4680 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4681 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4682 } 4683 4684 if (ictx->showinitial) { 4685 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 4686 } 4687 PetscFunctionReturn(0); 4688 } 4689 4690 /*@C 4691 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 4692 4693 Collective on TS 4694 4695 Input Parameters: 4696 + ts - the TS context 4697 . step - current time-step 4698 . ptime - current time 4699 - dummy - either a viewer or NULL 4700 4701 Level: intermediate 4702 4703 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4704 @*/ 4705 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4706 { 4707 PetscErrorCode ierr; 4708 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4709 PetscDraw draw; 4710 PetscDrawAxis axis; 4711 PetscInt n; 4712 PetscMPIInt size; 4713 PetscReal U0,U1,xl,yl,xr,yr,h; 4714 char time[32]; 4715 const PetscScalar *U; 4716 4717 PetscFunctionBegin; 4718 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 4719 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 4720 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 4721 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 4722 4723 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4724 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 4725 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 4726 if (!step) { 4727 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 4728 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 4729 } 4730 4731 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 4732 U0 = PetscRealPart(U[0]); 4733 U1 = PetscRealPart(U[1]); 4734 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 4735 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 4736 4737 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4738 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 4739 if (ictx->showtimestepandtime) { 4740 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4741 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4742 h = yl + .95*(yr - yl); 4743 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4744 } 4745 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4746 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4747 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 4748 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 4749 PetscFunctionReturn(0); 4750 } 4751 4752 /*@C 4753 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 4754 4755 Collective on TS 4756 4757 Input Parameters: 4758 . ctx - the monitor context 4759 4760 Level: intermediate 4761 4762 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 4763 @*/ 4764 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 4765 { 4766 PetscErrorCode ierr; 4767 4768 PetscFunctionBegin; 4769 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 4770 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 4771 ierr = PetscFree(*ictx);CHKERRQ(ierr); 4772 PetscFunctionReturn(0); 4773 } 4774 4775 /*@C 4776 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 4777 4778 Collective on TS 4779 4780 Input Parameter: 4781 . ts - time-step context 4782 4783 Output Patameter: 4784 . ctx - the monitor context 4785 4786 Options Database: 4787 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4788 4789 Level: intermediate 4790 4791 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 4792 @*/ 4793 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 4794 { 4795 PetscErrorCode ierr; 4796 4797 PetscFunctionBegin; 4798 ierr = PetscNew(ctx);CHKERRQ(ierr); 4799 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 4800 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 4801 4802 (*ctx)->howoften = howoften; 4803 (*ctx)->showinitial = PETSC_FALSE; 4804 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 4805 4806 (*ctx)->showtimestepandtime = PETSC_FALSE; 4807 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 4808 PetscFunctionReturn(0); 4809 } 4810 4811 /*@C 4812 TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling 4813 VecView() for the solution provided by TSSetSolutionFunction() at each timestep 4814 4815 Collective on TS 4816 4817 Input Parameters: 4818 + ts - the TS context 4819 . step - current time-step 4820 . ptime - current time 4821 - dummy - either a viewer or NULL 4822 4823 Options Database: 4824 . -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4825 4826 Level: intermediate 4827 4828 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4829 @*/ 4830 PetscErrorCode TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4831 { 4832 PetscErrorCode ierr; 4833 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4834 PetscViewer viewer = ctx->viewer; 4835 Vec work; 4836 4837 PetscFunctionBegin; 4838 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4839 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4840 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4841 ierr = VecView(work,viewer);CHKERRQ(ierr); 4842 ierr = VecDestroy(&work);CHKERRQ(ierr); 4843 PetscFunctionReturn(0); 4844 } 4845 4846 /*@C 4847 TSMonitorDrawError - Monitors progress of the TS solvers by calling 4848 VecView() for the error at each timestep 4849 4850 Collective on TS 4851 4852 Input Parameters: 4853 + ts - the TS context 4854 . step - current time-step 4855 . ptime - current time 4856 - dummy - either a viewer or NULL 4857 4858 Options Database: 4859 . -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4860 4861 Level: intermediate 4862 4863 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4864 @*/ 4865 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4866 { 4867 PetscErrorCode ierr; 4868 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4869 PetscViewer viewer = ctx->viewer; 4870 Vec work; 4871 4872 PetscFunctionBegin; 4873 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4874 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4875 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4876 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 4877 ierr = VecView(work,viewer);CHKERRQ(ierr); 4878 ierr = VecDestroy(&work);CHKERRQ(ierr); 4879 PetscFunctionReturn(0); 4880 } 4881 4882 #include <petsc/private/dmimpl.h> 4883 /*@ 4884 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 4885 4886 Logically Collective on ts 4887 4888 Input Parameters: 4889 + ts - the ODE integrator object 4890 - dm - the dm, cannot be NULL 4891 4892 Notes: 4893 A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 4894 even when not using interfaces like DMTSSetIFunction(). Use DMClone() to get a distinct DM when solving 4895 different problems using the same function space. 4896 4897 Level: intermediate 4898 4899 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4900 @*/ 4901 PetscErrorCode TSSetDM(TS ts,DM dm) 4902 { 4903 PetscErrorCode ierr; 4904 SNES snes; 4905 DMTS tsdm; 4906 4907 PetscFunctionBegin; 4908 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4909 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4910 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4911 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4912 if (ts->dm->dmts && !dm->dmts) { 4913 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4914 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4915 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4916 tsdm->originaldm = dm; 4917 } 4918 } 4919 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4920 } 4921 ts->dm = dm; 4922 4923 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4924 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4925 PetscFunctionReturn(0); 4926 } 4927 4928 /*@ 4929 TSGetDM - Gets the DM that may be used by some preconditioners 4930 4931 Not Collective 4932 4933 Input Parameter: 4934 . ts - the preconditioner context 4935 4936 Output Parameter: 4937 . dm - the dm 4938 4939 Level: intermediate 4940 4941 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4942 @*/ 4943 PetscErrorCode TSGetDM(TS ts,DM *dm) 4944 { 4945 PetscErrorCode ierr; 4946 4947 PetscFunctionBegin; 4948 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4949 if (!ts->dm) { 4950 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 4951 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 4952 } 4953 *dm = ts->dm; 4954 PetscFunctionReturn(0); 4955 } 4956 4957 /*@ 4958 SNESTSFormFunction - Function to evaluate nonlinear residual 4959 4960 Logically Collective on SNES 4961 4962 Input Parameter: 4963 + snes - nonlinear solver 4964 . U - the current state at which to evaluate the residual 4965 - ctx - user context, must be a TS 4966 4967 Output Parameter: 4968 . F - the nonlinear residual 4969 4970 Notes: 4971 This function is not normally called by users and is automatically registered with the SNES used by TS. 4972 It is most frequently passed to MatFDColoringSetFunction(). 4973 4974 Level: advanced 4975 4976 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 4977 @*/ 4978 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 4979 { 4980 TS ts = (TS)ctx; 4981 PetscErrorCode ierr; 4982 4983 PetscFunctionBegin; 4984 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4985 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4986 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 4987 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 4988 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 4989 PetscFunctionReturn(0); 4990 } 4991 4992 /*@ 4993 SNESTSFormJacobian - Function to evaluate the Jacobian 4994 4995 Collective on SNES 4996 4997 Input Parameter: 4998 + snes - nonlinear solver 4999 . U - the current state at which to evaluate the residual 5000 - ctx - user context, must be a TS 5001 5002 Output Parameter: 5003 + A - the Jacobian 5004 . B - the preconditioning matrix (may be the same as A) 5005 - flag - indicates any structure change in the matrix 5006 5007 Notes: 5008 This function is not normally called by users and is automatically registered with the SNES used by TS. 5009 5010 Level: developer 5011 5012 .seealso: SNESSetJacobian() 5013 @*/ 5014 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 5015 { 5016 TS ts = (TS)ctx; 5017 PetscErrorCode ierr; 5018 5019 PetscFunctionBegin; 5020 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5021 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5022 PetscValidPointer(A,3); 5023 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 5024 PetscValidPointer(B,4); 5025 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 5026 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 5027 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 5028 PetscFunctionReturn(0); 5029 } 5030 5031 /*@C 5032 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 5033 5034 Collective on TS 5035 5036 Input Arguments: 5037 + ts - time stepping context 5038 . t - time at which to evaluate 5039 . U - state at which to evaluate 5040 - ctx - context 5041 5042 Output Arguments: 5043 . F - right hand side 5044 5045 Level: intermediate 5046 5047 Notes: 5048 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 5049 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 5050 5051 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 5052 @*/ 5053 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 5054 { 5055 PetscErrorCode ierr; 5056 Mat Arhs,Brhs; 5057 5058 PetscFunctionBegin; 5059 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 5060 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 5061 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 5062 PetscFunctionReturn(0); 5063 } 5064 5065 /*@C 5066 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 5067 5068 Collective on TS 5069 5070 Input Arguments: 5071 + ts - time stepping context 5072 . t - time at which to evaluate 5073 . U - state at which to evaluate 5074 - ctx - context 5075 5076 Output Arguments: 5077 + A - pointer to operator 5078 . B - pointer to preconditioning matrix 5079 - flg - matrix structure flag 5080 5081 Level: intermediate 5082 5083 Notes: 5084 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 5085 5086 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 5087 @*/ 5088 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 5089 { 5090 PetscFunctionBegin; 5091 PetscFunctionReturn(0); 5092 } 5093 5094 /*@C 5095 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 5096 5097 Collective on TS 5098 5099 Input Arguments: 5100 + ts - time stepping context 5101 . t - time at which to evaluate 5102 . U - state at which to evaluate 5103 . Udot - time derivative of state vector 5104 - ctx - context 5105 5106 Output Arguments: 5107 . F - left hand side 5108 5109 Level: intermediate 5110 5111 Notes: 5112 The assumption here is that the left hand side is of the form A*Udot (and not A*Udot + B*U). For other cases, the 5113 user is required to write their own TSComputeIFunction. 5114 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 5115 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 5116 5117 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 5118 5119 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 5120 @*/ 5121 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 5122 { 5123 PetscErrorCode ierr; 5124 Mat A,B; 5125 5126 PetscFunctionBegin; 5127 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 5128 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 5129 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 5130 PetscFunctionReturn(0); 5131 } 5132 5133 /*@C 5134 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 5135 5136 Collective on TS 5137 5138 Input Arguments: 5139 + ts - time stepping context 5140 . t - time at which to evaluate 5141 . U - state at which to evaluate 5142 . Udot - time derivative of state vector 5143 . shift - shift to apply 5144 - ctx - context 5145 5146 Output Arguments: 5147 + A - pointer to operator 5148 . B - pointer to preconditioning matrix 5149 - flg - matrix structure flag 5150 5151 Level: advanced 5152 5153 Notes: 5154 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 5155 5156 It is only appropriate for problems of the form 5157 5158 $ M Udot = F(U,t) 5159 5160 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 5161 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 5162 an implicit operator of the form 5163 5164 $ shift*M + J 5165 5166 where J is the Jacobian of -F(U). Support may be added in a future version of PETSc, but for now, the user must store 5167 a copy of M or reassemble it when requested. 5168 5169 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 5170 @*/ 5171 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 5172 { 5173 PetscErrorCode ierr; 5174 5175 PetscFunctionBegin; 5176 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 5177 ts->ijacobian.shift = shift; 5178 PetscFunctionReturn(0); 5179 } 5180 5181 /*@ 5182 TSGetEquationType - Gets the type of the equation that TS is solving. 5183 5184 Not Collective 5185 5186 Input Parameter: 5187 . ts - the TS context 5188 5189 Output Parameter: 5190 . equation_type - see TSEquationType 5191 5192 Level: beginner 5193 5194 .seealso: TSSetEquationType(), TSEquationType 5195 @*/ 5196 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 5197 { 5198 PetscFunctionBegin; 5199 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5200 PetscValidPointer(equation_type,2); 5201 *equation_type = ts->equation_type; 5202 PetscFunctionReturn(0); 5203 } 5204 5205 /*@ 5206 TSSetEquationType - Sets the type of the equation that TS is solving. 5207 5208 Not Collective 5209 5210 Input Parameter: 5211 + ts - the TS context 5212 - equation_type - see TSEquationType 5213 5214 Level: advanced 5215 5216 .seealso: TSGetEquationType(), TSEquationType 5217 @*/ 5218 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 5219 { 5220 PetscFunctionBegin; 5221 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5222 ts->equation_type = equation_type; 5223 PetscFunctionReturn(0); 5224 } 5225 5226 /*@ 5227 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 5228 5229 Not Collective 5230 5231 Input Parameter: 5232 . ts - the TS context 5233 5234 Output Parameter: 5235 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5236 manual pages for the individual convergence tests for complete lists 5237 5238 Level: beginner 5239 5240 Notes: 5241 Can only be called after the call to TSSolve() is complete. 5242 5243 .seealso: TSSetConvergenceTest(), TSConvergedReason 5244 @*/ 5245 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 5246 { 5247 PetscFunctionBegin; 5248 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5249 PetscValidPointer(reason,2); 5250 *reason = ts->reason; 5251 PetscFunctionReturn(0); 5252 } 5253 5254 /*@ 5255 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 5256 5257 Logically Collective; reason must contain common value 5258 5259 Input Parameters: 5260 + ts - the TS context 5261 - reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5262 manual pages for the individual convergence tests for complete lists 5263 5264 Level: advanced 5265 5266 Notes: 5267 Can only be called while TSSolve() is active. 5268 5269 .seealso: TSConvergedReason 5270 @*/ 5271 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 5272 { 5273 PetscFunctionBegin; 5274 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5275 ts->reason = reason; 5276 PetscFunctionReturn(0); 5277 } 5278 5279 /*@ 5280 TSGetSolveTime - Gets the time after a call to TSSolve() 5281 5282 Not Collective 5283 5284 Input Parameter: 5285 . ts - the TS context 5286 5287 Output Parameter: 5288 . ftime - the final time. This time corresponds to the final time set with TSSetMaxTime() 5289 5290 Level: beginner 5291 5292 Notes: 5293 Can only be called after the call to TSSolve() is complete. 5294 5295 .seealso: TSSetConvergenceTest(), TSConvergedReason 5296 @*/ 5297 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 5298 { 5299 PetscFunctionBegin; 5300 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5301 PetscValidPointer(ftime,2); 5302 *ftime = ts->solvetime; 5303 PetscFunctionReturn(0); 5304 } 5305 5306 /*@ 5307 TSGetSNESIterations - Gets the total number of nonlinear iterations 5308 used by the time integrator. 5309 5310 Not Collective 5311 5312 Input Parameter: 5313 . ts - TS context 5314 5315 Output Parameter: 5316 . nits - number of nonlinear iterations 5317 5318 Notes: 5319 This counter is reset to zero for each successive call to TSSolve(). 5320 5321 Level: intermediate 5322 5323 .seealso: TSGetKSPIterations() 5324 @*/ 5325 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 5326 { 5327 PetscFunctionBegin; 5328 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5329 PetscValidIntPointer(nits,2); 5330 *nits = ts->snes_its; 5331 PetscFunctionReturn(0); 5332 } 5333 5334 /*@ 5335 TSGetKSPIterations - Gets the total number of linear iterations 5336 used by the time integrator. 5337 5338 Not Collective 5339 5340 Input Parameter: 5341 . ts - TS context 5342 5343 Output Parameter: 5344 . lits - number of linear iterations 5345 5346 Notes: 5347 This counter is reset to zero for each successive call to TSSolve(). 5348 5349 Level: intermediate 5350 5351 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 5352 @*/ 5353 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 5354 { 5355 PetscFunctionBegin; 5356 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5357 PetscValidIntPointer(lits,2); 5358 *lits = ts->ksp_its; 5359 PetscFunctionReturn(0); 5360 } 5361 5362 /*@ 5363 TSGetStepRejections - Gets the total number of rejected steps. 5364 5365 Not Collective 5366 5367 Input Parameter: 5368 . ts - TS context 5369 5370 Output Parameter: 5371 . rejects - number of steps rejected 5372 5373 Notes: 5374 This counter is reset to zero for each successive call to TSSolve(). 5375 5376 Level: intermediate 5377 5378 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 5379 @*/ 5380 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 5381 { 5382 PetscFunctionBegin; 5383 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5384 PetscValidIntPointer(rejects,2); 5385 *rejects = ts->reject; 5386 PetscFunctionReturn(0); 5387 } 5388 5389 /*@ 5390 TSGetSNESFailures - Gets the total number of failed SNES solves 5391 5392 Not Collective 5393 5394 Input Parameter: 5395 . ts - TS context 5396 5397 Output Parameter: 5398 . fails - number of failed nonlinear solves 5399 5400 Notes: 5401 This counter is reset to zero for each successive call to TSSolve(). 5402 5403 Level: intermediate 5404 5405 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5406 @*/ 5407 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5408 { 5409 PetscFunctionBegin; 5410 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5411 PetscValidIntPointer(fails,2); 5412 *fails = ts->num_snes_failures; 5413 PetscFunctionReturn(0); 5414 } 5415 5416 /*@ 5417 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5418 5419 Not Collective 5420 5421 Input Parameter: 5422 + ts - TS context 5423 - rejects - maximum number of rejected steps, pass -1 for unlimited 5424 5425 Notes: 5426 The counter is reset to zero for each step 5427 5428 Options Database Key: 5429 . -ts_max_reject - Maximum number of step rejections before a step fails 5430 5431 Level: intermediate 5432 5433 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5434 @*/ 5435 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5436 { 5437 PetscFunctionBegin; 5438 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5439 ts->max_reject = rejects; 5440 PetscFunctionReturn(0); 5441 } 5442 5443 /*@ 5444 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5445 5446 Not Collective 5447 5448 Input Parameter: 5449 + ts - TS context 5450 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5451 5452 Notes: 5453 The counter is reset to zero for each successive call to TSSolve(). 5454 5455 Options Database Key: 5456 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5457 5458 Level: intermediate 5459 5460 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5461 @*/ 5462 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5463 { 5464 PetscFunctionBegin; 5465 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5466 ts->max_snes_failures = fails; 5467 PetscFunctionReturn(0); 5468 } 5469 5470 /*@ 5471 TSSetErrorIfStepFails - Error if no step succeeds 5472 5473 Not Collective 5474 5475 Input Parameter: 5476 + ts - TS context 5477 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5478 5479 Options Database Key: 5480 . -ts_error_if_step_fails - Error if no step succeeds 5481 5482 Level: intermediate 5483 5484 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5485 @*/ 5486 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5487 { 5488 PetscFunctionBegin; 5489 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5490 ts->errorifstepfailed = err; 5491 PetscFunctionReturn(0); 5492 } 5493 5494 /*@C 5495 TSMonitorSolution - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file or a PetscDraw object 5496 5497 Collective on TS 5498 5499 Input Parameters: 5500 + ts - the TS context 5501 . step - current time-step 5502 . ptime - current time 5503 . u - current state 5504 - vf - viewer and its format 5505 5506 Level: intermediate 5507 5508 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5509 @*/ 5510 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5511 { 5512 PetscErrorCode ierr; 5513 5514 PetscFunctionBegin; 5515 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5516 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5517 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5518 PetscFunctionReturn(0); 5519 } 5520 5521 /*@C 5522 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5523 5524 Collective on TS 5525 5526 Input Parameters: 5527 + ts - the TS context 5528 . step - current time-step 5529 . ptime - current time 5530 . u - current state 5531 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5532 5533 Level: intermediate 5534 5535 Notes: 5536 The VTK format does not allow writing multiple time steps in the same file, therefore a different file will be written for each time step. 5537 These are named according to the file name template. 5538 5539 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5540 5541 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5542 @*/ 5543 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5544 { 5545 PetscErrorCode ierr; 5546 char filename[PETSC_MAX_PATH_LEN]; 5547 PetscViewer viewer; 5548 5549 PetscFunctionBegin; 5550 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5551 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5552 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5553 ierr = VecView(u,viewer);CHKERRQ(ierr); 5554 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5555 PetscFunctionReturn(0); 5556 } 5557 5558 /*@C 5559 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5560 5561 Collective on TS 5562 5563 Input Parameters: 5564 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5565 5566 Level: intermediate 5567 5568 Note: 5569 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 5570 5571 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 5572 @*/ 5573 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 5574 { 5575 PetscErrorCode ierr; 5576 5577 PetscFunctionBegin; 5578 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 5579 PetscFunctionReturn(0); 5580 } 5581 5582 /*@ 5583 TSGetAdapt - Get the adaptive controller context for the current method 5584 5585 Collective on TS if controller has not been created yet 5586 5587 Input Arguments: 5588 . ts - time stepping context 5589 5590 Output Arguments: 5591 . adapt - adaptive controller 5592 5593 Level: intermediate 5594 5595 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 5596 @*/ 5597 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 5598 { 5599 PetscErrorCode ierr; 5600 5601 PetscFunctionBegin; 5602 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5603 PetscValidPointer(adapt,2); 5604 if (!ts->adapt) { 5605 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 5606 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 5607 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 5608 } 5609 *adapt = ts->adapt; 5610 PetscFunctionReturn(0); 5611 } 5612 5613 /*@ 5614 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 5615 5616 Logically Collective 5617 5618 Input Arguments: 5619 + ts - time integration context 5620 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 5621 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 5622 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 5623 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 5624 5625 Options Database keys: 5626 + -ts_rtol <rtol> - relative tolerance for local truncation error 5627 - -ts_atol <atol> Absolute tolerance for local truncation error 5628 5629 Notes: 5630 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 5631 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 5632 computed only for the differential or the algebraic part then this can be done using the vector of 5633 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 5634 differential part and infinity for the algebraic part, the LTE calculation will include only the 5635 differential variables. 5636 5637 Level: beginner 5638 5639 .seealso: TS, TSAdapt, TSErrorWeightedNorm(), TSGetTolerances() 5640 @*/ 5641 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 5642 { 5643 PetscErrorCode ierr; 5644 5645 PetscFunctionBegin; 5646 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 5647 if (vatol) { 5648 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 5649 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 5650 ts->vatol = vatol; 5651 } 5652 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 5653 if (vrtol) { 5654 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 5655 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 5656 ts->vrtol = vrtol; 5657 } 5658 PetscFunctionReturn(0); 5659 } 5660 5661 /*@ 5662 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5663 5664 Logically Collective 5665 5666 Input Arguments: 5667 . ts - time integration context 5668 5669 Output Arguments: 5670 + atol - scalar absolute tolerances, NULL to ignore 5671 . vatol - vector of absolute tolerances, NULL to ignore 5672 . rtol - scalar relative tolerances, NULL to ignore 5673 - vrtol - vector of relative tolerances, NULL to ignore 5674 5675 Level: beginner 5676 5677 .seealso: TS, TSAdapt, TSErrorWeightedNorm(), TSSetTolerances() 5678 @*/ 5679 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 5680 { 5681 PetscFunctionBegin; 5682 if (atol) *atol = ts->atol; 5683 if (vatol) *vatol = ts->vatol; 5684 if (rtol) *rtol = ts->rtol; 5685 if (vrtol) *vrtol = ts->vrtol; 5686 PetscFunctionReturn(0); 5687 } 5688 5689 /*@ 5690 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 5691 5692 Collective on TS 5693 5694 Input Arguments: 5695 + ts - time stepping context 5696 . U - state vector, usually ts->vec_sol 5697 - Y - state vector to be compared to U 5698 5699 Output Arguments: 5700 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5701 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5702 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5703 5704 Level: developer 5705 5706 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 5707 @*/ 5708 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5709 { 5710 PetscErrorCode ierr; 5711 PetscInt i,n,N,rstart; 5712 PetscInt n_loc,na_loc,nr_loc; 5713 PetscReal n_glb,na_glb,nr_glb; 5714 const PetscScalar *u,*y; 5715 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 5716 PetscReal tol,tola,tolr; 5717 PetscReal err_loc[6],err_glb[6]; 5718 5719 PetscFunctionBegin; 5720 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5721 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5722 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5723 PetscValidType(U,2); 5724 PetscValidType(Y,3); 5725 PetscCheckSameComm(U,2,Y,3); 5726 PetscValidPointer(norm,4); 5727 PetscValidPointer(norma,5); 5728 PetscValidPointer(normr,6); 5729 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5730 5731 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5732 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5733 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5734 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5735 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5736 sum = 0.; n_loc = 0; 5737 suma = 0.; na_loc = 0; 5738 sumr = 0.; nr_loc = 0; 5739 if (ts->vatol && ts->vrtol) { 5740 const PetscScalar *atol,*rtol; 5741 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5742 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5743 for (i=0; i<n; i++) { 5744 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5745 diff = PetscAbsScalar(y[i] - u[i]); 5746 tola = PetscRealPart(atol[i]); 5747 if (tola>0.){ 5748 suma += PetscSqr(diff/tola); 5749 na_loc++; 5750 } 5751 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5752 if (tolr>0.){ 5753 sumr += PetscSqr(diff/tolr); 5754 nr_loc++; 5755 } 5756 tol=tola+tolr; 5757 if (tol>0.){ 5758 sum += PetscSqr(diff/tol); 5759 n_loc++; 5760 } 5761 } 5762 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5763 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5764 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5765 const PetscScalar *atol; 5766 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5767 for (i=0; i<n; i++) { 5768 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5769 diff = PetscAbsScalar(y[i] - u[i]); 5770 tola = PetscRealPart(atol[i]); 5771 if (tola>0.){ 5772 suma += PetscSqr(diff/tola); 5773 na_loc++; 5774 } 5775 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5776 if (tolr>0.){ 5777 sumr += PetscSqr(diff/tolr); 5778 nr_loc++; 5779 } 5780 tol=tola+tolr; 5781 if (tol>0.){ 5782 sum += PetscSqr(diff/tol); 5783 n_loc++; 5784 } 5785 } 5786 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5787 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5788 const PetscScalar *rtol; 5789 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5790 for (i=0; i<n; i++) { 5791 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5792 diff = PetscAbsScalar(y[i] - u[i]); 5793 tola = ts->atol; 5794 if (tola>0.){ 5795 suma += PetscSqr(diff/tola); 5796 na_loc++; 5797 } 5798 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5799 if (tolr>0.){ 5800 sumr += PetscSqr(diff/tolr); 5801 nr_loc++; 5802 } 5803 tol=tola+tolr; 5804 if (tol>0.){ 5805 sum += PetscSqr(diff/tol); 5806 n_loc++; 5807 } 5808 } 5809 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5810 } else { /* scalar atol, scalar rtol */ 5811 for (i=0; i<n; i++) { 5812 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5813 diff = PetscAbsScalar(y[i] - u[i]); 5814 tola = ts->atol; 5815 if (tola>0.){ 5816 suma += PetscSqr(diff/tola); 5817 na_loc++; 5818 } 5819 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5820 if (tolr>0.){ 5821 sumr += PetscSqr(diff/tolr); 5822 nr_loc++; 5823 } 5824 tol=tola+tolr; 5825 if (tol>0.){ 5826 sum += PetscSqr(diff/tol); 5827 n_loc++; 5828 } 5829 } 5830 } 5831 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5832 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5833 5834 err_loc[0] = sum; 5835 err_loc[1] = suma; 5836 err_loc[2] = sumr; 5837 err_loc[3] = (PetscReal)n_loc; 5838 err_loc[4] = (PetscReal)na_loc; 5839 err_loc[5] = (PetscReal)nr_loc; 5840 5841 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5842 5843 gsum = err_glb[0]; 5844 gsuma = err_glb[1]; 5845 gsumr = err_glb[2]; 5846 n_glb = err_glb[3]; 5847 na_glb = err_glb[4]; 5848 nr_glb = err_glb[5]; 5849 5850 *norm = 0.; 5851 if (n_glb>0.){*norm = PetscSqrtReal(gsum / n_glb);} 5852 *norma = 0.; 5853 if (na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5854 *normr = 0.; 5855 if (nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5856 5857 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5858 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5859 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5860 PetscFunctionReturn(0); 5861 } 5862 5863 /*@ 5864 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5865 5866 Collective on TS 5867 5868 Input Arguments: 5869 + ts - time stepping context 5870 . U - state vector, usually ts->vec_sol 5871 - Y - state vector to be compared to U 5872 5873 Output Arguments: 5874 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5875 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5876 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5877 5878 Level: developer 5879 5880 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5881 @*/ 5882 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5883 { 5884 PetscErrorCode ierr; 5885 PetscInt i,n,N,rstart; 5886 const PetscScalar *u,*y; 5887 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 5888 PetscReal tol,tola,tolr,diff; 5889 PetscReal err_loc[3],err_glb[3]; 5890 5891 PetscFunctionBegin; 5892 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5893 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5894 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5895 PetscValidType(U,2); 5896 PetscValidType(Y,3); 5897 PetscCheckSameComm(U,2,Y,3); 5898 PetscValidPointer(norm,4); 5899 PetscValidPointer(norma,5); 5900 PetscValidPointer(normr,6); 5901 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5902 5903 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5904 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5905 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5906 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5907 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5908 5909 max=0.; 5910 maxa=0.; 5911 maxr=0.; 5912 5913 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5914 const PetscScalar *atol,*rtol; 5915 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5916 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5917 5918 for (i=0; i<n; i++) { 5919 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5920 diff = PetscAbsScalar(y[i] - u[i]); 5921 tola = PetscRealPart(atol[i]); 5922 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5923 tol = tola+tolr; 5924 if (tola>0.){ 5925 maxa = PetscMax(maxa,diff / tola); 5926 } 5927 if (tolr>0.){ 5928 maxr = PetscMax(maxr,diff / tolr); 5929 } 5930 if (tol>0.){ 5931 max = PetscMax(max,diff / tol); 5932 } 5933 } 5934 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5935 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5936 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5937 const PetscScalar *atol; 5938 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5939 for (i=0; i<n; i++) { 5940 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5941 diff = PetscAbsScalar(y[i] - u[i]); 5942 tola = PetscRealPart(atol[i]); 5943 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5944 tol = tola+tolr; 5945 if (tola>0.){ 5946 maxa = PetscMax(maxa,diff / tola); 5947 } 5948 if (tolr>0.){ 5949 maxr = PetscMax(maxr,diff / tolr); 5950 } 5951 if (tol>0.){ 5952 max = PetscMax(max,diff / tol); 5953 } 5954 } 5955 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5956 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5957 const PetscScalar *rtol; 5958 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5959 5960 for (i=0; i<n; i++) { 5961 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5962 diff = PetscAbsScalar(y[i] - u[i]); 5963 tola = ts->atol; 5964 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5965 tol = tola+tolr; 5966 if (tola>0.){ 5967 maxa = PetscMax(maxa,diff / tola); 5968 } 5969 if (tolr>0.){ 5970 maxr = PetscMax(maxr,diff / tolr); 5971 } 5972 if (tol>0.){ 5973 max = PetscMax(max,diff / tol); 5974 } 5975 } 5976 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5977 } else { /* scalar atol, scalar rtol */ 5978 5979 for (i=0; i<n; i++) { 5980 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5981 diff = PetscAbsScalar(y[i] - u[i]); 5982 tola = ts->atol; 5983 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5984 tol = tola+tolr; 5985 if (tola>0.){ 5986 maxa = PetscMax(maxa,diff / tola); 5987 } 5988 if (tolr>0.){ 5989 maxr = PetscMax(maxr,diff / tolr); 5990 } 5991 if (tol>0.){ 5992 max = PetscMax(max,diff / tol); 5993 } 5994 } 5995 } 5996 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5997 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5998 err_loc[0] = max; 5999 err_loc[1] = maxa; 6000 err_loc[2] = maxr; 6001 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6002 gmax = err_glb[0]; 6003 gmaxa = err_glb[1]; 6004 gmaxr = err_glb[2]; 6005 6006 *norm = gmax; 6007 *norma = gmaxa; 6008 *normr = gmaxr; 6009 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6010 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6011 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6012 PetscFunctionReturn(0); 6013 } 6014 6015 /*@ 6016 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 6017 6018 Collective on TS 6019 6020 Input Arguments: 6021 + ts - time stepping context 6022 . U - state vector, usually ts->vec_sol 6023 . Y - state vector to be compared to U 6024 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6025 6026 Output Arguments: 6027 + norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6028 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6029 - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6030 6031 Options Database Keys: 6032 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6033 6034 Level: developer 6035 6036 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 6037 @*/ 6038 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6039 { 6040 PetscErrorCode ierr; 6041 6042 PetscFunctionBegin; 6043 if (wnormtype == NORM_2) { 6044 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6045 } else if (wnormtype == NORM_INFINITY) { 6046 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6047 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6048 PetscFunctionReturn(0); 6049 } 6050 6051 6052 /*@ 6053 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 6054 6055 Collective on TS 6056 6057 Input Arguments: 6058 + ts - time stepping context 6059 . E - error vector 6060 . U - state vector, usually ts->vec_sol 6061 - Y - state vector, previous time step 6062 6063 Output Arguments: 6064 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6065 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6066 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6067 6068 Level: developer 6069 6070 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 6071 @*/ 6072 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6073 { 6074 PetscErrorCode ierr; 6075 PetscInt i,n,N,rstart; 6076 PetscInt n_loc,na_loc,nr_loc; 6077 PetscReal n_glb,na_glb,nr_glb; 6078 const PetscScalar *e,*u,*y; 6079 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 6080 PetscReal tol,tola,tolr; 6081 PetscReal err_loc[6],err_glb[6]; 6082 6083 PetscFunctionBegin; 6084 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6085 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6086 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6087 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6088 PetscValidType(E,2); 6089 PetscValidType(U,3); 6090 PetscValidType(Y,4); 6091 PetscCheckSameComm(E,2,U,3); 6092 PetscCheckSameComm(U,2,Y,3); 6093 PetscValidPointer(norm,5); 6094 PetscValidPointer(norma,6); 6095 PetscValidPointer(normr,7); 6096 6097 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6098 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6099 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6100 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6101 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6102 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6103 sum = 0.; n_loc = 0; 6104 suma = 0.; na_loc = 0; 6105 sumr = 0.; nr_loc = 0; 6106 if (ts->vatol && ts->vrtol) { 6107 const PetscScalar *atol,*rtol; 6108 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6109 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6110 for (i=0; i<n; i++) { 6111 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6112 err = PetscAbsScalar(e[i]); 6113 tola = PetscRealPart(atol[i]); 6114 if (tola>0.){ 6115 suma += PetscSqr(err/tola); 6116 na_loc++; 6117 } 6118 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6119 if (tolr>0.){ 6120 sumr += PetscSqr(err/tolr); 6121 nr_loc++; 6122 } 6123 tol=tola+tolr; 6124 if (tol>0.){ 6125 sum += PetscSqr(err/tol); 6126 n_loc++; 6127 } 6128 } 6129 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6130 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6131 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6132 const PetscScalar *atol; 6133 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6134 for (i=0; i<n; i++) { 6135 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6136 err = PetscAbsScalar(e[i]); 6137 tola = PetscRealPart(atol[i]); 6138 if (tola>0.){ 6139 suma += PetscSqr(err/tola); 6140 na_loc++; 6141 } 6142 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6143 if (tolr>0.){ 6144 sumr += PetscSqr(err/tolr); 6145 nr_loc++; 6146 } 6147 tol=tola+tolr; 6148 if (tol>0.){ 6149 sum += PetscSqr(err/tol); 6150 n_loc++; 6151 } 6152 } 6153 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6154 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6155 const PetscScalar *rtol; 6156 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6157 for (i=0; i<n; i++) { 6158 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6159 err = PetscAbsScalar(e[i]); 6160 tola = ts->atol; 6161 if (tola>0.){ 6162 suma += PetscSqr(err/tola); 6163 na_loc++; 6164 } 6165 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6166 if (tolr>0.){ 6167 sumr += PetscSqr(err/tolr); 6168 nr_loc++; 6169 } 6170 tol=tola+tolr; 6171 if (tol>0.){ 6172 sum += PetscSqr(err/tol); 6173 n_loc++; 6174 } 6175 } 6176 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6177 } else { /* scalar atol, scalar rtol */ 6178 for (i=0; i<n; i++) { 6179 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6180 err = PetscAbsScalar(e[i]); 6181 tola = ts->atol; 6182 if (tola>0.){ 6183 suma += PetscSqr(err/tola); 6184 na_loc++; 6185 } 6186 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6187 if (tolr>0.){ 6188 sumr += PetscSqr(err/tolr); 6189 nr_loc++; 6190 } 6191 tol=tola+tolr; 6192 if (tol>0.){ 6193 sum += PetscSqr(err/tol); 6194 n_loc++; 6195 } 6196 } 6197 } 6198 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6199 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6200 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6201 6202 err_loc[0] = sum; 6203 err_loc[1] = suma; 6204 err_loc[2] = sumr; 6205 err_loc[3] = (PetscReal)n_loc; 6206 err_loc[4] = (PetscReal)na_loc; 6207 err_loc[5] = (PetscReal)nr_loc; 6208 6209 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6210 6211 gsum = err_glb[0]; 6212 gsuma = err_glb[1]; 6213 gsumr = err_glb[2]; 6214 n_glb = err_glb[3]; 6215 na_glb = err_glb[4]; 6216 nr_glb = err_glb[5]; 6217 6218 *norm = 0.; 6219 if (n_glb>0.){*norm = PetscSqrtReal(gsum / n_glb);} 6220 *norma = 0.; 6221 if (na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 6222 *normr = 0.; 6223 if (nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 6224 6225 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6226 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6227 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6228 PetscFunctionReturn(0); 6229 } 6230 6231 /*@ 6232 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 6233 Collective on TS 6234 6235 Input Arguments: 6236 + ts - time stepping context 6237 . E - error vector 6238 . U - state vector, usually ts->vec_sol 6239 - Y - state vector, previous time step 6240 6241 Output Arguments: 6242 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6243 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6244 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6245 6246 Level: developer 6247 6248 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 6249 @*/ 6250 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6251 { 6252 PetscErrorCode ierr; 6253 PetscInt i,n,N,rstart; 6254 const PetscScalar *e,*u,*y; 6255 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 6256 PetscReal tol,tola,tolr; 6257 PetscReal err_loc[3],err_glb[3]; 6258 6259 PetscFunctionBegin; 6260 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6261 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6262 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6263 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6264 PetscValidType(E,2); 6265 PetscValidType(U,3); 6266 PetscValidType(Y,4); 6267 PetscCheckSameComm(E,2,U,3); 6268 PetscCheckSameComm(U,2,Y,3); 6269 PetscValidPointer(norm,5); 6270 PetscValidPointer(norma,6); 6271 PetscValidPointer(normr,7); 6272 6273 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6274 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6275 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6276 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6277 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6278 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6279 6280 max=0.; 6281 maxa=0.; 6282 maxr=0.; 6283 6284 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6285 const PetscScalar *atol,*rtol; 6286 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6287 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6288 6289 for (i=0; i<n; i++) { 6290 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6291 err = PetscAbsScalar(e[i]); 6292 tola = PetscRealPart(atol[i]); 6293 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6294 tol = tola+tolr; 6295 if (tola>0.){ 6296 maxa = PetscMax(maxa,err / tola); 6297 } 6298 if (tolr>0.){ 6299 maxr = PetscMax(maxr,err / tolr); 6300 } 6301 if (tol>0.){ 6302 max = PetscMax(max,err / tol); 6303 } 6304 } 6305 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6306 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6307 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6308 const PetscScalar *atol; 6309 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6310 for (i=0; i<n; i++) { 6311 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6312 err = PetscAbsScalar(e[i]); 6313 tola = PetscRealPart(atol[i]); 6314 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6315 tol = tola+tolr; 6316 if (tola>0.){ 6317 maxa = PetscMax(maxa,err / tola); 6318 } 6319 if (tolr>0.){ 6320 maxr = PetscMax(maxr,err / tolr); 6321 } 6322 if (tol>0.){ 6323 max = PetscMax(max,err / tol); 6324 } 6325 } 6326 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6327 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6328 const PetscScalar *rtol; 6329 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6330 6331 for (i=0; i<n; i++) { 6332 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6333 err = PetscAbsScalar(e[i]); 6334 tola = ts->atol; 6335 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6336 tol = tola+tolr; 6337 if (tola>0.){ 6338 maxa = PetscMax(maxa,err / tola); 6339 } 6340 if (tolr>0.){ 6341 maxr = PetscMax(maxr,err / tolr); 6342 } 6343 if (tol>0.){ 6344 max = PetscMax(max,err / tol); 6345 } 6346 } 6347 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6348 } else { /* scalar atol, scalar rtol */ 6349 6350 for (i=0; i<n; i++) { 6351 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6352 err = PetscAbsScalar(e[i]); 6353 tola = ts->atol; 6354 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6355 tol = tola+tolr; 6356 if (tola>0.){ 6357 maxa = PetscMax(maxa,err / tola); 6358 } 6359 if (tolr>0.){ 6360 maxr = PetscMax(maxr,err / tolr); 6361 } 6362 if (tol>0.){ 6363 max = PetscMax(max,err / tol); 6364 } 6365 } 6366 } 6367 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6368 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6369 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6370 err_loc[0] = max; 6371 err_loc[1] = maxa; 6372 err_loc[2] = maxr; 6373 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6374 gmax = err_glb[0]; 6375 gmaxa = err_glb[1]; 6376 gmaxr = err_glb[2]; 6377 6378 *norm = gmax; 6379 *norma = gmaxa; 6380 *normr = gmaxr; 6381 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6382 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6383 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6384 PetscFunctionReturn(0); 6385 } 6386 6387 /*@ 6388 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 6389 6390 Collective on TS 6391 6392 Input Arguments: 6393 + ts - time stepping context 6394 . E - error vector 6395 . U - state vector, usually ts->vec_sol 6396 . Y - state vector, previous time step 6397 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6398 6399 Output Arguments: 6400 + norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6401 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6402 - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6403 6404 Options Database Keys: 6405 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6406 6407 Level: developer 6408 6409 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6410 @*/ 6411 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6412 { 6413 PetscErrorCode ierr; 6414 6415 PetscFunctionBegin; 6416 if (wnormtype == NORM_2) { 6417 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6418 } else if (wnormtype == NORM_INFINITY) { 6419 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6420 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6421 PetscFunctionReturn(0); 6422 } 6423 6424 6425 /*@ 6426 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6427 6428 Logically Collective on TS 6429 6430 Input Arguments: 6431 + ts - time stepping context 6432 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6433 6434 Note: 6435 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6436 6437 Level: intermediate 6438 6439 .seealso: TSGetCFLTime(), TSADAPTCFL 6440 @*/ 6441 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6442 { 6443 PetscFunctionBegin; 6444 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6445 ts->cfltime_local = cfltime; 6446 ts->cfltime = -1.; 6447 PetscFunctionReturn(0); 6448 } 6449 6450 /*@ 6451 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6452 6453 Collective on TS 6454 6455 Input Arguments: 6456 . ts - time stepping context 6457 6458 Output Arguments: 6459 . cfltime - maximum stable time step for forward Euler 6460 6461 Level: advanced 6462 6463 .seealso: TSSetCFLTimeLocal() 6464 @*/ 6465 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6466 { 6467 PetscErrorCode ierr; 6468 6469 PetscFunctionBegin; 6470 if (ts->cfltime < 0) { 6471 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6472 } 6473 *cfltime = ts->cfltime; 6474 PetscFunctionReturn(0); 6475 } 6476 6477 /*@ 6478 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6479 6480 Input Parameters: 6481 + ts - the TS context. 6482 . xl - lower bound. 6483 - xu - upper bound. 6484 6485 Notes: 6486 If this routine is not called then the lower and upper bounds are set to 6487 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6488 6489 Level: advanced 6490 6491 @*/ 6492 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6493 { 6494 PetscErrorCode ierr; 6495 SNES snes; 6496 6497 PetscFunctionBegin; 6498 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6499 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6500 PetscFunctionReturn(0); 6501 } 6502 6503 /*@C 6504 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 6505 in a time based line graph 6506 6507 Collective on TS 6508 6509 Input Parameters: 6510 + ts - the TS context 6511 . step - current time-step 6512 . ptime - current time 6513 . u - current solution 6514 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 6515 6516 Options Database: 6517 . -ts_monitor_lg_solution_variables 6518 6519 Level: intermediate 6520 6521 Notes: 6522 Each process in a parallel run displays its component solutions in a separate window 6523 6524 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 6525 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 6526 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 6527 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 6528 @*/ 6529 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6530 { 6531 PetscErrorCode ierr; 6532 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 6533 const PetscScalar *yy; 6534 Vec v; 6535 6536 PetscFunctionBegin; 6537 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6538 if (!step) { 6539 PetscDrawAxis axis; 6540 PetscInt dim; 6541 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6542 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 6543 if (!ctx->names) { 6544 PetscBool flg; 6545 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 6546 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 6547 if (flg) { 6548 PetscInt i,n; 6549 char **names; 6550 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 6551 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 6552 for (i=0; i<n; i++) { 6553 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 6554 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 6555 } 6556 names[n] = NULL; 6557 ctx->names = names; 6558 } 6559 } 6560 if (ctx->names && !ctx->displaynames) { 6561 char **displaynames; 6562 PetscBool flg; 6563 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6564 ierr = PetscCalloc1(dim+1,&displaynames);CHKERRQ(ierr); 6565 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 6566 if (flg) { 6567 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 6568 } 6569 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 6570 } 6571 if (ctx->displaynames) { 6572 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 6573 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 6574 } else if (ctx->names) { 6575 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6576 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6577 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 6578 } else { 6579 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6580 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6581 } 6582 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6583 } 6584 6585 if (!ctx->transform) v = u; 6586 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 6587 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 6588 if (ctx->displaynames) { 6589 PetscInt i; 6590 for (i=0; i<ctx->ndisplayvariables; i++) 6591 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 6592 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 6593 } else { 6594 #if defined(PETSC_USE_COMPLEX) 6595 PetscInt i,n; 6596 PetscReal *yreal; 6597 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 6598 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6599 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6600 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6601 ierr = PetscFree(yreal);CHKERRQ(ierr); 6602 #else 6603 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6604 #endif 6605 } 6606 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 6607 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 6608 6609 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6610 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6611 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6612 } 6613 PetscFunctionReturn(0); 6614 } 6615 6616 /*@C 6617 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6618 6619 Collective on TS 6620 6621 Input Parameters: 6622 + ts - the TS context 6623 - names - the names of the components, final string must be NULL 6624 6625 Level: intermediate 6626 6627 Notes: 6628 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6629 6630 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 6631 @*/ 6632 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 6633 { 6634 PetscErrorCode ierr; 6635 PetscInt i; 6636 6637 PetscFunctionBegin; 6638 for (i=0; i<ts->numbermonitors; i++) { 6639 if (ts->monitor[i] == TSMonitorLGSolution) { 6640 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 6641 break; 6642 } 6643 } 6644 PetscFunctionReturn(0); 6645 } 6646 6647 /*@C 6648 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6649 6650 Collective on TS 6651 6652 Input Parameters: 6653 + ts - the TS context 6654 - names - the names of the components, final string must be NULL 6655 6656 Level: intermediate 6657 6658 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 6659 @*/ 6660 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 6661 { 6662 PetscErrorCode ierr; 6663 6664 PetscFunctionBegin; 6665 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 6666 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 6667 PetscFunctionReturn(0); 6668 } 6669 6670 /*@C 6671 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 6672 6673 Collective on TS 6674 6675 Input Parameter: 6676 . ts - the TS context 6677 6678 Output Parameter: 6679 . names - the names of the components, final string must be NULL 6680 6681 Level: intermediate 6682 6683 Notes: 6684 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6685 6686 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 6687 @*/ 6688 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 6689 { 6690 PetscInt i; 6691 6692 PetscFunctionBegin; 6693 *names = NULL; 6694 for (i=0; i<ts->numbermonitors; i++) { 6695 if (ts->monitor[i] == TSMonitorLGSolution) { 6696 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 6697 *names = (const char *const *)ctx->names; 6698 break; 6699 } 6700 } 6701 PetscFunctionReturn(0); 6702 } 6703 6704 /*@C 6705 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 6706 6707 Collective on TS 6708 6709 Input Parameters: 6710 + ctx - the TSMonitorLG context 6711 - displaynames - the names of the components, final string must be NULL 6712 6713 Level: intermediate 6714 6715 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6716 @*/ 6717 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 6718 { 6719 PetscInt j = 0,k; 6720 PetscErrorCode ierr; 6721 6722 PetscFunctionBegin; 6723 if (!ctx->names) PetscFunctionReturn(0); 6724 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 6725 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 6726 while (displaynames[j]) j++; 6727 ctx->ndisplayvariables = j; 6728 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 6729 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 6730 j = 0; 6731 while (displaynames[j]) { 6732 k = 0; 6733 while (ctx->names[k]) { 6734 PetscBool flg; 6735 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 6736 if (flg) { 6737 ctx->displayvariables[j] = k; 6738 break; 6739 } 6740 k++; 6741 } 6742 j++; 6743 } 6744 PetscFunctionReturn(0); 6745 } 6746 6747 /*@C 6748 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 6749 6750 Collective on TS 6751 6752 Input Parameters: 6753 + ts - the TS context 6754 - displaynames - the names of the components, final string must be NULL 6755 6756 Notes: 6757 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6758 6759 Level: intermediate 6760 6761 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6762 @*/ 6763 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 6764 { 6765 PetscInt i; 6766 PetscErrorCode ierr; 6767 6768 PetscFunctionBegin; 6769 for (i=0; i<ts->numbermonitors; i++) { 6770 if (ts->monitor[i] == TSMonitorLGSolution) { 6771 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 6772 break; 6773 } 6774 } 6775 PetscFunctionReturn(0); 6776 } 6777 6778 /*@C 6779 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 6780 6781 Collective on TS 6782 6783 Input Parameters: 6784 + ts - the TS context 6785 . transform - the transform function 6786 . destroy - function to destroy the optional context 6787 - ctx - optional context used by transform function 6788 6789 Notes: 6790 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6791 6792 Level: intermediate 6793 6794 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 6795 @*/ 6796 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6797 { 6798 PetscInt i; 6799 PetscErrorCode ierr; 6800 6801 PetscFunctionBegin; 6802 for (i=0; i<ts->numbermonitors; i++) { 6803 if (ts->monitor[i] == TSMonitorLGSolution) { 6804 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 6805 } 6806 } 6807 PetscFunctionReturn(0); 6808 } 6809 6810 /*@C 6811 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 6812 6813 Collective on TSLGCtx 6814 6815 Input Parameters: 6816 + ts - the TS context 6817 . transform - the transform function 6818 . destroy - function to destroy the optional context 6819 - ctx - optional context used by transform function 6820 6821 Level: intermediate 6822 6823 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 6824 @*/ 6825 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6826 { 6827 PetscFunctionBegin; 6828 ctx->transform = transform; 6829 ctx->transformdestroy = destroy; 6830 ctx->transformctx = tctx; 6831 PetscFunctionReturn(0); 6832 } 6833 6834 /*@C 6835 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error 6836 in a time based line graph 6837 6838 Collective on TS 6839 6840 Input Parameters: 6841 + ts - the TS context 6842 . step - current time-step 6843 . ptime - current time 6844 . u - current solution 6845 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 6846 6847 Level: intermediate 6848 6849 Notes: 6850 Each process in a parallel run displays its component errors in a separate window 6851 6852 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6853 6854 Options Database Keys: 6855 . -ts_monitor_lg_error - create a graphical monitor of error history 6856 6857 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6858 @*/ 6859 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 6860 { 6861 PetscErrorCode ierr; 6862 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 6863 const PetscScalar *yy; 6864 Vec y; 6865 6866 PetscFunctionBegin; 6867 if (!step) { 6868 PetscDrawAxis axis; 6869 PetscInt dim; 6870 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6871 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr); 6872 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6873 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6874 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6875 } 6876 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6877 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6878 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6879 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 6880 #if defined(PETSC_USE_COMPLEX) 6881 { 6882 PetscReal *yreal; 6883 PetscInt i,n; 6884 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 6885 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6886 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6887 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6888 ierr = PetscFree(yreal);CHKERRQ(ierr); 6889 } 6890 #else 6891 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6892 #endif 6893 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 6894 ierr = VecDestroy(&y);CHKERRQ(ierr); 6895 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6896 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6897 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6898 } 6899 PetscFunctionReturn(0); 6900 } 6901 6902 /*@C 6903 TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot 6904 6905 Input Parameters: 6906 + ts - the TS context 6907 . step - current time-step 6908 . ptime - current time 6909 . u - current solution 6910 - dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate() 6911 6912 Options Database: 6913 . -ts_monitor_sp_swarm 6914 6915 Level: intermediate 6916 6917 @*/ 6918 PetscErrorCode TSMonitorSPSwarmSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6919 { 6920 PetscErrorCode ierr; 6921 TSMonitorSPCtx ctx = (TSMonitorSPCtx)dctx; 6922 const PetscScalar *yy; 6923 PetscReal *y,*x; 6924 PetscInt Np, p, dim=2; 6925 DM dm; 6926 6927 PetscFunctionBegin; 6928 6929 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6930 if (!step) { 6931 PetscDrawAxis axis; 6932 ierr = PetscDrawSPGetAxis(ctx->sp,&axis);CHKERRQ(ierr); 6933 ierr = PetscDrawAxisSetLabels(axis,"Particles","X","Y");CHKERRQ(ierr); 6934 ierr = PetscDrawAxisSetLimits(axis, -5, 5, -5, 5);CHKERRQ(ierr); 6935 ierr = PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE);CHKERRQ(ierr); 6936 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 6937 ierr = DMGetDimension(dm, &dim); 6938 if (dim!=2) SETERRQ(PETSC_COMM_SELF, ierr, "Dimensions improper for monitor arguments! Current support: two dimensions.");CHKERRQ(ierr); 6939 ierr = VecGetLocalSize(u, &Np);CHKERRQ(ierr); 6940 Np /= 2*dim; 6941 ierr = PetscDrawSPSetDimension(ctx->sp, Np);CHKERRQ(ierr); 6942 ierr = PetscDrawSPReset(ctx->sp);CHKERRQ(ierr); 6943 } 6944 6945 ierr = VecGetLocalSize(u, &Np);CHKERRQ(ierr); 6946 Np /= 2*dim; 6947 ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr); 6948 ierr = PetscMalloc2(Np, &x, Np, &y);CHKERRQ(ierr); 6949 /* get points from solution vector */ 6950 for (p=0; p<Np; ++p){ 6951 x[p] = PetscRealPart(yy[2*dim*p]); 6952 y[p] = PetscRealPart(yy[2*dim*p+1]); 6953 } 6954 ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr); 6955 6956 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6957 ierr = PetscDrawSPAddPoint(ctx->sp,x,y);CHKERRQ(ierr); 6958 ierr = PetscDrawSPDraw(ctx->sp,PETSC_FALSE);CHKERRQ(ierr); 6959 ierr = PetscDrawSPSave(ctx->sp);CHKERRQ(ierr); 6960 } 6961 6962 ierr = PetscFree2(x, y);CHKERRQ(ierr); 6963 6964 PetscFunctionReturn(0); 6965 } 6966 6967 6968 6969 /*@C 6970 TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep 6971 6972 Collective on TS 6973 6974 Input Parameters: 6975 + ts - the TS context 6976 . step - current time-step 6977 . ptime - current time 6978 . u - current solution 6979 - dctx - unused context 6980 6981 Level: intermediate 6982 6983 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6984 6985 Options Database Keys: 6986 . -ts_monitor_error - create a graphical monitor of error history 6987 6988 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6989 @*/ 6990 PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 6991 { 6992 PetscErrorCode ierr; 6993 Vec y; 6994 PetscReal nrm; 6995 PetscBool flg; 6996 6997 PetscFunctionBegin; 6998 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6999 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 7000 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 7001 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg);CHKERRQ(ierr); 7002 if (flg) { 7003 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 7004 ierr = PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm);CHKERRQ(ierr); 7005 } 7006 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg);CHKERRQ(ierr); 7007 if (flg) { 7008 ierr = VecView(y,vf->viewer);CHKERRQ(ierr); 7009 } 7010 ierr = VecDestroy(&y);CHKERRQ(ierr); 7011 PetscFunctionReturn(0); 7012 } 7013 7014 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7015 { 7016 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7017 PetscReal x = ptime,y; 7018 PetscErrorCode ierr; 7019 PetscInt its; 7020 7021 PetscFunctionBegin; 7022 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7023 if (!n) { 7024 PetscDrawAxis axis; 7025 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7026 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 7027 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7028 ctx->snes_its = 0; 7029 } 7030 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 7031 y = its - ctx->snes_its; 7032 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7033 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7034 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7035 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7036 } 7037 ctx->snes_its = its; 7038 PetscFunctionReturn(0); 7039 } 7040 7041 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7042 { 7043 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7044 PetscReal x = ptime,y; 7045 PetscErrorCode ierr; 7046 PetscInt its; 7047 7048 PetscFunctionBegin; 7049 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7050 if (!n) { 7051 PetscDrawAxis axis; 7052 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7053 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 7054 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7055 ctx->ksp_its = 0; 7056 } 7057 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 7058 y = its - ctx->ksp_its; 7059 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7060 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7061 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7062 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7063 } 7064 ctx->ksp_its = its; 7065 PetscFunctionReturn(0); 7066 } 7067 7068 /*@ 7069 TSComputeLinearStability - computes the linear stability function at a point 7070 7071 Collective on TS 7072 7073 Input Parameters: 7074 + ts - the TS context 7075 - xr,xi - real and imaginary part of input arguments 7076 7077 Output Parameters: 7078 . yr,yi - real and imaginary part of function value 7079 7080 Level: developer 7081 7082 .seealso: TSSetRHSFunction(), TSComputeIFunction() 7083 @*/ 7084 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 7085 { 7086 PetscErrorCode ierr; 7087 7088 PetscFunctionBegin; 7089 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7090 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 7091 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 7092 PetscFunctionReturn(0); 7093 } 7094 7095 /* ------------------------------------------------------------------------*/ 7096 /*@C 7097 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 7098 7099 Collective on TS 7100 7101 Input Parameters: 7102 . ts - the ODE solver object 7103 7104 Output Parameter: 7105 . ctx - the context 7106 7107 Level: intermediate 7108 7109 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 7110 7111 @*/ 7112 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 7113 { 7114 PetscErrorCode ierr; 7115 7116 PetscFunctionBegin; 7117 ierr = PetscNew(ctx);CHKERRQ(ierr); 7118 PetscFunctionReturn(0); 7119 } 7120 7121 /*@C 7122 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 7123 7124 Collective on TS 7125 7126 Input Parameters: 7127 + ts - the TS context 7128 . step - current time-step 7129 . ptime - current time 7130 . u - current solution 7131 - dctx - the envelope context 7132 7133 Options Database: 7134 . -ts_monitor_envelope 7135 7136 Level: intermediate 7137 7138 Notes: 7139 after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 7140 7141 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 7142 @*/ 7143 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 7144 { 7145 PetscErrorCode ierr; 7146 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 7147 7148 PetscFunctionBegin; 7149 if (!ctx->max) { 7150 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 7151 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 7152 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 7153 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 7154 } else { 7155 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 7156 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 7157 } 7158 PetscFunctionReturn(0); 7159 } 7160 7161 /*@C 7162 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 7163 7164 Collective on TS 7165 7166 Input Parameter: 7167 . ts - the TS context 7168 7169 Output Parameter: 7170 + max - the maximum values 7171 - min - the minimum values 7172 7173 Notes: 7174 If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7175 7176 Level: intermediate 7177 7178 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7179 @*/ 7180 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7181 { 7182 PetscInt i; 7183 7184 PetscFunctionBegin; 7185 if (max) *max = NULL; 7186 if (min) *min = NULL; 7187 for (i=0; i<ts->numbermonitors; i++) { 7188 if (ts->monitor[i] == TSMonitorEnvelope) { 7189 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7190 if (max) *max = ctx->max; 7191 if (min) *min = ctx->min; 7192 break; 7193 } 7194 } 7195 PetscFunctionReturn(0); 7196 } 7197 7198 /*@C 7199 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7200 7201 Collective on TSMonitorEnvelopeCtx 7202 7203 Input Parameter: 7204 . ctx - the monitor context 7205 7206 Level: intermediate 7207 7208 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7209 @*/ 7210 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7211 { 7212 PetscErrorCode ierr; 7213 7214 PetscFunctionBegin; 7215 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7216 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7217 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7218 PetscFunctionReturn(0); 7219 } 7220 7221 /*@ 7222 TSRestartStep - Flags the solver to restart the next step 7223 7224 Collective on TS 7225 7226 Input Parameter: 7227 . ts - the TS context obtained from TSCreate() 7228 7229 Level: advanced 7230 7231 Notes: 7232 Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of 7233 discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution 7234 vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For 7235 the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce 7236 discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with 7237 discontinuous source terms). 7238 7239 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep() 7240 @*/ 7241 PetscErrorCode TSRestartStep(TS ts) 7242 { 7243 PetscFunctionBegin; 7244 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7245 ts->steprestart = PETSC_TRUE; 7246 PetscFunctionReturn(0); 7247 } 7248 7249 /*@ 7250 TSRollBack - Rolls back one time step 7251 7252 Collective on TS 7253 7254 Input Parameter: 7255 . ts - the TS context obtained from TSCreate() 7256 7257 Level: advanced 7258 7259 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7260 @*/ 7261 PetscErrorCode TSRollBack(TS ts) 7262 { 7263 PetscErrorCode ierr; 7264 7265 PetscFunctionBegin; 7266 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7267 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7268 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7269 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7270 ts->time_step = ts->ptime - ts->ptime_prev; 7271 ts->ptime = ts->ptime_prev; 7272 ts->ptime_prev = ts->ptime_prev_rollback; 7273 ts->steps--; 7274 ts->steprollback = PETSC_TRUE; 7275 PetscFunctionReturn(0); 7276 } 7277 7278 /*@ 7279 TSGetStages - Get the number of stages and stage values 7280 7281 Input Parameter: 7282 . ts - the TS context obtained from TSCreate() 7283 7284 Output Parameters: 7285 + ns - the number of stages 7286 - Y - the current stage vectors 7287 7288 Level: advanced 7289 7290 Notes: Both ns and Y can be NULL. 7291 7292 .seealso: TSCreate() 7293 @*/ 7294 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7295 { 7296 PetscErrorCode ierr; 7297 7298 PetscFunctionBegin; 7299 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7300 if (ns) PetscValidPointer(ns,2); 7301 if (Y) PetscValidPointer(Y,3); 7302 if (!ts->ops->getstages) { 7303 if (ns) *ns = 0; 7304 if (Y) *Y = NULL; 7305 } else { 7306 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7307 } 7308 PetscFunctionReturn(0); 7309 } 7310 7311 /*@C 7312 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7313 7314 Collective on SNES 7315 7316 Input Parameters: 7317 + ts - the TS context 7318 . t - current timestep 7319 . U - state vector 7320 . Udot - time derivative of state vector 7321 . shift - shift to apply, see note below 7322 - ctx - an optional user context 7323 7324 Output Parameters: 7325 + J - Jacobian matrix (not altered in this routine) 7326 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7327 7328 Level: intermediate 7329 7330 Notes: 7331 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7332 7333 dF/dU + shift*dF/dUdot 7334 7335 Most users should not need to explicitly call this routine, as it 7336 is used internally within the nonlinear solvers. 7337 7338 This will first try to get the coloring from the DM. If the DM type has no coloring 7339 routine, then it will try to get the coloring from the matrix. This requires that the 7340 matrix have nonzero entries precomputed. 7341 7342 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7343 @*/ 7344 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7345 { 7346 SNES snes; 7347 MatFDColoring color; 7348 PetscBool hascolor, matcolor = PETSC_FALSE; 7349 PetscErrorCode ierr; 7350 7351 PetscFunctionBegin; 7352 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7353 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7354 if (!color) { 7355 DM dm; 7356 ISColoring iscoloring; 7357 7358 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 7359 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 7360 if (hascolor && !matcolor) { 7361 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 7362 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7363 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7364 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7365 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7366 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7367 } else { 7368 MatColoring mc; 7369 7370 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 7371 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 7372 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 7373 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 7374 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 7375 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 7376 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7377 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7378 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7379 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7380 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7381 } 7382 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 7383 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 7384 } 7385 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 7386 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 7387 if (J != B) { 7388 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7389 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7390 } 7391 PetscFunctionReturn(0); 7392 } 7393 7394 /*@ 7395 TSSetFunctionDomainError - Set a function that tests if the current state vector is valid 7396 7397 Input Parameters: 7398 + ts - the TS context 7399 - func - function called within TSFunctionDomainError 7400 7401 Calling sequence of func: 7402 $ PetscErrorCode func(TS ts,PetscReal time,Vec state,PetscBool reject) 7403 7404 + ts - the TS context 7405 . time - the current time (of the stage) 7406 . state - the state to check if it is valid 7407 - reject - (output parameter) PETSC_FALSE if the state is acceptable, PETSC_TRUE if not acceptable 7408 7409 Level: intermediate 7410 7411 Notes: 7412 If an implicit ODE solver is being used then, in addition to providing this routine, the 7413 user's code should call SNESSetFunctionDomainError() when domain errors occur during 7414 function evaluations where the functions are provided by TSSetIFunction() or TSSetRHSFunction(). 7415 Use TSGetSNES() to obtain the SNES object 7416 7417 Developer Notes: 7418 The naming of this function is inconsistent with the SNESSetFunctionDomainError() 7419 since one takes a function pointer and the other does not. 7420 7421 .seealso: TSAdaptCheckStage(), TSFunctionDomainError(), SNESSetFunctionDomainError(), TSGetSNES() 7422 @*/ 7423 7424 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 7425 { 7426 PetscFunctionBegin; 7427 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7428 ts->functiondomainerror = func; 7429 PetscFunctionReturn(0); 7430 } 7431 7432 /*@ 7433 TSFunctionDomainError - Checks if the current state is valid 7434 7435 Input Parameters: 7436 + ts - the TS context 7437 . stagetime - time of the simulation 7438 - Y - state vector to check. 7439 7440 Output Parameter: 7441 . accept - Set to PETSC_FALSE if the current state vector is valid. 7442 7443 Note: 7444 This function is called by the TS integration routines and calls the user provided function (set with TSSetFunctionDomainError()) 7445 to check if the current state is valid. 7446 7447 Level: developer 7448 7449 .seealso: TSSetFunctionDomainError() 7450 @*/ 7451 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 7452 { 7453 PetscFunctionBegin; 7454 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7455 *accept = PETSC_TRUE; 7456 if (ts->functiondomainerror) { 7457 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 7458 } 7459 PetscFunctionReturn(0); 7460 } 7461 7462 /*@C 7463 TSClone - This function clones a time step object. 7464 7465 Collective 7466 7467 Input Parameter: 7468 . tsin - The input TS 7469 7470 Output Parameter: 7471 . tsout - The output TS (cloned) 7472 7473 Notes: 7474 This function is used to create a clone of a TS object. It is used in ARKIMEX for initializing the slope for first stage explicit methods. It will likely be replaced in the future with a mechanism of switching methods on the fly. 7475 7476 When using TSDestroy() on a clone the user has to first reset the correct TS reference in the embedded SNES object: e.g.: by running SNES snes_dup=NULL; TSGetSNES(ts,&snes_dup); TSSetSNES(ts,snes_dup); 7477 7478 Level: developer 7479 7480 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 7481 @*/ 7482 PetscErrorCode TSClone(TS tsin, TS *tsout) 7483 { 7484 TS t; 7485 PetscErrorCode ierr; 7486 SNES snes_start; 7487 DM dm; 7488 TSType type; 7489 7490 PetscFunctionBegin; 7491 PetscValidPointer(tsin,1); 7492 *tsout = NULL; 7493 7494 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 7495 7496 /* General TS description */ 7497 t->numbermonitors = 0; 7498 t->setupcalled = 0; 7499 t->ksp_its = 0; 7500 t->snes_its = 0; 7501 t->nwork = 0; 7502 t->rhsjacobian.time = PETSC_MIN_REAL; 7503 t->rhsjacobian.scale = 1.; 7504 t->ijacobian.shift = 1.; 7505 7506 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 7507 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 7508 7509 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 7510 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 7511 7512 t->adapt = tsin->adapt; 7513 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 7514 7515 t->trajectory = tsin->trajectory; 7516 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 7517 7518 t->event = tsin->event; 7519 if (t->event) t->event->refct++; 7520 7521 t->problem_type = tsin->problem_type; 7522 t->ptime = tsin->ptime; 7523 t->ptime_prev = tsin->ptime_prev; 7524 t->time_step = tsin->time_step; 7525 t->max_time = tsin->max_time; 7526 t->steps = tsin->steps; 7527 t->max_steps = tsin->max_steps; 7528 t->equation_type = tsin->equation_type; 7529 t->atol = tsin->atol; 7530 t->rtol = tsin->rtol; 7531 t->max_snes_failures = tsin->max_snes_failures; 7532 t->max_reject = tsin->max_reject; 7533 t->errorifstepfailed = tsin->errorifstepfailed; 7534 7535 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 7536 ierr = TSSetType(t,type);CHKERRQ(ierr); 7537 7538 t->vec_sol = NULL; 7539 7540 t->cfltime = tsin->cfltime; 7541 t->cfltime_local = tsin->cfltime_local; 7542 t->exact_final_time = tsin->exact_final_time; 7543 7544 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 7545 7546 if (((PetscObject)tsin)->fortran_func_pointers) { 7547 PetscInt i; 7548 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 7549 for (i=0; i<10; i++) { 7550 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 7551 } 7552 } 7553 *tsout = t; 7554 PetscFunctionReturn(0); 7555 } 7556 7557 static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void* ctx,Vec x,Vec y) 7558 { 7559 PetscErrorCode ierr; 7560 TS ts = (TS) ctx; 7561 7562 PetscFunctionBegin; 7563 ierr = TSComputeRHSFunction(ts,0,x,y);CHKERRQ(ierr); 7564 PetscFunctionReturn(0); 7565 } 7566 7567 /*@ 7568 TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function. 7569 7570 Logically Collective on TS 7571 7572 Input Parameters: 7573 TS - the time stepping routine 7574 7575 Output Parameter: 7576 . flg - PETSC_TRUE if the multiply is likely correct 7577 7578 Options Database: 7579 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator 7580 7581 Level: advanced 7582 7583 Notes: 7584 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7585 7586 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTestTranspose() 7587 @*/ 7588 PetscErrorCode TSRHSJacobianTest(TS ts,PetscBool *flg) 7589 { 7590 Mat J,B; 7591 PetscErrorCode ierr; 7592 TSRHSJacobian func; 7593 void* ctx; 7594 7595 PetscFunctionBegin; 7596 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7597 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7598 ierr = MatShellTestMult(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7599 PetscFunctionReturn(0); 7600 } 7601 7602 /*@C 7603 TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function. 7604 7605 Logically Collective on TS 7606 7607 Input Parameters: 7608 TS - the time stepping routine 7609 7610 Output Parameter: 7611 . flg - PETSC_TRUE if the multiply is likely correct 7612 7613 Options Database: 7614 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator 7615 7616 Notes: 7617 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7618 7619 Level: advanced 7620 7621 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTest() 7622 @*/ 7623 PetscErrorCode TSRHSJacobianTestTranspose(TS ts,PetscBool *flg) 7624 { 7625 Mat J,B; 7626 PetscErrorCode ierr; 7627 void *ctx; 7628 TSRHSJacobian func; 7629 7630 PetscFunctionBegin; 7631 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7632 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7633 ierr = MatShellTestMultTranspose(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7634 PetscFunctionReturn(0); 7635 } 7636 7637 /*@ 7638 TSSetUseSplitRHSFunction - Use the split RHSFunction when a multirate method is used. 7639 7640 Logically collective 7641 7642 Input Parameter: 7643 + ts - timestepping context 7644 - use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used 7645 7646 Options Database: 7647 . -ts_use_splitrhsfunction - <true,false> 7648 7649 Notes: 7650 This is only useful for multirate methods 7651 7652 Level: intermediate 7653 7654 .seealso: TSGetUseSplitRHSFunction() 7655 @*/ 7656 PetscErrorCode TSSetUseSplitRHSFunction(TS ts, PetscBool use_splitrhsfunction) 7657 { 7658 PetscFunctionBegin; 7659 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7660 ts->use_splitrhsfunction = use_splitrhsfunction; 7661 PetscFunctionReturn(0); 7662 } 7663 7664 /*@ 7665 TSGetUseSplitRHSFunction - Gets whether to use the split RHSFunction when a multirate method is used. 7666 7667 Not collective 7668 7669 Input Parameter: 7670 . ts - timestepping context 7671 7672 Output Parameter: 7673 . use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used 7674 7675 Level: intermediate 7676 7677 .seealso: TSSetUseSplitRHSFunction() 7678 @*/ 7679 PetscErrorCode TSGetUseSplitRHSFunction(TS ts, PetscBool *use_splitrhsfunction) 7680 { 7681 PetscFunctionBegin; 7682 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7683 *use_splitrhsfunction = ts->use_splitrhsfunction; 7684 PetscFunctionReturn(0); 7685 } 7686