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