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