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