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