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_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 11 12 const char *const TSExactFinalTimeOptions[] = {"STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",0}; 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "TSSetTypeFromOptions" 16 /* 17 TSSetTypeFromOptions - Sets the type of ts from user options. 18 19 Collective on TS 20 21 Input Parameter: 22 . ts - The ts 23 24 Level: intermediate 25 26 .keywords: TS, set, options, database, type 27 .seealso: TSSetFromOptions(), TSSetType() 28 */ 29 static PetscErrorCode TSSetTypeFromOptions(TS ts) 30 { 31 PetscBool opt; 32 const char *defaultType; 33 char typeName[256]; 34 PetscErrorCode ierr; 35 36 PetscFunctionBegin; 37 if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name; 38 else defaultType = TSEULER; 39 40 if (!TSRegisterAllCalled) {ierr = TSRegisterAll(NULL);CHKERRQ(ierr);} 41 ierr = PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr); 42 if (opt) { 43 ierr = TSSetType(ts, typeName);CHKERRQ(ierr); 44 } else { 45 ierr = TSSetType(ts, defaultType);CHKERRQ(ierr); 46 } 47 PetscFunctionReturn(0); 48 } 49 50 struct _n_TSMonitorDrawCtx { 51 PetscViewer viewer; 52 PetscDrawAxis axis; 53 Vec initialsolution; 54 PetscBool showinitial; 55 PetscInt howoften; /* when > 0 uses step % howoften, when negative only final solution plotted */ 56 PetscBool showtimestepandtime; 57 int color; 58 }; 59 60 #undef __FUNCT__ 61 #define __FUNCT__ "TSSetFromOptions" 62 /*@ 63 TSSetFromOptions - Sets various TS parameters from user options. 64 65 Collective on TS 66 67 Input Parameter: 68 . ts - the TS context obtained from TSCreate() 69 70 Options Database Keys: 71 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP 72 . -ts_max_steps maxsteps - maximum number of time-steps to take 73 . -ts_final_time time - maximum time to compute to 74 . -ts_dt dt - initial time step 75 . -ts_monitor - print information at each timestep 76 . -ts_monitor_lg_timestep - Monitor timestep size graphically 77 . -ts_monitor_lg_solution - Monitor solution graphically 78 . -ts_monitor_lg_error - Monitor error graphically 79 . -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically 80 . -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically 81 . -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically 82 . -ts_monitor_draw_solution - Monitor solution graphically 83 . -ts_monitor_draw_solution_phase - Monitor solution graphically with phase diagram 84 . -ts_monitor_draw_error - Monitor error graphically 85 . -ts_monitor_solution_binary <filename> - Save each solution to a binary file 86 - -ts_monitor_solution_vtk <filename.vts> - Save each time step to a binary file, use filename-%%03D.vts 87 88 Developer Note: We should unify all the -ts_monitor options in the way that -xxx_view has been unified 89 90 Level: beginner 91 92 .keywords: TS, timestep, set, options, database 93 94 .seealso: TSGetType() 95 @*/ 96 PetscErrorCode TSSetFromOptions(TS ts) 97 { 98 PetscBool opt,flg; 99 PetscErrorCode ierr; 100 PetscViewer monviewer; 101 char monfilename[PETSC_MAX_PATH_LEN]; 102 SNES snes; 103 TSAdapt adapt; 104 PetscReal time_step; 105 TSExactFinalTimeOption eftopt; 106 char dir[16]; 107 108 PetscFunctionBegin; 109 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 110 ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr); 111 /* Handle TS type options */ 112 ierr = TSSetTypeFromOptions(ts);CHKERRQ(ierr); 113 114 /* Handle generic TS options */ 115 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,NULL);CHKERRQ(ierr); 116 ierr = PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr); 117 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);CHKERRQ(ierr); 118 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr); 119 if (flg) { 120 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 121 } 122 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); 123 if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);} 124 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);CHKERRQ(ierr); 125 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);CHKERRQ(ierr); 126 ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);CHKERRQ(ierr); 127 ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);CHKERRQ(ierr); 128 ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);CHKERRQ(ierr); 129 130 /* Monitor options */ 131 ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 132 if (flg) { 133 ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ts),monfilename,&monviewer);CHKERRQ(ierr); 134 ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 135 } 136 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 137 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 138 139 ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 140 if (opt) { 141 TSMonitorLGCtx ctx; 142 PetscInt howoften = 1; 143 144 ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 145 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 146 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 147 } 148 ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr); 149 if (opt) { 150 TSMonitorLGCtx ctx; 151 PetscInt howoften = 1; 152 153 ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 154 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 155 ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 156 } 157 ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr); 158 if (opt) { 159 TSMonitorLGCtx ctx; 160 PetscInt howoften = 1; 161 162 ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);CHKERRQ(ierr); 163 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 164 ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 165 } 166 ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr); 167 if (opt) { 168 TSMonitorLGCtx ctx; 169 PetscInt howoften = 1; 170 171 ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 172 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 173 ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 174 } 175 ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr); 176 if (opt) { 177 TSMonitorLGCtx ctx; 178 PetscInt howoften = 1; 179 180 ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 181 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 182 ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 183 } 184 ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr); 185 if (opt) { 186 TSMonitorSPEigCtx ctx; 187 PetscInt howoften = 1; 188 189 ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);CHKERRQ(ierr); 190 ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 191 ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr); 192 } 193 opt = PETSC_FALSE; 194 ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr); 195 if (opt) { 196 TSMonitorDrawCtx ctx; 197 PetscInt howoften = 1; 198 199 ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 200 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 201 ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 202 } 203 opt = PETSC_FALSE; 204 ierr = PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);CHKERRQ(ierr); 205 if (opt) { 206 TSMonitorDrawCtx ctx; 207 PetscReal bounds[4]; 208 PetscInt n = 4; 209 PetscDraw draw; 210 211 ierr = PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);CHKERRQ(ierr); 212 if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field"); 213 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,1,&ctx);CHKERRQ(ierr); 214 ierr = PetscViewerDrawGetDraw(ctx->viewer,0,&draw);CHKERRQ(ierr); 215 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 216 ierr = PetscDrawAxisCreate(draw,&ctx->axis);CHKERRQ(ierr); 217 ierr = PetscDrawAxisSetLimits(ctx->axis,bounds[0],bounds[2],bounds[1],bounds[3]);CHKERRQ(ierr); 218 ierr = PetscDrawAxisDraw(ctx->axis);CHKERRQ(ierr); 219 // ierr = PetscDrawSetCoordinates(draw,bounds[0],bounds[1],bounds[2],bounds[3]);CHKERRQ(ierr); 220 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 221 } 222 opt = PETSC_FALSE; 223 ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr); 224 if (opt) { 225 TSMonitorDrawCtx ctx; 226 PetscInt howoften = 1; 227 228 ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);CHKERRQ(ierr); 229 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 230 ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 231 } 232 opt = PETSC_FALSE; 233 ierr = PetscOptionsString("-ts_monitor_solution_binary","Save each solution to a binary file","TSMonitorSolutionBinary",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 234 if (flg) { 235 PetscViewer ctx; 236 if (monfilename[0]) { 237 ierr = PetscViewerBinaryOpen(PetscObjectComm((PetscObject)ts),monfilename,FILE_MODE_WRITE,&ctx);CHKERRQ(ierr); 238 ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 239 } else { 240 ctx = PETSC_VIEWER_BINARY_(PetscObjectComm((PetscObject)ts)); 241 ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))NULL);CHKERRQ(ierr); 242 } 243 } 244 opt = PETSC_FALSE; 245 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); 246 if (flg) { 247 const char *ptr,*ptr2; 248 char *filetemplate; 249 if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 250 /* Do some cursory validation of the input. */ 251 ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr); 252 if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 253 for (ptr++; ptr && *ptr; ptr++) { 254 ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr); 255 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"); 256 if (ptr2) break; 257 } 258 ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr); 259 ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr); 260 } 261 262 ierr = PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,16,&flg);CHKERRQ(ierr); 263 if (flg) { 264 TSMonitorDMDARayCtx *rayctx; 265 int ray = 0; 266 DMDADirection ddir; 267 DM da; 268 PetscMPIInt rank; 269 270 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 271 if (dir[0] == 'x') ddir = DMDA_X; 272 else if (dir[0] == 'y') ddir = DMDA_Y; 273 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 274 sscanf(dir+2,"%d",&ray); 275 276 ierr = PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %D\n",dir[0],ray);CHKERRQ(ierr); 277 ierr = PetscNew(TSMonitorDMDARayCtx,&rayctx);CHKERRQ(ierr); 278 ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 279 ierr = DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);CHKERRQ(ierr); 280 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr); 281 if (!rank) { 282 ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,0,0,0,600,300,&rayctx->viewer);CHKERRQ(ierr); 283 } 284 ierr = TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);CHKERRQ(ierr); 285 } 286 287 ierr = TSGetTSAdapt(ts,&adapt);CHKERRQ(ierr); 288 ierr = TSAdaptSetFromOptions(adapt);CHKERRQ(ierr); 289 290 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 291 if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);} 292 293 /* Handle specific TS options */ 294 if (ts->ops->setfromoptions) { 295 ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr); 296 } 297 298 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 299 ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr); 300 ierr = PetscOptionsEnd();CHKERRQ(ierr); 301 PetscFunctionReturn(0); 302 } 303 304 #undef __FUNCT__ 305 #undef __FUNCT__ 306 #define __FUNCT__ "TSComputeRHSJacobian" 307 /*@ 308 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 309 set with TSSetRHSJacobian(). 310 311 Collective on TS and Vec 312 313 Input Parameters: 314 + ts - the TS context 315 . t - current timestep 316 - U - input vector 317 318 Output Parameters: 319 + A - Jacobian matrix 320 . B - optional preconditioning matrix 321 - flag - flag indicating matrix structure 322 323 Notes: 324 Most users should not need to explicitly call this routine, as it 325 is used internally within the nonlinear solvers. 326 327 See KSPSetOperators() for important information about setting the 328 flag parameter. 329 330 Level: developer 331 332 .keywords: SNES, compute, Jacobian, matrix 333 334 .seealso: TSSetRHSJacobian(), KSPSetOperators() 335 @*/ 336 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg) 337 { 338 PetscErrorCode ierr; 339 PetscInt Ustate; 340 DM dm; 341 DMTS tsdm; 342 TSRHSJacobian rhsjacobianfunc; 343 void *ctx; 344 TSIJacobian ijacobianfunc; 345 346 PetscFunctionBegin; 347 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 348 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 349 PetscCheckSameComm(ts,1,U,3); 350 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 351 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 352 ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr); 353 ierr = DMTSGetIJacobian(dm,&ijacobianfunc,NULL);CHKERRQ(ierr); 354 ierr = PetscObjectStateQuery((PetscObject)U,&Ustate);CHKERRQ(ierr); 355 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == U && ts->rhsjacobian.Xstate == Ustate))) { 356 *flg = ts->rhsjacobian.mstructure; 357 PetscFunctionReturn(0); 358 } 359 360 if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 361 362 if (rhsjacobianfunc) { 363 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr); 364 *flg = DIFFERENT_NONZERO_PATTERN; 365 PetscStackPush("TS user Jacobian function"); 366 ierr = (*rhsjacobianfunc)(ts,t,U,A,B,flg,ctx);CHKERRQ(ierr); 367 PetscStackPop; 368 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr); 369 /* make sure user returned a correct Jacobian and preconditioner */ 370 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 371 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 372 } else { 373 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 374 if (*A != *B) {ierr = MatZeroEntries(*B);CHKERRQ(ierr);} 375 *flg = SAME_NONZERO_PATTERN; 376 } 377 ts->rhsjacobian.time = t; 378 ts->rhsjacobian.X = U; 379 ierr = PetscObjectStateQuery((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 380 ts->rhsjacobian.mstructure = *flg; 381 PetscFunctionReturn(0); 382 } 383 384 #undef __FUNCT__ 385 #define __FUNCT__ "TSComputeRHSFunction" 386 /*@ 387 TSComputeRHSFunction - Evaluates the right-hand-side function. 388 389 Collective on TS and Vec 390 391 Input Parameters: 392 + ts - the TS context 393 . t - current time 394 - U - state vector 395 396 Output Parameter: 397 . y - right hand side 398 399 Note: 400 Most users should not need to explicitly call this routine, as it 401 is used internally within the nonlinear solvers. 402 403 Level: developer 404 405 .keywords: TS, compute 406 407 .seealso: TSSetRHSFunction(), TSComputeIFunction() 408 @*/ 409 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y) 410 { 411 PetscErrorCode ierr; 412 TSRHSFunction rhsfunction; 413 TSIFunction ifunction; 414 void *ctx; 415 DM dm; 416 417 PetscFunctionBegin; 418 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 419 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 420 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 421 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 422 ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr); 423 ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr); 424 425 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 426 427 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 428 if (rhsfunction) { 429 PetscStackPush("TS user right-hand-side function"); 430 ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr); 431 PetscStackPop; 432 } else { 433 ierr = VecZeroEntries(y);CHKERRQ(ierr); 434 } 435 436 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 437 PetscFunctionReturn(0); 438 } 439 440 #undef __FUNCT__ 441 #define __FUNCT__ "TSComputeSolutionFunction" 442 /*@ 443 TSComputeSolutionFunction - Evaluates the solution function. 444 445 Collective on TS and Vec 446 447 Input Parameters: 448 + ts - the TS context 449 - t - current time 450 451 Output Parameter: 452 . U - the solution 453 454 Note: 455 Most users should not need to explicitly call this routine, as it 456 is used internally within the nonlinear solvers. 457 458 Level: developer 459 460 .keywords: TS, compute 461 462 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 463 @*/ 464 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U) 465 { 466 PetscErrorCode ierr; 467 TSSolutionFunction solutionfunction; 468 void *ctx; 469 DM dm; 470 471 PetscFunctionBegin; 472 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 473 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 474 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 475 ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr); 476 477 if (solutionfunction) { 478 PetscStackPush("TS user solution function"); 479 ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr); 480 PetscStackPop; 481 } 482 PetscFunctionReturn(0); 483 } 484 #undef __FUNCT__ 485 #define __FUNCT__ "TSComputeForcingFunction" 486 /*@ 487 TSComputeForcingFunction - Evaluates the forcing function. 488 489 Collective on TS and Vec 490 491 Input Parameters: 492 + ts - the TS context 493 - t - current time 494 495 Output Parameter: 496 . U - the function value 497 498 Note: 499 Most users should not need to explicitly call this routine, as it 500 is used internally within the nonlinear solvers. 501 502 Level: developer 503 504 .keywords: TS, compute 505 506 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 507 @*/ 508 PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U) 509 { 510 PetscErrorCode ierr, (*forcing)(TS,PetscReal,Vec,void*); 511 void *ctx; 512 DM dm; 513 514 PetscFunctionBegin; 515 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 516 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 517 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 518 ierr = DMTSGetForcingFunction(dm,&forcing,&ctx);CHKERRQ(ierr); 519 520 if (forcing) { 521 PetscStackPush("TS user forcing function"); 522 ierr = (*forcing)(ts,t,U,ctx);CHKERRQ(ierr); 523 PetscStackPop; 524 } 525 PetscFunctionReturn(0); 526 } 527 528 #undef __FUNCT__ 529 #define __FUNCT__ "TSGetRHSVec_Private" 530 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 531 { 532 Vec F; 533 PetscErrorCode ierr; 534 535 PetscFunctionBegin; 536 *Frhs = NULL; 537 ierr = TSGetIFunction(ts,&F,NULL,NULL);CHKERRQ(ierr); 538 if (!ts->Frhs) { 539 ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr); 540 } 541 *Frhs = ts->Frhs; 542 PetscFunctionReturn(0); 543 } 544 545 #undef __FUNCT__ 546 #define __FUNCT__ "TSGetRHSMats_Private" 547 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 548 { 549 Mat A,B; 550 PetscErrorCode ierr; 551 552 PetscFunctionBegin; 553 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 554 if (Arhs) { 555 if (!ts->Arhs) { 556 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 557 } 558 *Arhs = ts->Arhs; 559 } 560 if (Brhs) { 561 if (!ts->Brhs) { 562 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 563 } 564 *Brhs = ts->Brhs; 565 } 566 PetscFunctionReturn(0); 567 } 568 569 #undef __FUNCT__ 570 #define __FUNCT__ "TSComputeIFunction" 571 /*@ 572 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0 573 574 Collective on TS and Vec 575 576 Input Parameters: 577 + ts - the TS context 578 . t - current time 579 . U - state vector 580 . Udot - time derivative of state vector 581 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 582 583 Output Parameter: 584 . Y - right hand side 585 586 Note: 587 Most users should not need to explicitly call this routine, as it 588 is used internally within the nonlinear solvers. 589 590 If the user did did not write their equations in implicit form, this 591 function recasts them in implicit form. 592 593 Level: developer 594 595 .keywords: TS, compute 596 597 .seealso: TSSetIFunction(), TSComputeRHSFunction() 598 @*/ 599 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex) 600 { 601 PetscErrorCode ierr; 602 TSIFunction ifunction; 603 TSRHSFunction rhsfunction; 604 void *ctx; 605 DM dm; 606 607 PetscFunctionBegin; 608 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 609 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 610 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 611 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 612 613 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 614 ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr); 615 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 616 617 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 618 619 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 620 if (ifunction) { 621 PetscStackPush("TS user implicit function"); 622 ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr); 623 PetscStackPop; 624 } 625 if (imex) { 626 if (!ifunction) { 627 ierr = VecCopy(Udot,Y);CHKERRQ(ierr); 628 } 629 } else if (rhsfunction) { 630 if (ifunction) { 631 Vec Frhs; 632 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 633 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 634 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 635 } else { 636 ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr); 637 ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr); 638 } 639 } 640 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 641 PetscFunctionReturn(0); 642 } 643 644 #undef __FUNCT__ 645 #define __FUNCT__ "TSComputeIJacobian" 646 /*@ 647 TSComputeIJacobian - Evaluates the Jacobian of the DAE 648 649 Collective on TS and Vec 650 651 Input 652 Input Parameters: 653 + ts - the TS context 654 . t - current timestep 655 . U - state vector 656 . Udot - time derivative of state vector 657 . shift - shift to apply, see note below 658 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 659 660 Output Parameters: 661 + A - Jacobian matrix 662 . B - optional preconditioning matrix 663 - flag - flag indicating matrix structure 664 665 Notes: 666 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 667 668 dF/dU + shift*dF/dUdot 669 670 Most users should not need to explicitly call this routine, as it 671 is used internally within the nonlinear solvers. 672 673 Level: developer 674 675 .keywords: TS, compute, Jacobian, matrix 676 677 .seealso: TSSetIJacobian() 678 @*/ 679 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex) 680 { 681 PetscInt Ustate, Udotstate; 682 PetscErrorCode ierr; 683 TSIJacobian ijacobian; 684 TSRHSJacobian rhsjacobian; 685 DM dm; 686 void *ctx; 687 688 PetscFunctionBegin; 689 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 690 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 691 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 692 PetscValidPointer(A,6); 693 PetscValidHeaderSpecific(*A,MAT_CLASSID,6); 694 PetscValidPointer(B,7); 695 PetscValidHeaderSpecific(*B,MAT_CLASSID,7); 696 PetscValidPointer(flg,8); 697 698 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 699 ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr); 700 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 701 702 ierr = PetscObjectStateQuery((PetscObject)U,&Ustate);CHKERRQ(ierr); 703 ierr = PetscObjectStateQuery((PetscObject)Udot,&Udotstate);CHKERRQ(ierr); 704 if (ts->ijacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->ijacobian.X == U && ts->ijacobian.Xstate == Ustate && ts->ijacobian.Xdot == Udot && ts->ijacobian.Xdotstate == Udotstate && ts->ijacobian.imex == imex))) { 705 *flg = ts->ijacobian.mstructure; 706 ierr = MatScale(*A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 707 PetscFunctionReturn(0); 708 } 709 710 if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 711 712 *flg = SAME_NONZERO_PATTERN; /* In case we're solving a linear problem in which case it wouldn't get initialized below. */ 713 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr); 714 if (ijacobian) { 715 *flg = DIFFERENT_NONZERO_PATTERN; 716 PetscStackPush("TS user implicit Jacobian"); 717 ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,flg,ctx);CHKERRQ(ierr); 718 PetscStackPop; 719 /* make sure user returned a correct Jacobian and preconditioner */ 720 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 721 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 722 } 723 if (imex) { 724 if (!ijacobian) { /* system was written as Udot = G(t,U) */ 725 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 726 ierr = MatShift(*A,shift);CHKERRQ(ierr); 727 if (*A != *B) { 728 ierr = MatZeroEntries(*B);CHKERRQ(ierr); 729 ierr = MatShift(*B,shift);CHKERRQ(ierr); 730 } 731 *flg = SAME_PRECONDITIONER; 732 } 733 } else { 734 if (!ijacobian) { 735 ierr = TSComputeRHSJacobian(ts,t,U,A,B,flg);CHKERRQ(ierr); 736 ierr = MatScale(*A,-1);CHKERRQ(ierr); 737 ierr = MatShift(*A,shift);CHKERRQ(ierr); 738 if (*A != *B) { 739 ierr = MatScale(*B,-1);CHKERRQ(ierr); 740 ierr = MatShift(*B,shift);CHKERRQ(ierr); 741 } 742 } else if (rhsjacobian) { 743 Mat Arhs,Brhs; 744 MatStructure axpy,flg2 = DIFFERENT_NONZERO_PATTERN; 745 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 746 ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 747 axpy = (*flg == flg2) ? SAME_NONZERO_PATTERN : DIFFERENT_NONZERO_PATTERN; 748 ierr = MatAXPY(*A,-1,Arhs,axpy);CHKERRQ(ierr); 749 if (*A != *B) { 750 ierr = MatAXPY(*B,-1,Brhs,axpy);CHKERRQ(ierr); 751 } 752 *flg = PetscMin(*flg,flg2); 753 } 754 } 755 756 ts->ijacobian.time = t; 757 ts->ijacobian.X = U; 758 ts->ijacobian.Xdot = Udot; 759 760 ierr = PetscObjectStateQuery((PetscObject)U,&ts->ijacobian.Xstate);CHKERRQ(ierr); 761 ierr = PetscObjectStateQuery((PetscObject)Udot,&ts->ijacobian.Xdotstate);CHKERRQ(ierr); 762 763 ts->ijacobian.shift = shift; 764 ts->ijacobian.imex = imex; 765 ts->ijacobian.mstructure = *flg; 766 767 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr); 768 PetscFunctionReturn(0); 769 } 770 771 #undef __FUNCT__ 772 #define __FUNCT__ "TSSetRHSFunction" 773 /*@C 774 TSSetRHSFunction - Sets the routine for evaluating the function, 775 where U_t = G(t,u). 776 777 Logically Collective on TS 778 779 Input Parameters: 780 + ts - the TS context obtained from TSCreate() 781 . r - vector to put the computed right hand side (or NULL to have it created) 782 . f - routine for evaluating the right-hand-side function 783 - ctx - [optional] user-defined context for private data for the 784 function evaluation routine (may be NULL) 785 786 Calling sequence of func: 787 $ func (TS ts,PetscReal t,Vec u,Vec F,void *ctx); 788 789 + t - current timestep 790 . u - input vector 791 . F - function vector 792 - ctx - [optional] user-defined function context 793 794 Level: beginner 795 796 .keywords: TS, timestep, set, right-hand-side, function 797 798 .seealso: TSSetRHSJacobian(), TSSetIJacobian() 799 @*/ 800 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 801 { 802 PetscErrorCode ierr; 803 SNES snes; 804 Vec ralloc = NULL; 805 DM dm; 806 807 PetscFunctionBegin; 808 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 809 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 810 811 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 812 ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr); 813 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 814 if (!r && !ts->dm && ts->vec_sol) { 815 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 816 r = ralloc; 817 } 818 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 819 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 820 PetscFunctionReturn(0); 821 } 822 823 #undef __FUNCT__ 824 #define __FUNCT__ "TSSetSolutionFunction" 825 /*@C 826 TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE 827 828 Logically Collective on TS 829 830 Input Parameters: 831 + ts - the TS context obtained from TSCreate() 832 . f - routine for evaluating the solution 833 - ctx - [optional] user-defined context for private data for the 834 function evaluation routine (may be NULL) 835 836 Calling sequence of func: 837 $ func (TS ts,PetscReal t,Vec u,void *ctx); 838 839 + t - current timestep 840 . u - output vector 841 - ctx - [optional] user-defined function context 842 843 Notes: 844 This routine is used for testing accuracy of time integration schemes when you already know the solution. 845 If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to 846 create closed-form solutions with non-physical forcing terms. 847 848 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 849 850 Level: beginner 851 852 .keywords: TS, timestep, set, right-hand-side, function 853 854 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction() 855 @*/ 856 PetscErrorCode TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 857 { 858 PetscErrorCode ierr; 859 DM dm; 860 861 PetscFunctionBegin; 862 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 863 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 864 ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr); 865 PetscFunctionReturn(0); 866 } 867 868 #undef __FUNCT__ 869 #define __FUNCT__ "TSSetForcingFunction" 870 /*@C 871 TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE 872 873 Logically Collective on TS 874 875 Input Parameters: 876 + ts - the TS context obtained from TSCreate() 877 . f - routine for evaluating the forcing function 878 - ctx - [optional] user-defined context for private data for the 879 function evaluation routine (may be NULL) 880 881 Calling sequence of func: 882 $ func (TS ts,PetscReal t,Vec u,void *ctx); 883 884 + t - current timestep 885 . u - output vector 886 - ctx - [optional] user-defined function context 887 888 Notes: 889 This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to 890 create closed-form solutions with a non-physical forcing term. 891 892 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 893 894 Level: beginner 895 896 .keywords: TS, timestep, set, right-hand-side, function 897 898 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction() 899 @*/ 900 PetscErrorCode TSSetForcingFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 901 { 902 PetscErrorCode ierr; 903 DM dm; 904 905 PetscFunctionBegin; 906 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 907 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 908 ierr = DMTSSetForcingFunction(dm,f,ctx);CHKERRQ(ierr); 909 PetscFunctionReturn(0); 910 } 911 912 #undef __FUNCT__ 913 #define __FUNCT__ "TSSetRHSJacobian" 914 /*@C 915 TSSetRHSJacobian - Sets the function to compute the Jacobian of F, 916 where U_t = G(U,t), as well as the location to store the matrix. 917 918 Logically Collective on TS 919 920 Input Parameters: 921 + ts - the TS context obtained from TSCreate() 922 . A - Jacobian matrix 923 . B - preconditioner matrix (usually same as A) 924 . f - the Jacobian evaluation routine 925 - ctx - [optional] user-defined context for private data for the 926 Jacobian evaluation routine (may be NULL) 927 928 Calling sequence of func: 929 $ func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx); 930 931 + t - current timestep 932 . u - input vector 933 . A - matrix A, where U_t = A(t)u 934 . B - preconditioner matrix, usually the same as A 935 . flag - flag indicating information about the preconditioner matrix 936 structure (same as flag in KSPSetOperators()) 937 - ctx - [optional] user-defined context for matrix evaluation routine 938 939 Notes: 940 See KSPSetOperators() for important information about setting the flag 941 output parameter in the routine func(). Be sure to read this information! 942 943 The routine func() takes Mat * as the matrix arguments rather than Mat. 944 This allows the matrix evaluation routine to replace A and/or B with a 945 completely new matrix structure (not just different matrix elements) 946 when appropriate, for instance, if the nonzero structure is changing 947 throughout the global iterations. 948 949 Level: beginner 950 951 .keywords: TS, timestep, set, right-hand-side, Jacobian 952 953 .seealso: SNESDefaultComputeJacobianColor(), TSSetRHSFunction() 954 955 @*/ 956 PetscErrorCode TSSetRHSJacobian(TS ts,Mat A,Mat B,TSRHSJacobian f,void *ctx) 957 { 958 PetscErrorCode ierr; 959 SNES snes; 960 DM dm; 961 TSIJacobian ijacobian; 962 963 PetscFunctionBegin; 964 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 965 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 966 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 967 if (A) PetscCheckSameComm(ts,1,A,2); 968 if (B) PetscCheckSameComm(ts,1,B,3); 969 970 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 971 ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr); 972 ierr = DMTSGetIJacobian(dm,&ijacobian,NULL);CHKERRQ(ierr); 973 974 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 975 if (!ijacobian) { 976 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 977 } 978 if (A) { 979 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 980 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 981 982 ts->Arhs = A; 983 } 984 if (B) { 985 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 986 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 987 988 ts->Brhs = B; 989 } 990 PetscFunctionReturn(0); 991 } 992 993 994 #undef __FUNCT__ 995 #define __FUNCT__ "TSSetIFunction" 996 /*@C 997 TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved. 998 999 Logically Collective on TS 1000 1001 Input Parameters: 1002 + ts - the TS context obtained from TSCreate() 1003 . r - vector to hold the residual (or NULL to have it created internally) 1004 . f - the function evaluation routine 1005 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1006 1007 Calling sequence of f: 1008 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 1009 1010 + t - time at step/stage being solved 1011 . u - state vector 1012 . u_t - time derivative of state vector 1013 . F - function vector 1014 - ctx - [optional] user-defined context for matrix evaluation routine 1015 1016 Important: 1017 The user MUST call either this routine, TSSetRHSFunction(). This routine must be used when not solving an ODE, for example a DAE. 1018 1019 Level: beginner 1020 1021 .keywords: TS, timestep, set, DAE, Jacobian 1022 1023 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian() 1024 @*/ 1025 PetscErrorCode TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx) 1026 { 1027 PetscErrorCode ierr; 1028 SNES snes; 1029 Vec resalloc = NULL; 1030 DM dm; 1031 1032 PetscFunctionBegin; 1033 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1034 if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2); 1035 1036 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1037 ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr); 1038 1039 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1040 if (!res && !ts->dm && ts->vec_sol) { 1041 ierr = VecDuplicate(ts->vec_sol,&resalloc);CHKERRQ(ierr); 1042 res = resalloc; 1043 } 1044 ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr); 1045 ierr = VecDestroy(&resalloc);CHKERRQ(ierr); 1046 PetscFunctionReturn(0); 1047 } 1048 1049 #undef __FUNCT__ 1050 #define __FUNCT__ "TSGetIFunction" 1051 /*@C 1052 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1053 1054 Not Collective 1055 1056 Input Parameter: 1057 . ts - the TS context 1058 1059 Output Parameter: 1060 + r - vector to hold residual (or NULL) 1061 . func - the function to compute residual (or NULL) 1062 - ctx - the function context (or NULL) 1063 1064 Level: advanced 1065 1066 .keywords: TS, nonlinear, get, function 1067 1068 .seealso: TSSetIFunction(), SNESGetFunction() 1069 @*/ 1070 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 1071 { 1072 PetscErrorCode ierr; 1073 SNES snes; 1074 DM dm; 1075 1076 PetscFunctionBegin; 1077 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1078 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1079 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1080 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1081 ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr); 1082 PetscFunctionReturn(0); 1083 } 1084 1085 #undef __FUNCT__ 1086 #define __FUNCT__ "TSGetRHSFunction" 1087 /*@C 1088 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 1089 1090 Not Collective 1091 1092 Input Parameter: 1093 . ts - the TS context 1094 1095 Output Parameter: 1096 + r - vector to hold computed right hand side (or NULL) 1097 . func - the function to compute right hand side (or NULL) 1098 - ctx - the function context (or NULL) 1099 1100 Level: advanced 1101 1102 .keywords: TS, nonlinear, get, function 1103 1104 .seealso: TSSetRhsfunction(), SNESGetFunction() 1105 @*/ 1106 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 1107 { 1108 PetscErrorCode ierr; 1109 SNES snes; 1110 DM dm; 1111 1112 PetscFunctionBegin; 1113 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1114 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1115 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1116 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1117 ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr); 1118 PetscFunctionReturn(0); 1119 } 1120 1121 #undef __FUNCT__ 1122 #define __FUNCT__ "TSSetIJacobian" 1123 /*@C 1124 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 1125 you provided with TSSetIFunction(). 1126 1127 Logically Collective on TS 1128 1129 Input Parameters: 1130 + ts - the TS context obtained from TSCreate() 1131 . A - Jacobian matrix 1132 . B - preconditioning matrix for A (may be same as A) 1133 . f - the Jacobian evaluation routine 1134 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1135 1136 Calling sequence of f: 1137 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx); 1138 1139 + t - time at step/stage being solved 1140 . U - state vector 1141 . U_t - time derivative of state vector 1142 . a - shift 1143 . A - Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 1144 . B - preconditioning matrix for A, may be same as A 1145 . flag - flag indicating information about the preconditioner matrix 1146 structure (same as flag in KSPSetOperators()) 1147 - ctx - [optional] user-defined context for matrix evaluation routine 1148 1149 Notes: 1150 The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve. 1151 1152 The matrix dF/dU + a*dF/dU_t you provide turns out to be 1153 the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 1154 The time integrator internally approximates U_t by W+a*U where the positive "shift" 1155 a and vector W depend on the integration method, step size, and past states. For example with 1156 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 1157 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 1158 1159 Level: beginner 1160 1161 .keywords: TS, timestep, DAE, Jacobian 1162 1163 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESDefaultComputeJacobianColor(), SNESDefaultComputeJacobian() 1164 1165 @*/ 1166 PetscErrorCode TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx) 1167 { 1168 PetscErrorCode ierr; 1169 SNES snes; 1170 DM dm; 1171 1172 PetscFunctionBegin; 1173 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1174 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 1175 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1176 if (A) PetscCheckSameComm(ts,1,A,2); 1177 if (B) PetscCheckSameComm(ts,1,B,3); 1178 1179 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1180 ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr); 1181 1182 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1183 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1184 PetscFunctionReturn(0); 1185 } 1186 1187 #undef __FUNCT__ 1188 #define __FUNCT__ "TSLoad" 1189 /*@C 1190 TSLoad - Loads a KSP that has been stored in binary with KSPView(). 1191 1192 Collective on PetscViewer 1193 1194 Input Parameters: 1195 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or 1196 some related function before a call to TSLoad(). 1197 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 1198 1199 Level: intermediate 1200 1201 Notes: 1202 The type is determined by the data in the file, any type set into the TS before this call is ignored. 1203 1204 Notes for advanced users: 1205 Most users should not need to know the details of the binary storage 1206 format, since TSLoad() and TSView() completely hide these details. 1207 But for anyone who's interested, the standard binary matrix storage 1208 format is 1209 .vb 1210 has not yet been determined 1211 .ve 1212 1213 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad() 1214 @*/ 1215 PetscErrorCode TSLoad(TS ts, PetscViewer viewer) 1216 { 1217 PetscErrorCode ierr; 1218 PetscBool isbinary; 1219 PetscInt classid; 1220 char type[256]; 1221 DMTS sdm; 1222 DM dm; 1223 1224 PetscFunctionBegin; 1225 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1226 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1227 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1228 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 1229 1230 ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 1231 if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file"); 1232 ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr); 1233 ierr = TSSetType(ts, type);CHKERRQ(ierr); 1234 if (ts->ops->load) { 1235 ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr); 1236 } 1237 ierr = DMCreate(PetscObjectComm((PetscObject)ts),&dm);CHKERRQ(ierr); 1238 ierr = DMLoad(dm,viewer);CHKERRQ(ierr); 1239 ierr = TSSetDM(ts,dm);CHKERRQ(ierr); 1240 ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr); 1241 ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr); 1242 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1243 ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr); 1244 PetscFunctionReturn(0); 1245 } 1246 1247 #include <petscdraw.h> 1248 #undef __FUNCT__ 1249 #define __FUNCT__ "TSView" 1250 /*@C 1251 TSView - Prints the TS data structure. 1252 1253 Collective on TS 1254 1255 Input Parameters: 1256 + ts - the TS context obtained from TSCreate() 1257 - viewer - visualization context 1258 1259 Options Database Key: 1260 . -ts_view - calls TSView() at end of TSStep() 1261 1262 Notes: 1263 The available visualization contexts include 1264 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 1265 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 1266 output where only the first processor opens 1267 the file. All other processors send their 1268 data to the first processor to print. 1269 1270 The user can open an alternative visualization context with 1271 PetscViewerASCIIOpen() - output to a specified file. 1272 1273 Level: beginner 1274 1275 .keywords: TS, timestep, view 1276 1277 .seealso: PetscViewerASCIIOpen() 1278 @*/ 1279 PetscErrorCode TSView(TS ts,PetscViewer viewer) 1280 { 1281 PetscErrorCode ierr; 1282 TSType type; 1283 PetscBool iascii,isstring,isundials,isbinary,isdraw; 1284 DMTS sdm; 1285 1286 PetscFunctionBegin; 1287 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1288 if (!viewer) { 1289 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr); 1290 } 1291 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1292 PetscCheckSameComm(ts,1,viewer,2); 1293 1294 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1295 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1296 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1297 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1298 if (iascii) { 1299 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr); 1300 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 1301 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%G\n",ts->max_time);CHKERRQ(ierr); 1302 if (ts->problem_type == TS_NONLINEAR) { 1303 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr); 1304 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr); 1305 } 1306 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr); 1307 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 1308 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1309 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1310 if (ts->ops->view) { 1311 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1312 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1313 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1314 } 1315 } else if (isstring) { 1316 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 1317 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 1318 } else if (isbinary) { 1319 PetscInt classid = TS_FILE_CLASSID; 1320 MPI_Comm comm; 1321 PetscMPIInt rank; 1322 char type[256]; 1323 1324 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 1325 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 1326 if (!rank) { 1327 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 1328 ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr); 1329 ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 1330 } 1331 if (ts->ops->view) { 1332 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1333 } 1334 ierr = DMView(ts->dm,viewer);CHKERRQ(ierr); 1335 ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr); 1336 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1337 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1338 } else if (isdraw) { 1339 PetscDraw draw; 1340 char str[36]; 1341 PetscReal x,y,bottom,h; 1342 1343 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1344 ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 1345 ierr = PetscStrcpy(str,"TS: ");CHKERRQ(ierr); 1346 ierr = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr); 1347 ierr = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 1348 bottom = y - h; 1349 ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 1350 if (ts->ops->view) { 1351 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1352 } 1353 ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 1354 } 1355 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1356 ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 1357 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1358 PetscFunctionReturn(0); 1359 } 1360 1361 1362 #undef __FUNCT__ 1363 #define __FUNCT__ "TSSetApplicationContext" 1364 /*@ 1365 TSSetApplicationContext - Sets an optional user-defined context for 1366 the timesteppers. 1367 1368 Logically Collective on TS 1369 1370 Input Parameters: 1371 + ts - the TS context obtained from TSCreate() 1372 - usrP - optional user context 1373 1374 Level: intermediate 1375 1376 .keywords: TS, timestep, set, application, context 1377 1378 .seealso: TSGetApplicationContext() 1379 @*/ 1380 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 1381 { 1382 PetscFunctionBegin; 1383 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1384 ts->user = usrP; 1385 PetscFunctionReturn(0); 1386 } 1387 1388 #undef __FUNCT__ 1389 #define __FUNCT__ "TSGetApplicationContext" 1390 /*@ 1391 TSGetApplicationContext - Gets the user-defined context for the 1392 timestepper. 1393 1394 Not Collective 1395 1396 Input Parameter: 1397 . ts - the TS context obtained from TSCreate() 1398 1399 Output Parameter: 1400 . usrP - user context 1401 1402 Level: intermediate 1403 1404 .keywords: TS, timestep, get, application, context 1405 1406 .seealso: TSSetApplicationContext() 1407 @*/ 1408 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 1409 { 1410 PetscFunctionBegin; 1411 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1412 *(void**)usrP = ts->user; 1413 PetscFunctionReturn(0); 1414 } 1415 1416 #undef __FUNCT__ 1417 #define __FUNCT__ "TSGetTimeStepNumber" 1418 /*@ 1419 TSGetTimeStepNumber - Gets the number of time steps completed. 1420 1421 Not Collective 1422 1423 Input Parameter: 1424 . ts - the TS context obtained from TSCreate() 1425 1426 Output Parameter: 1427 . iter - number of steps completed so far 1428 1429 Level: intermediate 1430 1431 .keywords: TS, timestep, get, iteration, number 1432 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStep() 1433 @*/ 1434 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *iter) 1435 { 1436 PetscFunctionBegin; 1437 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1438 PetscValidIntPointer(iter,2); 1439 *iter = ts->steps; 1440 PetscFunctionReturn(0); 1441 } 1442 1443 #undef __FUNCT__ 1444 #define __FUNCT__ "TSSetInitialTimeStep" 1445 /*@ 1446 TSSetInitialTimeStep - Sets the initial timestep to be used, 1447 as well as the initial time. 1448 1449 Logically Collective on TS 1450 1451 Input Parameters: 1452 + ts - the TS context obtained from TSCreate() 1453 . initial_time - the initial time 1454 - time_step - the size of the timestep 1455 1456 Level: intermediate 1457 1458 .seealso: TSSetTimeStep(), TSGetTimeStep() 1459 1460 .keywords: TS, set, initial, timestep 1461 @*/ 1462 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 1463 { 1464 PetscErrorCode ierr; 1465 1466 PetscFunctionBegin; 1467 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1468 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 1469 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 1470 PetscFunctionReturn(0); 1471 } 1472 1473 #undef __FUNCT__ 1474 #define __FUNCT__ "TSSetTimeStep" 1475 /*@ 1476 TSSetTimeStep - Allows one to reset the timestep at any time, 1477 useful for simple pseudo-timestepping codes. 1478 1479 Logically Collective on TS 1480 1481 Input Parameters: 1482 + ts - the TS context obtained from TSCreate() 1483 - time_step - the size of the timestep 1484 1485 Level: intermediate 1486 1487 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1488 1489 .keywords: TS, set, timestep 1490 @*/ 1491 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 1492 { 1493 PetscFunctionBegin; 1494 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1495 PetscValidLogicalCollectiveReal(ts,time_step,2); 1496 ts->time_step = time_step; 1497 ts->time_step_orig = time_step; 1498 PetscFunctionReturn(0); 1499 } 1500 1501 #undef __FUNCT__ 1502 #define __FUNCT__ "TSSetExactFinalTime" 1503 /*@ 1504 TSSetExactFinalTime - Determines whether to adapt the final time step to 1505 match the exact final time, interpolate solution to the exact final time, 1506 or just return at the final time TS computed. 1507 1508 Logically Collective on TS 1509 1510 Input Parameter: 1511 + ts - the time-step context 1512 - eftopt - exact final time option 1513 1514 Level: beginner 1515 1516 .seealso: TSExactFinalTimeOption 1517 @*/ 1518 PetscErrorCode TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt) 1519 { 1520 PetscFunctionBegin; 1521 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1522 PetscValidLogicalCollectiveEnum(ts,eftopt,2); 1523 ts->exact_final_time = eftopt; 1524 PetscFunctionReturn(0); 1525 } 1526 1527 #undef __FUNCT__ 1528 #define __FUNCT__ "TSGetTimeStep" 1529 /*@ 1530 TSGetTimeStep - Gets the current timestep size. 1531 1532 Not Collective 1533 1534 Input Parameter: 1535 . ts - the TS context obtained from TSCreate() 1536 1537 Output Parameter: 1538 . dt - the current timestep size 1539 1540 Level: intermediate 1541 1542 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1543 1544 .keywords: TS, get, timestep 1545 @*/ 1546 PetscErrorCode TSGetTimeStep(TS ts,PetscReal *dt) 1547 { 1548 PetscFunctionBegin; 1549 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1550 PetscValidRealPointer(dt,2); 1551 *dt = ts->time_step; 1552 PetscFunctionReturn(0); 1553 } 1554 1555 #undef __FUNCT__ 1556 #define __FUNCT__ "TSGetSolution" 1557 /*@ 1558 TSGetSolution - Returns the solution at the present timestep. It 1559 is valid to call this routine inside the function that you are evaluating 1560 in order to move to the new timestep. This vector not changed until 1561 the solution at the next timestep has been calculated. 1562 1563 Not Collective, but Vec returned is parallel if TS is parallel 1564 1565 Input Parameter: 1566 . ts - the TS context obtained from TSCreate() 1567 1568 Output Parameter: 1569 . v - the vector containing the solution 1570 1571 Level: intermediate 1572 1573 .seealso: TSGetTimeStep() 1574 1575 .keywords: TS, timestep, get, solution 1576 @*/ 1577 PetscErrorCode TSGetSolution(TS ts,Vec *v) 1578 { 1579 PetscFunctionBegin; 1580 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1581 PetscValidPointer(v,2); 1582 *v = ts->vec_sol; 1583 PetscFunctionReturn(0); 1584 } 1585 1586 /* ----- Routines to initialize and destroy a timestepper ---- */ 1587 #undef __FUNCT__ 1588 #define __FUNCT__ "TSSetProblemType" 1589 /*@ 1590 TSSetProblemType - Sets the type of problem to be solved. 1591 1592 Not collective 1593 1594 Input Parameters: 1595 + ts - The TS 1596 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1597 .vb 1598 U_t - A U = 0 (linear) 1599 U_t - A(t) U = 0 (linear) 1600 F(t,U,U_t) = 0 (nonlinear) 1601 .ve 1602 1603 Level: beginner 1604 1605 .keywords: TS, problem type 1606 .seealso: TSSetUp(), TSProblemType, TS 1607 @*/ 1608 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 1609 { 1610 PetscErrorCode ierr; 1611 1612 PetscFunctionBegin; 1613 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1614 ts->problem_type = type; 1615 if (type == TS_LINEAR) { 1616 SNES snes; 1617 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1618 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 1619 } 1620 PetscFunctionReturn(0); 1621 } 1622 1623 #undef __FUNCT__ 1624 #define __FUNCT__ "TSGetProblemType" 1625 /*@C 1626 TSGetProblemType - Gets the type of problem to be solved. 1627 1628 Not collective 1629 1630 Input Parameter: 1631 . ts - The TS 1632 1633 Output Parameter: 1634 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1635 .vb 1636 M U_t = A U 1637 M(t) U_t = A(t) U 1638 F(t,U,U_t) 1639 .ve 1640 1641 Level: beginner 1642 1643 .keywords: TS, problem type 1644 .seealso: TSSetUp(), TSProblemType, TS 1645 @*/ 1646 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 1647 { 1648 PetscFunctionBegin; 1649 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1650 PetscValidIntPointer(type,2); 1651 *type = ts->problem_type; 1652 PetscFunctionReturn(0); 1653 } 1654 1655 #undef __FUNCT__ 1656 #define __FUNCT__ "TSSetUp" 1657 /*@ 1658 TSSetUp - Sets up the internal data structures for the later use 1659 of a timestepper. 1660 1661 Collective on TS 1662 1663 Input Parameter: 1664 . ts - the TS context obtained from TSCreate() 1665 1666 Notes: 1667 For basic use of the TS solvers the user need not explicitly call 1668 TSSetUp(), since these actions will automatically occur during 1669 the call to TSStep(). However, if one wishes to control this 1670 phase separately, TSSetUp() should be called after TSCreate() 1671 and optional routines of the form TSSetXXX(), but before TSStep(). 1672 1673 Level: advanced 1674 1675 .keywords: TS, timestep, setup 1676 1677 .seealso: TSCreate(), TSStep(), TSDestroy() 1678 @*/ 1679 PetscErrorCode TSSetUp(TS ts) 1680 { 1681 PetscErrorCode ierr; 1682 DM dm; 1683 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 1684 PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 1685 TSIJacobian ijac; 1686 TSRHSJacobian rhsjac; 1687 1688 PetscFunctionBegin; 1689 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1690 if (ts->setupcalled) PetscFunctionReturn(0); 1691 1692 if (!((PetscObject)ts)->type_name) { 1693 ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); 1694 } 1695 1696 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 1697 1698 ierr = TSGetTSAdapt(ts,&ts->adapt);CHKERRQ(ierr); 1699 1700 if (ts->ops->setup) { 1701 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 1702 } 1703 1704 /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction 1705 to be set right but can't do it elsewhere due to the overreliance on ctx=ts. 1706 */ 1707 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1708 ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr); 1709 if (!func) { 1710 ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr); 1711 } 1712 /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it. 1713 Otherwise, the SNES will use coloring internally to form the Jacobian. 1714 */ 1715 ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr); 1716 ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr); 1717 ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr); 1718 if (!jac && (ijac || rhsjac)) { 1719 ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1720 } 1721 ts->setupcalled = PETSC_TRUE; 1722 PetscFunctionReturn(0); 1723 } 1724 1725 #undef __FUNCT__ 1726 #define __FUNCT__ "TSReset" 1727 /*@ 1728 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 1729 1730 Collective on TS 1731 1732 Input Parameter: 1733 . ts - the TS context obtained from TSCreate() 1734 1735 Level: beginner 1736 1737 .keywords: TS, timestep, reset 1738 1739 .seealso: TSCreate(), TSSetup(), TSDestroy() 1740 @*/ 1741 PetscErrorCode TSReset(TS ts) 1742 { 1743 PetscErrorCode ierr; 1744 1745 PetscFunctionBegin; 1746 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1747 if (ts->ops->reset) { 1748 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 1749 } 1750 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 1751 1752 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1753 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1754 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 1755 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1756 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 1757 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 1758 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 1759 1760 ts->setupcalled = PETSC_FALSE; 1761 PetscFunctionReturn(0); 1762 } 1763 1764 #undef __FUNCT__ 1765 #define __FUNCT__ "TSDestroy" 1766 /*@ 1767 TSDestroy - Destroys the timestepper context that was created 1768 with TSCreate(). 1769 1770 Collective on TS 1771 1772 Input Parameter: 1773 . ts - the TS context obtained from TSCreate() 1774 1775 Level: beginner 1776 1777 .keywords: TS, timestepper, destroy 1778 1779 .seealso: TSCreate(), TSSetUp(), TSSolve() 1780 @*/ 1781 PetscErrorCode TSDestroy(TS *ts) 1782 { 1783 PetscErrorCode ierr; 1784 1785 PetscFunctionBegin; 1786 if (!*ts) PetscFunctionReturn(0); 1787 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 1788 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 1789 1790 ierr = TSReset((*ts));CHKERRQ(ierr); 1791 1792 /* if memory was published with AMS then destroy it */ 1793 ierr = PetscObjectDepublish((*ts));CHKERRQ(ierr); 1794 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 1795 1796 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 1797 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 1798 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 1799 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 1800 1801 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 1802 PetscFunctionReturn(0); 1803 } 1804 1805 #undef __FUNCT__ 1806 #define __FUNCT__ "TSGetSNES" 1807 /*@ 1808 TSGetSNES - Returns the SNES (nonlinear solver) associated with 1809 a TS (timestepper) context. Valid only for nonlinear problems. 1810 1811 Not Collective, but SNES is parallel if TS is parallel 1812 1813 Input Parameter: 1814 . ts - the TS context obtained from TSCreate() 1815 1816 Output Parameter: 1817 . snes - the nonlinear solver context 1818 1819 Notes: 1820 The user can then directly manipulate the SNES context to set various 1821 options, etc. Likewise, the user can then extract and manipulate the 1822 KSP, KSP, and PC contexts as well. 1823 1824 TSGetSNES() does not work for integrators that do not use SNES; in 1825 this case TSGetSNES() returns NULL in snes. 1826 1827 Level: beginner 1828 1829 .keywords: timestep, get, SNES 1830 @*/ 1831 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 1832 { 1833 PetscErrorCode ierr; 1834 1835 PetscFunctionBegin; 1836 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1837 PetscValidPointer(snes,2); 1838 if (!ts->snes) { 1839 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 1840 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 1841 ierr = PetscLogObjectParent(ts,ts->snes);CHKERRQ(ierr); 1842 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 1843 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 1844 if (ts->problem_type == TS_LINEAR) { 1845 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 1846 } 1847 } 1848 *snes = ts->snes; 1849 PetscFunctionReturn(0); 1850 } 1851 1852 #undef __FUNCT__ 1853 #define __FUNCT__ "TSSetSNES" 1854 /*@ 1855 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 1856 1857 Collective 1858 1859 Input Parameter: 1860 + ts - the TS context obtained from TSCreate() 1861 - snes - the nonlinear solver context 1862 1863 Notes: 1864 Most users should have the TS created by calling TSGetSNES() 1865 1866 Level: developer 1867 1868 .keywords: timestep, set, SNES 1869 @*/ 1870 PetscErrorCode TSSetSNES(TS ts,SNES snes) 1871 { 1872 PetscErrorCode ierr; 1873 PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 1874 1875 PetscFunctionBegin; 1876 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1877 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 1878 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 1879 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 1880 1881 ts->snes = snes; 1882 1883 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 1884 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 1885 if (func == SNESTSFormJacobian) { 1886 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1887 } 1888 PetscFunctionReturn(0); 1889 } 1890 1891 #undef __FUNCT__ 1892 #define __FUNCT__ "TSGetKSP" 1893 /*@ 1894 TSGetKSP - Returns the KSP (linear solver) associated with 1895 a TS (timestepper) context. 1896 1897 Not Collective, but KSP is parallel if TS is parallel 1898 1899 Input Parameter: 1900 . ts - the TS context obtained from TSCreate() 1901 1902 Output Parameter: 1903 . ksp - the nonlinear solver context 1904 1905 Notes: 1906 The user can then directly manipulate the KSP context to set various 1907 options, etc. Likewise, the user can then extract and manipulate the 1908 KSP and PC contexts as well. 1909 1910 TSGetKSP() does not work for integrators that do not use KSP; 1911 in this case TSGetKSP() returns NULL in ksp. 1912 1913 Level: beginner 1914 1915 .keywords: timestep, get, KSP 1916 @*/ 1917 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 1918 { 1919 PetscErrorCode ierr; 1920 SNES snes; 1921 1922 PetscFunctionBegin; 1923 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1924 PetscValidPointer(ksp,2); 1925 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 1926 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 1927 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1928 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 1929 PetscFunctionReturn(0); 1930 } 1931 1932 /* ----------- Routines to set solver parameters ---------- */ 1933 1934 #undef __FUNCT__ 1935 #define __FUNCT__ "TSGetDuration" 1936 /*@ 1937 TSGetDuration - Gets the maximum number of timesteps to use and 1938 maximum time for iteration. 1939 1940 Not Collective 1941 1942 Input Parameters: 1943 + ts - the TS context obtained from TSCreate() 1944 . maxsteps - maximum number of iterations to use, or NULL 1945 - maxtime - final time to iterate to, or NULL 1946 1947 Level: intermediate 1948 1949 .keywords: TS, timestep, get, maximum, iterations, time 1950 @*/ 1951 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 1952 { 1953 PetscFunctionBegin; 1954 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1955 if (maxsteps) { 1956 PetscValidIntPointer(maxsteps,2); 1957 *maxsteps = ts->max_steps; 1958 } 1959 if (maxtime) { 1960 PetscValidScalarPointer(maxtime,3); 1961 *maxtime = ts->max_time; 1962 } 1963 PetscFunctionReturn(0); 1964 } 1965 1966 #undef __FUNCT__ 1967 #define __FUNCT__ "TSSetDuration" 1968 /*@ 1969 TSSetDuration - Sets the maximum number of timesteps to use and 1970 maximum time for iteration. 1971 1972 Logically Collective on TS 1973 1974 Input Parameters: 1975 + ts - the TS context obtained from TSCreate() 1976 . maxsteps - maximum number of iterations to use 1977 - maxtime - final time to iterate to 1978 1979 Options Database Keys: 1980 . -ts_max_steps <maxsteps> - Sets maxsteps 1981 . -ts_final_time <maxtime> - Sets maxtime 1982 1983 Notes: 1984 The default maximum number of iterations is 5000. Default time is 5.0 1985 1986 Level: intermediate 1987 1988 .keywords: TS, timestep, set, maximum, iterations 1989 1990 .seealso: TSSetExactFinalTime() 1991 @*/ 1992 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 1993 { 1994 PetscFunctionBegin; 1995 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1996 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 1997 PetscValidLogicalCollectiveReal(ts,maxtime,2); 1998 if (maxsteps >= 0) ts->max_steps = maxsteps; 1999 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 2000 PetscFunctionReturn(0); 2001 } 2002 2003 #undef __FUNCT__ 2004 #define __FUNCT__ "TSSetSolution" 2005 /*@ 2006 TSSetSolution - Sets the initial solution vector 2007 for use by the TS routines. 2008 2009 Logically Collective on TS and Vec 2010 2011 Input Parameters: 2012 + ts - the TS context obtained from TSCreate() 2013 - u - the solution vector 2014 2015 Level: beginner 2016 2017 .keywords: TS, timestep, set, solution, initial conditions 2018 @*/ 2019 PetscErrorCode TSSetSolution(TS ts,Vec u) 2020 { 2021 PetscErrorCode ierr; 2022 DM dm; 2023 2024 PetscFunctionBegin; 2025 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2026 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2027 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 2028 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2029 2030 ts->vec_sol = u; 2031 2032 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2033 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 2034 PetscFunctionReturn(0); 2035 } 2036 2037 #undef __FUNCT__ 2038 #define __FUNCT__ "TSSetPreStep" 2039 /*@C 2040 TSSetPreStep - Sets the general-purpose function 2041 called once at the beginning of each time step. 2042 2043 Logically Collective on TS 2044 2045 Input Parameters: 2046 + ts - The TS context obtained from TSCreate() 2047 - func - The function 2048 2049 Calling sequence of func: 2050 . func (TS ts); 2051 2052 Level: intermediate 2053 2054 Note: 2055 If a step is rejected, TSStep() will call this routine again before each attempt. 2056 The last completed time step number can be queried using TSGetTimeStepNumber(), the 2057 size of the step being attempted can be obtained using TSGetTimeStep(). 2058 2059 .keywords: TS, timestep 2060 .seealso: TSSetPreStage(), TSSetPostStep(), TSStep() 2061 @*/ 2062 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 2063 { 2064 PetscFunctionBegin; 2065 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2066 ts->ops->prestep = func; 2067 PetscFunctionReturn(0); 2068 } 2069 2070 #undef __FUNCT__ 2071 #define __FUNCT__ "TSPreStep" 2072 /*@ 2073 TSPreStep - Runs the user-defined pre-step function. 2074 2075 Collective on TS 2076 2077 Input Parameters: 2078 . ts - The TS context obtained from TSCreate() 2079 2080 Notes: 2081 TSPreStep() is typically used within time stepping implementations, 2082 so most users would not generally call this routine themselves. 2083 2084 Level: developer 2085 2086 .keywords: TS, timestep 2087 .seealso: TSSetPreStep(), TSPreStage(), TSPostStep() 2088 @*/ 2089 PetscErrorCode TSPreStep(TS ts) 2090 { 2091 PetscErrorCode ierr; 2092 2093 PetscFunctionBegin; 2094 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2095 if (ts->ops->prestep) { 2096 PetscStackPush("TS PreStep function"); 2097 ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr); 2098 PetscStackPop; 2099 } 2100 PetscFunctionReturn(0); 2101 } 2102 2103 #undef __FUNCT__ 2104 #define __FUNCT__ "TSSetPreStage" 2105 /*@C 2106 TSSetPreStage - Sets the general-purpose function 2107 called once at the beginning of each stage. 2108 2109 Logically Collective on TS 2110 2111 Input Parameters: 2112 + ts - The TS context obtained from TSCreate() 2113 - func - The function 2114 2115 Calling sequence of func: 2116 . PetscErrorCode func(TS ts, PetscReal stagetime); 2117 2118 Level: intermediate 2119 2120 Note: 2121 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 2122 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 2123 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 2124 2125 .keywords: TS, timestep 2126 .seealso: TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 2127 @*/ 2128 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 2129 { 2130 PetscFunctionBegin; 2131 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2132 ts->ops->prestage = func; 2133 PetscFunctionReturn(0); 2134 } 2135 2136 #undef __FUNCT__ 2137 #define __FUNCT__ "TSPreStage" 2138 /*@ 2139 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 2140 2141 Collective on TS 2142 2143 Input Parameters: 2144 . ts - The TS context obtained from TSCreate() 2145 2146 Notes: 2147 TSPreStage() is typically used within time stepping implementations, 2148 most users would not generally call this routine themselves. 2149 2150 Level: developer 2151 2152 .keywords: TS, timestep 2153 .seealso: TSSetPreStep(), TSPreStep(), TSPostStep() 2154 @*/ 2155 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 2156 { 2157 PetscErrorCode ierr; 2158 2159 PetscFunctionBegin; 2160 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2161 if (ts->ops->prestage) { 2162 PetscStackPush("TS PreStage function"); 2163 ierr = (*ts->ops->prestage)(ts,stagetime);CHKERRQ(ierr); 2164 PetscStackPop; 2165 } 2166 PetscFunctionReturn(0); 2167 } 2168 2169 #undef __FUNCT__ 2170 #define __FUNCT__ "TSSetPostStep" 2171 /*@C 2172 TSSetPostStep - Sets the general-purpose function 2173 called once at the end of each time step. 2174 2175 Logically Collective on TS 2176 2177 Input Parameters: 2178 + ts - The TS context obtained from TSCreate() 2179 - func - The function 2180 2181 Calling sequence of func: 2182 $ func (TS ts); 2183 2184 Level: intermediate 2185 2186 .keywords: TS, timestep 2187 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime() 2188 @*/ 2189 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 2190 { 2191 PetscFunctionBegin; 2192 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2193 ts->ops->poststep = func; 2194 PetscFunctionReturn(0); 2195 } 2196 2197 #undef __FUNCT__ 2198 #define __FUNCT__ "TSPostStep" 2199 /*@ 2200 TSPostStep - Runs the user-defined post-step function. 2201 2202 Collective on TS 2203 2204 Input Parameters: 2205 . ts - The TS context obtained from TSCreate() 2206 2207 Notes: 2208 TSPostStep() is typically used within time stepping implementations, 2209 so most users would not generally call this routine themselves. 2210 2211 Level: developer 2212 2213 .keywords: TS, timestep 2214 @*/ 2215 PetscErrorCode TSPostStep(TS ts) 2216 { 2217 PetscErrorCode ierr; 2218 2219 PetscFunctionBegin; 2220 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2221 if (ts->ops->poststep) { 2222 PetscStackPush("TS PostStep function"); 2223 ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr); 2224 PetscStackPop; 2225 } 2226 PetscFunctionReturn(0); 2227 } 2228 2229 /* ------------ Routines to set performance monitoring options ----------- */ 2230 2231 #undef __FUNCT__ 2232 #define __FUNCT__ "TSMonitorSet" 2233 /*@C 2234 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 2235 timestep to display the iteration's progress. 2236 2237 Logically Collective on TS 2238 2239 Input Parameters: 2240 + ts - the TS context obtained from TSCreate() 2241 . monitor - monitoring routine 2242 . mctx - [optional] user-defined context for private data for the 2243 monitor routine (use NULL if no context is desired) 2244 - monitordestroy - [optional] routine that frees monitor context 2245 (may be NULL) 2246 2247 Calling sequence of monitor: 2248 $ int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 2249 2250 + ts - the TS context 2251 . 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 2252 been interpolated to) 2253 . time - current time 2254 . u - current iterate 2255 - mctx - [optional] monitoring context 2256 2257 Notes: 2258 This routine adds an additional monitor to the list of monitors that 2259 already has been loaded. 2260 2261 Fortran notes: Only a single monitor function can be set for each TS object 2262 2263 Level: intermediate 2264 2265 .keywords: TS, timestep, set, monitor 2266 2267 .seealso: TSMonitorDefault(), TSMonitorCancel() 2268 @*/ 2269 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 2270 { 2271 PetscFunctionBegin; 2272 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2273 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2274 ts->monitor[ts->numbermonitors] = monitor; 2275 ts->monitordestroy[ts->numbermonitors] = mdestroy; 2276 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 2277 PetscFunctionReturn(0); 2278 } 2279 2280 #undef __FUNCT__ 2281 #define __FUNCT__ "TSMonitorCancel" 2282 /*@C 2283 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 2284 2285 Logically Collective on TS 2286 2287 Input Parameters: 2288 . ts - the TS context obtained from TSCreate() 2289 2290 Notes: 2291 There is no way to remove a single, specific monitor. 2292 2293 Level: intermediate 2294 2295 .keywords: TS, timestep, set, monitor 2296 2297 .seealso: TSMonitorDefault(), TSMonitorSet() 2298 @*/ 2299 PetscErrorCode TSMonitorCancel(TS ts) 2300 { 2301 PetscErrorCode ierr; 2302 PetscInt i; 2303 2304 PetscFunctionBegin; 2305 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2306 for (i=0; i<ts->numbermonitors; i++) { 2307 if (ts->monitordestroy[i]) { 2308 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 2309 } 2310 } 2311 ts->numbermonitors = 0; 2312 PetscFunctionReturn(0); 2313 } 2314 2315 #undef __FUNCT__ 2316 #define __FUNCT__ "TSMonitorDefault" 2317 /*@ 2318 TSMonitorDefault - Sets the Default monitor 2319 2320 Level: intermediate 2321 2322 .keywords: TS, set, monitor 2323 2324 .seealso: TSMonitorDefault(), TSMonitorSet() 2325 @*/ 2326 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy) 2327 { 2328 PetscErrorCode ierr; 2329 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ts)); 2330 2331 PetscFunctionBegin; 2332 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 2333 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr); 2334 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 2335 PetscFunctionReturn(0); 2336 } 2337 2338 #undef __FUNCT__ 2339 #define __FUNCT__ "TSSetRetainStages" 2340 /*@ 2341 TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available. 2342 2343 Logically Collective on TS 2344 2345 Input Argument: 2346 . ts - time stepping context 2347 2348 Output Argument: 2349 . flg - PETSC_TRUE or PETSC_FALSE 2350 2351 Level: intermediate 2352 2353 .keywords: TS, set 2354 2355 .seealso: TSInterpolate(), TSSetPostStep() 2356 @*/ 2357 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg) 2358 { 2359 PetscFunctionBegin; 2360 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2361 ts->retain_stages = flg; 2362 PetscFunctionReturn(0); 2363 } 2364 2365 #undef __FUNCT__ 2366 #define __FUNCT__ "TSInterpolate" 2367 /*@ 2368 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 2369 2370 Collective on TS 2371 2372 Input Argument: 2373 + ts - time stepping context 2374 - t - time to interpolate to 2375 2376 Output Argument: 2377 . U - state at given time 2378 2379 Notes: 2380 The user should call TSSetRetainStages() before taking a step in which interpolation will be requested. 2381 2382 Level: intermediate 2383 2384 Developer Notes: 2385 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 2386 2387 .keywords: TS, set 2388 2389 .seealso: TSSetRetainStages(), TSSetPostStep() 2390 @*/ 2391 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 2392 { 2393 PetscErrorCode ierr; 2394 2395 PetscFunctionBegin; 2396 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2397 if (t < ts->ptime - ts->time_step_prev || t > ts->ptime) SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Requested time %G not in last time steps [%G,%G]",t,ts->ptime-ts->time_step_prev,ts->ptime); 2398 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 2399 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 2400 PetscFunctionReturn(0); 2401 } 2402 2403 #undef __FUNCT__ 2404 #define __FUNCT__ "TSStep" 2405 /*@ 2406 TSStep - Steps one time step 2407 2408 Collective on TS 2409 2410 Input Parameter: 2411 . ts - the TS context obtained from TSCreate() 2412 2413 Level: intermediate 2414 2415 Notes: 2416 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 2417 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 2418 2419 This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the 2420 time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 2421 2422 .keywords: TS, timestep, solve 2423 2424 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 2425 @*/ 2426 PetscErrorCode TSStep(TS ts) 2427 { 2428 PetscReal ptime_prev; 2429 PetscErrorCode ierr; 2430 2431 PetscFunctionBegin; 2432 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2433 ierr = TSSetUp(ts);CHKERRQ(ierr); 2434 2435 ts->reason = TS_CONVERGED_ITERATING; 2436 ptime_prev = ts->ptime; 2437 2438 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 2439 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 2440 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 2441 2442 ts->time_step_prev = ts->ptime - ptime_prev; 2443 2444 if (ts->reason < 0) { 2445 if (ts->errorifstepfailed) { 2446 if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) { 2447 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]); 2448 } else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 2449 } 2450 } else if (!ts->reason) { 2451 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 2452 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 2453 } 2454 PetscFunctionReturn(0); 2455 } 2456 2457 #undef __FUNCT__ 2458 #define __FUNCT__ "TSEvaluateStep" 2459 /*@ 2460 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 2461 2462 Collective on TS 2463 2464 Input Arguments: 2465 + ts - time stepping context 2466 . order - desired order of accuracy 2467 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 2468 2469 Output Arguments: 2470 . U - state at the end of the current step 2471 2472 Level: advanced 2473 2474 Notes: 2475 This function cannot be called until all stages have been evaluated. 2476 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. 2477 2478 .seealso: TSStep(), TSAdapt 2479 @*/ 2480 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 2481 { 2482 PetscErrorCode ierr; 2483 2484 PetscFunctionBegin; 2485 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2486 PetscValidType(ts,1); 2487 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 2488 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 2489 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 2490 PetscFunctionReturn(0); 2491 } 2492 2493 #undef __FUNCT__ 2494 #define __FUNCT__ "TSSolve" 2495 /*@ 2496 TSSolve - Steps the requested number of timesteps. 2497 2498 Collective on TS 2499 2500 Input Parameter: 2501 + ts - the TS context obtained from TSCreate() 2502 - u - the solution vector (can be null if TSSetSolution() was used, otherwise must contain the initial conditions) 2503 2504 Level: beginner 2505 2506 Notes: 2507 The final time returned by this function may be different from the time of the internally 2508 held state accessible by TSGetSolution() and TSGetTime() because the method may have 2509 stepped over the final time. 2510 2511 .keywords: TS, timestep, solve 2512 2513 .seealso: TSCreate(), TSSetSolution(), TSStep() 2514 @*/ 2515 PetscErrorCode TSSolve(TS ts,Vec u) 2516 { 2517 PetscBool flg; 2518 PetscViewer viewer; 2519 PetscErrorCode ierr; 2520 PetscViewerFormat format; 2521 2522 PetscFunctionBegin; 2523 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2524 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2525 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 */ 2526 if (!ts->vec_sol || u == ts->vec_sol) { 2527 Vec y; 2528 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 2529 ierr = TSSetSolution(ts,y);CHKERRQ(ierr); 2530 ierr = VecDestroy(&y);CHKERRQ(ierr); /* grant ownership */ 2531 } 2532 if (u) { 2533 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 2534 } 2535 } else if (u) { 2536 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 2537 } 2538 ierr = TSSetUp(ts);CHKERRQ(ierr); 2539 /* reset time step and iteration counters */ 2540 ts->steps = 0; 2541 ts->ksp_its = 0; 2542 ts->snes_its = 0; 2543 ts->num_snes_failures = 0; 2544 ts->reject = 0; 2545 ts->reason = TS_CONVERGED_ITERATING; 2546 2547 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 2548 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 2549 ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr); 2550 2551 ts->solvetime = ts->ptime; 2552 } else { 2553 /* steps the requested number of timesteps. */ 2554 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 2555 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 2556 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 2557 while (!ts->reason) { 2558 ierr = TSStep(ts);CHKERRQ(ierr); 2559 ierr = TSPostStep(ts);CHKERRQ(ierr); 2560 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 2561 } 2562 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 2563 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 2564 2565 ts->solvetime = ts->max_time; 2566 } else { 2567 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 2568 ts->solvetime = ts->ptime; 2569 } 2570 } 2571 ierr = TSMonitor(ts,-1,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 2572 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject)ts)->prefix,"-ts_view",&viewer,&format,&flg);CHKERRQ(ierr); 2573 if (flg && !PetscPreLoadingOn) { 2574 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 2575 ierr = TSView(ts,viewer);CHKERRQ(ierr); 2576 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 2577 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2578 } 2579 PetscFunctionReturn(0); 2580 } 2581 2582 #undef __FUNCT__ 2583 #define __FUNCT__ "TSMonitor" 2584 /*@ 2585 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 2586 2587 Collective on TS 2588 2589 Input Parameters: 2590 + ts - time stepping context obtained from TSCreate() 2591 . step - step number that has just completed 2592 . ptime - model time of the state 2593 - u - state at the current model time 2594 2595 Notes: 2596 TSMonitor() is typically used within the time stepping implementations. 2597 Users might call this function when using the TSStep() interface instead of TSSolve(). 2598 2599 Level: advanced 2600 2601 .keywords: TS, timestep 2602 @*/ 2603 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 2604 { 2605 PetscErrorCode ierr; 2606 PetscInt i,n = ts->numbermonitors; 2607 2608 PetscFunctionBegin; 2609 for (i=0; i<n; i++) { 2610 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 2611 } 2612 PetscFunctionReturn(0); 2613 } 2614 2615 /* ------------------------------------------------------------------------*/ 2616 struct _n_TSMonitorLGCtx { 2617 PetscDrawLG lg; 2618 PetscInt howoften; /* when > 0 uses step % howoften, when negative only final solution plotted */ 2619 PetscInt ksp_its,snes_its; 2620 }; 2621 2622 2623 #undef __FUNCT__ 2624 #define __FUNCT__ "TSMonitorLGCtxCreate" 2625 /*@C 2626 TSMonitorLGCtxCreate - Creates a line graph context for use with 2627 TS to monitor the solution process graphically in various ways 2628 2629 Collective on TS 2630 2631 Input Parameters: 2632 + host - the X display to open, or null for the local machine 2633 . label - the title to put in the title bar 2634 . x, y - the screen coordinates of the upper left coordinate of the window 2635 . m, n - the screen width and height in pixels 2636 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 2637 2638 Output Parameter: 2639 . ctx - the context 2640 2641 Options Database Key: 2642 + -ts_monitor_lg_timestep - automatically sets line graph monitor 2643 . -ts_monitor_lg_solution - 2644 . -ts_monitor_lg_error - 2645 . -ts_monitor_lg_ksp_iterations - 2646 . -ts_monitor_lg_snes_iterations - 2647 - -lg_indicate_data_points <true,false> - indicate the data points (at each time step) on the plot; default is true 2648 2649 Notes: 2650 Use TSMonitorLGCtxDestroy() to destroy. 2651 2652 Level: intermediate 2653 2654 .keywords: TS, monitor, line graph, residual, seealso 2655 2656 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 2657 2658 @*/ 2659 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 2660 { 2661 PetscDraw win; 2662 PetscErrorCode ierr; 2663 PetscBool flg = PETSC_TRUE; 2664 2665 PetscFunctionBegin; 2666 ierr = PetscNew(struct _n_TSMonitorLGCtx,ctx);CHKERRQ(ierr); 2667 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 2668 ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr); 2669 ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr); 2670 ierr = PetscOptionsGetBool(NULL,"-lg_indicate_data_points",&flg,NULL);CHKERRQ(ierr); 2671 if (flg) { 2672 ierr = PetscDrawLGIndicateDataPoints((*ctx)->lg);CHKERRQ(ierr); 2673 } 2674 ierr = PetscLogObjectParent((*ctx)->lg,win);CHKERRQ(ierr); 2675 (*ctx)->howoften = howoften; 2676 PetscFunctionReturn(0); 2677 } 2678 2679 #undef __FUNCT__ 2680 #define __FUNCT__ "TSMonitorLGTimeStep" 2681 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 2682 { 2683 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 2684 PetscReal x = ptime,y; 2685 PetscErrorCode ierr; 2686 2687 PetscFunctionBegin; 2688 if (!n) { 2689 PetscDrawAxis axis; 2690 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 2691 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr); 2692 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 2693 } 2694 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 2695 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 2696 if (((ctx->howoften > 0) && (!(n % ctx->howoften))) || ((ctx->howoften == -1) && (n == -1))) { 2697 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 2698 } 2699 PetscFunctionReturn(0); 2700 } 2701 2702 #undef __FUNCT__ 2703 #define __FUNCT__ "TSMonitorLGCtxDestroy" 2704 /*@C 2705 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 2706 with TSMonitorLGCtxCreate(). 2707 2708 Collective on TSMonitorLGCtx 2709 2710 Input Parameter: 2711 . ctx - the monitor context 2712 2713 Level: intermediate 2714 2715 .keywords: TS, monitor, line graph, destroy 2716 2717 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 2718 @*/ 2719 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 2720 { 2721 PetscDraw draw; 2722 PetscErrorCode ierr; 2723 2724 PetscFunctionBegin; 2725 ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr); 2726 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 2727 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 2728 ierr = PetscFree(*ctx);CHKERRQ(ierr); 2729 PetscFunctionReturn(0); 2730 } 2731 2732 #undef __FUNCT__ 2733 #define __FUNCT__ "TSGetTime" 2734 /*@ 2735 TSGetTime - Gets the time of the most recently completed step. 2736 2737 Not Collective 2738 2739 Input Parameter: 2740 . ts - the TS context obtained from TSCreate() 2741 2742 Output Parameter: 2743 . t - the current time 2744 2745 Level: beginner 2746 2747 Note: 2748 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 2749 TSSetPreStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 2750 2751 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 2752 2753 .keywords: TS, get, time 2754 @*/ 2755 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 2756 { 2757 PetscFunctionBegin; 2758 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2759 PetscValidRealPointer(t,2); 2760 *t = ts->ptime; 2761 PetscFunctionReturn(0); 2762 } 2763 2764 #undef __FUNCT__ 2765 #define __FUNCT__ "TSSetTime" 2766 /*@ 2767 TSSetTime - Allows one to reset the time. 2768 2769 Logically Collective on TS 2770 2771 Input Parameters: 2772 + ts - the TS context obtained from TSCreate() 2773 - time - the time 2774 2775 Level: intermediate 2776 2777 .seealso: TSGetTime(), TSSetDuration() 2778 2779 .keywords: TS, set, time 2780 @*/ 2781 PetscErrorCode TSSetTime(TS ts, PetscReal t) 2782 { 2783 PetscFunctionBegin; 2784 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2785 PetscValidLogicalCollectiveReal(ts,t,2); 2786 ts->ptime = t; 2787 PetscFunctionReturn(0); 2788 } 2789 2790 #undef __FUNCT__ 2791 #define __FUNCT__ "TSSetOptionsPrefix" 2792 /*@C 2793 TSSetOptionsPrefix - Sets the prefix used for searching for all 2794 TS options in the database. 2795 2796 Logically Collective on TS 2797 2798 Input Parameter: 2799 + ts - The TS context 2800 - prefix - The prefix to prepend to all option names 2801 2802 Notes: 2803 A hyphen (-) must NOT be given at the beginning of the prefix name. 2804 The first character of all runtime options is AUTOMATICALLY the 2805 hyphen. 2806 2807 Level: advanced 2808 2809 .keywords: TS, set, options, prefix, database 2810 2811 .seealso: TSSetFromOptions() 2812 2813 @*/ 2814 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 2815 { 2816 PetscErrorCode ierr; 2817 SNES snes; 2818 2819 PetscFunctionBegin; 2820 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2821 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2822 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2823 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2824 PetscFunctionReturn(0); 2825 } 2826 2827 2828 #undef __FUNCT__ 2829 #define __FUNCT__ "TSAppendOptionsPrefix" 2830 /*@C 2831 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 2832 TS options in the database. 2833 2834 Logically Collective on TS 2835 2836 Input Parameter: 2837 + ts - The TS context 2838 - prefix - The prefix to prepend to all option names 2839 2840 Notes: 2841 A hyphen (-) must NOT be given at the beginning of the prefix name. 2842 The first character of all runtime options is AUTOMATICALLY the 2843 hyphen. 2844 2845 Level: advanced 2846 2847 .keywords: TS, append, options, prefix, database 2848 2849 .seealso: TSGetOptionsPrefix() 2850 2851 @*/ 2852 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 2853 { 2854 PetscErrorCode ierr; 2855 SNES snes; 2856 2857 PetscFunctionBegin; 2858 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2859 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2860 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2861 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2862 PetscFunctionReturn(0); 2863 } 2864 2865 #undef __FUNCT__ 2866 #define __FUNCT__ "TSGetOptionsPrefix" 2867 /*@C 2868 TSGetOptionsPrefix - Sets the prefix used for searching for all 2869 TS options in the database. 2870 2871 Not Collective 2872 2873 Input Parameter: 2874 . ts - The TS context 2875 2876 Output Parameter: 2877 . prefix - A pointer to the prefix string used 2878 2879 Notes: On the fortran side, the user should pass in a string 'prifix' of 2880 sufficient length to hold the prefix. 2881 2882 Level: intermediate 2883 2884 .keywords: TS, get, options, prefix, database 2885 2886 .seealso: TSAppendOptionsPrefix() 2887 @*/ 2888 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 2889 { 2890 PetscErrorCode ierr; 2891 2892 PetscFunctionBegin; 2893 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2894 PetscValidPointer(prefix,2); 2895 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2896 PetscFunctionReturn(0); 2897 } 2898 2899 #undef __FUNCT__ 2900 #define __FUNCT__ "TSGetRHSJacobian" 2901 /*@C 2902 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 2903 2904 Not Collective, but parallel objects are returned if TS is parallel 2905 2906 Input Parameter: 2907 . ts - The TS context obtained from TSCreate() 2908 2909 Output Parameters: 2910 + J - The Jacobian J of F, where U_t = G(U,t) 2911 . M - The preconditioner matrix, usually the same as J 2912 . func - Function to compute the Jacobian of the RHS 2913 - ctx - User-defined context for Jacobian evaluation routine 2914 2915 Notes: You can pass in NULL for any return argument you do not need. 2916 2917 Level: intermediate 2918 2919 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2920 2921 .keywords: TS, timestep, get, matrix, Jacobian 2922 @*/ 2923 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx) 2924 { 2925 PetscErrorCode ierr; 2926 SNES snes; 2927 DM dm; 2928 2929 PetscFunctionBegin; 2930 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2931 ierr = SNESGetJacobian(snes,J,M,NULL,NULL);CHKERRQ(ierr); 2932 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2933 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 2934 PetscFunctionReturn(0); 2935 } 2936 2937 #undef __FUNCT__ 2938 #define __FUNCT__ "TSGetIJacobian" 2939 /*@C 2940 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 2941 2942 Not Collective, but parallel objects are returned if TS is parallel 2943 2944 Input Parameter: 2945 . ts - The TS context obtained from TSCreate() 2946 2947 Output Parameters: 2948 + A - The Jacobian of F(t,U,U_t) 2949 . B - The preconditioner matrix, often the same as A 2950 . f - The function to compute the matrices 2951 - ctx - User-defined context for Jacobian evaluation routine 2952 2953 Notes: You can pass in NULL for any return argument you do not need. 2954 2955 Level: advanced 2956 2957 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2958 2959 .keywords: TS, timestep, get, matrix, Jacobian 2960 @*/ 2961 PetscErrorCode TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx) 2962 { 2963 PetscErrorCode ierr; 2964 SNES snes; 2965 DM dm; 2966 2967 PetscFunctionBegin; 2968 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2969 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 2970 ierr = SNESGetJacobian(snes,A,B,NULL,NULL);CHKERRQ(ierr); 2971 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2972 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 2973 PetscFunctionReturn(0); 2974 } 2975 2976 2977 #undef __FUNCT__ 2978 #define __FUNCT__ "TSMonitorDrawSolution" 2979 /*@C 2980 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 2981 VecView() for the solution at each timestep 2982 2983 Collective on TS 2984 2985 Input Parameters: 2986 + ts - the TS context 2987 . step - current time-step 2988 . ptime - current time 2989 - dummy - either a viewer or NULL 2990 2991 Options Database: 2992 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 2993 2994 Notes: the initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 2995 will look bad 2996 2997 Level: intermediate 2998 2999 .keywords: TS, vector, monitor, view 3000 3001 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3002 @*/ 3003 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3004 { 3005 PetscErrorCode ierr; 3006 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 3007 PetscDraw draw; 3008 3009 PetscFunctionBegin; 3010 if (!step && ictx->showinitial) { 3011 if (!ictx->initialsolution) { 3012 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 3013 } 3014 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 3015 } 3016 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften)) && (step > -1)) || ((ictx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0); 3017 3018 if (ictx->showinitial) { 3019 PetscReal pause; 3020 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 3021 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 3022 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 3023 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 3024 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 3025 } 3026 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 3027 if (ictx->showtimestepandtime) { 3028 PetscReal xl,yl,xr,yr,tw,w,h; 3029 char time[32]; 3030 size_t len; 3031 3032 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 3033 ierr = PetscSNPrintf(time,32,"Timestep %d Time %f",(int)step,(double)ptime);CHKERRQ(ierr); 3034 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 3035 ierr = PetscStrlen(time,&len);CHKERRQ(ierr); 3036 ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr); 3037 w = xl + .5*(xr - xl) - .5*len*tw; 3038 h = yl + .95*(yr - yl); 3039 ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 3040 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 3041 } 3042 3043 if (ictx->showinitial) { 3044 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 3045 } 3046 PetscFunctionReturn(0); 3047 } 3048 3049 #undef __FUNCT__ 3050 #define __FUNCT__ "TSMonitorDrawSolutionPhase" 3051 /*@C 3052 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 3053 3054 Collective on TS 3055 3056 Input Parameters: 3057 + ts - the TS context 3058 . step - current time-step 3059 . ptime - current time 3060 - dummy - either a viewer or NULL 3061 3062 Level: intermediate 3063 3064 .keywords: TS, vector, monitor, view 3065 3066 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3067 @*/ 3068 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3069 { 3070 PetscErrorCode ierr; 3071 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 3072 PetscDraw draw; 3073 MPI_Comm comm; 3074 PetscInt n; 3075 PetscMPIInt size; 3076 PetscReal xl,yl,xr,yr,tw,w,h; 3077 char time[32]; 3078 size_t len; 3079 const PetscScalar *U; 3080 3081 PetscFunctionBegin; 3082 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 3083 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 3084 if (size != 1) SETERRQ(comm,PETSC_ERR_SUP,"Only allowed for sequential runs"); 3085 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 3086 if (n != 2) SETERRQ(comm,PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 3087 3088 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 3089 3090 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 3091 ierr = PetscDrawAxisGetLimits(ictx->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 3092 if ((U[0] < xl) || (U[1] < yl) || (U[0] > xr) || (U[1] > yr)) { 3093 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 3094 PetscFunctionReturn(0); 3095 } 3096 if (!step) ictx->color++; 3097 ierr = PetscDrawPoint(draw,PetscRealPart(U[0]),PetscRealPart(U[1]),ictx->color);CHKERRQ(ierr); 3098 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 3099 3100 if (ictx->showtimestepandtime) { 3101 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 3102 ierr = PetscSNPrintf(time,32,"Timestep %d Time %f",(int)step,(double)ptime);CHKERRQ(ierr); 3103 ierr = PetscStrlen(time,&len);CHKERRQ(ierr); 3104 ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr); 3105 w = xl + .5*(xr - xl) - .5*len*tw; 3106 h = yl + .95*(yr - yl); 3107 ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 3108 } 3109 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 3110 PetscFunctionReturn(0); 3111 } 3112 3113 3114 #undef __FUNCT__ 3115 #define __FUNCT__ "TSMonitorDrawCtxDestroy" 3116 /*@C 3117 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 3118 3119 Collective on TS 3120 3121 Input Parameters: 3122 . ctx - the monitor context 3123 3124 Level: intermediate 3125 3126 .keywords: TS, vector, monitor, view 3127 3128 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 3129 @*/ 3130 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 3131 { 3132 PetscErrorCode ierr; 3133 3134 PetscFunctionBegin; 3135 ierr = PetscDrawAxisDestroy(&(*ictx)->axis);CHKERRQ(ierr); 3136 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 3137 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 3138 ierr = PetscFree(*ictx);CHKERRQ(ierr); 3139 PetscFunctionReturn(0); 3140 } 3141 3142 #undef __FUNCT__ 3143 #define __FUNCT__ "TSMonitorDrawCtxCreate" 3144 /*@C 3145 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 3146 3147 Collective on TS 3148 3149 Input Parameter: 3150 . ts - time-step context 3151 3152 Output Patameter: 3153 . ctx - the monitor context 3154 3155 Options Database: 3156 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 3157 3158 Level: intermediate 3159 3160 .keywords: TS, vector, monitor, view 3161 3162 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 3163 @*/ 3164 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 3165 { 3166 PetscErrorCode ierr; 3167 3168 PetscFunctionBegin; 3169 ierr = PetscNew(struct _n_TSMonitorDrawCtx,ctx);CHKERRQ(ierr); 3170 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 3171 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 3172 3173 (*ctx)->howoften = howoften; 3174 (*ctx)->showinitial = PETSC_FALSE; 3175 ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 3176 3177 (*ctx)->showtimestepandtime = PETSC_FALSE; 3178 ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 3179 (*ctx)->color = PETSC_DRAW_WHITE; 3180 PetscFunctionReturn(0); 3181 } 3182 3183 #undef __FUNCT__ 3184 #define __FUNCT__ "TSMonitorDrawError" 3185 /*@C 3186 TSMonitorDrawError - Monitors progress of the TS solvers by calling 3187 VecView() for the error at each timestep 3188 3189 Collective on TS 3190 3191 Input Parameters: 3192 + ts - the TS context 3193 . step - current time-step 3194 . ptime - current time 3195 - dummy - either a viewer or NULL 3196 3197 Level: intermediate 3198 3199 .keywords: TS, vector, monitor, view 3200 3201 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3202 @*/ 3203 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3204 { 3205 PetscErrorCode ierr; 3206 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 3207 PetscViewer viewer = ctx->viewer; 3208 Vec work; 3209 3210 PetscFunctionBegin; 3211 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0); 3212 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 3213 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 3214 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 3215 ierr = VecView(work,viewer);CHKERRQ(ierr); 3216 ierr = VecDestroy(&work);CHKERRQ(ierr); 3217 PetscFunctionReturn(0); 3218 } 3219 3220 #include <petsc-private/dmimpl.h> 3221 #undef __FUNCT__ 3222 #define __FUNCT__ "TSSetDM" 3223 /*@ 3224 TSSetDM - Sets the DM that may be used by some preconditioners 3225 3226 Logically Collective on TS and DM 3227 3228 Input Parameters: 3229 + ts - the preconditioner context 3230 - dm - the dm 3231 3232 Level: intermediate 3233 3234 3235 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 3236 @*/ 3237 PetscErrorCode TSSetDM(TS ts,DM dm) 3238 { 3239 PetscErrorCode ierr; 3240 SNES snes; 3241 DMTS tsdm; 3242 3243 PetscFunctionBegin; 3244 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3245 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 3246 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 3247 if (ts->dm->dmts && !dm->dmts) { 3248 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 3249 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 3250 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 3251 tsdm->originaldm = dm; 3252 } 3253 } 3254 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 3255 } 3256 ts->dm = dm; 3257 3258 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3259 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 3260 PetscFunctionReturn(0); 3261 } 3262 3263 #undef __FUNCT__ 3264 #define __FUNCT__ "TSGetDM" 3265 /*@ 3266 TSGetDM - Gets the DM that may be used by some preconditioners 3267 3268 Not Collective 3269 3270 Input Parameter: 3271 . ts - the preconditioner context 3272 3273 Output Parameter: 3274 . dm - the dm 3275 3276 Level: intermediate 3277 3278 3279 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 3280 @*/ 3281 PetscErrorCode TSGetDM(TS ts,DM *dm) 3282 { 3283 PetscErrorCode ierr; 3284 3285 PetscFunctionBegin; 3286 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3287 if (!ts->dm) { 3288 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 3289 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 3290 } 3291 *dm = ts->dm; 3292 PetscFunctionReturn(0); 3293 } 3294 3295 #undef __FUNCT__ 3296 #define __FUNCT__ "SNESTSFormFunction" 3297 /*@ 3298 SNESTSFormFunction - Function to evaluate nonlinear residual 3299 3300 Logically Collective on SNES 3301 3302 Input Parameter: 3303 + snes - nonlinear solver 3304 . U - the current state at which to evaluate the residual 3305 - ctx - user context, must be a TS 3306 3307 Output Parameter: 3308 . F - the nonlinear residual 3309 3310 Notes: 3311 This function is not normally called by users and is automatically registered with the SNES used by TS. 3312 It is most frequently passed to MatFDColoringSetFunction(). 3313 3314 Level: advanced 3315 3316 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 3317 @*/ 3318 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 3319 { 3320 TS ts = (TS)ctx; 3321 PetscErrorCode ierr; 3322 3323 PetscFunctionBegin; 3324 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3325 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 3326 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 3327 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 3328 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 3329 PetscFunctionReturn(0); 3330 } 3331 3332 #undef __FUNCT__ 3333 #define __FUNCT__ "SNESTSFormJacobian" 3334 /*@ 3335 SNESTSFormJacobian - Function to evaluate the Jacobian 3336 3337 Collective on SNES 3338 3339 Input Parameter: 3340 + snes - nonlinear solver 3341 . U - the current state at which to evaluate the residual 3342 - ctx - user context, must be a TS 3343 3344 Output Parameter: 3345 + A - the Jacobian 3346 . B - the preconditioning matrix (may be the same as A) 3347 - flag - indicates any structure change in the matrix 3348 3349 Notes: 3350 This function is not normally called by users and is automatically registered with the SNES used by TS. 3351 3352 Level: developer 3353 3354 .seealso: SNESSetJacobian() 3355 @*/ 3356 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat *A,Mat *B,MatStructure *flag,void *ctx) 3357 { 3358 TS ts = (TS)ctx; 3359 PetscErrorCode ierr; 3360 3361 PetscFunctionBegin; 3362 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3363 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 3364 PetscValidPointer(A,3); 3365 PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 3366 PetscValidPointer(B,4); 3367 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); 3368 PetscValidPointer(flag,5); 3369 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 3370 ierr = (ts->ops->snesjacobian)(snes,U,A,B,flag,ts);CHKERRQ(ierr); 3371 PetscFunctionReturn(0); 3372 } 3373 3374 #undef __FUNCT__ 3375 #define __FUNCT__ "TSComputeRHSFunctionLinear" 3376 /*@C 3377 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only 3378 3379 Collective on TS 3380 3381 Input Arguments: 3382 + ts - time stepping context 3383 . t - time at which to evaluate 3384 . U - state at which to evaluate 3385 - ctx - context 3386 3387 Output Arguments: 3388 . F - right hand side 3389 3390 Level: intermediate 3391 3392 Notes: 3393 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 3394 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 3395 3396 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 3397 @*/ 3398 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 3399 { 3400 PetscErrorCode ierr; 3401 Mat Arhs,Brhs; 3402 MatStructure flg2; 3403 3404 PetscFunctionBegin; 3405 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 3406 ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 3407 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 3408 PetscFunctionReturn(0); 3409 } 3410 3411 #undef __FUNCT__ 3412 #define __FUNCT__ "TSComputeRHSJacobianConstant" 3413 /*@C 3414 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 3415 3416 Collective on TS 3417 3418 Input Arguments: 3419 + ts - time stepping context 3420 . t - time at which to evaluate 3421 . U - state at which to evaluate 3422 - ctx - context 3423 3424 Output Arguments: 3425 + A - pointer to operator 3426 . B - pointer to preconditioning matrix 3427 - flg - matrix structure flag 3428 3429 Level: intermediate 3430 3431 Notes: 3432 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 3433 3434 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 3435 @*/ 3436 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg,void *ctx) 3437 { 3438 PetscFunctionBegin; 3439 *flg = SAME_PRECONDITIONER; 3440 PetscFunctionReturn(0); 3441 } 3442 3443 #undef __FUNCT__ 3444 #define __FUNCT__ "TSComputeIFunctionLinear" 3445 /*@C 3446 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 3447 3448 Collective on TS 3449 3450 Input Arguments: 3451 + ts - time stepping context 3452 . t - time at which to evaluate 3453 . U - state at which to evaluate 3454 . Udot - time derivative of state vector 3455 - ctx - context 3456 3457 Output Arguments: 3458 . F - left hand side 3459 3460 Level: intermediate 3461 3462 Notes: 3463 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 3464 user is required to write their own TSComputeIFunction. 3465 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 3466 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 3467 3468 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant() 3469 @*/ 3470 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 3471 { 3472 PetscErrorCode ierr; 3473 Mat A,B; 3474 MatStructure flg2; 3475 3476 PetscFunctionBegin; 3477 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 3478 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr); 3479 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 3480 PetscFunctionReturn(0); 3481 } 3482 3483 #undef __FUNCT__ 3484 #define __FUNCT__ "TSComputeIJacobianConstant" 3485 /*@C 3486 TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent. 3487 3488 Collective on TS 3489 3490 Input Arguments: 3491 + ts - time stepping context 3492 . t - time at which to evaluate 3493 . U - state at which to evaluate 3494 . Udot - time derivative of state vector 3495 . shift - shift to apply 3496 - ctx - context 3497 3498 Output Arguments: 3499 + A - pointer to operator 3500 . B - pointer to preconditioning matrix 3501 - flg - matrix structure flag 3502 3503 Level: intermediate 3504 3505 Notes: 3506 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 3507 3508 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 3509 @*/ 3510 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx) 3511 { 3512 PetscFunctionBegin; 3513 *flg = SAME_PRECONDITIONER; 3514 PetscFunctionReturn(0); 3515 } 3516 #undef __FUNCT__ 3517 #define __FUNCT__ "TSGetEquationType" 3518 /*@ 3519 TSGetEquationType - Gets the type of the equation that TS is solving. 3520 3521 Not Collective 3522 3523 Input Parameter: 3524 . ts - the TS context 3525 3526 Output Parameter: 3527 . equation_type - see TSEquatioType 3528 3529 Level: beginner 3530 3531 .keywords: TS, equation type 3532 3533 .seealso: TSSetEquationType(), TSEquationType 3534 @*/ 3535 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 3536 { 3537 PetscFunctionBegin; 3538 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3539 PetscValidPointer(equation_type,2); 3540 *equation_type = ts->equation_type; 3541 PetscFunctionReturn(0); 3542 } 3543 3544 #undef __FUNCT__ 3545 #define __FUNCT__ "TSSetEquationType" 3546 /*@ 3547 TSSetEquationType - Sets the type of the equation that TS is solving. 3548 3549 Not Collective 3550 3551 Input Parameter: 3552 + ts - the TS context 3553 . equation_type - see TSEquatioType 3554 3555 Level: advanced 3556 3557 .keywords: TS, equation type 3558 3559 .seealso: TSGetEquationType(), TSEquationType 3560 @*/ 3561 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 3562 { 3563 PetscFunctionBegin; 3564 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3565 ts->equation_type = equation_type; 3566 PetscFunctionReturn(0); 3567 } 3568 3569 #undef __FUNCT__ 3570 #define __FUNCT__ "TSGetConvergedReason" 3571 /*@ 3572 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 3573 3574 Not Collective 3575 3576 Input Parameter: 3577 . ts - the TS context 3578 3579 Output Parameter: 3580 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 3581 manual pages for the individual convergence tests for complete lists 3582 3583 Level: beginner 3584 3585 Notes: 3586 Can only be called after the call to TSSolve() is complete. 3587 3588 .keywords: TS, nonlinear, set, convergence, test 3589 3590 .seealso: TSSetConvergenceTest(), TSConvergedReason 3591 @*/ 3592 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 3593 { 3594 PetscFunctionBegin; 3595 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3596 PetscValidPointer(reason,2); 3597 *reason = ts->reason; 3598 PetscFunctionReturn(0); 3599 } 3600 3601 #undef __FUNCT__ 3602 #define __FUNCT__ "TSSetConvergedReason" 3603 /*@ 3604 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 3605 3606 Not Collective 3607 3608 Input Parameter: 3609 + ts - the TS context 3610 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 3611 manual pages for the individual convergence tests for complete lists 3612 3613 Level: advanced 3614 3615 Notes: 3616 Can only be called during TSSolve() is active. 3617 3618 .keywords: TS, nonlinear, set, convergence, test 3619 3620 .seealso: TSConvergedReason 3621 @*/ 3622 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 3623 { 3624 PetscFunctionBegin; 3625 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3626 ts->reason = reason; 3627 PetscFunctionReturn(0); 3628 } 3629 3630 #undef __FUNCT__ 3631 #define __FUNCT__ "TSGetSolveTime" 3632 /*@ 3633 TSGetSolveTime - Gets the time after a call to TSSolve() 3634 3635 Not Collective 3636 3637 Input Parameter: 3638 . ts - the TS context 3639 3640 Output Parameter: 3641 . ftime - the final time. This time should correspond to the final time set with TSSetDuration() 3642 3643 Level: beginner 3644 3645 Notes: 3646 Can only be called after the call to TSSolve() is complete. 3647 3648 .keywords: TS, nonlinear, set, convergence, test 3649 3650 .seealso: TSSetConvergenceTest(), TSConvergedReason 3651 @*/ 3652 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 3653 { 3654 PetscFunctionBegin; 3655 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3656 PetscValidPointer(ftime,2); 3657 *ftime = ts->solvetime; 3658 PetscFunctionReturn(0); 3659 } 3660 3661 #undef __FUNCT__ 3662 #define __FUNCT__ "TSGetSNESIterations" 3663 /*@ 3664 TSGetSNESIterations - Gets the total number of nonlinear iterations 3665 used by the time integrator. 3666 3667 Not Collective 3668 3669 Input Parameter: 3670 . ts - TS context 3671 3672 Output Parameter: 3673 . nits - number of nonlinear iterations 3674 3675 Notes: 3676 This counter is reset to zero for each successive call to TSSolve(). 3677 3678 Level: intermediate 3679 3680 .keywords: TS, get, number, nonlinear, iterations 3681 3682 .seealso: TSGetKSPIterations() 3683 @*/ 3684 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 3685 { 3686 PetscFunctionBegin; 3687 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3688 PetscValidIntPointer(nits,2); 3689 *nits = ts->snes_its; 3690 PetscFunctionReturn(0); 3691 } 3692 3693 #undef __FUNCT__ 3694 #define __FUNCT__ "TSGetKSPIterations" 3695 /*@ 3696 TSGetKSPIterations - Gets the total number of linear iterations 3697 used by the time integrator. 3698 3699 Not Collective 3700 3701 Input Parameter: 3702 . ts - TS context 3703 3704 Output Parameter: 3705 . lits - number of linear iterations 3706 3707 Notes: 3708 This counter is reset to zero for each successive call to TSSolve(). 3709 3710 Level: intermediate 3711 3712 .keywords: TS, get, number, linear, iterations 3713 3714 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 3715 @*/ 3716 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 3717 { 3718 PetscFunctionBegin; 3719 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3720 PetscValidIntPointer(lits,2); 3721 *lits = ts->ksp_its; 3722 PetscFunctionReturn(0); 3723 } 3724 3725 #undef __FUNCT__ 3726 #define __FUNCT__ "TSGetStepRejections" 3727 /*@ 3728 TSGetStepRejections - Gets the total number of rejected steps. 3729 3730 Not Collective 3731 3732 Input Parameter: 3733 . ts - TS context 3734 3735 Output Parameter: 3736 . rejects - number of steps rejected 3737 3738 Notes: 3739 This counter is reset to zero for each successive call to TSSolve(). 3740 3741 Level: intermediate 3742 3743 .keywords: TS, get, number 3744 3745 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 3746 @*/ 3747 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 3748 { 3749 PetscFunctionBegin; 3750 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3751 PetscValidIntPointer(rejects,2); 3752 *rejects = ts->reject; 3753 PetscFunctionReturn(0); 3754 } 3755 3756 #undef __FUNCT__ 3757 #define __FUNCT__ "TSGetSNESFailures" 3758 /*@ 3759 TSGetSNESFailures - Gets the total number of failed SNES solves 3760 3761 Not Collective 3762 3763 Input Parameter: 3764 . ts - TS context 3765 3766 Output Parameter: 3767 . fails - number of failed nonlinear solves 3768 3769 Notes: 3770 This counter is reset to zero for each successive call to TSSolve(). 3771 3772 Level: intermediate 3773 3774 .keywords: TS, get, number 3775 3776 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 3777 @*/ 3778 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 3779 { 3780 PetscFunctionBegin; 3781 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3782 PetscValidIntPointer(fails,2); 3783 *fails = ts->num_snes_failures; 3784 PetscFunctionReturn(0); 3785 } 3786 3787 #undef __FUNCT__ 3788 #define __FUNCT__ "TSSetMaxStepRejections" 3789 /*@ 3790 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 3791 3792 Not Collective 3793 3794 Input Parameter: 3795 + ts - TS context 3796 - rejects - maximum number of rejected steps, pass -1 for unlimited 3797 3798 Notes: 3799 The counter is reset to zero for each step 3800 3801 Options Database Key: 3802 . -ts_max_reject - Maximum number of step rejections before a step fails 3803 3804 Level: intermediate 3805 3806 .keywords: TS, set, maximum, number 3807 3808 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3809 @*/ 3810 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 3811 { 3812 PetscFunctionBegin; 3813 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3814 ts->max_reject = rejects; 3815 PetscFunctionReturn(0); 3816 } 3817 3818 #undef __FUNCT__ 3819 #define __FUNCT__ "TSSetMaxSNESFailures" 3820 /*@ 3821 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 3822 3823 Not Collective 3824 3825 Input Parameter: 3826 + ts - TS context 3827 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 3828 3829 Notes: 3830 The counter is reset to zero for each successive call to TSSolve(). 3831 3832 Options Database Key: 3833 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 3834 3835 Level: intermediate 3836 3837 .keywords: TS, set, maximum, number 3838 3839 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 3840 @*/ 3841 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 3842 { 3843 PetscFunctionBegin; 3844 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3845 ts->max_snes_failures = fails; 3846 PetscFunctionReturn(0); 3847 } 3848 3849 #undef __FUNCT__ 3850 #define __FUNCT__ "TSSetErrorIfStepFails()" 3851 /*@ 3852 TSSetErrorIfStepFails - Error if no step succeeds 3853 3854 Not Collective 3855 3856 Input Parameter: 3857 + ts - TS context 3858 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 3859 3860 Options Database Key: 3861 . -ts_error_if_step_fails - Error if no step succeeds 3862 3863 Level: intermediate 3864 3865 .keywords: TS, set, error 3866 3867 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3868 @*/ 3869 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 3870 { 3871 PetscFunctionBegin; 3872 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3873 ts->errorifstepfailed = err; 3874 PetscFunctionReturn(0); 3875 } 3876 3877 #undef __FUNCT__ 3878 #define __FUNCT__ "TSMonitorSolutionBinary" 3879 /*@C 3880 TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file 3881 3882 Collective on TS 3883 3884 Input Parameters: 3885 + ts - the TS context 3886 . step - current time-step 3887 . ptime - current time 3888 . u - current state 3889 - viewer - binary viewer 3890 3891 Level: intermediate 3892 3893 .keywords: TS, vector, monitor, view 3894 3895 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3896 @*/ 3897 PetscErrorCode TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer) 3898 { 3899 PetscErrorCode ierr; 3900 PetscViewer v = (PetscViewer)viewer; 3901 3902 PetscFunctionBegin; 3903 ierr = VecView(u,v);CHKERRQ(ierr); 3904 PetscFunctionReturn(0); 3905 } 3906 3907 #undef __FUNCT__ 3908 #define __FUNCT__ "TSMonitorSolutionVTK" 3909 /*@C 3910 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 3911 3912 Collective on TS 3913 3914 Input Parameters: 3915 + ts - the TS context 3916 . step - current time-step 3917 . ptime - current time 3918 . u - current state 3919 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 3920 3921 Level: intermediate 3922 3923 Notes: 3924 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. 3925 These are named according to the file name template. 3926 3927 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 3928 3929 .keywords: TS, vector, monitor, view 3930 3931 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3932 @*/ 3933 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 3934 { 3935 PetscErrorCode ierr; 3936 char filename[PETSC_MAX_PATH_LEN]; 3937 PetscViewer viewer; 3938 3939 PetscFunctionBegin; 3940 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 3941 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 3942 ierr = VecView(u,viewer);CHKERRQ(ierr); 3943 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3944 PetscFunctionReturn(0); 3945 } 3946 3947 #undef __FUNCT__ 3948 #define __FUNCT__ "TSMonitorSolutionVTKDestroy" 3949 /*@C 3950 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 3951 3952 Collective on TS 3953 3954 Input Parameters: 3955 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 3956 3957 Level: intermediate 3958 3959 Note: 3960 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 3961 3962 .keywords: TS, vector, monitor, view 3963 3964 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 3965 @*/ 3966 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 3967 { 3968 PetscErrorCode ierr; 3969 3970 PetscFunctionBegin; 3971 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 3972 PetscFunctionReturn(0); 3973 } 3974 3975 #undef __FUNCT__ 3976 #define __FUNCT__ "TSGetTSAdapt" 3977 /*@ 3978 TSGetTSAdapt - Get the adaptive controller context for the current method 3979 3980 Collective on TS if controller has not been created yet 3981 3982 Input Arguments: 3983 . ts - time stepping context 3984 3985 Output Arguments: 3986 . adapt - adaptive controller 3987 3988 Level: intermediate 3989 3990 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 3991 @*/ 3992 PetscErrorCode TSGetTSAdapt(TS ts,TSAdapt *adapt) 3993 { 3994 PetscErrorCode ierr; 3995 3996 PetscFunctionBegin; 3997 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3998 PetscValidPointer(adapt,2); 3999 if (!ts->adapt) { 4000 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 4001 ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr); 4002 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 4003 } 4004 *adapt = ts->adapt; 4005 PetscFunctionReturn(0); 4006 } 4007 4008 #undef __FUNCT__ 4009 #define __FUNCT__ "TSSetTolerances" 4010 /*@ 4011 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 4012 4013 Logically Collective 4014 4015 Input Arguments: 4016 + ts - time integration context 4017 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 4018 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 4019 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 4020 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 4021 4022 Level: beginner 4023 4024 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 4025 @*/ 4026 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 4027 { 4028 PetscErrorCode ierr; 4029 4030 PetscFunctionBegin; 4031 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 4032 if (vatol) { 4033 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 4034 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 4035 4036 ts->vatol = vatol; 4037 } 4038 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 4039 if (vrtol) { 4040 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 4041 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 4042 4043 ts->vrtol = vrtol; 4044 } 4045 PetscFunctionReturn(0); 4046 } 4047 4048 #undef __FUNCT__ 4049 #define __FUNCT__ "TSGetTolerances" 4050 /*@ 4051 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 4052 4053 Logically Collective 4054 4055 Input Arguments: 4056 . ts - time integration context 4057 4058 Output Arguments: 4059 + atol - scalar absolute tolerances, NULL to ignore 4060 . vatol - vector of absolute tolerances, NULL to ignore 4061 . rtol - scalar relative tolerances, NULL to ignore 4062 - vrtol - vector of relative tolerances, NULL to ignore 4063 4064 Level: beginner 4065 4066 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 4067 @*/ 4068 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 4069 { 4070 PetscFunctionBegin; 4071 if (atol) *atol = ts->atol; 4072 if (vatol) *vatol = ts->vatol; 4073 if (rtol) *rtol = ts->rtol; 4074 if (vrtol) *vrtol = ts->vrtol; 4075 PetscFunctionReturn(0); 4076 } 4077 4078 #undef __FUNCT__ 4079 #define __FUNCT__ "TSErrorNormWRMS" 4080 /*@ 4081 TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state 4082 4083 Collective on TS 4084 4085 Input Arguments: 4086 + ts - time stepping context 4087 - Y - state vector to be compared to ts->vec_sol 4088 4089 Output Arguments: 4090 . norm - weighted norm, a value of 1.0 is considered small 4091 4092 Level: developer 4093 4094 .seealso: TSSetTolerances() 4095 @*/ 4096 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm) 4097 { 4098 PetscErrorCode ierr; 4099 PetscInt i,n,N; 4100 const PetscScalar *u,*y; 4101 Vec U; 4102 PetscReal sum,gsum; 4103 4104 PetscFunctionBegin; 4105 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4106 PetscValidHeaderSpecific(Y,VEC_CLASSID,2); 4107 PetscValidPointer(norm,3); 4108 U = ts->vec_sol; 4109 PetscCheckSameTypeAndComm(U,1,Y,2); 4110 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector"); 4111 4112 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 4113 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 4114 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 4115 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 4116 sum = 0.; 4117 if (ts->vatol && ts->vrtol) { 4118 const PetscScalar *atol,*rtol; 4119 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4120 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4121 for (i=0; i<n; i++) { 4122 PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4123 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4124 } 4125 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4126 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4127 } else if (ts->vatol) { /* vector atol, scalar rtol */ 4128 const PetscScalar *atol; 4129 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4130 for (i=0; i<n; i++) { 4131 PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4132 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4133 } 4134 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4135 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 4136 const PetscScalar *rtol; 4137 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4138 for (i=0; i<n; i++) { 4139 PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4140 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4141 } 4142 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4143 } else { /* scalar atol, scalar rtol */ 4144 for (i=0; i<n; i++) { 4145 PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4146 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4147 } 4148 } 4149 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 4150 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 4151 4152 ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 4153 *norm = PetscSqrtReal(gsum / N); 4154 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 4155 PetscFunctionReturn(0); 4156 } 4157 4158 #undef __FUNCT__ 4159 #define __FUNCT__ "TSSetCFLTimeLocal" 4160 /*@ 4161 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 4162 4163 Logically Collective on TS 4164 4165 Input Arguments: 4166 + ts - time stepping context 4167 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 4168 4169 Note: 4170 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 4171 4172 Level: intermediate 4173 4174 .seealso: TSGetCFLTime(), TSADAPTCFL 4175 @*/ 4176 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 4177 { 4178 PetscFunctionBegin; 4179 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4180 ts->cfltime_local = cfltime; 4181 ts->cfltime = -1.; 4182 PetscFunctionReturn(0); 4183 } 4184 4185 #undef __FUNCT__ 4186 #define __FUNCT__ "TSGetCFLTime" 4187 /*@ 4188 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 4189 4190 Collective on TS 4191 4192 Input Arguments: 4193 . ts - time stepping context 4194 4195 Output Arguments: 4196 . cfltime - maximum stable time step for forward Euler 4197 4198 Level: advanced 4199 4200 .seealso: TSSetCFLTimeLocal() 4201 @*/ 4202 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 4203 { 4204 PetscErrorCode ierr; 4205 4206 PetscFunctionBegin; 4207 if (ts->cfltime < 0) { 4208 ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 4209 } 4210 *cfltime = ts->cfltime; 4211 PetscFunctionReturn(0); 4212 } 4213 4214 #undef __FUNCT__ 4215 #define __FUNCT__ "TSVISetVariableBounds" 4216 /*@ 4217 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 4218 4219 Input Parameters: 4220 . ts - the TS context. 4221 . xl - lower bound. 4222 . xu - upper bound. 4223 4224 Notes: 4225 If this routine is not called then the lower and upper bounds are set to 4226 SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp(). 4227 4228 Level: advanced 4229 4230 @*/ 4231 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 4232 { 4233 PetscErrorCode ierr; 4234 SNES snes; 4235 4236 PetscFunctionBegin; 4237 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4238 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 4239 PetscFunctionReturn(0); 4240 } 4241 4242 #if defined(PETSC_HAVE_MATLAB_ENGINE) 4243 #include <mex.h> 4244 4245 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 4246 4247 #undef __FUNCT__ 4248 #define __FUNCT__ "TSComputeFunction_Matlab" 4249 /* 4250 TSComputeFunction_Matlab - Calls the function that has been set with 4251 TSSetFunctionMatlab(). 4252 4253 Collective on TS 4254 4255 Input Parameters: 4256 + snes - the TS context 4257 - u - input vector 4258 4259 Output Parameter: 4260 . y - function vector, as set by TSSetFunction() 4261 4262 Notes: 4263 TSComputeFunction() is typically used within nonlinear solvers 4264 implementations, so most users would not generally call this routine 4265 themselves. 4266 4267 Level: developer 4268 4269 .keywords: TS, nonlinear, compute, function 4270 4271 .seealso: TSSetFunction(), TSGetFunction() 4272 */ 4273 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 4274 { 4275 PetscErrorCode ierr; 4276 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 4277 int nlhs = 1,nrhs = 7; 4278 mxArray *plhs[1],*prhs[7]; 4279 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 4280 4281 PetscFunctionBegin; 4282 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 4283 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 4284 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 4285 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 4286 PetscCheckSameComm(snes,1,u,3); 4287 PetscCheckSameComm(snes,1,y,5); 4288 4289 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4290 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 4291 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 4292 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 4293 4294 prhs[0] = mxCreateDoubleScalar((double)ls); 4295 prhs[1] = mxCreateDoubleScalar(time); 4296 prhs[2] = mxCreateDoubleScalar((double)lx); 4297 prhs[3] = mxCreateDoubleScalar((double)lxdot); 4298 prhs[4] = mxCreateDoubleScalar((double)ly); 4299 prhs[5] = mxCreateString(sctx->funcname); 4300 prhs[6] = sctx->ctx; 4301 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 4302 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4303 mxDestroyArray(prhs[0]); 4304 mxDestroyArray(prhs[1]); 4305 mxDestroyArray(prhs[2]); 4306 mxDestroyArray(prhs[3]); 4307 mxDestroyArray(prhs[4]); 4308 mxDestroyArray(prhs[5]); 4309 mxDestroyArray(plhs[0]); 4310 PetscFunctionReturn(0); 4311 } 4312 4313 4314 #undef __FUNCT__ 4315 #define __FUNCT__ "TSSetFunctionMatlab" 4316 /* 4317 TSSetFunctionMatlab - Sets the function evaluation routine and function 4318 vector for use by the TS routines in solving ODEs 4319 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 4320 4321 Logically Collective on TS 4322 4323 Input Parameters: 4324 + ts - the TS context 4325 - func - function evaluation routine 4326 4327 Calling sequence of func: 4328 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 4329 4330 Level: beginner 4331 4332 .keywords: TS, nonlinear, set, function 4333 4334 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 4335 */ 4336 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 4337 { 4338 PetscErrorCode ierr; 4339 TSMatlabContext *sctx; 4340 4341 PetscFunctionBegin; 4342 /* currently sctx is memory bleed */ 4343 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 4344 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4345 /* 4346 This should work, but it doesn't 4347 sctx->ctx = ctx; 4348 mexMakeArrayPersistent(sctx->ctx); 4349 */ 4350 sctx->ctx = mxDuplicateArray(ctx); 4351 4352 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 4353 PetscFunctionReturn(0); 4354 } 4355 4356 #undef __FUNCT__ 4357 #define __FUNCT__ "TSComputeJacobian_Matlab" 4358 /* 4359 TSComputeJacobian_Matlab - Calls the function that has been set with 4360 TSSetJacobianMatlab(). 4361 4362 Collective on TS 4363 4364 Input Parameters: 4365 + ts - the TS context 4366 . u - input vector 4367 . A, B - the matrices 4368 - ctx - user context 4369 4370 Output Parameter: 4371 . flag - structure of the matrix 4372 4373 Level: developer 4374 4375 .keywords: TS, nonlinear, compute, function 4376 4377 .seealso: TSSetFunction(), TSGetFunction() 4378 @*/ 4379 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx) 4380 { 4381 PetscErrorCode ierr; 4382 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 4383 int nlhs = 2,nrhs = 9; 4384 mxArray *plhs[2],*prhs[9]; 4385 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 4386 4387 PetscFunctionBegin; 4388 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4389 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 4390 4391 /* call Matlab function in ctx with arguments u and y */ 4392 4393 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 4394 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 4395 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 4396 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 4397 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 4398 4399 prhs[0] = mxCreateDoubleScalar((double)ls); 4400 prhs[1] = mxCreateDoubleScalar((double)time); 4401 prhs[2] = mxCreateDoubleScalar((double)lx); 4402 prhs[3] = mxCreateDoubleScalar((double)lxdot); 4403 prhs[4] = mxCreateDoubleScalar((double)shift); 4404 prhs[5] = mxCreateDoubleScalar((double)lA); 4405 prhs[6] = mxCreateDoubleScalar((double)lB); 4406 prhs[7] = mxCreateString(sctx->funcname); 4407 prhs[8] = sctx->ctx; 4408 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 4409 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4410 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 4411 mxDestroyArray(prhs[0]); 4412 mxDestroyArray(prhs[1]); 4413 mxDestroyArray(prhs[2]); 4414 mxDestroyArray(prhs[3]); 4415 mxDestroyArray(prhs[4]); 4416 mxDestroyArray(prhs[5]); 4417 mxDestroyArray(prhs[6]); 4418 mxDestroyArray(prhs[7]); 4419 mxDestroyArray(plhs[0]); 4420 mxDestroyArray(plhs[1]); 4421 PetscFunctionReturn(0); 4422 } 4423 4424 4425 #undef __FUNCT__ 4426 #define __FUNCT__ "TSSetJacobianMatlab" 4427 /* 4428 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 4429 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 4430 4431 Logically Collective on TS 4432 4433 Input Parameters: 4434 + ts - the TS context 4435 . A,B - Jacobian matrices 4436 . func - function evaluation routine 4437 - ctx - user context 4438 4439 Calling sequence of func: 4440 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 4441 4442 4443 Level: developer 4444 4445 .keywords: TS, nonlinear, set, function 4446 4447 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 4448 */ 4449 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 4450 { 4451 PetscErrorCode ierr; 4452 TSMatlabContext *sctx; 4453 4454 PetscFunctionBegin; 4455 /* currently sctx is memory bleed */ 4456 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 4457 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4458 /* 4459 This should work, but it doesn't 4460 sctx->ctx = ctx; 4461 mexMakeArrayPersistent(sctx->ctx); 4462 */ 4463 sctx->ctx = mxDuplicateArray(ctx); 4464 4465 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 4466 PetscFunctionReturn(0); 4467 } 4468 4469 #undef __FUNCT__ 4470 #define __FUNCT__ "TSMonitor_Matlab" 4471 /* 4472 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 4473 4474 Collective on TS 4475 4476 .seealso: TSSetFunction(), TSGetFunction() 4477 @*/ 4478 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 4479 { 4480 PetscErrorCode ierr; 4481 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 4482 int nlhs = 1,nrhs = 6; 4483 mxArray *plhs[1],*prhs[6]; 4484 long long int lx = 0,ls = 0; 4485 4486 PetscFunctionBegin; 4487 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4488 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4489 4490 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 4491 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 4492 4493 prhs[0] = mxCreateDoubleScalar((double)ls); 4494 prhs[1] = mxCreateDoubleScalar((double)it); 4495 prhs[2] = mxCreateDoubleScalar((double)time); 4496 prhs[3] = mxCreateDoubleScalar((double)lx); 4497 prhs[4] = mxCreateString(sctx->funcname); 4498 prhs[5] = sctx->ctx; 4499 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 4500 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4501 mxDestroyArray(prhs[0]); 4502 mxDestroyArray(prhs[1]); 4503 mxDestroyArray(prhs[2]); 4504 mxDestroyArray(prhs[3]); 4505 mxDestroyArray(prhs[4]); 4506 mxDestroyArray(plhs[0]); 4507 PetscFunctionReturn(0); 4508 } 4509 4510 4511 #undef __FUNCT__ 4512 #define __FUNCT__ "TSMonitorSetMatlab" 4513 /* 4514 TSMonitorSetMatlab - Sets the monitor function from Matlab 4515 4516 Level: developer 4517 4518 .keywords: TS, nonlinear, set, function 4519 4520 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 4521 */ 4522 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 4523 { 4524 PetscErrorCode ierr; 4525 TSMatlabContext *sctx; 4526 4527 PetscFunctionBegin; 4528 /* currently sctx is memory bleed */ 4529 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 4530 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4531 /* 4532 This should work, but it doesn't 4533 sctx->ctx = ctx; 4534 mexMakeArrayPersistent(sctx->ctx); 4535 */ 4536 sctx->ctx = mxDuplicateArray(ctx); 4537 4538 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 4539 PetscFunctionReturn(0); 4540 } 4541 #endif 4542 4543 4544 4545 #undef __FUNCT__ 4546 #define __FUNCT__ "TSMonitorLGSolution" 4547 /*@C 4548 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 4549 in a time based line graph 4550 4551 Collective on TS 4552 4553 Input Parameters: 4554 + ts - the TS context 4555 . step - current time-step 4556 . ptime - current time 4557 - lg - a line graph object 4558 4559 Level: intermediate 4560 4561 Notes: each process in a parallel run displays its component solutions in a separate window 4562 4563 .keywords: TS, vector, monitor, view 4564 4565 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4566 @*/ 4567 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4568 { 4569 PetscErrorCode ierr; 4570 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 4571 const PetscScalar *yy; 4572 PetscInt dim; 4573 4574 PetscFunctionBegin; 4575 if (!step) { 4576 PetscDrawAxis axis; 4577 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4578 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 4579 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 4580 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 4581 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4582 } 4583 ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr); 4584 #if defined(PETSC_USE_COMPLEX) 4585 { 4586 PetscReal *yreal; 4587 PetscInt i,n; 4588 ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr); 4589 ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr); 4590 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 4591 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 4592 ierr = PetscFree(yreal);CHKERRQ(ierr); 4593 } 4594 #else 4595 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 4596 #endif 4597 ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr); 4598 if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))) { 4599 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4600 } 4601 PetscFunctionReturn(0); 4602 } 4603 4604 #undef __FUNCT__ 4605 #define __FUNCT__ "TSMonitorLGError" 4606 /*@C 4607 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector 4608 in a time based line graph 4609 4610 Collective on TS 4611 4612 Input Parameters: 4613 + ts - the TS context 4614 . step - current time-step 4615 . ptime - current time 4616 - lg - a line graph object 4617 4618 Level: intermediate 4619 4620 Notes: 4621 Only for sequential solves. 4622 4623 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 4624 4625 Options Database Keys: 4626 . -ts_monitor_lg_error - create a graphical monitor of error history 4627 4628 .keywords: TS, vector, monitor, view 4629 4630 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4631 @*/ 4632 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4633 { 4634 PetscErrorCode ierr; 4635 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 4636 const PetscScalar *yy; 4637 Vec y; 4638 PetscInt dim; 4639 4640 PetscFunctionBegin; 4641 if (!step) { 4642 PetscDrawAxis axis; 4643 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4644 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr); 4645 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 4646 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 4647 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4648 } 4649 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 4650 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 4651 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 4652 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 4653 #if defined(PETSC_USE_COMPLEX) 4654 { 4655 PetscReal *yreal; 4656 PetscInt i,n; 4657 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 4658 ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr); 4659 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 4660 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 4661 ierr = PetscFree(yreal);CHKERRQ(ierr); 4662 } 4663 #else 4664 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 4665 #endif 4666 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 4667 ierr = VecDestroy(&y);CHKERRQ(ierr); 4668 if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))) { 4669 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4670 } 4671 PetscFunctionReturn(0); 4672 } 4673 4674 #undef __FUNCT__ 4675 #define __FUNCT__ "TSMonitorLGSNESIterations" 4676 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 4677 { 4678 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4679 PetscReal x = ptime,y; 4680 PetscErrorCode ierr; 4681 PetscInt its; 4682 4683 PetscFunctionBegin; 4684 if (!n) { 4685 PetscDrawAxis axis; 4686 4687 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4688 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 4689 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4690 4691 ctx->snes_its = 0; 4692 } 4693 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 4694 y = its - ctx->snes_its; 4695 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4696 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 4697 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4698 } 4699 ctx->snes_its = its; 4700 PetscFunctionReturn(0); 4701 } 4702 4703 #undef __FUNCT__ 4704 #define __FUNCT__ "TSMonitorLGKSPIterations" 4705 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 4706 { 4707 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4708 PetscReal x = ptime,y; 4709 PetscErrorCode ierr; 4710 PetscInt its; 4711 4712 PetscFunctionBegin; 4713 if (!n) { 4714 PetscDrawAxis axis; 4715 4716 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4717 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 4718 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4719 4720 ctx->ksp_its = 0; 4721 } 4722 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 4723 y = its - ctx->ksp_its; 4724 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4725 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 4726 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4727 } 4728 ctx->ksp_its = its; 4729 PetscFunctionReturn(0); 4730 } 4731 4732 #undef __FUNCT__ 4733 #define __FUNCT__ "TSComputeLinearStability" 4734 /*@ 4735 TSComputeLinearStability - computes the linear stability function at a point 4736 4737 Collective on TS and Vec 4738 4739 Input Parameters: 4740 + ts - the TS context 4741 - xr,xi - real and imaginary part of input arguments 4742 4743 Output Parameters: 4744 . yr,yi - real and imaginary part of function value 4745 4746 Level: developer 4747 4748 .keywords: TS, compute 4749 4750 .seealso: TSSetRHSFunction(), TSComputeIFunction() 4751 @*/ 4752 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 4753 { 4754 PetscErrorCode ierr; 4755 4756 PetscFunctionBegin; 4757 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4758 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 4759 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 4760 PetscFunctionReturn(0); 4761 } 4762