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