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