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