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