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