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