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