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