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