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