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