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