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 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 4136 } 4137 if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */ 4138 ierr = TSForwardStep(ts);CHKERRQ(ierr); 4139 } 4140 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4141 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. */ 4142 if (ts->steprollback) { 4143 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4144 } 4145 if (!ts->steprollback) { 4146 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4147 ierr = TSPostStep(ts);CHKERRQ(ierr); 4148 } 4149 } 4150 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4151 4152 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 4153 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 4154 ts->solvetime = ts->max_time; 4155 solution = u; 4156 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 4157 } else { 4158 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4159 ts->solvetime = ts->ptime; 4160 solution = ts->vec_sol; 4161 } 4162 } 4163 4164 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 4165 ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr); 4166 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 4167 if (ts->adjoint_solve) { 4168 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 4169 } 4170 PetscFunctionReturn(0); 4171 } 4172 4173 /*@C 4174 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 4175 4176 Collective on TS 4177 4178 Input Parameters: 4179 + ts - time stepping context obtained from TSCreate() 4180 . step - step number that has just completed 4181 . ptime - model time of the state 4182 - u - state at the current model time 4183 4184 Notes: 4185 TSMonitor() is typically used automatically within the time stepping implementations. 4186 Users would almost never call this routine directly. 4187 4188 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 4189 4190 Level: developer 4191 4192 @*/ 4193 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 4194 { 4195 DM dm; 4196 PetscInt i,n = ts->numbermonitors; 4197 PetscErrorCode ierr; 4198 4199 PetscFunctionBegin; 4200 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4201 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4202 4203 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4204 ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr); 4205 4206 ierr = VecLockReadPush(u);CHKERRQ(ierr); 4207 for (i=0; i<n; i++) { 4208 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 4209 } 4210 ierr = VecLockReadPop(u);CHKERRQ(ierr); 4211 PetscFunctionReturn(0); 4212 } 4213 4214 /* ------------------------------------------------------------------------*/ 4215 /*@C 4216 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 4217 TS to monitor the solution process graphically in various ways 4218 4219 Collective on TS 4220 4221 Input Parameters: 4222 + host - the X display to open, or null for the local machine 4223 . label - the title to put in the title bar 4224 . x, y - the screen coordinates of the upper left coordinate of the window 4225 . m, n - the screen width and height in pixels 4226 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 4227 4228 Output Parameter: 4229 . ctx - the context 4230 4231 Options Database Key: 4232 + -ts_monitor_lg_timestep - automatically sets line graph monitor 4233 + -ts_monitor_lg_timestep_log - automatically sets line graph monitor 4234 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 4235 . -ts_monitor_lg_error - monitor the error 4236 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 4237 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 4238 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 4239 4240 Notes: 4241 Use TSMonitorLGCtxDestroy() to destroy. 4242 4243 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 4244 4245 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 4246 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 4247 as the first argument. 4248 4249 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 4250 4251 Level: intermediate 4252 4253 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 4254 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 4255 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 4256 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 4257 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 4258 4259 @*/ 4260 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 4261 { 4262 PetscDraw draw; 4263 PetscErrorCode ierr; 4264 4265 PetscFunctionBegin; 4266 ierr = PetscNew(ctx);CHKERRQ(ierr); 4267 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 4268 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 4269 ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr); 4270 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 4271 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4272 (*ctx)->howoften = howoften; 4273 PetscFunctionReturn(0); 4274 } 4275 4276 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 4277 { 4278 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4279 PetscReal x = ptime,y; 4280 PetscErrorCode ierr; 4281 4282 PetscFunctionBegin; 4283 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 4284 if (!step) { 4285 PetscDrawAxis axis; 4286 const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step"; 4287 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4288 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr); 4289 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4290 } 4291 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 4292 if (ctx->semilogy) y = PetscLog10Real(y); 4293 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4294 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4295 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4296 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 4297 } 4298 PetscFunctionReturn(0); 4299 } 4300 4301 /*@C 4302 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 4303 with TSMonitorLGCtxCreate(). 4304 4305 Collective on TSMonitorLGCtx 4306 4307 Input Parameter: 4308 . ctx - the monitor context 4309 4310 Level: intermediate 4311 4312 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 4313 @*/ 4314 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 4315 { 4316 PetscErrorCode ierr; 4317 4318 PetscFunctionBegin; 4319 if ((*ctx)->transformdestroy) { 4320 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 4321 } 4322 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 4323 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 4324 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 4325 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 4326 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 4327 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4328 PetscFunctionReturn(0); 4329 } 4330 4331 /* 4332 4333 Creates a TS Monitor SPCtx for use with DM Swarm particle visualizations 4334 4335 */ 4336 PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorSPCtx *ctx) 4337 { 4338 PetscDraw draw; 4339 PetscErrorCode ierr; 4340 4341 PetscFunctionBegin; 4342 ierr = PetscNew(ctx);CHKERRQ(ierr); 4343 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 4344 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 4345 ierr = PetscDrawSPCreate(draw,1,&(*ctx)->sp);CHKERRQ(ierr); 4346 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4347 (*ctx)->howoften = howoften; 4348 PetscFunctionReturn(0); 4349 4350 } 4351 4352 /* 4353 Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate 4354 */ 4355 PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx) 4356 { 4357 PetscErrorCode ierr; 4358 4359 PetscFunctionBegin; 4360 4361 ierr = PetscDrawSPDestroy(&(*ctx)->sp);CHKERRQ(ierr); 4362 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4363 4364 PetscFunctionReturn(0); 4365 4366 } 4367 4368 /*@ 4369 TSGetTime - Gets the time of the most recently completed step. 4370 4371 Not Collective 4372 4373 Input Parameter: 4374 . ts - the TS context obtained from TSCreate() 4375 4376 Output Parameter: 4377 . t - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime(). 4378 4379 Level: beginner 4380 4381 Note: 4382 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 4383 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 4384 4385 .seealso: TSGetSolveTime(), TSSetTime(), TSGetTimeStep(), TSGetStepNumber() 4386 4387 @*/ 4388 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 4389 { 4390 PetscFunctionBegin; 4391 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4392 PetscValidRealPointer(t,2); 4393 *t = ts->ptime; 4394 PetscFunctionReturn(0); 4395 } 4396 4397 /*@ 4398 TSGetPrevTime - Gets the starting time of the previously completed step. 4399 4400 Not Collective 4401 4402 Input Parameter: 4403 . ts - the TS context obtained from TSCreate() 4404 4405 Output Parameter: 4406 . t - the previous time 4407 4408 Level: beginner 4409 4410 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep() 4411 4412 @*/ 4413 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 4414 { 4415 PetscFunctionBegin; 4416 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4417 PetscValidRealPointer(t,2); 4418 *t = ts->ptime_prev; 4419 PetscFunctionReturn(0); 4420 } 4421 4422 /*@ 4423 TSSetTime - Allows one to reset the time. 4424 4425 Logically Collective on TS 4426 4427 Input Parameters: 4428 + ts - the TS context obtained from TSCreate() 4429 - time - the time 4430 4431 Level: intermediate 4432 4433 .seealso: TSGetTime(), TSSetMaxSteps() 4434 4435 @*/ 4436 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4437 { 4438 PetscFunctionBegin; 4439 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4440 PetscValidLogicalCollectiveReal(ts,t,2); 4441 ts->ptime = t; 4442 PetscFunctionReturn(0); 4443 } 4444 4445 /*@C 4446 TSSetOptionsPrefix - Sets the prefix used for searching for all 4447 TS options in the database. 4448 4449 Logically Collective on TS 4450 4451 Input Parameter: 4452 + ts - The TS context 4453 - prefix - The prefix to prepend to all option names 4454 4455 Notes: 4456 A hyphen (-) must NOT be given at the beginning of the prefix name. 4457 The first character of all runtime options is AUTOMATICALLY the 4458 hyphen. 4459 4460 Level: advanced 4461 4462 .seealso: TSSetFromOptions() 4463 4464 @*/ 4465 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4466 { 4467 PetscErrorCode ierr; 4468 SNES snes; 4469 4470 PetscFunctionBegin; 4471 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4472 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4473 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4474 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4475 PetscFunctionReturn(0); 4476 } 4477 4478 /*@C 4479 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4480 TS options in the database. 4481 4482 Logically Collective on TS 4483 4484 Input Parameter: 4485 + ts - The TS context 4486 - prefix - The prefix to prepend to all option names 4487 4488 Notes: 4489 A hyphen (-) must NOT be given at the beginning of the prefix name. 4490 The first character of all runtime options is AUTOMATICALLY the 4491 hyphen. 4492 4493 Level: advanced 4494 4495 .seealso: TSGetOptionsPrefix() 4496 4497 @*/ 4498 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4499 { 4500 PetscErrorCode ierr; 4501 SNES snes; 4502 4503 PetscFunctionBegin; 4504 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4505 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4506 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4507 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4508 PetscFunctionReturn(0); 4509 } 4510 4511 /*@C 4512 TSGetOptionsPrefix - Sets the prefix used for searching for all 4513 TS options in the database. 4514 4515 Not Collective 4516 4517 Input Parameter: 4518 . ts - The TS context 4519 4520 Output Parameter: 4521 . prefix - A pointer to the prefix string used 4522 4523 Notes: 4524 On the fortran side, the user should pass in a string 'prifix' of 4525 sufficient length to hold the prefix. 4526 4527 Level: intermediate 4528 4529 .seealso: TSAppendOptionsPrefix() 4530 @*/ 4531 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4532 { 4533 PetscErrorCode ierr; 4534 4535 PetscFunctionBegin; 4536 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4537 PetscValidPointer(prefix,2); 4538 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4539 PetscFunctionReturn(0); 4540 } 4541 4542 /*@C 4543 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4544 4545 Not Collective, but parallel objects are returned if TS is parallel 4546 4547 Input Parameter: 4548 . ts - The TS context obtained from TSCreate() 4549 4550 Output Parameters: 4551 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4552 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4553 . func - Function to compute the Jacobian of the RHS (or NULL) 4554 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4555 4556 Notes: 4557 You can pass in NULL for any return argument you do not need. 4558 4559 Level: intermediate 4560 4561 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4562 4563 @*/ 4564 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4565 { 4566 PetscErrorCode ierr; 4567 DM dm; 4568 4569 PetscFunctionBegin; 4570 if (Amat || Pmat) { 4571 SNES snes; 4572 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4573 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4574 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4575 } 4576 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4577 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4578 PetscFunctionReturn(0); 4579 } 4580 4581 /*@C 4582 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4583 4584 Not Collective, but parallel objects are returned if TS is parallel 4585 4586 Input Parameter: 4587 . ts - The TS context obtained from TSCreate() 4588 4589 Output Parameters: 4590 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4591 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4592 . f - The function to compute the matrices 4593 - ctx - User-defined context for Jacobian evaluation routine 4594 4595 Notes: 4596 You can pass in NULL for any return argument you do not need. 4597 4598 Level: advanced 4599 4600 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4601 4602 @*/ 4603 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4604 { 4605 PetscErrorCode ierr; 4606 DM dm; 4607 4608 PetscFunctionBegin; 4609 if (Amat || Pmat) { 4610 SNES snes; 4611 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4612 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4613 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4614 } 4615 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4616 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4617 PetscFunctionReturn(0); 4618 } 4619 4620 /*@C 4621 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4622 VecView() for the solution at each timestep 4623 4624 Collective on TS 4625 4626 Input Parameters: 4627 + ts - the TS context 4628 . step - current time-step 4629 . ptime - current time 4630 - dummy - either a viewer or NULL 4631 4632 Options Database: 4633 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4634 4635 Notes: 4636 the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4637 will look bad 4638 4639 Level: intermediate 4640 4641 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4642 @*/ 4643 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4644 { 4645 PetscErrorCode ierr; 4646 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4647 PetscDraw draw; 4648 4649 PetscFunctionBegin; 4650 if (!step && ictx->showinitial) { 4651 if (!ictx->initialsolution) { 4652 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 4653 } 4654 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 4655 } 4656 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4657 4658 if (ictx->showinitial) { 4659 PetscReal pause; 4660 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 4661 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 4662 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 4663 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 4664 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 4665 } 4666 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 4667 if (ictx->showtimestepandtime) { 4668 PetscReal xl,yl,xr,yr,h; 4669 char time[32]; 4670 4671 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4672 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4673 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4674 h = yl + .95*(yr - yl); 4675 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4676 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4677 } 4678 4679 if (ictx->showinitial) { 4680 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 4681 } 4682 PetscFunctionReturn(0); 4683 } 4684 4685 /*@C 4686 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 4687 4688 Collective on TS 4689 4690 Input Parameters: 4691 + ts - the TS context 4692 . step - current time-step 4693 . ptime - current time 4694 - dummy - either a viewer or NULL 4695 4696 Level: intermediate 4697 4698 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4699 @*/ 4700 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4701 { 4702 PetscErrorCode ierr; 4703 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4704 PetscDraw draw; 4705 PetscDrawAxis axis; 4706 PetscInt n; 4707 PetscMPIInt size; 4708 PetscReal U0,U1,xl,yl,xr,yr,h; 4709 char time[32]; 4710 const PetscScalar *U; 4711 4712 PetscFunctionBegin; 4713 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 4714 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 4715 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 4716 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 4717 4718 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4719 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 4720 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 4721 if (!step) { 4722 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 4723 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 4724 } 4725 4726 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 4727 U0 = PetscRealPart(U[0]); 4728 U1 = PetscRealPart(U[1]); 4729 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 4730 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 4731 4732 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4733 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 4734 if (ictx->showtimestepandtime) { 4735 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4736 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4737 h = yl + .95*(yr - yl); 4738 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4739 } 4740 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4741 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4742 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 4743 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 4744 PetscFunctionReturn(0); 4745 } 4746 4747 /*@C 4748 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 4749 4750 Collective on TS 4751 4752 Input Parameters: 4753 . ctx - the monitor context 4754 4755 Level: intermediate 4756 4757 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 4758 @*/ 4759 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 4760 { 4761 PetscErrorCode ierr; 4762 4763 PetscFunctionBegin; 4764 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 4765 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 4766 ierr = PetscFree(*ictx);CHKERRQ(ierr); 4767 PetscFunctionReturn(0); 4768 } 4769 4770 /*@C 4771 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 4772 4773 Collective on TS 4774 4775 Input Parameter: 4776 . ts - time-step context 4777 4778 Output Patameter: 4779 . ctx - the monitor context 4780 4781 Options Database: 4782 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4783 4784 Level: intermediate 4785 4786 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 4787 @*/ 4788 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 4789 { 4790 PetscErrorCode ierr; 4791 4792 PetscFunctionBegin; 4793 ierr = PetscNew(ctx);CHKERRQ(ierr); 4794 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 4795 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 4796 4797 (*ctx)->howoften = howoften; 4798 (*ctx)->showinitial = PETSC_FALSE; 4799 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 4800 4801 (*ctx)->showtimestepandtime = PETSC_FALSE; 4802 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 4803 PetscFunctionReturn(0); 4804 } 4805 4806 /*@C 4807 TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling 4808 VecView() for the solution provided by TSSetSolutionFunction() at each timestep 4809 4810 Collective on TS 4811 4812 Input Parameters: 4813 + ts - the TS context 4814 . step - current time-step 4815 . ptime - current time 4816 - dummy - either a viewer or NULL 4817 4818 Options Database: 4819 . -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4820 4821 Level: intermediate 4822 4823 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4824 @*/ 4825 PetscErrorCode TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4826 { 4827 PetscErrorCode ierr; 4828 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4829 PetscViewer viewer = ctx->viewer; 4830 Vec work; 4831 4832 PetscFunctionBegin; 4833 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4834 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4835 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4836 ierr = VecView(work,viewer);CHKERRQ(ierr); 4837 ierr = VecDestroy(&work);CHKERRQ(ierr); 4838 PetscFunctionReturn(0); 4839 } 4840 4841 /*@C 4842 TSMonitorDrawError - Monitors progress of the TS solvers by calling 4843 VecView() for the error at each timestep 4844 4845 Collective on TS 4846 4847 Input Parameters: 4848 + ts - the TS context 4849 . step - current time-step 4850 . ptime - current time 4851 - dummy - either a viewer or NULL 4852 4853 Options Database: 4854 . -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4855 4856 Level: intermediate 4857 4858 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4859 @*/ 4860 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4861 { 4862 PetscErrorCode ierr; 4863 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4864 PetscViewer viewer = ctx->viewer; 4865 Vec work; 4866 4867 PetscFunctionBegin; 4868 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4869 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4870 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4871 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 4872 ierr = VecView(work,viewer);CHKERRQ(ierr); 4873 ierr = VecDestroy(&work);CHKERRQ(ierr); 4874 PetscFunctionReturn(0); 4875 } 4876 4877 #include <petsc/private/dmimpl.h> 4878 /*@ 4879 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 4880 4881 Logically Collective on ts 4882 4883 Input Parameters: 4884 + ts - the ODE integrator object 4885 - dm - the dm, cannot be NULL 4886 4887 Notes: 4888 A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 4889 even when not using interfaces like DMTSSetIFunction(). Use DMClone() to get a distinct DM when solving 4890 different problems using the same function space. 4891 4892 Level: intermediate 4893 4894 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4895 @*/ 4896 PetscErrorCode TSSetDM(TS ts,DM dm) 4897 { 4898 PetscErrorCode ierr; 4899 SNES snes; 4900 DMTS tsdm; 4901 4902 PetscFunctionBegin; 4903 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4904 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4905 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4906 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4907 if (ts->dm->dmts && !dm->dmts) { 4908 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4909 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4910 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4911 tsdm->originaldm = dm; 4912 } 4913 } 4914 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4915 } 4916 ts->dm = dm; 4917 4918 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4919 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4920 PetscFunctionReturn(0); 4921 } 4922 4923 /*@ 4924 TSGetDM - Gets the DM that may be used by some preconditioners 4925 4926 Not Collective 4927 4928 Input Parameter: 4929 . ts - the preconditioner context 4930 4931 Output Parameter: 4932 . dm - the dm 4933 4934 Level: intermediate 4935 4936 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4937 @*/ 4938 PetscErrorCode TSGetDM(TS ts,DM *dm) 4939 { 4940 PetscErrorCode ierr; 4941 4942 PetscFunctionBegin; 4943 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4944 if (!ts->dm) { 4945 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 4946 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 4947 } 4948 *dm = ts->dm; 4949 PetscFunctionReturn(0); 4950 } 4951 4952 /*@ 4953 SNESTSFormFunction - Function to evaluate nonlinear residual 4954 4955 Logically Collective on SNES 4956 4957 Input Parameter: 4958 + snes - nonlinear solver 4959 . U - the current state at which to evaluate the residual 4960 - ctx - user context, must be a TS 4961 4962 Output Parameter: 4963 . F - the nonlinear residual 4964 4965 Notes: 4966 This function is not normally called by users and is automatically registered with the SNES used by TS. 4967 It is most frequently passed to MatFDColoringSetFunction(). 4968 4969 Level: advanced 4970 4971 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 4972 @*/ 4973 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 4974 { 4975 TS ts = (TS)ctx; 4976 PetscErrorCode ierr; 4977 4978 PetscFunctionBegin; 4979 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4980 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4981 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 4982 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 4983 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 4984 PetscFunctionReturn(0); 4985 } 4986 4987 /*@ 4988 SNESTSFormJacobian - Function to evaluate the Jacobian 4989 4990 Collective on SNES 4991 4992 Input Parameter: 4993 + snes - nonlinear solver 4994 . U - the current state at which to evaluate the residual 4995 - ctx - user context, must be a TS 4996 4997 Output Parameter: 4998 + A - the Jacobian 4999 . B - the preconditioning matrix (may be the same as A) 5000 - flag - indicates any structure change in the matrix 5001 5002 Notes: 5003 This function is not normally called by users and is automatically registered with the SNES used by TS. 5004 5005 Level: developer 5006 5007 .seealso: SNESSetJacobian() 5008 @*/ 5009 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 5010 { 5011 TS ts = (TS)ctx; 5012 PetscErrorCode ierr; 5013 5014 PetscFunctionBegin; 5015 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5016 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5017 PetscValidPointer(A,3); 5018 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 5019 PetscValidPointer(B,4); 5020 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 5021 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 5022 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 5023 PetscFunctionReturn(0); 5024 } 5025 5026 /*@C 5027 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 5028 5029 Collective on TS 5030 5031 Input Arguments: 5032 + ts - time stepping context 5033 . t - time at which to evaluate 5034 . U - state at which to evaluate 5035 - ctx - context 5036 5037 Output Arguments: 5038 . F - right hand side 5039 5040 Level: intermediate 5041 5042 Notes: 5043 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 5044 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 5045 5046 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 5047 @*/ 5048 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 5049 { 5050 PetscErrorCode ierr; 5051 Mat Arhs,Brhs; 5052 5053 PetscFunctionBegin; 5054 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 5055 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 5056 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 5057 PetscFunctionReturn(0); 5058 } 5059 5060 /*@C 5061 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 5062 5063 Collective on TS 5064 5065 Input Arguments: 5066 + ts - time stepping context 5067 . t - time at which to evaluate 5068 . U - state at which to evaluate 5069 - ctx - context 5070 5071 Output Arguments: 5072 + A - pointer to operator 5073 . B - pointer to preconditioning matrix 5074 - flg - matrix structure flag 5075 5076 Level: intermediate 5077 5078 Notes: 5079 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 5080 5081 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 5082 @*/ 5083 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 5084 { 5085 PetscFunctionBegin; 5086 PetscFunctionReturn(0); 5087 } 5088 5089 /*@C 5090 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 5091 5092 Collective on TS 5093 5094 Input Arguments: 5095 + ts - time stepping context 5096 . t - time at which to evaluate 5097 . U - state at which to evaluate 5098 . Udot - time derivative of state vector 5099 - ctx - context 5100 5101 Output Arguments: 5102 . F - left hand side 5103 5104 Level: intermediate 5105 5106 Notes: 5107 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 5108 user is required to write their own TSComputeIFunction. 5109 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 5110 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 5111 5112 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 5113 5114 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 5115 @*/ 5116 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 5117 { 5118 PetscErrorCode ierr; 5119 Mat A,B; 5120 5121 PetscFunctionBegin; 5122 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 5123 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 5124 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 5125 PetscFunctionReturn(0); 5126 } 5127 5128 /*@C 5129 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 5130 5131 Collective on TS 5132 5133 Input Arguments: 5134 + ts - time stepping context 5135 . t - time at which to evaluate 5136 . U - state at which to evaluate 5137 . Udot - time derivative of state vector 5138 . shift - shift to apply 5139 - ctx - context 5140 5141 Output Arguments: 5142 + A - pointer to operator 5143 . B - pointer to preconditioning matrix 5144 - flg - matrix structure flag 5145 5146 Level: advanced 5147 5148 Notes: 5149 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 5150 5151 It is only appropriate for problems of the form 5152 5153 $ M Udot = F(U,t) 5154 5155 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 5156 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 5157 an implicit operator of the form 5158 5159 $ shift*M + J 5160 5161 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 5162 a copy of M or reassemble it when requested. 5163 5164 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 5165 @*/ 5166 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 5167 { 5168 PetscErrorCode ierr; 5169 5170 PetscFunctionBegin; 5171 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 5172 ts->ijacobian.shift = shift; 5173 PetscFunctionReturn(0); 5174 } 5175 5176 /*@ 5177 TSGetEquationType - Gets the type of the equation that TS is solving. 5178 5179 Not Collective 5180 5181 Input Parameter: 5182 . ts - the TS context 5183 5184 Output Parameter: 5185 . equation_type - see TSEquationType 5186 5187 Level: beginner 5188 5189 .seealso: TSSetEquationType(), TSEquationType 5190 @*/ 5191 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 5192 { 5193 PetscFunctionBegin; 5194 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5195 PetscValidPointer(equation_type,2); 5196 *equation_type = ts->equation_type; 5197 PetscFunctionReturn(0); 5198 } 5199 5200 /*@ 5201 TSSetEquationType - Sets the type of the equation that TS is solving. 5202 5203 Not Collective 5204 5205 Input Parameter: 5206 + ts - the TS context 5207 - equation_type - see TSEquationType 5208 5209 Level: advanced 5210 5211 .seealso: TSGetEquationType(), TSEquationType 5212 @*/ 5213 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 5214 { 5215 PetscFunctionBegin; 5216 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5217 ts->equation_type = equation_type; 5218 PetscFunctionReturn(0); 5219 } 5220 5221 /*@ 5222 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 5223 5224 Not Collective 5225 5226 Input Parameter: 5227 . ts - the TS context 5228 5229 Output Parameter: 5230 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5231 manual pages for the individual convergence tests for complete lists 5232 5233 Level: beginner 5234 5235 Notes: 5236 Can only be called after the call to TSSolve() is complete. 5237 5238 .seealso: TSSetConvergenceTest(), TSConvergedReason 5239 @*/ 5240 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 5241 { 5242 PetscFunctionBegin; 5243 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5244 PetscValidPointer(reason,2); 5245 *reason = ts->reason; 5246 PetscFunctionReturn(0); 5247 } 5248 5249 /*@ 5250 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 5251 5252 Logically Collective; reason must contain common value 5253 5254 Input Parameters: 5255 + ts - the TS context 5256 - reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5257 manual pages for the individual convergence tests for complete lists 5258 5259 Level: advanced 5260 5261 Notes: 5262 Can only be called while TSSolve() is active. 5263 5264 .seealso: TSConvergedReason 5265 @*/ 5266 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 5267 { 5268 PetscFunctionBegin; 5269 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5270 ts->reason = reason; 5271 PetscFunctionReturn(0); 5272 } 5273 5274 /*@ 5275 TSGetSolveTime - Gets the time after a call to TSSolve() 5276 5277 Not Collective 5278 5279 Input Parameter: 5280 . ts - the TS context 5281 5282 Output Parameter: 5283 . ftime - the final time. This time corresponds to the final time set with TSSetMaxTime() 5284 5285 Level: beginner 5286 5287 Notes: 5288 Can only be called after the call to TSSolve() is complete. 5289 5290 .seealso: TSSetConvergenceTest(), TSConvergedReason 5291 @*/ 5292 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 5293 { 5294 PetscFunctionBegin; 5295 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5296 PetscValidPointer(ftime,2); 5297 *ftime = ts->solvetime; 5298 PetscFunctionReturn(0); 5299 } 5300 5301 /*@ 5302 TSGetSNESIterations - Gets the total number of nonlinear iterations 5303 used by the time integrator. 5304 5305 Not Collective 5306 5307 Input Parameter: 5308 . ts - TS context 5309 5310 Output Parameter: 5311 . nits - number of nonlinear iterations 5312 5313 Notes: 5314 This counter is reset to zero for each successive call to TSSolve(). 5315 5316 Level: intermediate 5317 5318 .seealso: TSGetKSPIterations() 5319 @*/ 5320 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 5321 { 5322 PetscFunctionBegin; 5323 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5324 PetscValidIntPointer(nits,2); 5325 *nits = ts->snes_its; 5326 PetscFunctionReturn(0); 5327 } 5328 5329 /*@ 5330 TSGetKSPIterations - Gets the total number of linear iterations 5331 used by the time integrator. 5332 5333 Not Collective 5334 5335 Input Parameter: 5336 . ts - TS context 5337 5338 Output Parameter: 5339 . lits - number of linear iterations 5340 5341 Notes: 5342 This counter is reset to zero for each successive call to TSSolve(). 5343 5344 Level: intermediate 5345 5346 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 5347 @*/ 5348 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 5349 { 5350 PetscFunctionBegin; 5351 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5352 PetscValidIntPointer(lits,2); 5353 *lits = ts->ksp_its; 5354 PetscFunctionReturn(0); 5355 } 5356 5357 /*@ 5358 TSGetStepRejections - Gets the total number of rejected steps. 5359 5360 Not Collective 5361 5362 Input Parameter: 5363 . ts - TS context 5364 5365 Output Parameter: 5366 . rejects - number of steps rejected 5367 5368 Notes: 5369 This counter is reset to zero for each successive call to TSSolve(). 5370 5371 Level: intermediate 5372 5373 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 5374 @*/ 5375 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 5376 { 5377 PetscFunctionBegin; 5378 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5379 PetscValidIntPointer(rejects,2); 5380 *rejects = ts->reject; 5381 PetscFunctionReturn(0); 5382 } 5383 5384 /*@ 5385 TSGetSNESFailures - Gets the total number of failed SNES solves 5386 5387 Not Collective 5388 5389 Input Parameter: 5390 . ts - TS context 5391 5392 Output Parameter: 5393 . fails - number of failed nonlinear solves 5394 5395 Notes: 5396 This counter is reset to zero for each successive call to TSSolve(). 5397 5398 Level: intermediate 5399 5400 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5401 @*/ 5402 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5403 { 5404 PetscFunctionBegin; 5405 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5406 PetscValidIntPointer(fails,2); 5407 *fails = ts->num_snes_failures; 5408 PetscFunctionReturn(0); 5409 } 5410 5411 /*@ 5412 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5413 5414 Not Collective 5415 5416 Input Parameter: 5417 + ts - TS context 5418 - rejects - maximum number of rejected steps, pass -1 for unlimited 5419 5420 Notes: 5421 The counter is reset to zero for each step 5422 5423 Options Database Key: 5424 . -ts_max_reject - Maximum number of step rejections before a step fails 5425 5426 Level: intermediate 5427 5428 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5429 @*/ 5430 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5431 { 5432 PetscFunctionBegin; 5433 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5434 ts->max_reject = rejects; 5435 PetscFunctionReturn(0); 5436 } 5437 5438 /*@ 5439 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5440 5441 Not Collective 5442 5443 Input Parameter: 5444 + ts - TS context 5445 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5446 5447 Notes: 5448 The counter is reset to zero for each successive call to TSSolve(). 5449 5450 Options Database Key: 5451 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5452 5453 Level: intermediate 5454 5455 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5456 @*/ 5457 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5458 { 5459 PetscFunctionBegin; 5460 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5461 ts->max_snes_failures = fails; 5462 PetscFunctionReturn(0); 5463 } 5464 5465 /*@ 5466 TSSetErrorIfStepFails - Error if no step succeeds 5467 5468 Not Collective 5469 5470 Input Parameter: 5471 + ts - TS context 5472 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5473 5474 Options Database Key: 5475 . -ts_error_if_step_fails - Error if no step succeeds 5476 5477 Level: intermediate 5478 5479 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5480 @*/ 5481 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5482 { 5483 PetscFunctionBegin; 5484 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5485 ts->errorifstepfailed = err; 5486 PetscFunctionReturn(0); 5487 } 5488 5489 /*@C 5490 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 5491 5492 Collective on TS 5493 5494 Input Parameters: 5495 + ts - the TS context 5496 . step - current time-step 5497 . ptime - current time 5498 . u - current state 5499 - vf - viewer and its format 5500 5501 Level: intermediate 5502 5503 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5504 @*/ 5505 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5506 { 5507 PetscErrorCode ierr; 5508 5509 PetscFunctionBegin; 5510 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5511 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5512 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5513 PetscFunctionReturn(0); 5514 } 5515 5516 /*@C 5517 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5518 5519 Collective on TS 5520 5521 Input Parameters: 5522 + ts - the TS context 5523 . step - current time-step 5524 . ptime - current time 5525 . u - current state 5526 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5527 5528 Level: intermediate 5529 5530 Notes: 5531 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. 5532 These are named according to the file name template. 5533 5534 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5535 5536 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5537 @*/ 5538 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5539 { 5540 PetscErrorCode ierr; 5541 char filename[PETSC_MAX_PATH_LEN]; 5542 PetscViewer viewer; 5543 5544 PetscFunctionBegin; 5545 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5546 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5547 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5548 ierr = VecView(u,viewer);CHKERRQ(ierr); 5549 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5550 PetscFunctionReturn(0); 5551 } 5552 5553 /*@C 5554 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5555 5556 Collective on TS 5557 5558 Input Parameters: 5559 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5560 5561 Level: intermediate 5562 5563 Note: 5564 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 5565 5566 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 5567 @*/ 5568 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 5569 { 5570 PetscErrorCode ierr; 5571 5572 PetscFunctionBegin; 5573 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 5574 PetscFunctionReturn(0); 5575 } 5576 5577 /*@ 5578 TSGetAdapt - Get the adaptive controller context for the current method 5579 5580 Collective on TS if controller has not been created yet 5581 5582 Input Arguments: 5583 . ts - time stepping context 5584 5585 Output Arguments: 5586 . adapt - adaptive controller 5587 5588 Level: intermediate 5589 5590 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 5591 @*/ 5592 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 5593 { 5594 PetscErrorCode ierr; 5595 5596 PetscFunctionBegin; 5597 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5598 PetscValidPointer(adapt,2); 5599 if (!ts->adapt) { 5600 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 5601 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 5602 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 5603 } 5604 *adapt = ts->adapt; 5605 PetscFunctionReturn(0); 5606 } 5607 5608 /*@ 5609 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 5610 5611 Logically Collective 5612 5613 Input Arguments: 5614 + ts - time integration context 5615 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 5616 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 5617 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 5618 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 5619 5620 Options Database keys: 5621 + -ts_rtol <rtol> - relative tolerance for local truncation error 5622 - -ts_atol <atol> Absolute tolerance for local truncation error 5623 5624 Notes: 5625 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 5626 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 5627 computed only for the differential or the algebraic part then this can be done using the vector of 5628 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 5629 differential part and infinity for the algebraic part, the LTE calculation will include only the 5630 differential variables. 5631 5632 Level: beginner 5633 5634 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 5635 @*/ 5636 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 5637 { 5638 PetscErrorCode ierr; 5639 5640 PetscFunctionBegin; 5641 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 5642 if (vatol) { 5643 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 5644 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 5645 ts->vatol = vatol; 5646 } 5647 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 5648 if (vrtol) { 5649 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 5650 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 5651 ts->vrtol = vrtol; 5652 } 5653 PetscFunctionReturn(0); 5654 } 5655 5656 /*@ 5657 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5658 5659 Logically Collective 5660 5661 Input Arguments: 5662 . ts - time integration context 5663 5664 Output Arguments: 5665 + atol - scalar absolute tolerances, NULL to ignore 5666 . vatol - vector of absolute tolerances, NULL to ignore 5667 . rtol - scalar relative tolerances, NULL to ignore 5668 - vrtol - vector of relative tolerances, NULL to ignore 5669 5670 Level: beginner 5671 5672 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 5673 @*/ 5674 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 5675 { 5676 PetscFunctionBegin; 5677 if (atol) *atol = ts->atol; 5678 if (vatol) *vatol = ts->vatol; 5679 if (rtol) *rtol = ts->rtol; 5680 if (vrtol) *vrtol = ts->vrtol; 5681 PetscFunctionReturn(0); 5682 } 5683 5684 /*@ 5685 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 5686 5687 Collective on TS 5688 5689 Input Arguments: 5690 + ts - time stepping context 5691 . U - state vector, usually ts->vec_sol 5692 - Y - state vector to be compared to U 5693 5694 Output Arguments: 5695 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5696 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5697 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5698 5699 Level: developer 5700 5701 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 5702 @*/ 5703 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5704 { 5705 PetscErrorCode ierr; 5706 PetscInt i,n,N,rstart; 5707 PetscInt n_loc,na_loc,nr_loc; 5708 PetscReal n_glb,na_glb,nr_glb; 5709 const PetscScalar *u,*y; 5710 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 5711 PetscReal tol,tola,tolr; 5712 PetscReal err_loc[6],err_glb[6]; 5713 5714 PetscFunctionBegin; 5715 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5716 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5717 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5718 PetscValidType(U,2); 5719 PetscValidType(Y,3); 5720 PetscCheckSameComm(U,2,Y,3); 5721 PetscValidPointer(norm,4); 5722 PetscValidPointer(norma,5); 5723 PetscValidPointer(normr,6); 5724 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5725 5726 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5727 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5728 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5729 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5730 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5731 sum = 0.; n_loc = 0; 5732 suma = 0.; na_loc = 0; 5733 sumr = 0.; nr_loc = 0; 5734 if (ts->vatol && ts->vrtol) { 5735 const PetscScalar *atol,*rtol; 5736 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5737 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5738 for (i=0; i<n; i++) { 5739 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5740 diff = PetscAbsScalar(y[i] - u[i]); 5741 tola = PetscRealPart(atol[i]); 5742 if(tola>0.){ 5743 suma += PetscSqr(diff/tola); 5744 na_loc++; 5745 } 5746 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5747 if(tolr>0.){ 5748 sumr += PetscSqr(diff/tolr); 5749 nr_loc++; 5750 } 5751 tol=tola+tolr; 5752 if(tol>0.){ 5753 sum += PetscSqr(diff/tol); 5754 n_loc++; 5755 } 5756 } 5757 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5758 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5759 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5760 const PetscScalar *atol; 5761 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5762 for (i=0; i<n; i++) { 5763 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5764 diff = PetscAbsScalar(y[i] - u[i]); 5765 tola = PetscRealPart(atol[i]); 5766 if(tola>0.){ 5767 suma += PetscSqr(diff/tola); 5768 na_loc++; 5769 } 5770 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5771 if(tolr>0.){ 5772 sumr += PetscSqr(diff/tolr); 5773 nr_loc++; 5774 } 5775 tol=tola+tolr; 5776 if(tol>0.){ 5777 sum += PetscSqr(diff/tol); 5778 n_loc++; 5779 } 5780 } 5781 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5782 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5783 const PetscScalar *rtol; 5784 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5785 for (i=0; i<n; i++) { 5786 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5787 diff = PetscAbsScalar(y[i] - u[i]); 5788 tola = ts->atol; 5789 if(tola>0.){ 5790 suma += PetscSqr(diff/tola); 5791 na_loc++; 5792 } 5793 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5794 if(tolr>0.){ 5795 sumr += PetscSqr(diff/tolr); 5796 nr_loc++; 5797 } 5798 tol=tola+tolr; 5799 if(tol>0.){ 5800 sum += PetscSqr(diff/tol); 5801 n_loc++; 5802 } 5803 } 5804 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5805 } else { /* scalar atol, scalar rtol */ 5806 for (i=0; i<n; i++) { 5807 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5808 diff = PetscAbsScalar(y[i] - u[i]); 5809 tola = ts->atol; 5810 if(tola>0.){ 5811 suma += PetscSqr(diff/tola); 5812 na_loc++; 5813 } 5814 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5815 if(tolr>0.){ 5816 sumr += PetscSqr(diff/tolr); 5817 nr_loc++; 5818 } 5819 tol=tola+tolr; 5820 if(tol>0.){ 5821 sum += PetscSqr(diff/tol); 5822 n_loc++; 5823 } 5824 } 5825 } 5826 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5827 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5828 5829 err_loc[0] = sum; 5830 err_loc[1] = suma; 5831 err_loc[2] = sumr; 5832 err_loc[3] = (PetscReal)n_loc; 5833 err_loc[4] = (PetscReal)na_loc; 5834 err_loc[5] = (PetscReal)nr_loc; 5835 5836 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5837 5838 gsum = err_glb[0]; 5839 gsuma = err_glb[1]; 5840 gsumr = err_glb[2]; 5841 n_glb = err_glb[3]; 5842 na_glb = err_glb[4]; 5843 nr_glb = err_glb[5]; 5844 5845 *norm = 0.; 5846 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 5847 *norma = 0.; 5848 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5849 *normr = 0.; 5850 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5851 5852 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5853 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5854 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5855 PetscFunctionReturn(0); 5856 } 5857 5858 /*@ 5859 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5860 5861 Collective on TS 5862 5863 Input Arguments: 5864 + ts - time stepping context 5865 . U - state vector, usually ts->vec_sol 5866 - Y - state vector to be compared to U 5867 5868 Output Arguments: 5869 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5870 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5871 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5872 5873 Level: developer 5874 5875 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5876 @*/ 5877 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5878 { 5879 PetscErrorCode ierr; 5880 PetscInt i,n,N,rstart; 5881 const PetscScalar *u,*y; 5882 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 5883 PetscReal tol,tola,tolr,diff; 5884 PetscReal err_loc[3],err_glb[3]; 5885 5886 PetscFunctionBegin; 5887 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5888 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5889 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5890 PetscValidType(U,2); 5891 PetscValidType(Y,3); 5892 PetscCheckSameComm(U,2,Y,3); 5893 PetscValidPointer(norm,4); 5894 PetscValidPointer(norma,5); 5895 PetscValidPointer(normr,6); 5896 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5897 5898 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5899 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5900 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5901 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5902 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5903 5904 max=0.; 5905 maxa=0.; 5906 maxr=0.; 5907 5908 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5909 const PetscScalar *atol,*rtol; 5910 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5911 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5912 5913 for (i=0; i<n; i++) { 5914 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5915 diff = PetscAbsScalar(y[i] - u[i]); 5916 tola = PetscRealPart(atol[i]); 5917 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5918 tol = tola+tolr; 5919 if(tola>0.){ 5920 maxa = PetscMax(maxa,diff / tola); 5921 } 5922 if(tolr>0.){ 5923 maxr = PetscMax(maxr,diff / tolr); 5924 } 5925 if(tol>0.){ 5926 max = PetscMax(max,diff / tol); 5927 } 5928 } 5929 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5930 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5931 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5932 const PetscScalar *atol; 5933 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5934 for (i=0; i<n; i++) { 5935 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5936 diff = PetscAbsScalar(y[i] - u[i]); 5937 tola = PetscRealPart(atol[i]); 5938 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5939 tol = tola+tolr; 5940 if(tola>0.){ 5941 maxa = PetscMax(maxa,diff / tola); 5942 } 5943 if(tolr>0.){ 5944 maxr = PetscMax(maxr,diff / tolr); 5945 } 5946 if(tol>0.){ 5947 max = PetscMax(max,diff / tol); 5948 } 5949 } 5950 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5951 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5952 const PetscScalar *rtol; 5953 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5954 5955 for (i=0; i<n; i++) { 5956 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5957 diff = PetscAbsScalar(y[i] - u[i]); 5958 tola = ts->atol; 5959 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5960 tol = tola+tolr; 5961 if(tola>0.){ 5962 maxa = PetscMax(maxa,diff / tola); 5963 } 5964 if(tolr>0.){ 5965 maxr = PetscMax(maxr,diff / tolr); 5966 } 5967 if(tol>0.){ 5968 max = PetscMax(max,diff / tol); 5969 } 5970 } 5971 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5972 } else { /* scalar atol, scalar rtol */ 5973 5974 for (i=0; i<n; i++) { 5975 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5976 diff = PetscAbsScalar(y[i] - u[i]); 5977 tola = ts->atol; 5978 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5979 tol = tola+tolr; 5980 if(tola>0.){ 5981 maxa = PetscMax(maxa,diff / tola); 5982 } 5983 if(tolr>0.){ 5984 maxr = PetscMax(maxr,diff / tolr); 5985 } 5986 if(tol>0.){ 5987 max = PetscMax(max,diff / tol); 5988 } 5989 } 5990 } 5991 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5992 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5993 err_loc[0] = max; 5994 err_loc[1] = maxa; 5995 err_loc[2] = maxr; 5996 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5997 gmax = err_glb[0]; 5998 gmaxa = err_glb[1]; 5999 gmaxr = err_glb[2]; 6000 6001 *norm = gmax; 6002 *norma = gmaxa; 6003 *normr = gmaxr; 6004 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6005 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6006 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6007 PetscFunctionReturn(0); 6008 } 6009 6010 /*@ 6011 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 6012 6013 Collective on TS 6014 6015 Input Arguments: 6016 + ts - time stepping context 6017 . U - state vector, usually ts->vec_sol 6018 . Y - state vector to be compared to U 6019 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6020 6021 Output Arguments: 6022 + norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6023 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6024 - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6025 6026 Options Database Keys: 6027 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6028 6029 Level: developer 6030 6031 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 6032 @*/ 6033 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6034 { 6035 PetscErrorCode ierr; 6036 6037 PetscFunctionBegin; 6038 if (wnormtype == NORM_2) { 6039 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6040 } else if(wnormtype == NORM_INFINITY) { 6041 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6042 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6043 PetscFunctionReturn(0); 6044 } 6045 6046 6047 /*@ 6048 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 6049 6050 Collective on TS 6051 6052 Input Arguments: 6053 + ts - time stepping context 6054 . E - error vector 6055 . U - state vector, usually ts->vec_sol 6056 - Y - state vector, previous time step 6057 6058 Output Arguments: 6059 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6060 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6061 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6062 6063 Level: developer 6064 6065 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 6066 @*/ 6067 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6068 { 6069 PetscErrorCode ierr; 6070 PetscInt i,n,N,rstart; 6071 PetscInt n_loc,na_loc,nr_loc; 6072 PetscReal n_glb,na_glb,nr_glb; 6073 const PetscScalar *e,*u,*y; 6074 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 6075 PetscReal tol,tola,tolr; 6076 PetscReal err_loc[6],err_glb[6]; 6077 6078 PetscFunctionBegin; 6079 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6080 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6081 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6082 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6083 PetscValidType(E,2); 6084 PetscValidType(U,3); 6085 PetscValidType(Y,4); 6086 PetscCheckSameComm(E,2,U,3); 6087 PetscCheckSameComm(U,2,Y,3); 6088 PetscValidPointer(norm,5); 6089 PetscValidPointer(norma,6); 6090 PetscValidPointer(normr,7); 6091 6092 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6093 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6094 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6095 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6096 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6097 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6098 sum = 0.; n_loc = 0; 6099 suma = 0.; na_loc = 0; 6100 sumr = 0.; nr_loc = 0; 6101 if (ts->vatol && ts->vrtol) { 6102 const PetscScalar *atol,*rtol; 6103 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6104 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6105 for (i=0; i<n; i++) { 6106 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6107 err = PetscAbsScalar(e[i]); 6108 tola = PetscRealPart(atol[i]); 6109 if(tola>0.){ 6110 suma += PetscSqr(err/tola); 6111 na_loc++; 6112 } 6113 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6114 if(tolr>0.){ 6115 sumr += PetscSqr(err/tolr); 6116 nr_loc++; 6117 } 6118 tol=tola+tolr; 6119 if(tol>0.){ 6120 sum += PetscSqr(err/tol); 6121 n_loc++; 6122 } 6123 } 6124 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6125 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6126 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6127 const PetscScalar *atol; 6128 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6129 for (i=0; i<n; i++) { 6130 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6131 err = PetscAbsScalar(e[i]); 6132 tola = PetscRealPart(atol[i]); 6133 if(tola>0.){ 6134 suma += PetscSqr(err/tola); 6135 na_loc++; 6136 } 6137 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6138 if(tolr>0.){ 6139 sumr += PetscSqr(err/tolr); 6140 nr_loc++; 6141 } 6142 tol=tola+tolr; 6143 if(tol>0.){ 6144 sum += PetscSqr(err/tol); 6145 n_loc++; 6146 } 6147 } 6148 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6149 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6150 const PetscScalar *rtol; 6151 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6152 for (i=0; i<n; i++) { 6153 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6154 err = PetscAbsScalar(e[i]); 6155 tola = ts->atol; 6156 if(tola>0.){ 6157 suma += PetscSqr(err/tola); 6158 na_loc++; 6159 } 6160 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6161 if(tolr>0.){ 6162 sumr += PetscSqr(err/tolr); 6163 nr_loc++; 6164 } 6165 tol=tola+tolr; 6166 if(tol>0.){ 6167 sum += PetscSqr(err/tol); 6168 n_loc++; 6169 } 6170 } 6171 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6172 } else { /* scalar atol, scalar rtol */ 6173 for (i=0; i<n; i++) { 6174 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6175 err = PetscAbsScalar(e[i]); 6176 tola = ts->atol; 6177 if(tola>0.){ 6178 suma += PetscSqr(err/tola); 6179 na_loc++; 6180 } 6181 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6182 if(tolr>0.){ 6183 sumr += PetscSqr(err/tolr); 6184 nr_loc++; 6185 } 6186 tol=tola+tolr; 6187 if(tol>0.){ 6188 sum += PetscSqr(err/tol); 6189 n_loc++; 6190 } 6191 } 6192 } 6193 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6194 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6195 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6196 6197 err_loc[0] = sum; 6198 err_loc[1] = suma; 6199 err_loc[2] = sumr; 6200 err_loc[3] = (PetscReal)n_loc; 6201 err_loc[4] = (PetscReal)na_loc; 6202 err_loc[5] = (PetscReal)nr_loc; 6203 6204 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6205 6206 gsum = err_glb[0]; 6207 gsuma = err_glb[1]; 6208 gsumr = err_glb[2]; 6209 n_glb = err_glb[3]; 6210 na_glb = err_glb[4]; 6211 nr_glb = err_glb[5]; 6212 6213 *norm = 0.; 6214 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 6215 *norma = 0.; 6216 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 6217 *normr = 0.; 6218 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 6219 6220 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6221 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6222 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6223 PetscFunctionReturn(0); 6224 } 6225 6226 /*@ 6227 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 6228 Collective on TS 6229 6230 Input Arguments: 6231 + ts - time stepping context 6232 . E - error vector 6233 . U - state vector, usually ts->vec_sol 6234 - Y - state vector, previous time step 6235 6236 Output Arguments: 6237 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6238 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6239 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6240 6241 Level: developer 6242 6243 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 6244 @*/ 6245 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6246 { 6247 PetscErrorCode ierr; 6248 PetscInt i,n,N,rstart; 6249 const PetscScalar *e,*u,*y; 6250 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 6251 PetscReal tol,tola,tolr; 6252 PetscReal err_loc[3],err_glb[3]; 6253 6254 PetscFunctionBegin; 6255 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6256 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6257 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6258 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6259 PetscValidType(E,2); 6260 PetscValidType(U,3); 6261 PetscValidType(Y,4); 6262 PetscCheckSameComm(E,2,U,3); 6263 PetscCheckSameComm(U,2,Y,3); 6264 PetscValidPointer(norm,5); 6265 PetscValidPointer(norma,6); 6266 PetscValidPointer(normr,7); 6267 6268 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6269 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6270 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6271 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6272 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6273 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6274 6275 max=0.; 6276 maxa=0.; 6277 maxr=0.; 6278 6279 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6280 const PetscScalar *atol,*rtol; 6281 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6282 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6283 6284 for (i=0; i<n; i++) { 6285 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6286 err = PetscAbsScalar(e[i]); 6287 tola = PetscRealPart(atol[i]); 6288 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6289 tol = tola+tolr; 6290 if(tola>0.){ 6291 maxa = PetscMax(maxa,err / tola); 6292 } 6293 if(tolr>0.){ 6294 maxr = PetscMax(maxr,err / tolr); 6295 } 6296 if(tol>0.){ 6297 max = PetscMax(max,err / tol); 6298 } 6299 } 6300 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6301 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6302 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6303 const PetscScalar *atol; 6304 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6305 for (i=0; i<n; i++) { 6306 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6307 err = PetscAbsScalar(e[i]); 6308 tola = PetscRealPart(atol[i]); 6309 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6310 tol = tola+tolr; 6311 if(tola>0.){ 6312 maxa = PetscMax(maxa,err / tola); 6313 } 6314 if(tolr>0.){ 6315 maxr = PetscMax(maxr,err / tolr); 6316 } 6317 if(tol>0.){ 6318 max = PetscMax(max,err / tol); 6319 } 6320 } 6321 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6322 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6323 const PetscScalar *rtol; 6324 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6325 6326 for (i=0; i<n; i++) { 6327 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6328 err = PetscAbsScalar(e[i]); 6329 tola = ts->atol; 6330 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6331 tol = tola+tolr; 6332 if(tola>0.){ 6333 maxa = PetscMax(maxa,err / tola); 6334 } 6335 if(tolr>0.){ 6336 maxr = PetscMax(maxr,err / tolr); 6337 } 6338 if(tol>0.){ 6339 max = PetscMax(max,err / tol); 6340 } 6341 } 6342 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6343 } else { /* scalar atol, scalar rtol */ 6344 6345 for (i=0; i<n; i++) { 6346 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6347 err = PetscAbsScalar(e[i]); 6348 tola = ts->atol; 6349 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6350 tol = tola+tolr; 6351 if(tola>0.){ 6352 maxa = PetscMax(maxa,err / tola); 6353 } 6354 if(tolr>0.){ 6355 maxr = PetscMax(maxr,err / tolr); 6356 } 6357 if(tol>0.){ 6358 max = PetscMax(max,err / tol); 6359 } 6360 } 6361 } 6362 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6363 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6364 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6365 err_loc[0] = max; 6366 err_loc[1] = maxa; 6367 err_loc[2] = maxr; 6368 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6369 gmax = err_glb[0]; 6370 gmaxa = err_glb[1]; 6371 gmaxr = err_glb[2]; 6372 6373 *norm = gmax; 6374 *norma = gmaxa; 6375 *normr = gmaxr; 6376 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6377 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6378 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6379 PetscFunctionReturn(0); 6380 } 6381 6382 /*@ 6383 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 6384 6385 Collective on TS 6386 6387 Input Arguments: 6388 + ts - time stepping context 6389 . E - error vector 6390 . U - state vector, usually ts->vec_sol 6391 . Y - state vector, previous time step 6392 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6393 6394 Output Arguments: 6395 + norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6396 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6397 - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6398 6399 Options Database Keys: 6400 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6401 6402 Level: developer 6403 6404 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6405 @*/ 6406 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6407 { 6408 PetscErrorCode ierr; 6409 6410 PetscFunctionBegin; 6411 if (wnormtype == NORM_2) { 6412 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6413 } else if(wnormtype == NORM_INFINITY) { 6414 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6415 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6416 PetscFunctionReturn(0); 6417 } 6418 6419 6420 /*@ 6421 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6422 6423 Logically Collective on TS 6424 6425 Input Arguments: 6426 + ts - time stepping context 6427 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6428 6429 Note: 6430 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6431 6432 Level: intermediate 6433 6434 .seealso: TSGetCFLTime(), TSADAPTCFL 6435 @*/ 6436 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6437 { 6438 PetscFunctionBegin; 6439 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6440 ts->cfltime_local = cfltime; 6441 ts->cfltime = -1.; 6442 PetscFunctionReturn(0); 6443 } 6444 6445 /*@ 6446 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6447 6448 Collective on TS 6449 6450 Input Arguments: 6451 . ts - time stepping context 6452 6453 Output Arguments: 6454 . cfltime - maximum stable time step for forward Euler 6455 6456 Level: advanced 6457 6458 .seealso: TSSetCFLTimeLocal() 6459 @*/ 6460 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6461 { 6462 PetscErrorCode ierr; 6463 6464 PetscFunctionBegin; 6465 if (ts->cfltime < 0) { 6466 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6467 } 6468 *cfltime = ts->cfltime; 6469 PetscFunctionReturn(0); 6470 } 6471 6472 /*@ 6473 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6474 6475 Input Parameters: 6476 + ts - the TS context. 6477 . xl - lower bound. 6478 - xu - upper bound. 6479 6480 Notes: 6481 If this routine is not called then the lower and upper bounds are set to 6482 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6483 6484 Level: advanced 6485 6486 @*/ 6487 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6488 { 6489 PetscErrorCode ierr; 6490 SNES snes; 6491 6492 PetscFunctionBegin; 6493 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6494 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6495 PetscFunctionReturn(0); 6496 } 6497 6498 /*@C 6499 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 6500 in a time based line graph 6501 6502 Collective on TS 6503 6504 Input Parameters: 6505 + ts - the TS context 6506 . step - current time-step 6507 . ptime - current time 6508 . u - current solution 6509 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 6510 6511 Options Database: 6512 . -ts_monitor_lg_solution_variables 6513 6514 Level: intermediate 6515 6516 Notes: 6517 Each process in a parallel run displays its component solutions in a separate window 6518 6519 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 6520 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 6521 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 6522 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 6523 @*/ 6524 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6525 { 6526 PetscErrorCode ierr; 6527 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 6528 const PetscScalar *yy; 6529 Vec v; 6530 6531 PetscFunctionBegin; 6532 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6533 if (!step) { 6534 PetscDrawAxis axis; 6535 PetscInt dim; 6536 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6537 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 6538 if (!ctx->names) { 6539 PetscBool flg; 6540 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 6541 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 6542 if (flg) { 6543 PetscInt i,n; 6544 char **names; 6545 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 6546 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 6547 for (i=0; i<n; i++) { 6548 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 6549 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 6550 } 6551 names[n] = NULL; 6552 ctx->names = names; 6553 } 6554 } 6555 if (ctx->names && !ctx->displaynames) { 6556 char **displaynames; 6557 PetscBool flg; 6558 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6559 ierr = PetscCalloc1(dim+1,&displaynames);CHKERRQ(ierr); 6560 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 6561 if (flg) { 6562 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 6563 } 6564 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 6565 } 6566 if (ctx->displaynames) { 6567 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 6568 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 6569 } else if (ctx->names) { 6570 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6571 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6572 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 6573 } else { 6574 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6575 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6576 } 6577 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6578 } 6579 6580 if (!ctx->transform) v = u; 6581 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 6582 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 6583 if (ctx->displaynames) { 6584 PetscInt i; 6585 for (i=0; i<ctx->ndisplayvariables; i++) 6586 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 6587 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 6588 } else { 6589 #if defined(PETSC_USE_COMPLEX) 6590 PetscInt i,n; 6591 PetscReal *yreal; 6592 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 6593 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6594 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6595 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6596 ierr = PetscFree(yreal);CHKERRQ(ierr); 6597 #else 6598 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6599 #endif 6600 } 6601 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 6602 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 6603 6604 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6605 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6606 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6607 } 6608 PetscFunctionReturn(0); 6609 } 6610 6611 /*@C 6612 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6613 6614 Collective on TS 6615 6616 Input Parameters: 6617 + ts - the TS context 6618 - names - the names of the components, final string must be NULL 6619 6620 Level: intermediate 6621 6622 Notes: 6623 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6624 6625 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 6626 @*/ 6627 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 6628 { 6629 PetscErrorCode ierr; 6630 PetscInt i; 6631 6632 PetscFunctionBegin; 6633 for (i=0; i<ts->numbermonitors; i++) { 6634 if (ts->monitor[i] == TSMonitorLGSolution) { 6635 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 6636 break; 6637 } 6638 } 6639 PetscFunctionReturn(0); 6640 } 6641 6642 /*@C 6643 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6644 6645 Collective on TS 6646 6647 Input Parameters: 6648 + ts - the TS context 6649 - names - the names of the components, final string must be NULL 6650 6651 Level: intermediate 6652 6653 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 6654 @*/ 6655 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 6656 { 6657 PetscErrorCode ierr; 6658 6659 PetscFunctionBegin; 6660 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 6661 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 6662 PetscFunctionReturn(0); 6663 } 6664 6665 /*@C 6666 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 6667 6668 Collective on TS 6669 6670 Input Parameter: 6671 . ts - the TS context 6672 6673 Output Parameter: 6674 . names - the names of the components, final string must be NULL 6675 6676 Level: intermediate 6677 6678 Notes: 6679 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6680 6681 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 6682 @*/ 6683 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 6684 { 6685 PetscInt i; 6686 6687 PetscFunctionBegin; 6688 *names = NULL; 6689 for (i=0; i<ts->numbermonitors; i++) { 6690 if (ts->monitor[i] == TSMonitorLGSolution) { 6691 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 6692 *names = (const char *const *)ctx->names; 6693 break; 6694 } 6695 } 6696 PetscFunctionReturn(0); 6697 } 6698 6699 /*@C 6700 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 6701 6702 Collective on TS 6703 6704 Input Parameters: 6705 + ctx - the TSMonitorLG context 6706 - displaynames - the names of the components, final string must be NULL 6707 6708 Level: intermediate 6709 6710 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6711 @*/ 6712 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 6713 { 6714 PetscInt j = 0,k; 6715 PetscErrorCode ierr; 6716 6717 PetscFunctionBegin; 6718 if (!ctx->names) PetscFunctionReturn(0); 6719 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 6720 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 6721 while (displaynames[j]) j++; 6722 ctx->ndisplayvariables = j; 6723 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 6724 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 6725 j = 0; 6726 while (displaynames[j]) { 6727 k = 0; 6728 while (ctx->names[k]) { 6729 PetscBool flg; 6730 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 6731 if (flg) { 6732 ctx->displayvariables[j] = k; 6733 break; 6734 } 6735 k++; 6736 } 6737 j++; 6738 } 6739 PetscFunctionReturn(0); 6740 } 6741 6742 /*@C 6743 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 6744 6745 Collective on TS 6746 6747 Input Parameters: 6748 + ts - the TS context 6749 - displaynames - the names of the components, final string must be NULL 6750 6751 Notes: 6752 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6753 6754 Level: intermediate 6755 6756 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6757 @*/ 6758 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 6759 { 6760 PetscInt i; 6761 PetscErrorCode ierr; 6762 6763 PetscFunctionBegin; 6764 for (i=0; i<ts->numbermonitors; i++) { 6765 if (ts->monitor[i] == TSMonitorLGSolution) { 6766 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 6767 break; 6768 } 6769 } 6770 PetscFunctionReturn(0); 6771 } 6772 6773 /*@C 6774 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 6775 6776 Collective on TS 6777 6778 Input Parameters: 6779 + ts - the TS context 6780 . transform - the transform function 6781 . destroy - function to destroy the optional context 6782 - ctx - optional context used by transform function 6783 6784 Notes: 6785 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6786 6787 Level: intermediate 6788 6789 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 6790 @*/ 6791 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6792 { 6793 PetscInt i; 6794 PetscErrorCode ierr; 6795 6796 PetscFunctionBegin; 6797 for (i=0; i<ts->numbermonitors; i++) { 6798 if (ts->monitor[i] == TSMonitorLGSolution) { 6799 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 6800 } 6801 } 6802 PetscFunctionReturn(0); 6803 } 6804 6805 /*@C 6806 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 6807 6808 Collective on TSLGCtx 6809 6810 Input Parameters: 6811 + ts - the TS context 6812 . transform - the transform function 6813 . destroy - function to destroy the optional context 6814 - ctx - optional context used by transform function 6815 6816 Level: intermediate 6817 6818 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 6819 @*/ 6820 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6821 { 6822 PetscFunctionBegin; 6823 ctx->transform = transform; 6824 ctx->transformdestroy = destroy; 6825 ctx->transformctx = tctx; 6826 PetscFunctionReturn(0); 6827 } 6828 6829 /*@C 6830 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error 6831 in a time based line graph 6832 6833 Collective on TS 6834 6835 Input Parameters: 6836 + ts - the TS context 6837 . step - current time-step 6838 . ptime - current time 6839 . u - current solution 6840 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 6841 6842 Level: intermediate 6843 6844 Notes: 6845 Each process in a parallel run displays its component errors in a separate window 6846 6847 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6848 6849 Options Database Keys: 6850 . -ts_monitor_lg_error - create a graphical monitor of error history 6851 6852 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6853 @*/ 6854 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 6855 { 6856 PetscErrorCode ierr; 6857 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 6858 const PetscScalar *yy; 6859 Vec y; 6860 6861 PetscFunctionBegin; 6862 if (!step) { 6863 PetscDrawAxis axis; 6864 PetscInt dim; 6865 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6866 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr); 6867 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6868 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6869 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6870 } 6871 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6872 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6873 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6874 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 6875 #if defined(PETSC_USE_COMPLEX) 6876 { 6877 PetscReal *yreal; 6878 PetscInt i,n; 6879 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 6880 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6881 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6882 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6883 ierr = PetscFree(yreal);CHKERRQ(ierr); 6884 } 6885 #else 6886 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6887 #endif 6888 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 6889 ierr = VecDestroy(&y);CHKERRQ(ierr); 6890 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6891 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6892 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6893 } 6894 PetscFunctionReturn(0); 6895 } 6896 6897 /*@C 6898 TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot 6899 6900 Input Parameters: 6901 + ts - the TS context 6902 . step - current time-step 6903 . ptime - current time 6904 . u - current solution 6905 - dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate() 6906 6907 Options Database: 6908 . -ts_monitor_sp_swarm 6909 6910 Level: intermediate 6911 6912 @*/ 6913 PetscErrorCode TSMonitorSPSwarmSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6914 { 6915 PetscErrorCode ierr; 6916 TSMonitorSPCtx ctx = (TSMonitorSPCtx)dctx; 6917 const PetscScalar *yy; 6918 PetscReal *y,*x; 6919 PetscInt Np, p, dim=2; 6920 DM dm; 6921 6922 PetscFunctionBegin; 6923 6924 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6925 if (!step) { 6926 PetscDrawAxis axis; 6927 ierr = PetscDrawSPGetAxis(ctx->sp,&axis);CHKERRQ(ierr); 6928 ierr = PetscDrawAxisSetLabels(axis,"Particles","X","Y");CHKERRQ(ierr); 6929 ierr = PetscDrawAxisSetLimits(axis, -5, 5, -5, 5);CHKERRQ(ierr); 6930 ierr = PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE);CHKERRQ(ierr); 6931 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 6932 ierr = DMGetDimension(dm, &dim); 6933 if(dim!=2) SETERRQ(PETSC_COMM_SELF, ierr, "Dimensions improper for monitor arguments! Current support: two dimensions.");CHKERRQ(ierr); 6934 ierr = VecGetLocalSize(u, &Np);CHKERRQ(ierr); 6935 Np /= 2*dim; 6936 ierr = PetscDrawSPSetDimension(ctx->sp, Np);CHKERRQ(ierr); 6937 ierr = PetscDrawSPReset(ctx->sp);CHKERRQ(ierr); 6938 } 6939 6940 ierr = VecGetLocalSize(u, &Np);CHKERRQ(ierr); 6941 Np /= 2*dim; 6942 ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr); 6943 ierr = PetscMalloc2(Np, &x, Np, &y);CHKERRQ(ierr); 6944 /* get points from solution vector */ 6945 for (p=0; p<Np; ++p){ 6946 x[p] = PetscRealPart(yy[2*dim*p]); 6947 y[p] = PetscRealPart(yy[2*dim*p+1]); 6948 } 6949 ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr); 6950 6951 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6952 ierr = PetscDrawSPAddPoint(ctx->sp,x,y);CHKERRQ(ierr); 6953 ierr = PetscDrawSPDraw(ctx->sp,PETSC_FALSE);CHKERRQ(ierr); 6954 ierr = PetscDrawSPSave(ctx->sp);CHKERRQ(ierr); 6955 } 6956 6957 ierr = PetscFree2(x, y);CHKERRQ(ierr); 6958 6959 PetscFunctionReturn(0); 6960 } 6961 6962 6963 6964 /*@C 6965 TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep 6966 6967 Collective on TS 6968 6969 Input Parameters: 6970 + ts - the TS context 6971 . step - current time-step 6972 . ptime - current time 6973 . u - current solution 6974 - dctx - unused context 6975 6976 Level: intermediate 6977 6978 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6979 6980 Options Database Keys: 6981 . -ts_monitor_error - create a graphical monitor of error history 6982 6983 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6984 @*/ 6985 PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 6986 { 6987 PetscErrorCode ierr; 6988 Vec y; 6989 PetscReal nrm; 6990 PetscBool flg; 6991 6992 PetscFunctionBegin; 6993 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6994 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6995 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6996 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg);CHKERRQ(ierr); 6997 if (flg) { 6998 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 6999 ierr = PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm);CHKERRQ(ierr); 7000 } 7001 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg);CHKERRQ(ierr); 7002 if (flg) { 7003 ierr = VecView(y,vf->viewer);CHKERRQ(ierr); 7004 } 7005 ierr = VecDestroy(&y);CHKERRQ(ierr); 7006 PetscFunctionReturn(0); 7007 } 7008 7009 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7010 { 7011 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7012 PetscReal x = ptime,y; 7013 PetscErrorCode ierr; 7014 PetscInt its; 7015 7016 PetscFunctionBegin; 7017 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7018 if (!n) { 7019 PetscDrawAxis axis; 7020 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7021 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 7022 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7023 ctx->snes_its = 0; 7024 } 7025 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 7026 y = its - ctx->snes_its; 7027 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7028 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7029 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7030 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7031 } 7032 ctx->snes_its = its; 7033 PetscFunctionReturn(0); 7034 } 7035 7036 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7037 { 7038 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7039 PetscReal x = ptime,y; 7040 PetscErrorCode ierr; 7041 PetscInt its; 7042 7043 PetscFunctionBegin; 7044 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7045 if (!n) { 7046 PetscDrawAxis axis; 7047 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7048 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 7049 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7050 ctx->ksp_its = 0; 7051 } 7052 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 7053 y = its - ctx->ksp_its; 7054 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7055 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7056 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7057 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7058 } 7059 ctx->ksp_its = its; 7060 PetscFunctionReturn(0); 7061 } 7062 7063 /*@ 7064 TSComputeLinearStability - computes the linear stability function at a point 7065 7066 Collective on TS 7067 7068 Input Parameters: 7069 + ts - the TS context 7070 - xr,xi - real and imaginary part of input arguments 7071 7072 Output Parameters: 7073 . yr,yi - real and imaginary part of function value 7074 7075 Level: developer 7076 7077 .seealso: TSSetRHSFunction(), TSComputeIFunction() 7078 @*/ 7079 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 7080 { 7081 PetscErrorCode ierr; 7082 7083 PetscFunctionBegin; 7084 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7085 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 7086 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 7087 PetscFunctionReturn(0); 7088 } 7089 7090 /* ------------------------------------------------------------------------*/ 7091 /*@C 7092 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 7093 7094 Collective on TS 7095 7096 Input Parameters: 7097 . ts - the ODE solver object 7098 7099 Output Parameter: 7100 . ctx - the context 7101 7102 Level: intermediate 7103 7104 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 7105 7106 @*/ 7107 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 7108 { 7109 PetscErrorCode ierr; 7110 7111 PetscFunctionBegin; 7112 ierr = PetscNew(ctx);CHKERRQ(ierr); 7113 PetscFunctionReturn(0); 7114 } 7115 7116 /*@C 7117 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 7118 7119 Collective on TS 7120 7121 Input Parameters: 7122 + ts - the TS context 7123 . step - current time-step 7124 . ptime - current time 7125 . u - current solution 7126 - dctx - the envelope context 7127 7128 Options Database: 7129 . -ts_monitor_envelope 7130 7131 Level: intermediate 7132 7133 Notes: 7134 after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 7135 7136 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 7137 @*/ 7138 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 7139 { 7140 PetscErrorCode ierr; 7141 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 7142 7143 PetscFunctionBegin; 7144 if (!ctx->max) { 7145 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 7146 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 7147 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 7148 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 7149 } else { 7150 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 7151 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 7152 } 7153 PetscFunctionReturn(0); 7154 } 7155 7156 /*@C 7157 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 7158 7159 Collective on TS 7160 7161 Input Parameter: 7162 . ts - the TS context 7163 7164 Output Parameter: 7165 + max - the maximum values 7166 - min - the minimum values 7167 7168 Notes: 7169 If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7170 7171 Level: intermediate 7172 7173 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7174 @*/ 7175 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7176 { 7177 PetscInt i; 7178 7179 PetscFunctionBegin; 7180 if (max) *max = NULL; 7181 if (min) *min = NULL; 7182 for (i=0; i<ts->numbermonitors; i++) { 7183 if (ts->monitor[i] == TSMonitorEnvelope) { 7184 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7185 if (max) *max = ctx->max; 7186 if (min) *min = ctx->min; 7187 break; 7188 } 7189 } 7190 PetscFunctionReturn(0); 7191 } 7192 7193 /*@C 7194 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7195 7196 Collective on TSMonitorEnvelopeCtx 7197 7198 Input Parameter: 7199 . ctx - the monitor context 7200 7201 Level: intermediate 7202 7203 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7204 @*/ 7205 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7206 { 7207 PetscErrorCode ierr; 7208 7209 PetscFunctionBegin; 7210 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7211 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7212 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7213 PetscFunctionReturn(0); 7214 } 7215 7216 /*@ 7217 TSRestartStep - Flags the solver to restart the next step 7218 7219 Collective on TS 7220 7221 Input Parameter: 7222 . ts - the TS context obtained from TSCreate() 7223 7224 Level: advanced 7225 7226 Notes: 7227 Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of 7228 discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution 7229 vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For 7230 the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce 7231 discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with 7232 discontinuous source terms). 7233 7234 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep() 7235 @*/ 7236 PetscErrorCode TSRestartStep(TS ts) 7237 { 7238 PetscFunctionBegin; 7239 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7240 ts->steprestart = PETSC_TRUE; 7241 PetscFunctionReturn(0); 7242 } 7243 7244 /*@ 7245 TSRollBack - Rolls back one time step 7246 7247 Collective on TS 7248 7249 Input Parameter: 7250 . ts - the TS context obtained from TSCreate() 7251 7252 Level: advanced 7253 7254 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7255 @*/ 7256 PetscErrorCode TSRollBack(TS ts) 7257 { 7258 PetscErrorCode ierr; 7259 7260 PetscFunctionBegin; 7261 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7262 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7263 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7264 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7265 ts->time_step = ts->ptime - ts->ptime_prev; 7266 ts->ptime = ts->ptime_prev; 7267 ts->ptime_prev = ts->ptime_prev_rollback; 7268 ts->steps--; 7269 ts->steprollback = PETSC_TRUE; 7270 PetscFunctionReturn(0); 7271 } 7272 7273 /*@ 7274 TSGetStages - Get the number of stages and stage values 7275 7276 Input Parameter: 7277 . ts - the TS context obtained from TSCreate() 7278 7279 Output Parameters: 7280 + ns - the number of stages 7281 - Y - the current stage vectors 7282 7283 Level: advanced 7284 7285 Notes: Both ns and Y can be NULL. 7286 7287 .seealso: TSCreate() 7288 @*/ 7289 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7290 { 7291 PetscErrorCode ierr; 7292 7293 PetscFunctionBegin; 7294 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7295 if (ns) PetscValidPointer(ns,2); 7296 if (Y) PetscValidPointer(Y,3); 7297 if (!ts->ops->getstages) { 7298 if (ns) *ns = 0; 7299 if (Y) *Y = NULL; 7300 } else { 7301 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7302 } 7303 PetscFunctionReturn(0); 7304 } 7305 7306 /*@C 7307 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7308 7309 Collective on SNES 7310 7311 Input Parameters: 7312 + ts - the TS context 7313 . t - current timestep 7314 . U - state vector 7315 . Udot - time derivative of state vector 7316 . shift - shift to apply, see note below 7317 - ctx - an optional user context 7318 7319 Output Parameters: 7320 + J - Jacobian matrix (not altered in this routine) 7321 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7322 7323 Level: intermediate 7324 7325 Notes: 7326 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7327 7328 dF/dU + shift*dF/dUdot 7329 7330 Most users should not need to explicitly call this routine, as it 7331 is used internally within the nonlinear solvers. 7332 7333 This will first try to get the coloring from the DM. If the DM type has no coloring 7334 routine, then it will try to get the coloring from the matrix. This requires that the 7335 matrix have nonzero entries precomputed. 7336 7337 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7338 @*/ 7339 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7340 { 7341 SNES snes; 7342 MatFDColoring color; 7343 PetscBool hascolor, matcolor = PETSC_FALSE; 7344 PetscErrorCode ierr; 7345 7346 PetscFunctionBegin; 7347 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7348 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7349 if (!color) { 7350 DM dm; 7351 ISColoring iscoloring; 7352 7353 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 7354 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 7355 if (hascolor && !matcolor) { 7356 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 7357 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7358 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7359 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7360 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7361 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7362 } else { 7363 MatColoring mc; 7364 7365 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 7366 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 7367 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 7368 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 7369 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 7370 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 7371 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7372 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7373 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7374 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7375 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7376 } 7377 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 7378 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 7379 } 7380 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 7381 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 7382 if (J != B) { 7383 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7384 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7385 } 7386 PetscFunctionReturn(0); 7387 } 7388 7389 /*@ 7390 TSSetFunctionDomainError - Set a function that tests if the current state vector is valid 7391 7392 Input Parameters: 7393 + ts - the TS context 7394 - func - function called within TSFunctionDomainError 7395 7396 Calling sequence of func: 7397 $ PetscErrorCode func(TS ts,PetscReal time,Vec state,PetscBool reject) 7398 7399 + ts - the TS context 7400 . time - the current time (of the stage) 7401 . state - the state to check if it is valid 7402 - reject - (output parameter) PETSC_FALSE if the state is acceptable, PETSC_TRUE if not acceptable 7403 7404 Level: intermediate 7405 7406 Notes: 7407 If an implicit ODE solver is being used then, in addition to providing this routine, the 7408 user's code should call SNESSetFunctionDomainError() when domain errors occur during 7409 function evaluations where the functions are provided by TSSetIFunction() or TSSetRHSFunction(). 7410 Use TSGetSNES() to obtain the SNES object 7411 7412 Developer Notes: 7413 The naming of this function is inconsistent with the SNESSetFunctionDomainError() 7414 since one takes a function pointer and the other does not. 7415 7416 .seealso: TSAdaptCheckStage(), TSFunctionDomainError(), SNESSetFunctionDomainError(), TSGetSNES() 7417 @*/ 7418 7419 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 7420 { 7421 PetscFunctionBegin; 7422 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7423 ts->functiondomainerror = func; 7424 PetscFunctionReturn(0); 7425 } 7426 7427 /*@ 7428 TSFunctionDomainError - Checks if the current state is valid 7429 7430 Input Parameters: 7431 + ts - the TS context 7432 . stagetime - time of the simulation 7433 - Y - state vector to check. 7434 7435 Output Parameter: 7436 . accept - Set to PETSC_FALSE if the current state vector is valid. 7437 7438 Note: 7439 This function is called by the TS integration routines and calls the user provided function (set with TSSetFunctionDomainError()) 7440 to check if the current state is valid. 7441 7442 Level: developer 7443 7444 .seealso: TSSetFunctionDomainError() 7445 @*/ 7446 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 7447 { 7448 PetscFunctionBegin; 7449 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7450 *accept = PETSC_TRUE; 7451 if (ts->functiondomainerror) { 7452 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 7453 } 7454 PetscFunctionReturn(0); 7455 } 7456 7457 /*@C 7458 TSClone - This function clones a time step object. 7459 7460 Collective 7461 7462 Input Parameter: 7463 . tsin - The input TS 7464 7465 Output Parameter: 7466 . tsout - The output TS (cloned) 7467 7468 Notes: 7469 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. 7470 7471 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); 7472 7473 Level: developer 7474 7475 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 7476 @*/ 7477 PetscErrorCode TSClone(TS tsin, TS *tsout) 7478 { 7479 TS t; 7480 PetscErrorCode ierr; 7481 SNES snes_start; 7482 DM dm; 7483 TSType type; 7484 7485 PetscFunctionBegin; 7486 PetscValidPointer(tsin,1); 7487 *tsout = NULL; 7488 7489 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 7490 7491 /* General TS description */ 7492 t->numbermonitors = 0; 7493 t->setupcalled = 0; 7494 t->ksp_its = 0; 7495 t->snes_its = 0; 7496 t->nwork = 0; 7497 t->rhsjacobian.time = PETSC_MIN_REAL; 7498 t->rhsjacobian.scale = 1.; 7499 t->ijacobian.shift = 1.; 7500 7501 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 7502 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 7503 7504 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 7505 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 7506 7507 t->adapt = tsin->adapt; 7508 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 7509 7510 t->trajectory = tsin->trajectory; 7511 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 7512 7513 t->event = tsin->event; 7514 if (t->event) t->event->refct++; 7515 7516 t->problem_type = tsin->problem_type; 7517 t->ptime = tsin->ptime; 7518 t->ptime_prev = tsin->ptime_prev; 7519 t->time_step = tsin->time_step; 7520 t->max_time = tsin->max_time; 7521 t->steps = tsin->steps; 7522 t->max_steps = tsin->max_steps; 7523 t->equation_type = tsin->equation_type; 7524 t->atol = tsin->atol; 7525 t->rtol = tsin->rtol; 7526 t->max_snes_failures = tsin->max_snes_failures; 7527 t->max_reject = tsin->max_reject; 7528 t->errorifstepfailed = tsin->errorifstepfailed; 7529 7530 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 7531 ierr = TSSetType(t,type);CHKERRQ(ierr); 7532 7533 t->vec_sol = NULL; 7534 7535 t->cfltime = tsin->cfltime; 7536 t->cfltime_local = tsin->cfltime_local; 7537 t->exact_final_time = tsin->exact_final_time; 7538 7539 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 7540 7541 if (((PetscObject)tsin)->fortran_func_pointers) { 7542 PetscInt i; 7543 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 7544 for (i=0; i<10; i++) { 7545 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 7546 } 7547 } 7548 *tsout = t; 7549 PetscFunctionReturn(0); 7550 } 7551 7552 static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void* ctx,Vec x,Vec y) 7553 { 7554 PetscErrorCode ierr; 7555 TS ts = (TS) ctx; 7556 7557 PetscFunctionBegin; 7558 ierr = TSComputeRHSFunction(ts,0,x,y);CHKERRQ(ierr); 7559 PetscFunctionReturn(0); 7560 } 7561 7562 /*@ 7563 TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function. 7564 7565 Logically Collective on TS 7566 7567 Input Parameters: 7568 TS - the time stepping routine 7569 7570 Output Parameter: 7571 . flg - PETSC_TRUE if the multiply is likely correct 7572 7573 Options Database: 7574 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator 7575 7576 Level: advanced 7577 7578 Notes: 7579 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7580 7581 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTestTranspose() 7582 @*/ 7583 PetscErrorCode TSRHSJacobianTest(TS ts,PetscBool *flg) 7584 { 7585 Mat J,B; 7586 PetscErrorCode ierr; 7587 TSRHSJacobian func; 7588 void* ctx; 7589 7590 PetscFunctionBegin; 7591 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7592 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7593 ierr = MatShellTestMult(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7594 PetscFunctionReturn(0); 7595 } 7596 7597 /*@C 7598 TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function. 7599 7600 Logically Collective on TS 7601 7602 Input Parameters: 7603 TS - the time stepping routine 7604 7605 Output Parameter: 7606 . flg - PETSC_TRUE if the multiply is likely correct 7607 7608 Options Database: 7609 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator 7610 7611 Notes: 7612 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7613 7614 Level: advanced 7615 7616 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTest() 7617 @*/ 7618 PetscErrorCode TSRHSJacobianTestTranspose(TS ts,PetscBool *flg) 7619 { 7620 Mat J,B; 7621 PetscErrorCode ierr; 7622 void *ctx; 7623 TSRHSJacobian func; 7624 7625 PetscFunctionBegin; 7626 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7627 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7628 ierr = MatShellTestMultTranspose(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7629 PetscFunctionReturn(0); 7630 } 7631 7632 /*@ 7633 TSSetUseSplitRHSFunction - Use the split RHSFunction when a multirate method is used. 7634 7635 Logically collective 7636 7637 Input Parameter: 7638 + ts - timestepping context 7639 - use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used 7640 7641 Options Database: 7642 . -ts_use_splitrhsfunction - <true,false> 7643 7644 Notes: 7645 This is only useful for multirate methods 7646 7647 Level: intermediate 7648 7649 .seealso: TSGetUseSplitRHSFunction() 7650 @*/ 7651 PetscErrorCode TSSetUseSplitRHSFunction(TS ts, PetscBool use_splitrhsfunction) 7652 { 7653 PetscFunctionBegin; 7654 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7655 ts->use_splitrhsfunction = use_splitrhsfunction; 7656 PetscFunctionReturn(0); 7657 } 7658 7659 /*@ 7660 TSGetUseSplitRHSFunction - Gets whether to use the split RHSFunction when a multirate method is used. 7661 7662 Not collective 7663 7664 Input Parameter: 7665 . ts - timestepping context 7666 7667 Output Parameter: 7668 . use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used 7669 7670 Level: intermediate 7671 7672 .seealso: TSSetUseSplitRHSFunction() 7673 @*/ 7674 PetscErrorCode TSGetUseSplitRHSFunction(TS ts, PetscBool *use_splitrhsfunction) 7675 { 7676 PetscFunctionBegin; 7677 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7678 *use_splitrhsfunction = ts->use_splitrhsfunction; 7679 PetscFunctionReturn(0); 7680 } 7681