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