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