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