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