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