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