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