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