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