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