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