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