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