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