1 2 #include <petsc-private/tsimpl.h> /*I "petscts.h" I*/ 3 #include <petscdmshell.h> 4 #include <petscdmda.h> 5 #include <petscviewer.h> 6 #include <petscdraw.h> 7 8 /* Logging support */ 9 PetscClassId TS_CLASSID, DMTS_CLASSID; 10 PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 11 12 const char *const TSExactFinalTimeOptions[] = {"STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",0}; 13 14 struct _n_TSMonitorDrawCtx { 15 PetscViewer viewer; 16 PetscDrawAxis axis; 17 Vec initialsolution; 18 PetscBool showinitial; 19 PetscInt howoften; /* when > 0 uses step % howoften, when negative only final solution plotted */ 20 PetscBool showtimestepandtime; 21 int color; 22 }; 23 24 #undef __FUNCT__ 25 #define __FUNCT__ "TSSetFromOptions" 26 /*@ 27 TSSetFromOptions - Sets various TS parameters from user options. 28 29 Collective on TS 30 31 Input Parameter: 32 . ts - the TS context obtained from TSCreate() 33 34 Options Database Keys: 35 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP 36 . -ts_save_trajectory - checkpoint the solution at each time-step 37 . -ts_max_steps <maxsteps> - maximum number of time-steps to take 38 . -ts_final_time <time> - maximum time to compute to 39 . -ts_dt <dt> - initial time step 40 . -ts_exact_final_time <stepover,interpolate,matchstep> whether to stop at the exact given final time and how to compute the solution at that ti,e 41 . -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed 42 . -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails 43 . -ts_error_if_step_fails <true,false> - Error if no step succeeds 44 . -ts_rtol <rtol> - relative tolerance for local truncation error 45 . -ts_atol <atol> Absolute tolerance for local truncation error 46 . -ts_adjoint_solve <yes,no> After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory) 47 . -ts_fd_color - Use finite differences with coloring to compute IJacobian 48 . -ts_monitor - print information at each timestep 49 . -ts_monitor_lg_timestep - Monitor timestep size graphically 50 . -ts_monitor_lg_solution - Monitor solution graphically 51 . -ts_monitor_lg_error - Monitor error graphically 52 . -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically 53 . -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically 54 . -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically 55 . -ts_monitor_draw_solution - Monitor solution graphically 56 . -ts_monitor_draw_solution_phase <xleft,yleft,xright,yright> - Monitor solution graphically with phase diagram, requires problem with exactly 2 degrees of freedom 57 . -ts_monitor_draw_error - Monitor error graphically, requires use to have provided TSSetSolutionFunction() 58 . -ts_monitor_solution_binary <filename> - Save each solution to a binary file 59 . -ts_monitor_solution_vtk <filename.vts> - Save each time step to a binary file, use filename-%%03D.vts 60 - -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time 61 62 Developer Note: We should unify all the -ts_monitor options in the way that -xxx_view has been unified 63 64 Level: beginner 65 66 .keywords: TS, timestep, set, options, database 67 68 .seealso: TSGetType() 69 @*/ 70 PetscErrorCode TSSetFromOptions(TS ts) 71 { 72 PetscBool opt,flg,tflg; 73 PetscErrorCode ierr; 74 PetscViewer monviewer; 75 char monfilename[PETSC_MAX_PATH_LEN]; 76 SNES snes; 77 TSAdapt adapt; 78 PetscReal time_step; 79 TSExactFinalTimeOption eftopt; 80 char dir[16]; 81 const char *defaultType; 82 char typeName[256]; 83 84 PetscFunctionBegin; 85 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 86 ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr); 87 if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name; 88 else defaultType = TSEULER; 89 90 ierr = TSRegisterAll();CHKERRQ(ierr); 91 ierr = PetscOptionsFList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr); 92 if (opt) { 93 ierr = TSSetType(ts, typeName);CHKERRQ(ierr); 94 } else { 95 ierr = TSSetType(ts, defaultType);CHKERRQ(ierr); 96 } 97 98 /* Handle generic TS options */ 99 if (ts->trajectory) tflg = PETSC_TRUE; 100 else tflg = PETSC_FALSE; 101 ierr = PetscOptionsBool("-ts_save_trajectory","Save the solution at each timestep","TSSetSaveTrajectory",tflg,&tflg,NULL);CHKERRQ(ierr); 102 if (tflg) {ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr);} 103 if (ts->adjoint_solve) tflg = PETSC_TRUE; 104 else tflg = PETSC_FALSE; 105 ierr = PetscOptionsBool("-ts_adjoint_solve","Solve the adjoint problem immediately after solving the forward problem","",tflg,&tflg,&flg);CHKERRQ(ierr); 106 if (flg) { 107 ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); 108 ts->adjoint_solve = tflg; 109 } 110 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,NULL);CHKERRQ(ierr); 111 ierr = PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr); 112 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);CHKERRQ(ierr); 113 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr); 114 if (flg) { 115 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 116 } 117 ierr = PetscOptionsEnum("-ts_exact_final_time","Option for handling of final time step","TSSetExactFinalTime",TSExactFinalTimeOptions,(PetscEnum)ts->exact_final_time,(PetscEnum*)&eftopt,&flg);CHKERRQ(ierr); 118 if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);} 119 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);CHKERRQ(ierr); 120 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);CHKERRQ(ierr); 121 ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);CHKERRQ(ierr); 122 ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);CHKERRQ(ierr); 123 ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);CHKERRQ(ierr); 124 125 #if defined(PETSC_HAVE_SAWS) 126 { 127 PetscBool set; 128 flg = PETSC_FALSE; 129 ierr = PetscOptionsBool("-ts_saws_block","Block for SAWs memory snooper at end of TSSolve","PetscObjectSAWsBlock",((PetscObject)ts)->amspublishblock,&flg,&set);CHKERRQ(ierr); 130 if (set) { 131 ierr = PetscObjectSAWsSetBlock((PetscObject)ts,flg);CHKERRQ(ierr); 132 } 133 } 134 #endif 135 136 /* Monitor options */ 137 ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 138 if (flg) { 139 ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ts),monfilename,&monviewer);CHKERRQ(ierr); 140 ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 141 } 142 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 143 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 144 145 ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 146 if (opt) { 147 TSMonitorLGCtx ctx; 148 PetscInt howoften = 1; 149 150 ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 151 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 152 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 153 } 154 ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr); 155 if (opt) { 156 TSMonitorLGCtx ctx; 157 PetscInt howoften = 1; 158 159 ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 160 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 161 ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 162 } 163 ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr); 164 if (opt) { 165 TSMonitorLGCtx ctx; 166 PetscInt howoften = 1; 167 168 ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);CHKERRQ(ierr); 169 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 170 ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 171 } 172 ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr); 173 if (opt) { 174 TSMonitorLGCtx ctx; 175 PetscInt howoften = 1; 176 177 ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 178 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 179 ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 180 } 181 ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr); 182 if (opt) { 183 TSMonitorLGCtx ctx; 184 PetscInt howoften = 1; 185 186 ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 187 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 188 ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 189 } 190 ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr); 191 if (opt) { 192 TSMonitorSPEigCtx ctx; 193 PetscInt howoften = 1; 194 195 ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);CHKERRQ(ierr); 196 ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 197 ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr); 198 } 199 opt = PETSC_FALSE; 200 ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr); 201 if (opt) { 202 TSMonitorDrawCtx ctx; 203 PetscInt howoften = 1; 204 205 ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 206 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 207 ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 208 } 209 opt = PETSC_FALSE; 210 ierr = PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);CHKERRQ(ierr); 211 if (opt) { 212 TSMonitorDrawCtx ctx; 213 PetscReal bounds[4]; 214 PetscInt n = 4; 215 PetscDraw draw; 216 217 ierr = PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);CHKERRQ(ierr); 218 if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field"); 219 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,1,&ctx);CHKERRQ(ierr); 220 ierr = PetscViewerDrawGetDraw(ctx->viewer,0,&draw);CHKERRQ(ierr); 221 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 222 ierr = PetscDrawAxisCreate(draw,&ctx->axis);CHKERRQ(ierr); 223 ierr = PetscDrawAxisSetLimits(ctx->axis,bounds[0],bounds[2],bounds[1],bounds[3]);CHKERRQ(ierr); 224 ierr = PetscDrawAxisSetLabels(ctx->axis,"Phase Diagram","Variable 1","Variable 2");CHKERRQ(ierr); 225 ierr = PetscDrawAxisDraw(ctx->axis);CHKERRQ(ierr); 226 /* ierr = PetscDrawSetCoordinates(draw,bounds[0],bounds[1],bounds[2],bounds[3]);CHKERRQ(ierr); */ 227 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 228 } 229 opt = PETSC_FALSE; 230 ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr); 231 if (opt) { 232 TSMonitorDrawCtx ctx; 233 PetscInt howoften = 1; 234 235 ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);CHKERRQ(ierr); 236 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 237 ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 238 } 239 opt = PETSC_FALSE; 240 ierr = PetscOptionsString("-ts_monitor_solution_binary","Save each solution to a binary file","TSMonitorSolutionBinary",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 241 if (flg) { 242 PetscViewer ctx; 243 if (monfilename[0]) { 244 ierr = PetscViewerBinaryOpen(PetscObjectComm((PetscObject)ts),monfilename,FILE_MODE_WRITE,&ctx);CHKERRQ(ierr); 245 ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 246 } else { 247 ctx = PETSC_VIEWER_BINARY_(PetscObjectComm((PetscObject)ts)); 248 ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))NULL);CHKERRQ(ierr); 249 } 250 } 251 opt = PETSC_FALSE; 252 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); 253 if (flg) { 254 const char *ptr,*ptr2; 255 char *filetemplate; 256 if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 257 /* Do some cursory validation of the input. */ 258 ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr); 259 if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 260 for (ptr++; ptr && *ptr; ptr++) { 261 ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr); 262 if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03D.vts"); 263 if (ptr2) break; 264 } 265 ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr); 266 ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr); 267 } 268 269 ierr = PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,16,&flg);CHKERRQ(ierr); 270 if (flg) { 271 TSMonitorDMDARayCtx *rayctx; 272 int ray = 0; 273 DMDADirection ddir; 274 DM da; 275 PetscMPIInt rank; 276 277 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 278 if (dir[0] == 'x') ddir = DMDA_X; 279 else if (dir[0] == 'y') ddir = DMDA_Y; 280 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 281 sscanf(dir+2,"%d",&ray); 282 283 ierr = PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %D\n",dir[0],ray);CHKERRQ(ierr); 284 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 285 ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 286 ierr = DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);CHKERRQ(ierr); 287 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr); 288 if (!rank) { 289 ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,0,0,0,600,300,&rayctx->viewer);CHKERRQ(ierr); 290 } 291 rayctx->lgctx = NULL; 292 ierr = TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);CHKERRQ(ierr); 293 } 294 ierr = PetscOptionsString("-ts_monitor_lg_dmda_ray","Display a ray of the solution","None","x=0",dir,16,&flg);CHKERRQ(ierr); 295 if (flg) { 296 TSMonitorDMDARayCtx *rayctx; 297 int ray = 0; 298 DMDADirection ddir; 299 DM da; 300 PetscInt howoften = 1; 301 302 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir); 303 if (dir[0] == 'x') ddir = DMDA_X; 304 else if (dir[0] == 'y') ddir = DMDA_Y; 305 else SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir); 306 sscanf(dir+2, "%d", &ray); 307 308 ierr = PetscInfo2(((PetscObject) ts),"Displaying LG DMDA ray %c = %D\n", dir[0], ray);CHKERRQ(ierr); 309 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 310 ierr = TSGetDM(ts, &da);CHKERRQ(ierr); 311 ierr = DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter);CHKERRQ(ierr); 312 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&rayctx->lgctx);CHKERRQ(ierr); 313 ierr = TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy);CHKERRQ(ierr); 314 } 315 316 ierr = PetscOptionsName("-ts_monitor_envelope","Monitor maximum and minimum value of each component of the solution","TSMonitorEnvelope",&opt);CHKERRQ(ierr); 317 if (opt) { 318 TSMonitorEnvelopeCtx ctx; 319 320 ierr = TSMonitorEnvelopeCtxCreate(ts,&ctx);CHKERRQ(ierr); 321 ierr = TSMonitorSet(ts,TSMonitorEnvelope,ctx,(PetscErrorCode (*)(void**))TSMonitorEnvelopeCtxDestroy);CHKERRQ(ierr); 322 } 323 324 flg = PETSC_FALSE; 325 ierr = PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeJacobianDefaultColor", flg, &flg, NULL);CHKERRQ(ierr); 326 if (flg) { 327 DM dm; 328 DMTS tdm; 329 330 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 331 ierr = DMGetDMTS(dm, &tdm);CHKERRQ(ierr); 332 tdm->ijacobianctx = NULL; 333 ierr = TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, 0);CHKERRQ(ierr); 334 ierr = PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 335 } 336 337 /* 338 This code is all wrong. One is creating objects inside the TSSetFromOptions() so if run with the options gui 339 will bleed memory. Also one is using a PetscOptionsBegin() inside a PetscOptionsBegin() 340 */ 341 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 342 ierr = TSAdaptSetFromOptions(PetscOptionsObject,adapt);CHKERRQ(ierr); 343 344 /* Handle specific TS options */ 345 if (ts->ops->setfromoptions) { 346 ierr = (*ts->ops->setfromoptions)(PetscOptionsObject,ts);CHKERRQ(ierr); 347 } 348 ierr = PetscOptionsEnd();CHKERRQ(ierr); 349 350 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 351 ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr); 352 353 if (ts->trajectory) { 354 ierr = TSTrajectorySetFromOptions(ts->trajectory);CHKERRQ(ierr); 355 } 356 357 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 358 if (snes) { 359 if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);} 360 ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr); 361 } 362 PetscFunctionReturn(0); 363 } 364 365 #undef __FUNCT__ 366 #define __FUNCT__ "TSSetSaveTrajectory" 367 /*@ 368 TSSetSaveTrajectory - Causes the TS to save its solutions as it iterates forward in time in a TSTrajectory object 369 370 Collective on TS 371 372 Input Parameters: 373 . ts - the TS context obtained from TSCreate() 374 375 376 Level: intermediate 377 378 .seealso: TSGetTrajectory(), TSAdjointSolve() 379 380 .keywords: TS, set, checkpoint, 381 @*/ 382 PetscErrorCode TSSetSaveTrajectory(TS ts) 383 { 384 PetscErrorCode ierr; 385 386 PetscFunctionBegin; 387 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 388 if (!ts->trajectory) { 389 ierr = TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory);CHKERRQ(ierr); 390 ierr = TSTrajectorySetType(ts->trajectory,TSTRAJECTORYBASIC);CHKERRQ(ierr); 391 } 392 PetscFunctionReturn(0); 393 } 394 395 #undef __FUNCT__ 396 #define __FUNCT__ "TSComputeRHSJacobian" 397 /*@ 398 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 399 set with TSSetRHSJacobian(). 400 401 Collective on TS and Vec 402 403 Input Parameters: 404 + ts - the TS context 405 . t - current timestep 406 - U - input vector 407 408 Output Parameters: 409 + A - Jacobian matrix 410 . B - optional preconditioning matrix 411 - flag - flag indicating matrix structure 412 413 Notes: 414 Most users should not need to explicitly call this routine, as it 415 is used internally within the nonlinear solvers. 416 417 See KSPSetOperators() for important information about setting the 418 flag parameter. 419 420 Level: developer 421 422 .keywords: SNES, compute, Jacobian, matrix 423 424 .seealso: TSSetRHSJacobian(), KSPSetOperators() 425 @*/ 426 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat B) 427 { 428 PetscErrorCode ierr; 429 PetscObjectState Ustate; 430 DM dm; 431 DMTS tsdm; 432 TSRHSJacobian rhsjacobianfunc; 433 void *ctx; 434 TSIJacobian ijacobianfunc; 435 436 PetscFunctionBegin; 437 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 438 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 439 PetscCheckSameComm(ts,1,U,3); 440 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 441 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 442 ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr); 443 ierr = DMTSGetIJacobian(dm,&ijacobianfunc,NULL);CHKERRQ(ierr); 444 ierr = PetscObjectStateGet((PetscObject)U,&Ustate);CHKERRQ(ierr); 445 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == U && ts->rhsjacobian.Xstate == Ustate))) { 446 PetscFunctionReturn(0); 447 } 448 449 if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 450 451 if (ts->rhsjacobian.reuse) { 452 ierr = MatShift(A,-ts->rhsjacobian.shift);CHKERRQ(ierr); 453 ierr = MatScale(A,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 454 if (A != B) { 455 ierr = MatShift(B,-ts->rhsjacobian.shift);CHKERRQ(ierr); 456 ierr = MatScale(B,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 457 } 458 ts->rhsjacobian.shift = 0; 459 ts->rhsjacobian.scale = 1.; 460 } 461 462 if (rhsjacobianfunc) { 463 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 464 PetscStackPush("TS user Jacobian function"); 465 ierr = (*rhsjacobianfunc)(ts,t,U,A,B,ctx);CHKERRQ(ierr); 466 PetscStackPop; 467 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 468 /* make sure user returned a correct Jacobian and preconditioner */ 469 PetscValidHeaderSpecific(A,MAT_CLASSID,4); 470 PetscValidHeaderSpecific(B,MAT_CLASSID,5); 471 } else { 472 ierr = MatZeroEntries(A);CHKERRQ(ierr); 473 if (A != B) {ierr = MatZeroEntries(B);CHKERRQ(ierr);} 474 } 475 ts->rhsjacobian.time = t; 476 ts->rhsjacobian.X = U; 477 ierr = PetscObjectStateGet((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 478 PetscFunctionReturn(0); 479 } 480 481 #undef __FUNCT__ 482 #define __FUNCT__ "TSComputeRHSFunction" 483 /*@ 484 TSComputeRHSFunction - Evaluates the right-hand-side function. 485 486 Collective on TS and Vec 487 488 Input Parameters: 489 + ts - the TS context 490 . t - current time 491 - U - state vector 492 493 Output Parameter: 494 . y - right hand side 495 496 Note: 497 Most users should not need to explicitly call this routine, as it 498 is used internally within the nonlinear solvers. 499 500 Level: developer 501 502 .keywords: TS, compute 503 504 .seealso: TSSetRHSFunction(), TSComputeIFunction() 505 @*/ 506 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y) 507 { 508 PetscErrorCode ierr; 509 TSRHSFunction rhsfunction; 510 TSIFunction ifunction; 511 void *ctx; 512 DM dm; 513 514 PetscFunctionBegin; 515 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 516 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 517 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 518 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 519 ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr); 520 ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr); 521 522 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 523 524 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 525 if (rhsfunction) { 526 PetscStackPush("TS user right-hand-side function"); 527 ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr); 528 PetscStackPop; 529 } else { 530 ierr = VecZeroEntries(y);CHKERRQ(ierr); 531 } 532 533 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 534 PetscFunctionReturn(0); 535 } 536 537 #undef __FUNCT__ 538 #define __FUNCT__ "TSComputeSolutionFunction" 539 /*@ 540 TSComputeSolutionFunction - Evaluates the solution function. 541 542 Collective on TS and Vec 543 544 Input Parameters: 545 + ts - the TS context 546 - t - current time 547 548 Output Parameter: 549 . U - the solution 550 551 Note: 552 Most users should not need to explicitly call this routine, as it 553 is used internally within the nonlinear solvers. 554 555 Level: developer 556 557 .keywords: TS, compute 558 559 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 560 @*/ 561 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U) 562 { 563 PetscErrorCode ierr; 564 TSSolutionFunction solutionfunction; 565 void *ctx; 566 DM dm; 567 568 PetscFunctionBegin; 569 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 570 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 571 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 572 ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr); 573 574 if (solutionfunction) { 575 PetscStackPush("TS user solution function"); 576 ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr); 577 PetscStackPop; 578 } 579 PetscFunctionReturn(0); 580 } 581 #undef __FUNCT__ 582 #define __FUNCT__ "TSComputeForcingFunction" 583 /*@ 584 TSComputeForcingFunction - Evaluates the forcing function. 585 586 Collective on TS and Vec 587 588 Input Parameters: 589 + ts - the TS context 590 - t - current time 591 592 Output Parameter: 593 . U - the function value 594 595 Note: 596 Most users should not need to explicitly call this routine, as it 597 is used internally within the nonlinear solvers. 598 599 Level: developer 600 601 .keywords: TS, compute 602 603 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 604 @*/ 605 PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U) 606 { 607 PetscErrorCode ierr, (*forcing)(TS,PetscReal,Vec,void*); 608 void *ctx; 609 DM dm; 610 611 PetscFunctionBegin; 612 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 613 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 614 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 615 ierr = DMTSGetForcingFunction(dm,&forcing,&ctx);CHKERRQ(ierr); 616 617 if (forcing) { 618 PetscStackPush("TS user forcing function"); 619 ierr = (*forcing)(ts,t,U,ctx);CHKERRQ(ierr); 620 PetscStackPop; 621 } 622 PetscFunctionReturn(0); 623 } 624 625 #undef __FUNCT__ 626 #define __FUNCT__ "TSGetRHSVec_Private" 627 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 628 { 629 Vec F; 630 PetscErrorCode ierr; 631 632 PetscFunctionBegin; 633 *Frhs = NULL; 634 ierr = TSGetIFunction(ts,&F,NULL,NULL);CHKERRQ(ierr); 635 if (!ts->Frhs) { 636 ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr); 637 } 638 *Frhs = ts->Frhs; 639 PetscFunctionReturn(0); 640 } 641 642 #undef __FUNCT__ 643 #define __FUNCT__ "TSGetRHSMats_Private" 644 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 645 { 646 Mat A,B; 647 PetscErrorCode ierr; 648 649 PetscFunctionBegin; 650 if (Arhs) *Arhs = NULL; 651 if (Brhs) *Brhs = NULL; 652 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 653 if (Arhs) { 654 if (!ts->Arhs) { 655 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 656 } 657 *Arhs = ts->Arhs; 658 } 659 if (Brhs) { 660 if (!ts->Brhs) { 661 if (A != B) { 662 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 663 } else { 664 ts->Brhs = ts->Arhs; 665 ierr = PetscObjectReference((PetscObject)ts->Arhs);CHKERRQ(ierr); 666 } 667 } 668 *Brhs = ts->Brhs; 669 } 670 PetscFunctionReturn(0); 671 } 672 673 #undef __FUNCT__ 674 #define __FUNCT__ "TSComputeIFunction" 675 /*@ 676 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0 677 678 Collective on TS and Vec 679 680 Input Parameters: 681 + ts - the TS context 682 . t - current time 683 . U - state vector 684 . Udot - time derivative of state vector 685 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 686 687 Output Parameter: 688 . Y - right hand side 689 690 Note: 691 Most users should not need to explicitly call this routine, as it 692 is used internally within the nonlinear solvers. 693 694 If the user did did not write their equations in implicit form, this 695 function recasts them in implicit form. 696 697 Level: developer 698 699 .keywords: TS, compute 700 701 .seealso: TSSetIFunction(), TSComputeRHSFunction() 702 @*/ 703 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex) 704 { 705 PetscErrorCode ierr; 706 TSIFunction ifunction; 707 TSRHSFunction rhsfunction; 708 void *ctx; 709 DM dm; 710 711 PetscFunctionBegin; 712 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 713 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 714 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 715 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 716 717 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 718 ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr); 719 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 720 721 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 722 723 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 724 if (ifunction) { 725 PetscStackPush("TS user implicit function"); 726 ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr); 727 PetscStackPop; 728 } 729 if (imex) { 730 if (!ifunction) { 731 ierr = VecCopy(Udot,Y);CHKERRQ(ierr); 732 } 733 } else if (rhsfunction) { 734 if (ifunction) { 735 Vec Frhs; 736 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 737 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 738 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 739 } else { 740 ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr); 741 ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr); 742 } 743 } 744 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 745 PetscFunctionReturn(0); 746 } 747 748 #undef __FUNCT__ 749 #define __FUNCT__ "TSComputeIJacobian" 750 /*@ 751 TSComputeIJacobian - Evaluates the Jacobian of the DAE 752 753 Collective on TS and Vec 754 755 Input 756 Input Parameters: 757 + ts - the TS context 758 . t - current timestep 759 . U - state vector 760 . Udot - time derivative of state vector 761 . shift - shift to apply, see note below 762 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 763 764 Output Parameters: 765 + A - Jacobian matrix 766 . B - optional preconditioning matrix 767 - flag - flag indicating matrix structure 768 769 Notes: 770 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 771 772 dF/dU + shift*dF/dUdot 773 774 Most users should not need to explicitly call this routine, as it 775 is used internally within the nonlinear solvers. 776 777 Level: developer 778 779 .keywords: TS, compute, Jacobian, matrix 780 781 .seealso: TSSetIJacobian() 782 @*/ 783 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,PetscBool imex) 784 { 785 PetscErrorCode ierr; 786 TSIJacobian ijacobian; 787 TSRHSJacobian rhsjacobian; 788 DM dm; 789 void *ctx; 790 791 PetscFunctionBegin; 792 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 793 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 794 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 795 PetscValidPointer(A,6); 796 PetscValidHeaderSpecific(A,MAT_CLASSID,6); 797 PetscValidPointer(B,7); 798 PetscValidHeaderSpecific(B,MAT_CLASSID,7); 799 800 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 801 ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr); 802 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 803 804 if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 805 806 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 807 if (ijacobian) { 808 PetscStackPush("TS user implicit Jacobian"); 809 ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,ctx);CHKERRQ(ierr); 810 PetscStackPop; 811 /* make sure user returned a correct Jacobian and preconditioner */ 812 PetscValidHeaderSpecific(A,MAT_CLASSID,4); 813 PetscValidHeaderSpecific(B,MAT_CLASSID,5); 814 } 815 if (imex) { 816 if (!ijacobian) { /* system was written as Udot = G(t,U) */ 817 ierr = MatZeroEntries(A);CHKERRQ(ierr); 818 ierr = MatShift(A,shift);CHKERRQ(ierr); 819 if (A != B) { 820 ierr = MatZeroEntries(B);CHKERRQ(ierr); 821 ierr = MatShift(B,shift);CHKERRQ(ierr); 822 } 823 } 824 } else { 825 Mat Arhs = NULL,Brhs = NULL; 826 if (rhsjacobian) { 827 if (ijacobian) { 828 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 829 } else { 830 ierr = TSGetIJacobian(ts,&Arhs,&Brhs,NULL,NULL);CHKERRQ(ierr); 831 } 832 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 833 } 834 if (Arhs == A) { /* No IJacobian, so we only have the RHS matrix */ 835 ts->rhsjacobian.scale = -1; 836 ts->rhsjacobian.shift = shift; 837 ierr = MatScale(A,-1);CHKERRQ(ierr); 838 ierr = MatShift(A,shift);CHKERRQ(ierr); 839 if (A != B) { 840 ierr = MatScale(B,-1);CHKERRQ(ierr); 841 ierr = MatShift(B,shift);CHKERRQ(ierr); 842 } 843 } else if (Arhs) { /* Both IJacobian and RHSJacobian */ 844 MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 845 if (!ijacobian) { /* No IJacobian provided, but we have a separate RHS matrix */ 846 ierr = MatZeroEntries(A);CHKERRQ(ierr); 847 ierr = MatShift(A,shift);CHKERRQ(ierr); 848 if (A != B) { 849 ierr = MatZeroEntries(B);CHKERRQ(ierr); 850 ierr = MatShift(B,shift);CHKERRQ(ierr); 851 } 852 } 853 ierr = MatAXPY(A,-1,Arhs,axpy);CHKERRQ(ierr); 854 if (A != B) { 855 ierr = MatAXPY(B,-1,Brhs,axpy);CHKERRQ(ierr); 856 } 857 } 858 } 859 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 860 PetscFunctionReturn(0); 861 } 862 863 #undef __FUNCT__ 864 #define __FUNCT__ "TSSetRHSFunction" 865 /*@C 866 TSSetRHSFunction - Sets the routine for evaluating the function, 867 where U_t = G(t,u). 868 869 Logically Collective on TS 870 871 Input Parameters: 872 + ts - the TS context obtained from TSCreate() 873 . r - vector to put the computed right hand side (or NULL to have it created) 874 . f - routine for evaluating the right-hand-side function 875 - ctx - [optional] user-defined context for private data for the 876 function evaluation routine (may be NULL) 877 878 Calling sequence of func: 879 $ func (TS ts,PetscReal t,Vec u,Vec F,void *ctx); 880 881 + t - current timestep 882 . u - input vector 883 . F - function vector 884 - ctx - [optional] user-defined function context 885 886 Level: beginner 887 888 Notes: You must call this function or TSSetIFunction() to define your ODE. You cannot use this function when solving a DAE. 889 890 .keywords: TS, timestep, set, right-hand-side, function 891 892 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSSetIFunction() 893 @*/ 894 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 895 { 896 PetscErrorCode ierr; 897 SNES snes; 898 Vec ralloc = NULL; 899 DM dm; 900 901 PetscFunctionBegin; 902 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 903 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 904 905 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 906 ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr); 907 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 908 if (!r && !ts->dm && ts->vec_sol) { 909 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 910 r = ralloc; 911 } 912 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 913 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 914 PetscFunctionReturn(0); 915 } 916 917 #undef __FUNCT__ 918 #define __FUNCT__ "TSSetSolutionFunction" 919 /*@C 920 TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE 921 922 Logically Collective on TS 923 924 Input Parameters: 925 + ts - the TS context obtained from TSCreate() 926 . f - routine for evaluating the solution 927 - ctx - [optional] user-defined context for private data for the 928 function evaluation routine (may be NULL) 929 930 Calling sequence of func: 931 $ func (TS ts,PetscReal t,Vec u,void *ctx); 932 933 + t - current timestep 934 . u - output vector 935 - ctx - [optional] user-defined function context 936 937 Notes: 938 This routine is used for testing accuracy of time integration schemes when you already know the solution. 939 If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to 940 create closed-form solutions with non-physical forcing terms. 941 942 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 943 944 Level: beginner 945 946 .keywords: TS, timestep, set, right-hand-side, function 947 948 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction() 949 @*/ 950 PetscErrorCode TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 951 { 952 PetscErrorCode ierr; 953 DM dm; 954 955 PetscFunctionBegin; 956 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 957 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 958 ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr); 959 PetscFunctionReturn(0); 960 } 961 962 #undef __FUNCT__ 963 #define __FUNCT__ "TSSetForcingFunction" 964 /*@C 965 TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE 966 967 Logically Collective on TS 968 969 Input Parameters: 970 + ts - the TS context obtained from TSCreate() 971 . f - routine for evaluating the forcing function 972 - ctx - [optional] user-defined context for private data for the 973 function evaluation routine (may be NULL) 974 975 Calling sequence of func: 976 $ func (TS ts,PetscReal t,Vec u,void *ctx); 977 978 + t - current timestep 979 . u - output vector 980 - ctx - [optional] user-defined function context 981 982 Notes: 983 This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to 984 create closed-form solutions with a non-physical forcing term. 985 986 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 987 988 Level: beginner 989 990 .keywords: TS, timestep, set, right-hand-side, function 991 992 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction() 993 @*/ 994 PetscErrorCode TSSetForcingFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 995 { 996 PetscErrorCode ierr; 997 DM dm; 998 999 PetscFunctionBegin; 1000 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1001 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1002 ierr = DMTSSetForcingFunction(dm,f,ctx);CHKERRQ(ierr); 1003 PetscFunctionReturn(0); 1004 } 1005 1006 #undef __FUNCT__ 1007 #define __FUNCT__ "TSSetRHSJacobian" 1008 /*@C 1009 TSSetRHSJacobian - Sets the function to compute the Jacobian of G, 1010 where U_t = G(U,t), as well as the location to store the matrix. 1011 1012 Logically Collective on TS 1013 1014 Input Parameters: 1015 + ts - the TS context obtained from TSCreate() 1016 . Amat - (approximate) Jacobian matrix 1017 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1018 . f - the Jacobian evaluation routine 1019 - ctx - [optional] user-defined context for private data for the 1020 Jacobian evaluation routine (may be NULL) 1021 1022 Calling sequence of f: 1023 $ func (TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx); 1024 1025 + t - current timestep 1026 . u - input vector 1027 . Amat - (approximate) Jacobian matrix 1028 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1029 - ctx - [optional] user-defined context for matrix evaluation routine 1030 1031 1032 Level: beginner 1033 1034 .keywords: TS, timestep, set, right-hand-side, Jacobian 1035 1036 .seealso: SNESComputeJacobianDefaultColor(), TSSetRHSFunction(), TSRHSJacobianSetReuse(), TSSetIJacobian() 1037 1038 @*/ 1039 PetscErrorCode TSSetRHSJacobian(TS ts,Mat Amat,Mat Pmat,TSRHSJacobian f,void *ctx) 1040 { 1041 PetscErrorCode ierr; 1042 SNES snes; 1043 DM dm; 1044 TSIJacobian ijacobian; 1045 1046 PetscFunctionBegin; 1047 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1048 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1049 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1050 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1051 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1052 1053 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1054 ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr); 1055 if (f == TSComputeRHSJacobianConstant) { 1056 /* Handle this case automatically for the user; otherwise user should call themselves. */ 1057 ierr = TSRHSJacobianSetReuse(ts,PETSC_TRUE);CHKERRQ(ierr); 1058 } 1059 ierr = DMTSGetIJacobian(dm,&ijacobian,NULL);CHKERRQ(ierr); 1060 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1061 if (!ijacobian) { 1062 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1063 } 1064 if (Amat) { 1065 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 1066 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1067 1068 ts->Arhs = Amat; 1069 } 1070 if (Pmat) { 1071 ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 1072 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1073 1074 ts->Brhs = Pmat; 1075 } 1076 PetscFunctionReturn(0); 1077 } 1078 1079 1080 #undef __FUNCT__ 1081 #define __FUNCT__ "TSSetIFunction" 1082 /*@C 1083 TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved. 1084 1085 Logically Collective on TS 1086 1087 Input Parameters: 1088 + ts - the TS context obtained from TSCreate() 1089 . r - vector to hold the residual (or NULL to have it created internally) 1090 . f - the function evaluation routine 1091 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1092 1093 Calling sequence of f: 1094 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 1095 1096 + t - time at step/stage being solved 1097 . u - state vector 1098 . u_t - time derivative of state vector 1099 . F - function vector 1100 - ctx - [optional] user-defined context for matrix evaluation routine 1101 1102 Important: 1103 The user MUST call either this routine or TSSetRHSFunction() to define the ODE. When solving DAEs you must use this function. 1104 1105 Level: beginner 1106 1107 .keywords: TS, timestep, set, DAE, Jacobian 1108 1109 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian() 1110 @*/ 1111 PetscErrorCode TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx) 1112 { 1113 PetscErrorCode ierr; 1114 SNES snes; 1115 Vec resalloc = NULL; 1116 DM dm; 1117 1118 PetscFunctionBegin; 1119 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1120 if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2); 1121 1122 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1123 ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr); 1124 1125 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1126 if (!res && !ts->dm && ts->vec_sol) { 1127 ierr = VecDuplicate(ts->vec_sol,&resalloc);CHKERRQ(ierr); 1128 res = resalloc; 1129 } 1130 ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr); 1131 ierr = VecDestroy(&resalloc);CHKERRQ(ierr); 1132 PetscFunctionReturn(0); 1133 } 1134 1135 #undef __FUNCT__ 1136 #define __FUNCT__ "TSGetIFunction" 1137 /*@C 1138 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1139 1140 Not Collective 1141 1142 Input Parameter: 1143 . ts - the TS context 1144 1145 Output Parameter: 1146 + r - vector to hold residual (or NULL) 1147 . func - the function to compute residual (or NULL) 1148 - ctx - the function context (or NULL) 1149 1150 Level: advanced 1151 1152 .keywords: TS, nonlinear, get, function 1153 1154 .seealso: TSSetIFunction(), SNESGetFunction() 1155 @*/ 1156 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 1157 { 1158 PetscErrorCode ierr; 1159 SNES snes; 1160 DM dm; 1161 1162 PetscFunctionBegin; 1163 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1164 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1165 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1166 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1167 ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr); 1168 PetscFunctionReturn(0); 1169 } 1170 1171 #undef __FUNCT__ 1172 #define __FUNCT__ "TSGetRHSFunction" 1173 /*@C 1174 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 1175 1176 Not Collective 1177 1178 Input Parameter: 1179 . ts - the TS context 1180 1181 Output Parameter: 1182 + r - vector to hold computed right hand side (or NULL) 1183 . func - the function to compute right hand side (or NULL) 1184 - ctx - the function context (or NULL) 1185 1186 Level: advanced 1187 1188 .keywords: TS, nonlinear, get, function 1189 1190 .seealso: TSSetRHSFunction(), SNESGetFunction() 1191 @*/ 1192 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 1193 { 1194 PetscErrorCode ierr; 1195 SNES snes; 1196 DM dm; 1197 1198 PetscFunctionBegin; 1199 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1200 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1201 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1202 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1203 ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr); 1204 PetscFunctionReturn(0); 1205 } 1206 1207 #undef __FUNCT__ 1208 #define __FUNCT__ "TSSetIJacobian" 1209 /*@C 1210 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 1211 provided with TSSetIFunction(). 1212 1213 Logically Collective on TS 1214 1215 Input Parameters: 1216 + ts - the TS context obtained from TSCreate() 1217 . Amat - (approximate) Jacobian matrix 1218 . Pmat - matrix used to compute preconditioner (usually the same as Amat) 1219 . f - the Jacobian evaluation routine 1220 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1221 1222 Calling sequence of f: 1223 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx); 1224 1225 + t - time at step/stage being solved 1226 . U - state vector 1227 . U_t - time derivative of state vector 1228 . a - shift 1229 . Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 1230 . Pmat - matrix used for constructing preconditioner, usually the same as Amat 1231 - ctx - [optional] user-defined context for matrix evaluation routine 1232 1233 Notes: 1234 The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve. 1235 1236 The matrix dF/dU + a*dF/dU_t you provide turns out to be 1237 the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 1238 The time integrator internally approximates U_t by W+a*U where the positive "shift" 1239 a and vector W depend on the integration method, step size, and past states. For example with 1240 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 1241 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 1242 1243 Level: beginner 1244 1245 .keywords: TS, timestep, DAE, Jacobian 1246 1247 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESComputeJacobianDefaultColor(), SNESComputeJacobianDefault(), TSSetRHSFunction() 1248 1249 @*/ 1250 PetscErrorCode TSSetIJacobian(TS ts,Mat Amat,Mat Pmat,TSIJacobian f,void *ctx) 1251 { 1252 PetscErrorCode ierr; 1253 SNES snes; 1254 DM dm; 1255 1256 PetscFunctionBegin; 1257 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1258 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1259 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1260 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1261 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1262 1263 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1264 ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr); 1265 1266 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1267 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1268 PetscFunctionReturn(0); 1269 } 1270 1271 #undef __FUNCT__ 1272 #define __FUNCT__ "TSRHSJacobianSetReuse" 1273 /*@ 1274 TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating. Without this flag, TS will change the sign and 1275 shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute 1276 the entire Jacobian. The reuse flag must be set if the evaluation function will assume that the matrix entries have 1277 not been changed by the TS. 1278 1279 Logically Collective 1280 1281 Input Arguments: 1282 + ts - TS context obtained from TSCreate() 1283 - reuse - PETSC_TRUE if the RHS Jacobian 1284 1285 Level: intermediate 1286 1287 .seealso: TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 1288 @*/ 1289 PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse) 1290 { 1291 PetscFunctionBegin; 1292 ts->rhsjacobian.reuse = reuse; 1293 PetscFunctionReturn(0); 1294 } 1295 1296 #undef __FUNCT__ 1297 #define __FUNCT__ "TSLoad" 1298 /*@C 1299 TSLoad - Loads a KSP that has been stored in binary with KSPView(). 1300 1301 Collective on PetscViewer 1302 1303 Input Parameters: 1304 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or 1305 some related function before a call to TSLoad(). 1306 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 1307 1308 Level: intermediate 1309 1310 Notes: 1311 The type is determined by the data in the file, any type set into the TS before this call is ignored. 1312 1313 Notes for advanced users: 1314 Most users should not need to know the details of the binary storage 1315 format, since TSLoad() and TSView() completely hide these details. 1316 But for anyone who's interested, the standard binary matrix storage 1317 format is 1318 .vb 1319 has not yet been determined 1320 .ve 1321 1322 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad() 1323 @*/ 1324 PetscErrorCode TSLoad(TS ts, PetscViewer viewer) 1325 { 1326 PetscErrorCode ierr; 1327 PetscBool isbinary; 1328 PetscInt classid; 1329 char type[256]; 1330 DMTS sdm; 1331 DM dm; 1332 1333 PetscFunctionBegin; 1334 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1335 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1336 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1337 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 1338 1339 ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 1340 if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file"); 1341 ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr); 1342 ierr = TSSetType(ts, type);CHKERRQ(ierr); 1343 if (ts->ops->load) { 1344 ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr); 1345 } 1346 ierr = DMCreate(PetscObjectComm((PetscObject)ts),&dm);CHKERRQ(ierr); 1347 ierr = DMLoad(dm,viewer);CHKERRQ(ierr); 1348 ierr = TSSetDM(ts,dm);CHKERRQ(ierr); 1349 ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr); 1350 ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr); 1351 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1352 ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr); 1353 PetscFunctionReturn(0); 1354 } 1355 1356 #include <petscdraw.h> 1357 #if defined(PETSC_HAVE_SAWS) 1358 #include <petscviewersaws.h> 1359 #endif 1360 #undef __FUNCT__ 1361 #define __FUNCT__ "TSView" 1362 /*@C 1363 TSView - Prints the TS data structure. 1364 1365 Collective on TS 1366 1367 Input Parameters: 1368 + ts - the TS context obtained from TSCreate() 1369 - viewer - visualization context 1370 1371 Options Database Key: 1372 . -ts_view - calls TSView() at end of TSStep() 1373 1374 Notes: 1375 The available visualization contexts include 1376 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 1377 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 1378 output where only the first processor opens 1379 the file. All other processors send their 1380 data to the first processor to print. 1381 1382 The user can open an alternative visualization context with 1383 PetscViewerASCIIOpen() - output to a specified file. 1384 1385 Level: beginner 1386 1387 .keywords: TS, timestep, view 1388 1389 .seealso: PetscViewerASCIIOpen() 1390 @*/ 1391 PetscErrorCode TSView(TS ts,PetscViewer viewer) 1392 { 1393 PetscErrorCode ierr; 1394 TSType type; 1395 PetscBool iascii,isstring,isundials,isbinary,isdraw; 1396 DMTS sdm; 1397 #if defined(PETSC_HAVE_SAWS) 1398 PetscBool issaws; 1399 #endif 1400 1401 PetscFunctionBegin; 1402 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1403 if (!viewer) { 1404 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr); 1405 } 1406 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1407 PetscCheckSameComm(ts,1,viewer,2); 1408 1409 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1410 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1411 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1412 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1413 #if defined(PETSC_HAVE_SAWS) 1414 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1415 #endif 1416 if (iascii) { 1417 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer);CHKERRQ(ierr); 1418 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 1419 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%g\n",(double)ts->max_time);CHKERRQ(ierr); 1420 if (ts->problem_type == TS_NONLINEAR) { 1421 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr); 1422 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr); 1423 } 1424 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr); 1425 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 1426 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1427 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1428 if (ts->ops->view) { 1429 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1430 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1431 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1432 } 1433 } else if (isstring) { 1434 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 1435 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 1436 } else if (isbinary) { 1437 PetscInt classid = TS_FILE_CLASSID; 1438 MPI_Comm comm; 1439 PetscMPIInt rank; 1440 char type[256]; 1441 1442 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 1443 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 1444 if (!rank) { 1445 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 1446 ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr); 1447 ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 1448 } 1449 if (ts->ops->view) { 1450 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1451 } 1452 ierr = DMView(ts->dm,viewer);CHKERRQ(ierr); 1453 ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr); 1454 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1455 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1456 } else if (isdraw) { 1457 PetscDraw draw; 1458 char str[36]; 1459 PetscReal x,y,bottom,h; 1460 1461 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1462 ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 1463 ierr = PetscStrcpy(str,"TS: ");CHKERRQ(ierr); 1464 ierr = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr); 1465 ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 1466 bottom = y - h; 1467 ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 1468 if (ts->ops->view) { 1469 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1470 } 1471 ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 1472 #if defined(PETSC_HAVE_SAWS) 1473 } else if (issaws) { 1474 PetscMPIInt rank; 1475 const char *name; 1476 1477 ierr = PetscObjectGetName((PetscObject)ts,&name);CHKERRQ(ierr); 1478 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1479 if (!((PetscObject)ts)->amsmem && !rank) { 1480 char dir[1024]; 1481 1482 ierr = PetscObjectViewSAWs((PetscObject)ts,viewer);CHKERRQ(ierr); 1483 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);CHKERRQ(ierr); 1484 PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT)); 1485 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);CHKERRQ(ierr); 1486 PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE)); 1487 } 1488 if (ts->ops->view) { 1489 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1490 } 1491 #endif 1492 } 1493 1494 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1495 ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 1496 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1497 PetscFunctionReturn(0); 1498 } 1499 1500 1501 #undef __FUNCT__ 1502 #define __FUNCT__ "TSSetApplicationContext" 1503 /*@ 1504 TSSetApplicationContext - Sets an optional user-defined context for 1505 the timesteppers. 1506 1507 Logically Collective on TS 1508 1509 Input Parameters: 1510 + ts - the TS context obtained from TSCreate() 1511 - usrP - optional user context 1512 1513 Level: intermediate 1514 1515 .keywords: TS, timestep, set, application, context 1516 1517 .seealso: TSGetApplicationContext() 1518 @*/ 1519 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 1520 { 1521 PetscFunctionBegin; 1522 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1523 ts->user = usrP; 1524 PetscFunctionReturn(0); 1525 } 1526 1527 #undef __FUNCT__ 1528 #define __FUNCT__ "TSGetApplicationContext" 1529 /*@ 1530 TSGetApplicationContext - Gets the user-defined context for the 1531 timestepper. 1532 1533 Not Collective 1534 1535 Input Parameter: 1536 . ts - the TS context obtained from TSCreate() 1537 1538 Output Parameter: 1539 . usrP - user context 1540 1541 Level: intermediate 1542 1543 .keywords: TS, timestep, get, application, context 1544 1545 .seealso: TSSetApplicationContext() 1546 @*/ 1547 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 1548 { 1549 PetscFunctionBegin; 1550 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1551 *(void**)usrP = ts->user; 1552 PetscFunctionReturn(0); 1553 } 1554 1555 #undef __FUNCT__ 1556 #define __FUNCT__ "TSGetTimeStepNumber" 1557 /*@ 1558 TSGetTimeStepNumber - Gets the number of time steps completed. 1559 1560 Not Collective 1561 1562 Input Parameter: 1563 . ts - the TS context obtained from TSCreate() 1564 1565 Output Parameter: 1566 . iter - number of steps completed so far 1567 1568 Level: intermediate 1569 1570 .keywords: TS, timestep, get, iteration, number 1571 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep() 1572 @*/ 1573 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *iter) 1574 { 1575 PetscFunctionBegin; 1576 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1577 PetscValidIntPointer(iter,2); 1578 *iter = ts->steps; 1579 PetscFunctionReturn(0); 1580 } 1581 1582 #undef __FUNCT__ 1583 #define __FUNCT__ "TSSetInitialTimeStep" 1584 /*@ 1585 TSSetInitialTimeStep - Sets the initial timestep to be used, 1586 as well as the initial time. 1587 1588 Logically Collective on TS 1589 1590 Input Parameters: 1591 + ts - the TS context obtained from TSCreate() 1592 . initial_time - the initial time 1593 - time_step - the size of the timestep 1594 1595 Level: intermediate 1596 1597 .seealso: TSSetTimeStep(), TSGetTimeStep() 1598 1599 .keywords: TS, set, initial, timestep 1600 @*/ 1601 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 1602 { 1603 PetscErrorCode ierr; 1604 1605 PetscFunctionBegin; 1606 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1607 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 1608 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 1609 PetscFunctionReturn(0); 1610 } 1611 1612 #undef __FUNCT__ 1613 #define __FUNCT__ "TSSetTimeStep" 1614 /*@ 1615 TSSetTimeStep - Allows one to reset the timestep at any time, 1616 useful for simple pseudo-timestepping codes. 1617 1618 Logically Collective on TS 1619 1620 Input Parameters: 1621 + ts - the TS context obtained from TSCreate() 1622 - time_step - the size of the timestep 1623 1624 Level: intermediate 1625 1626 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1627 1628 .keywords: TS, set, timestep 1629 @*/ 1630 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 1631 { 1632 PetscFunctionBegin; 1633 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1634 PetscValidLogicalCollectiveReal(ts,time_step,2); 1635 ts->time_step = time_step; 1636 ts->time_step_orig = time_step; 1637 PetscFunctionReturn(0); 1638 } 1639 1640 #undef __FUNCT__ 1641 #define __FUNCT__ "TSSetExactFinalTime" 1642 /*@ 1643 TSSetExactFinalTime - Determines whether to adapt the final time step to 1644 match the exact final time, interpolate solution to the exact final time, 1645 or just return at the final time TS computed. 1646 1647 Logically Collective on TS 1648 1649 Input Parameter: 1650 + ts - the time-step context 1651 - eftopt - exact final time option 1652 1653 Level: beginner 1654 1655 .seealso: TSExactFinalTimeOption 1656 @*/ 1657 PetscErrorCode TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt) 1658 { 1659 PetscFunctionBegin; 1660 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1661 PetscValidLogicalCollectiveEnum(ts,eftopt,2); 1662 ts->exact_final_time = eftopt; 1663 PetscFunctionReturn(0); 1664 } 1665 1666 #undef __FUNCT__ 1667 #define __FUNCT__ "TSGetTimeStep" 1668 /*@ 1669 TSGetTimeStep - Gets the current timestep size. 1670 1671 Not Collective 1672 1673 Input Parameter: 1674 . ts - the TS context obtained from TSCreate() 1675 1676 Output Parameter: 1677 . dt - the current timestep size 1678 1679 Level: intermediate 1680 1681 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1682 1683 .keywords: TS, get, timestep 1684 @*/ 1685 PetscErrorCode TSGetTimeStep(TS ts,PetscReal *dt) 1686 { 1687 PetscFunctionBegin; 1688 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1689 PetscValidRealPointer(dt,2); 1690 *dt = ts->time_step; 1691 PetscFunctionReturn(0); 1692 } 1693 1694 #undef __FUNCT__ 1695 #define __FUNCT__ "TSGetSolution" 1696 /*@ 1697 TSGetSolution - Returns the solution at the present timestep. It 1698 is valid to call this routine inside the function that you are evaluating 1699 in order to move to the new timestep. This vector not changed until 1700 the solution at the next timestep has been calculated. 1701 1702 Not Collective, but Vec returned is parallel if TS is parallel 1703 1704 Input Parameter: 1705 . ts - the TS context obtained from TSCreate() 1706 1707 Output Parameter: 1708 . v - the vector containing the solution 1709 1710 Level: intermediate 1711 1712 .seealso: TSGetTimeStep() 1713 1714 .keywords: TS, timestep, get, solution 1715 @*/ 1716 PetscErrorCode TSGetSolution(TS ts,Vec *v) 1717 { 1718 PetscFunctionBegin; 1719 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1720 PetscValidPointer(v,2); 1721 *v = ts->vec_sol; 1722 PetscFunctionReturn(0); 1723 } 1724 1725 #undef __FUNCT__ 1726 #define __FUNCT__ "TSAdjointGetCostGradients" 1727 /*@ 1728 TSAdjointGetCostGradients - Returns the gradients from the TSAdjointSolve() 1729 1730 Not Collective, but Vec returned is parallel if TS is parallel 1731 1732 Input Parameter: 1733 . ts - the TS context obtained from TSCreate() 1734 1735 Output Parameter: 1736 + lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 1737 - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 1738 1739 Level: intermediate 1740 1741 .seealso: TSGetTimeStep() 1742 1743 .keywords: TS, timestep, get, sensitivity 1744 @*/ 1745 PetscErrorCode TSAdjointGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu) 1746 { 1747 PetscFunctionBegin; 1748 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1749 if (numcost) *numcost = ts->numcost; 1750 if (lambda) *lambda = ts->vecs_sensi; 1751 if (mu) *mu = ts->vecs_sensip; 1752 PetscFunctionReturn(0); 1753 } 1754 1755 /* ----- Routines to initialize and destroy a timestepper ---- */ 1756 #undef __FUNCT__ 1757 #define __FUNCT__ "TSSetProblemType" 1758 /*@ 1759 TSSetProblemType - Sets the type of problem to be solved. 1760 1761 Not collective 1762 1763 Input Parameters: 1764 + ts - The TS 1765 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1766 .vb 1767 U_t - A U = 0 (linear) 1768 U_t - A(t) U = 0 (linear) 1769 F(t,U,U_t) = 0 (nonlinear) 1770 .ve 1771 1772 Level: beginner 1773 1774 .keywords: TS, problem type 1775 .seealso: TSSetUp(), TSProblemType, TS 1776 @*/ 1777 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 1778 { 1779 PetscErrorCode ierr; 1780 1781 PetscFunctionBegin; 1782 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1783 ts->problem_type = type; 1784 if (type == TS_LINEAR) { 1785 SNES snes; 1786 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1787 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 1788 } 1789 PetscFunctionReturn(0); 1790 } 1791 1792 #undef __FUNCT__ 1793 #define __FUNCT__ "TSGetProblemType" 1794 /*@C 1795 TSGetProblemType - Gets the type of problem to be solved. 1796 1797 Not collective 1798 1799 Input Parameter: 1800 . ts - The TS 1801 1802 Output Parameter: 1803 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1804 .vb 1805 M U_t = A U 1806 M(t) U_t = A(t) U 1807 F(t,U,U_t) 1808 .ve 1809 1810 Level: beginner 1811 1812 .keywords: TS, problem type 1813 .seealso: TSSetUp(), TSProblemType, TS 1814 @*/ 1815 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 1816 { 1817 PetscFunctionBegin; 1818 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1819 PetscValidIntPointer(type,2); 1820 *type = ts->problem_type; 1821 PetscFunctionReturn(0); 1822 } 1823 1824 #undef __FUNCT__ 1825 #define __FUNCT__ "TSSetUp" 1826 /*@ 1827 TSSetUp - Sets up the internal data structures for the later use 1828 of a timestepper. 1829 1830 Collective on TS 1831 1832 Input Parameter: 1833 . ts - the TS context obtained from TSCreate() 1834 1835 Notes: 1836 For basic use of the TS solvers the user need not explicitly call 1837 TSSetUp(), since these actions will automatically occur during 1838 the call to TSStep(). However, if one wishes to control this 1839 phase separately, TSSetUp() should be called after TSCreate() 1840 and optional routines of the form TSSetXXX(), but before TSStep(). 1841 1842 Level: advanced 1843 1844 .keywords: TS, timestep, setup 1845 1846 .seealso: TSCreate(), TSStep(), TSDestroy() 1847 @*/ 1848 PetscErrorCode TSSetUp(TS ts) 1849 { 1850 PetscErrorCode ierr; 1851 DM dm; 1852 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 1853 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 1854 TSIJacobian ijac; 1855 TSRHSJacobian rhsjac; 1856 1857 PetscFunctionBegin; 1858 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1859 if (ts->setupcalled) PetscFunctionReturn(0); 1860 1861 ts->total_steps = 0; 1862 if (!((PetscObject)ts)->type_name) { 1863 ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); 1864 } 1865 1866 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 1867 1868 1869 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 1870 1871 if (ts->rhsjacobian.reuse) { 1872 Mat Amat,Pmat; 1873 SNES snes; 1874 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1875 ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr); 1876 /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would 1877 * have displaced the RHS matrix */ 1878 if (Amat == ts->Arhs) { 1879 ierr = MatDuplicate(ts->Arhs,MAT_DO_NOT_COPY_VALUES,&Amat);CHKERRQ(ierr); 1880 ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr); 1881 ierr = MatDestroy(&Amat);CHKERRQ(ierr); 1882 } 1883 if (Pmat == ts->Brhs) { 1884 ierr = MatDuplicate(ts->Brhs,MAT_DO_NOT_COPY_VALUES,&Pmat);CHKERRQ(ierr); 1885 ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr); 1886 ierr = MatDestroy(&Pmat);CHKERRQ(ierr); 1887 } 1888 } 1889 if (ts->ops->setup) { 1890 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 1891 } 1892 1893 /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction 1894 to be set right but can't do it elsewhere due to the overreliance on ctx=ts. 1895 */ 1896 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1897 ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr); 1898 if (!func) { 1899 ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr); 1900 } 1901 /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it. 1902 Otherwise, the SNES will use coloring internally to form the Jacobian. 1903 */ 1904 ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr); 1905 ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr); 1906 ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr); 1907 if (!jac && (ijac || rhsjac)) { 1908 ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1909 } 1910 ts->setupcalled = PETSC_TRUE; 1911 PetscFunctionReturn(0); 1912 } 1913 1914 #undef __FUNCT__ 1915 #define __FUNCT__ "TSAdjointSetUp" 1916 /*@ 1917 TSAdjointSetUp - Sets up the internal data structures for the later use 1918 of an adjoint solver 1919 1920 Collective on TS 1921 1922 Input Parameter: 1923 . ts - the TS context obtained from TSCreate() 1924 1925 Notes: 1926 For basic use of the TS solvers the user need not explicitly call 1927 TSSetUp(), since these actions will automatically occur during 1928 the call to TSStep(). However, if one wishes to control this 1929 phase separately, TSSetUp() should be called after TSCreate() 1930 and optional routines of the form TSSetXXX(), but before TSStep(). 1931 1932 Level: advanced 1933 1934 .keywords: TS, timestep, setup 1935 1936 .seealso: TSCreate(), TSStep(), TSDestroy() 1937 @*/ 1938 PetscErrorCode TSAdjointSetUp(TS ts) 1939 { 1940 PetscErrorCode ierr; 1941 1942 PetscFunctionBegin; 1943 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1944 if (ts->adjointsetupcalled) PetscFunctionReturn(0); 1945 if (!ts->vecs_sensi) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSAdjointSetCostGradients() first"); 1946 1947 ierr = VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr); 1948 if (ts->vecs_sensip){ 1949 ierr = VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 1950 } 1951 1952 if (ts->ops->adjointsetup) { 1953 ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr); 1954 } 1955 ts->adjointsetupcalled = PETSC_TRUE; 1956 PetscFunctionReturn(0); 1957 } 1958 1959 #undef __FUNCT__ 1960 #define __FUNCT__ "TSReset" 1961 /*@ 1962 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 1963 1964 Collective on TS 1965 1966 Input Parameter: 1967 . ts - the TS context obtained from TSCreate() 1968 1969 Level: beginner 1970 1971 .keywords: TS, timestep, reset 1972 1973 .seealso: TSCreate(), TSSetup(), TSDestroy() 1974 @*/ 1975 PetscErrorCode TSReset(TS ts) 1976 { 1977 PetscErrorCode ierr; 1978 1979 PetscFunctionBegin; 1980 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1981 1982 if (ts->ops->reset) { 1983 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 1984 } 1985 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 1986 1987 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1988 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1989 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 1990 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1991 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 1992 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 1993 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 1994 ierr = ISDestroy(&ts->is_diff);CHKERRQ(ierr); 1995 1996 ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr); 1997 if (ts->vecs_drdp){ 1998 ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 1999 } 2000 ts->vecs_sensi = NULL; 2001 ts->vecs_sensip = NULL; 2002 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 2003 ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr); 2004 ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr); 2005 ts->setupcalled = PETSC_FALSE; 2006 PetscFunctionReturn(0); 2007 } 2008 2009 #undef __FUNCT__ 2010 #define __FUNCT__ "TSDestroy" 2011 /*@ 2012 TSDestroy - Destroys the timestepper context that was created 2013 with TSCreate(). 2014 2015 Collective on TS 2016 2017 Input Parameter: 2018 . ts - the TS context obtained from TSCreate() 2019 2020 Level: beginner 2021 2022 .keywords: TS, timestepper, destroy 2023 2024 .seealso: TSCreate(), TSSetUp(), TSSolve() 2025 @*/ 2026 PetscErrorCode TSDestroy(TS *ts) 2027 { 2028 PetscErrorCode ierr; 2029 2030 PetscFunctionBegin; 2031 if (!*ts) PetscFunctionReturn(0); 2032 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 2033 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 2034 2035 ierr = TSReset((*ts));CHKERRQ(ierr); 2036 2037 /* if memory was published with SAWs then destroy it */ 2038 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 2039 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 2040 2041 ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr); 2042 2043 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 2044 if ((*ts)->event) { 2045 ierr = TSEventMonitorDestroy(&(*ts)->event);CHKERRQ(ierr); 2046 } 2047 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 2048 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 2049 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 2050 2051 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 2052 PetscFunctionReturn(0); 2053 } 2054 2055 #undef __FUNCT__ 2056 #define __FUNCT__ "TSGetSNES" 2057 /*@ 2058 TSGetSNES - Returns the SNES (nonlinear solver) associated with 2059 a TS (timestepper) context. Valid only for nonlinear problems. 2060 2061 Not Collective, but SNES is parallel if TS is parallel 2062 2063 Input Parameter: 2064 . ts - the TS context obtained from TSCreate() 2065 2066 Output Parameter: 2067 . snes - the nonlinear solver context 2068 2069 Notes: 2070 The user can then directly manipulate the SNES context to set various 2071 options, etc. Likewise, the user can then extract and manipulate the 2072 KSP, KSP, and PC contexts as well. 2073 2074 TSGetSNES() does not work for integrators that do not use SNES; in 2075 this case TSGetSNES() returns NULL in snes. 2076 2077 Level: beginner 2078 2079 .keywords: timestep, get, SNES 2080 @*/ 2081 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 2082 { 2083 PetscErrorCode ierr; 2084 2085 PetscFunctionBegin; 2086 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2087 PetscValidPointer(snes,2); 2088 if (!ts->snes) { 2089 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 2090 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2091 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 2092 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 2093 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2094 if (ts->problem_type == TS_LINEAR) { 2095 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 2096 } 2097 } 2098 *snes = ts->snes; 2099 PetscFunctionReturn(0); 2100 } 2101 2102 #undef __FUNCT__ 2103 #define __FUNCT__ "TSSetSNES" 2104 /*@ 2105 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 2106 2107 Collective 2108 2109 Input Parameter: 2110 + ts - the TS context obtained from TSCreate() 2111 - snes - the nonlinear solver context 2112 2113 Notes: 2114 Most users should have the TS created by calling TSGetSNES() 2115 2116 Level: developer 2117 2118 .keywords: timestep, set, SNES 2119 @*/ 2120 PetscErrorCode TSSetSNES(TS ts,SNES snes) 2121 { 2122 PetscErrorCode ierr; 2123 PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 2124 2125 PetscFunctionBegin; 2126 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2127 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 2128 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 2129 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 2130 2131 ts->snes = snes; 2132 2133 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2134 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 2135 if (func == SNESTSFormJacobian) { 2136 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2137 } 2138 PetscFunctionReturn(0); 2139 } 2140 2141 #undef __FUNCT__ 2142 #define __FUNCT__ "TSGetKSP" 2143 /*@ 2144 TSGetKSP - Returns the KSP (linear solver) associated with 2145 a TS (timestepper) context. 2146 2147 Not Collective, but KSP is parallel if TS is parallel 2148 2149 Input Parameter: 2150 . ts - the TS context obtained from TSCreate() 2151 2152 Output Parameter: 2153 . ksp - the nonlinear solver context 2154 2155 Notes: 2156 The user can then directly manipulate the KSP context to set various 2157 options, etc. Likewise, the user can then extract and manipulate the 2158 KSP and PC contexts as well. 2159 2160 TSGetKSP() does not work for integrators that do not use KSP; 2161 in this case TSGetKSP() returns NULL in ksp. 2162 2163 Level: beginner 2164 2165 .keywords: timestep, get, KSP 2166 @*/ 2167 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2168 { 2169 PetscErrorCode ierr; 2170 SNES snes; 2171 2172 PetscFunctionBegin; 2173 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2174 PetscValidPointer(ksp,2); 2175 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2176 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2177 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2178 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2179 PetscFunctionReturn(0); 2180 } 2181 2182 /* ----------- Routines to set solver parameters ---------- */ 2183 2184 #undef __FUNCT__ 2185 #define __FUNCT__ "TSGetDuration" 2186 /*@ 2187 TSGetDuration - Gets the maximum number of timesteps to use and 2188 maximum time for iteration. 2189 2190 Not Collective 2191 2192 Input Parameters: 2193 + ts - the TS context obtained from TSCreate() 2194 . maxsteps - maximum number of iterations to use, or NULL 2195 - maxtime - final time to iterate to, or NULL 2196 2197 Level: intermediate 2198 2199 .keywords: TS, timestep, get, maximum, iterations, time 2200 @*/ 2201 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 2202 { 2203 PetscFunctionBegin; 2204 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2205 if (maxsteps) { 2206 PetscValidIntPointer(maxsteps,2); 2207 *maxsteps = ts->max_steps; 2208 } 2209 if (maxtime) { 2210 PetscValidScalarPointer(maxtime,3); 2211 *maxtime = ts->max_time; 2212 } 2213 PetscFunctionReturn(0); 2214 } 2215 2216 #undef __FUNCT__ 2217 #define __FUNCT__ "TSSetDuration" 2218 /*@ 2219 TSSetDuration - Sets the maximum number of timesteps to use and 2220 maximum time for iteration. 2221 2222 Logically Collective on TS 2223 2224 Input Parameters: 2225 + ts - the TS context obtained from TSCreate() 2226 . maxsteps - maximum number of iterations to use 2227 - maxtime - final time to iterate to 2228 2229 Options Database Keys: 2230 . -ts_max_steps <maxsteps> - Sets maxsteps 2231 . -ts_final_time <maxtime> - Sets maxtime 2232 2233 Notes: 2234 The default maximum number of iterations is 5000. Default time is 5.0 2235 2236 Level: intermediate 2237 2238 .keywords: TS, timestep, set, maximum, iterations 2239 2240 .seealso: TSSetExactFinalTime() 2241 @*/ 2242 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 2243 { 2244 PetscFunctionBegin; 2245 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2246 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2247 PetscValidLogicalCollectiveReal(ts,maxtime,2); 2248 if (maxsteps >= 0) ts->max_steps = maxsteps; 2249 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 2250 PetscFunctionReturn(0); 2251 } 2252 2253 #undef __FUNCT__ 2254 #define __FUNCT__ "TSSetSolution" 2255 /*@ 2256 TSSetSolution - Sets the initial solution vector 2257 for use by the TS routines. 2258 2259 Logically Collective on TS and Vec 2260 2261 Input Parameters: 2262 + ts - the TS context obtained from TSCreate() 2263 - u - the solution vector 2264 2265 Level: beginner 2266 2267 .keywords: TS, timestep, set, solution, initial conditions 2268 @*/ 2269 PetscErrorCode TSSetSolution(TS ts,Vec u) 2270 { 2271 PetscErrorCode ierr; 2272 DM dm; 2273 2274 PetscFunctionBegin; 2275 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2276 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2277 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 2278 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2279 2280 ts->vec_sol = u; 2281 2282 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2283 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 2284 PetscFunctionReturn(0); 2285 } 2286 2287 #undef __FUNCT__ 2288 #define __FUNCT__ "TSAdjointSetSteps" 2289 /*@ 2290 TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time 2291 2292 Logically Collective on TS 2293 2294 Input Parameters: 2295 + ts - the TS context obtained from TSCreate() 2296 . steps - number of steps to use 2297 2298 Level: intermediate 2299 2300 Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this 2301 so as to integrate back to less than the original timestep 2302 2303 .keywords: TS, timestep, set, maximum, iterations 2304 2305 .seealso: TSSetExactFinalTime() 2306 @*/ 2307 PetscErrorCode TSAdjointSetSteps(TS ts,PetscInt steps) 2308 { 2309 PetscFunctionBegin; 2310 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2311 PetscValidLogicalCollectiveInt(ts,steps,2); 2312 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps"); 2313 if (steps > ts->total_steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps"); 2314 ts->adjoint_max_steps = steps; 2315 PetscFunctionReturn(0); 2316 } 2317 2318 #undef __FUNCT__ 2319 #define __FUNCT__ "TSAdjointSetCostGradients" 2320 /*@ 2321 TSAdjointSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial conditions and w.r.t. the problem parameters 2322 for use by the TSAdjoint routines. 2323 2324 Logically Collective on TS and Vec 2325 2326 Input Parameters: 2327 + ts - the TS context obtained from TSCreate() 2328 . lambda - gradients with respect to the initial condition variables, the dimension and parallel layout of these vectors is the same as the ODE solution vector 2329 - mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 2330 2331 Level: beginner 2332 2333 Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime mu_i = df/dp|finaltime 2334 2335 .keywords: TS, timestep, set, sensitivity, initial conditions 2336 @*/ 2337 PetscErrorCode TSAdjointSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu) 2338 { 2339 PetscFunctionBegin; 2340 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2341 PetscValidPointer(lambda,2); 2342 ts->vecs_sensi = lambda; 2343 ts->vecs_sensip = mu; 2344 ts->numcost = numcost; 2345 PetscFunctionReturn(0); 2346 } 2347 2348 #undef __FUNCT__ 2349 #define __FUNCT__ "TSAdjointSetRHSJacobian" 2350 /*@C 2351 TSAdjointSetRHSJacobian - Sets the function that computes the Jacobian of G w.r.t. the parameters p where y_t = G(y,p,t), as well as the location to store the matrix. 2352 2353 Logically Collective on TS 2354 2355 Input Parameters: 2356 + ts - The TS context obtained from TSCreate() 2357 - func - The function 2358 2359 Calling sequence of func: 2360 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx); 2361 + t - current timestep 2362 . y - input vector (current ODE solution) 2363 . A - output matrix 2364 - ctx - [optional] user-defined function context 2365 2366 Level: intermediate 2367 2368 Notes: Amat has the same number of rows and the same row parallel layout as u, Amat has the same number of columns and parallel layout as p 2369 2370 .keywords: TS, sensitivity 2371 .seealso: 2372 @*/ 2373 PetscErrorCode TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx) 2374 { 2375 PetscErrorCode ierr; 2376 2377 PetscFunctionBegin; 2378 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2379 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2380 2381 ts->rhsjacobianp = func; 2382 ts->rhsjacobianpctx = ctx; 2383 if(Amat) { 2384 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 2385 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 2386 ts->Jacp = Amat; 2387 } 2388 PetscFunctionReturn(0); 2389 } 2390 2391 #undef __FUNCT__ 2392 #define __FUNCT__ "TSAdjointComputeRHSJacobian" 2393 /*@C 2394 TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function. 2395 2396 Collective on TS 2397 2398 Input Parameters: 2399 . ts - The TS context obtained from TSCreate() 2400 2401 Level: developer 2402 2403 .keywords: TS, sensitivity 2404 .seealso: TSAdjointSetRHSJacobian() 2405 @*/ 2406 PetscErrorCode TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat) 2407 { 2408 PetscErrorCode ierr; 2409 2410 PetscFunctionBegin; 2411 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2412 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 2413 PetscValidPointer(Amat,4); 2414 2415 PetscStackPush("TS user JacobianP function for sensitivity analysis"); 2416 ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr); 2417 PetscStackPop; 2418 PetscFunctionReturn(0); 2419 } 2420 2421 #undef __FUNCT__ 2422 #define __FUNCT__ "TSAdjointSetCostIntegrand" 2423 /*@C 2424 TSAdjointSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions 2425 2426 Logically Collective on TS 2427 2428 Input Parameters: 2429 + ts - the TS context obtained from TSCreate() 2430 . numcost - number of gradients to be computed, this is the number of cost functions 2431 . rf - routine for evaluating the integrand function 2432 . drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y 2433 . drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p 2434 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 2435 2436 Calling sequence of rf: 2437 $ rf(TS ts,PetscReal t,Vec y,Vec f[],void *ctx); 2438 2439 + t - current timestep 2440 . y - input vector 2441 . f - function result; one vector entry for each cost function 2442 - ctx - [optional] user-defined function context 2443 2444 Calling sequence of drdyf: 2445 $ PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx); 2446 2447 Calling sequence of drdpf: 2448 $ PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx); 2449 2450 Level: intermediate 2451 2452 Notes: For optimization there is generally a single cost function, numcost = 1. For sensitivities there may be multiple cost functions 2453 2454 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function 2455 2456 .seealso: TSAdjointSetRHSJacobian(),TSAdjointGetCostGradients(), TSAdjointSetCostGradients() 2457 @*/ 2458 PetscErrorCode TSAdjointSetCostIntegrand(TS ts,PetscInt numcost, PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*), 2459 PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*), 2460 PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*),void *ctx) 2461 { 2462 PetscErrorCode ierr; 2463 2464 PetscFunctionBegin; 2465 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2466 if (!ts->numcost) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Call TSAdjointSetCostGradients() first so that the number of cost functions can be determined."); 2467 if (ts->numcost && ts->numcost!=numcost) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"The number of cost functions (2rd parameter of TSAdjointSetCostIntegrand()) is inconsistent with the one set by TSAdjointSetCostGradients()"); 2468 2469 ierr = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr); 2470 ierr = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr); 2471 ts->costintegrand = rf; 2472 ts->costintegrandctx = ctx; 2473 ts->drdyfunction = drdyf; 2474 ts->drdpfunction = drdpf; 2475 PetscFunctionReturn(0); 2476 } 2477 2478 #undef __FUNCT__ 2479 #define __FUNCT__ "TSAdjointGetCostIntegral" 2480 /*@ 2481 TSAdjointGetCostIntegral - Returns the values of the integral term in the cost functions. 2482 It is valid to call the routine after a backward run. 2483 2484 Not Collective 2485 2486 Input Parameter: 2487 . ts - the TS context obtained from TSCreate() 2488 2489 Output Parameter: 2490 . v - the vector containing the integrals for each cost function 2491 2492 Level: intermediate 2493 2494 .seealso: TSAdjointSetCostIntegrand() 2495 2496 .keywords: TS, sensitivity analysis 2497 @*/ 2498 PetscErrorCode TSAdjointGetCostIntegral(TS ts,Vec *v) 2499 { 2500 PetscFunctionBegin; 2501 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2502 PetscValidPointer(v,2); 2503 *v = ts->vec_costintegral; 2504 PetscFunctionReturn(0); 2505 } 2506 2507 #undef __FUNCT__ 2508 #define __FUNCT__ "TSAdjointComputeCostIntegrand" 2509 /*@ 2510 TSAdjointComputeCostIntegrand - Evaluates the integral function in the cost functions. 2511 2512 Input Parameters: 2513 + ts - the TS context 2514 . t - current time 2515 - y - state vector, i.e. current solution 2516 2517 Output Parameter: 2518 . q - vector of size numcost to hold the outputs 2519 2520 Note: 2521 Most users should not need to explicitly call this routine, as it 2522 is used internally within the sensitivity analysis context. 2523 2524 Level: developer 2525 2526 .keywords: TS, compute 2527 2528 .seealso: TSAdjointSetCostIntegrand() 2529 @*/ 2530 PetscErrorCode TSAdjointComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q) 2531 { 2532 PetscErrorCode ierr; 2533 2534 PetscFunctionBegin; 2535 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2536 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2537 PetscValidHeaderSpecific(q,VEC_CLASSID,4); 2538 2539 ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 2540 if (ts->costintegrand) { 2541 PetscStackPush("TS user integrand in the cost function"); 2542 ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr); 2543 PetscStackPop; 2544 } else { 2545 ierr = VecZeroEntries(q);CHKERRQ(ierr); 2546 } 2547 2548 ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 2549 PetscFunctionReturn(0); 2550 } 2551 2552 #undef __FUNCT__ 2553 #define __FUNCT__ "TSAdjointComputeDRDYFunction" 2554 /*@ 2555 TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function. 2556 2557 Collective on TS 2558 2559 Input Parameters: 2560 . ts - The TS context obtained from TSCreate() 2561 2562 Notes: 2563 TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation, 2564 so most users would not generally call this routine themselves. 2565 2566 Level: developer 2567 2568 .keywords: TS, sensitivity 2569 .seealso: TSAdjointComputeDRDYFunction() 2570 @*/ 2571 PetscErrorCode TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy) 2572 { 2573 PetscErrorCode ierr; 2574 2575 PetscFunctionBegin; 2576 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2577 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2578 2579 PetscStackPush("TS user DRDY function for sensitivity analysis"); 2580 ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr); 2581 PetscStackPop; 2582 PetscFunctionReturn(0); 2583 } 2584 2585 #undef __FUNCT__ 2586 #define __FUNCT__ "TSAdjointComputeDRDPFunction" 2587 /*@ 2588 TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function. 2589 2590 Collective on TS 2591 2592 Input Parameters: 2593 . ts - The TS context obtained from TSCreate() 2594 2595 Notes: 2596 TSDRDPFunction() is typically used for sensitivity implementation, 2597 so most users would not generally call this routine themselves. 2598 2599 Level: developer 2600 2601 .keywords: TS, sensitivity 2602 .seealso: TSAdjointSetDRDPFunction() 2603 @*/ 2604 PetscErrorCode TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp) 2605 { 2606 PetscErrorCode ierr; 2607 2608 PetscFunctionBegin; 2609 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2610 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2611 2612 PetscStackPush("TS user DRDP function for sensitivity analysis"); 2613 ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr); 2614 PetscStackPop; 2615 PetscFunctionReturn(0); 2616 } 2617 2618 #undef __FUNCT__ 2619 #define __FUNCT__ "TSSetPreStep" 2620 /*@C 2621 TSSetPreStep - Sets the general-purpose function 2622 called once at the beginning of each time step. 2623 2624 Logically Collective on TS 2625 2626 Input Parameters: 2627 + ts - The TS context obtained from TSCreate() 2628 - func - The function 2629 2630 Calling sequence of func: 2631 . func (TS ts); 2632 2633 Level: intermediate 2634 2635 Note: 2636 If a step is rejected, TSStep() will call this routine again before each attempt. 2637 The last completed time step number can be queried using TSGetTimeStepNumber(), the 2638 size of the step being attempted can be obtained using TSGetTimeStep(). 2639 2640 .keywords: TS, timestep 2641 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep() 2642 @*/ 2643 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 2644 { 2645 PetscFunctionBegin; 2646 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2647 ts->prestep = func; 2648 PetscFunctionReturn(0); 2649 } 2650 2651 #undef __FUNCT__ 2652 #define __FUNCT__ "TSPreStep" 2653 /*@ 2654 TSPreStep - Runs the user-defined pre-step function. 2655 2656 Collective on TS 2657 2658 Input Parameters: 2659 . ts - The TS context obtained from TSCreate() 2660 2661 Notes: 2662 TSPreStep() is typically used within time stepping implementations, 2663 so most users would not generally call this routine themselves. 2664 2665 Level: developer 2666 2667 .keywords: TS, timestep 2668 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 2669 @*/ 2670 PetscErrorCode TSPreStep(TS ts) 2671 { 2672 PetscErrorCode ierr; 2673 2674 PetscFunctionBegin; 2675 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2676 if (ts->prestep) { 2677 PetscStackCallStandard((*ts->prestep),(ts)); 2678 } 2679 PetscFunctionReturn(0); 2680 } 2681 2682 #undef __FUNCT__ 2683 #define __FUNCT__ "TSSetPreStage" 2684 /*@C 2685 TSSetPreStage - Sets the general-purpose function 2686 called once at the beginning of each stage. 2687 2688 Logically Collective on TS 2689 2690 Input Parameters: 2691 + ts - The TS context obtained from TSCreate() 2692 - func - The function 2693 2694 Calling sequence of func: 2695 . PetscErrorCode func(TS ts, PetscReal stagetime); 2696 2697 Level: intermediate 2698 2699 Note: 2700 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 2701 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 2702 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 2703 2704 .keywords: TS, timestep 2705 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 2706 @*/ 2707 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 2708 { 2709 PetscFunctionBegin; 2710 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2711 ts->prestage = func; 2712 PetscFunctionReturn(0); 2713 } 2714 2715 #undef __FUNCT__ 2716 #define __FUNCT__ "TSSetPostStage" 2717 /*@C 2718 TSSetPostStage - Sets the general-purpose function 2719 called once at the end of each stage. 2720 2721 Logically Collective on TS 2722 2723 Input Parameters: 2724 + ts - The TS context obtained from TSCreate() 2725 - func - The function 2726 2727 Calling sequence of func: 2728 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 2729 2730 Level: intermediate 2731 2732 Note: 2733 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 2734 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 2735 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 2736 2737 .keywords: TS, timestep 2738 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 2739 @*/ 2740 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 2741 { 2742 PetscFunctionBegin; 2743 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2744 ts->poststage = func; 2745 PetscFunctionReturn(0); 2746 } 2747 2748 #undef __FUNCT__ 2749 #define __FUNCT__ "TSPreStage" 2750 /*@ 2751 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 2752 2753 Collective on TS 2754 2755 Input Parameters: 2756 . ts - The TS context obtained from TSCreate() 2757 stagetime - The absolute time of the current stage 2758 2759 Notes: 2760 TSPreStage() is typically used within time stepping implementations, 2761 most users would not generally call this routine themselves. 2762 2763 Level: developer 2764 2765 .keywords: TS, timestep 2766 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 2767 @*/ 2768 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 2769 { 2770 PetscErrorCode ierr; 2771 2772 PetscFunctionBegin; 2773 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2774 if (ts->prestage) { 2775 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 2776 } 2777 PetscFunctionReturn(0); 2778 } 2779 2780 #undef __FUNCT__ 2781 #define __FUNCT__ "TSPostStage" 2782 /*@ 2783 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 2784 2785 Collective on TS 2786 2787 Input Parameters: 2788 . ts - The TS context obtained from TSCreate() 2789 stagetime - The absolute time of the current stage 2790 stageindex - Stage number 2791 Y - Array of vectors (of size = total number 2792 of stages) with the stage solutions 2793 2794 Notes: 2795 TSPostStage() is typically used within time stepping implementations, 2796 most users would not generally call this routine themselves. 2797 2798 Level: developer 2799 2800 .keywords: TS, timestep 2801 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 2802 @*/ 2803 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 2804 { 2805 PetscErrorCode ierr; 2806 2807 PetscFunctionBegin; 2808 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2809 if (ts->poststage) { 2810 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 2811 } 2812 PetscFunctionReturn(0); 2813 } 2814 2815 #undef __FUNCT__ 2816 #define __FUNCT__ "TSSetPostStep" 2817 /*@C 2818 TSSetPostStep - Sets the general-purpose function 2819 called once at the end of each time step. 2820 2821 Logically Collective on TS 2822 2823 Input Parameters: 2824 + ts - The TS context obtained from TSCreate() 2825 - func - The function 2826 2827 Calling sequence of func: 2828 $ func (TS ts); 2829 2830 Level: intermediate 2831 2832 .keywords: TS, timestep 2833 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime() 2834 @*/ 2835 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 2836 { 2837 PetscFunctionBegin; 2838 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2839 ts->poststep = func; 2840 PetscFunctionReturn(0); 2841 } 2842 2843 #undef __FUNCT__ 2844 #define __FUNCT__ "TSPostStep" 2845 /*@ 2846 TSPostStep - Runs the user-defined post-step function. 2847 2848 Collective on TS 2849 2850 Input Parameters: 2851 . ts - The TS context obtained from TSCreate() 2852 2853 Notes: 2854 TSPostStep() is typically used within time stepping implementations, 2855 so most users would not generally call this routine themselves. 2856 2857 Level: developer 2858 2859 .keywords: TS, timestep 2860 @*/ 2861 PetscErrorCode TSPostStep(TS ts) 2862 { 2863 PetscErrorCode ierr; 2864 2865 PetscFunctionBegin; 2866 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2867 if (ts->poststep) { 2868 PetscStackCallStandard((*ts->poststep),(ts)); 2869 } 2870 PetscFunctionReturn(0); 2871 } 2872 2873 /* ------------ Routines to set performance monitoring options ----------- */ 2874 2875 #undef __FUNCT__ 2876 #define __FUNCT__ "TSMonitorSet" 2877 /*@C 2878 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 2879 timestep to display the iteration's progress. 2880 2881 Logically Collective on TS 2882 2883 Input Parameters: 2884 + ts - the TS context obtained from TSCreate() 2885 . monitor - monitoring routine 2886 . mctx - [optional] user-defined context for private data for the 2887 monitor routine (use NULL if no context is desired) 2888 - monitordestroy - [optional] routine that frees monitor context 2889 (may be NULL) 2890 2891 Calling sequence of monitor: 2892 $ int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 2893 2894 + ts - the TS context 2895 . steps - iteration number (after the final time step the monitor routine is called with a step of -1, this is at the final time which may have 2896 been interpolated to) 2897 . time - current time 2898 . u - current iterate 2899 - mctx - [optional] monitoring context 2900 2901 Notes: 2902 This routine adds an additional monitor to the list of monitors that 2903 already has been loaded. 2904 2905 Fortran notes: Only a single monitor function can be set for each TS object 2906 2907 Level: intermediate 2908 2909 .keywords: TS, timestep, set, monitor 2910 2911 .seealso: TSMonitorDefault(), TSMonitorCancel() 2912 @*/ 2913 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 2914 { 2915 PetscFunctionBegin; 2916 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2917 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2918 ts->monitor[ts->numbermonitors] = monitor; 2919 ts->monitordestroy[ts->numbermonitors] = mdestroy; 2920 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 2921 PetscFunctionReturn(0); 2922 } 2923 2924 #undef __FUNCT__ 2925 #define __FUNCT__ "TSMonitorCancel" 2926 /*@C 2927 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 2928 2929 Logically Collective on TS 2930 2931 Input Parameters: 2932 . ts - the TS context obtained from TSCreate() 2933 2934 Notes: 2935 There is no way to remove a single, specific monitor. 2936 2937 Level: intermediate 2938 2939 .keywords: TS, timestep, set, monitor 2940 2941 .seealso: TSMonitorDefault(), TSMonitorSet() 2942 @*/ 2943 PetscErrorCode TSMonitorCancel(TS ts) 2944 { 2945 PetscErrorCode ierr; 2946 PetscInt i; 2947 2948 PetscFunctionBegin; 2949 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2950 for (i=0; i<ts->numbermonitors; i++) { 2951 if (ts->monitordestroy[i]) { 2952 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 2953 } 2954 } 2955 ts->numbermonitors = 0; 2956 PetscFunctionReturn(0); 2957 } 2958 2959 #undef __FUNCT__ 2960 #define __FUNCT__ "TSMonitorDefault" 2961 /*@ 2962 TSMonitorDefault - Sets the Default monitor 2963 2964 Level: intermediate 2965 2966 .keywords: TS, set, monitor 2967 2968 .seealso: TSMonitorDefault(), TSMonitorSet() 2969 @*/ 2970 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy) 2971 { 2972 PetscErrorCode ierr; 2973 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ts)); 2974 2975 PetscFunctionBegin; 2976 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 2977 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g %s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? "(r)\n" : "\n");CHKERRQ(ierr); 2978 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 2979 PetscFunctionReturn(0); 2980 } 2981 2982 #undef __FUNCT__ 2983 #define __FUNCT__ "TSSetRetainStages" 2984 /*@ 2985 TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available. 2986 2987 Logically Collective on TS 2988 2989 Input Argument: 2990 . ts - time stepping context 2991 2992 Output Argument: 2993 . flg - PETSC_TRUE or PETSC_FALSE 2994 2995 Level: intermediate 2996 2997 .keywords: TS, set 2998 2999 .seealso: TSInterpolate(), TSSetPostStep() 3000 @*/ 3001 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg) 3002 { 3003 PetscFunctionBegin; 3004 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3005 ts->retain_stages = flg; 3006 PetscFunctionReturn(0); 3007 } 3008 3009 #undef __FUNCT__ 3010 #define __FUNCT__ "TSInterpolate" 3011 /*@ 3012 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 3013 3014 Collective on TS 3015 3016 Input Argument: 3017 + ts - time stepping context 3018 - t - time to interpolate to 3019 3020 Output Argument: 3021 . U - state at given time 3022 3023 Notes: 3024 The user should call TSSetRetainStages() before taking a step in which interpolation will be requested. 3025 3026 Level: intermediate 3027 3028 Developer Notes: 3029 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3030 3031 .keywords: TS, set 3032 3033 .seealso: TSSetRetainStages(), TSSetPostStep() 3034 @*/ 3035 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3036 { 3037 PetscErrorCode ierr; 3038 3039 PetscFunctionBegin; 3040 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3041 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3042 if (t < ts->ptime - ts->time_step_prev || t > ts->ptime) SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Requested time %g not in last time steps [%g,%g]",t,(double)(ts->ptime-ts->time_step_prev),(double)ts->ptime); 3043 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3044 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3045 PetscFunctionReturn(0); 3046 } 3047 3048 #undef __FUNCT__ 3049 #define __FUNCT__ "TSStep" 3050 /*@ 3051 TSStep - Steps one time step 3052 3053 Collective on TS 3054 3055 Input Parameter: 3056 . ts - the TS context obtained from TSCreate() 3057 3058 Level: developer 3059 3060 Notes: 3061 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3062 3063 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3064 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3065 3066 This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the 3067 time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3068 3069 .keywords: TS, timestep, solve 3070 3071 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3072 @*/ 3073 PetscErrorCode TSStep(TS ts) 3074 { 3075 DM dm; 3076 PetscErrorCode ierr; 3077 static PetscBool cite = PETSC_FALSE; 3078 3079 PetscFunctionBegin; 3080 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3081 ierr = PetscCitationsRegister("@techreport{tspaper,\n" 3082 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3083 " author = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n" 3084 " type = {Preprint},\n" 3085 " number = {ANL/MCS-P5061-0114},\n" 3086 " institution = {Argonne National Laboratory},\n" 3087 " year = {2014}\n}\n",&cite); 3088 3089 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 3090 ierr = TSSetUp(ts);CHKERRQ(ierr); 3091 3092 ts->reason = TS_CONVERGED_ITERATING; 3093 ts->ptime_prev = ts->ptime; 3094 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3095 3096 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3097 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3098 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3099 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3100 3101 ts->time_step_prev = ts->ptime - ts->ptime_prev; 3102 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3103 3104 if (ts->reason < 0) { 3105 if (ts->errorifstepfailed) { 3106 if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 3107 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3108 } 3109 } else if (!ts->reason) { 3110 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3111 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3112 } 3113 ts->total_steps++; 3114 ts->steprollback = PETSC_FALSE; 3115 PetscFunctionReturn(0); 3116 } 3117 3118 #undef __FUNCT__ 3119 #define __FUNCT__ "TSAdjointStep" 3120 /*@ 3121 TSAdjointStep - Steps one time step 3122 3123 Collective on TS 3124 3125 Input Parameter: 3126 . ts - the TS context obtained from TSCreate() 3127 3128 Level: intermediate 3129 3130 Notes: 3131 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3132 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3133 3134 This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the 3135 time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3136 3137 .keywords: TS, timestep, solve 3138 3139 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3140 @*/ 3141 PetscErrorCode TSAdjointStep(TS ts) 3142 { 3143 DM dm; 3144 PetscErrorCode ierr; 3145 3146 PetscFunctionBegin; 3147 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3148 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 3149 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 3150 3151 ts->reason = TS_CONVERGED_ITERATING; 3152 ts->ptime_prev = ts->ptime; 3153 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3154 ierr = VecViewFromOptions(ts->vec_sol, ((PetscObject) ts)->prefix, "-ts_view_solution");CHKERRQ(ierr); 3155 3156 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3157 if (!ts->ops->adjointstep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed because the adjoint of %s has not been implemented, try other time stepping methods for adjoint sensitivity analysis",((PetscObject)ts)->type_name); 3158 ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr); 3159 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3160 3161 ts->time_step_prev = ts->ptime - ts->ptime_prev; 3162 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3163 3164 if (ts->reason < 0) { 3165 if (ts->errorifstepfailed) { 3166 if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) { 3167 SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 3168 } else if (ts->reason == TS_DIVERGED_STEP_REJECTED) { 3169 SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_reject or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 3170 } else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3171 } 3172 } else if (!ts->reason) { 3173 if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 3174 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3175 } 3176 ts->total_steps--; 3177 PetscFunctionReturn(0); 3178 } 3179 3180 #undef __FUNCT__ 3181 #define __FUNCT__ "TSEvaluateStep" 3182 /*@ 3183 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 3184 3185 Collective on TS 3186 3187 Input Arguments: 3188 + ts - time stepping context 3189 . order - desired order of accuracy 3190 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 3191 3192 Output Arguments: 3193 . U - state at the end of the current step 3194 3195 Level: advanced 3196 3197 Notes: 3198 This function cannot be called until all stages have been evaluated. 3199 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. 3200 3201 .seealso: TSStep(), TSAdapt 3202 @*/ 3203 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 3204 { 3205 PetscErrorCode ierr; 3206 3207 PetscFunctionBegin; 3208 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3209 PetscValidType(ts,1); 3210 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3211 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3212 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 3213 PetscFunctionReturn(0); 3214 } 3215 3216 3217 #undef __FUNCT__ 3218 #define __FUNCT__ "TSSolve" 3219 /*@ 3220 TSSolve - Steps the requested number of timesteps. 3221 3222 Collective on TS 3223 3224 Input Parameter: 3225 + ts - the TS context obtained from TSCreate() 3226 - u - the solution vector (can be null if TSSetSolution() was used, otherwise must contain the initial conditions) 3227 3228 Level: beginner 3229 3230 Notes: 3231 The final time returned by this function may be different from the time of the internally 3232 held state accessible by TSGetSolution() and TSGetTime() because the method may have 3233 stepped over the final time. 3234 3235 .keywords: TS, timestep, solve 3236 3237 .seealso: TSCreate(), TSSetSolution(), TSStep() 3238 @*/ 3239 PetscErrorCode TSSolve(TS ts,Vec u) 3240 { 3241 Vec solution; 3242 PetscErrorCode ierr; 3243 3244 PetscFunctionBegin; 3245 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3246 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3247 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE) { /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */ 3248 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3249 if (!ts->vec_sol || u == ts->vec_sol) { 3250 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 3251 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 3252 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 3253 } 3254 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 3255 } else if (u) { 3256 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 3257 } 3258 ierr = TSSetUp(ts);CHKERRQ(ierr); 3259 /* reset time step and iteration counters */ 3260 ts->steps = 0; 3261 ts->ksp_its = 0; 3262 ts->snes_its = 0; 3263 ts->num_snes_failures = 0; 3264 ts->reject = 0; 3265 ts->reason = TS_CONVERGED_ITERATING; 3266 3267 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 3268 { 3269 DM dm; 3270 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 3271 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3272 } 3273 3274 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 3275 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 3276 ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr); 3277 ts->solvetime = ts->ptime; 3278 } else { 3279 /* steps the requested number of timesteps. */ 3280 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3281 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3282 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3283 if(ts->event) { 3284 ierr = TSEventMonitorInitialize(ts);CHKERRQ(ierr); 3285 } 3286 while (!ts->reason) { 3287 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3288 ierr = TSStep(ts);CHKERRQ(ierr); 3289 if (ts->event) { 3290 ierr = TSEventMonitor(ts);CHKERRQ(ierr); 3291 } 3292 if(!ts->steprollback) { 3293 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3294 ierr = TSPostStep(ts);CHKERRQ(ierr); 3295 } 3296 } 3297 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 3298 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 3299 ts->solvetime = ts->max_time; 3300 solution = u; 3301 } else { 3302 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 3303 ts->solvetime = ts->ptime; 3304 solution = ts->vec_sol; 3305 } 3306 ierr = TSMonitor(ts,ts->steps,ts->solvetime,solution);CHKERRQ(ierr); 3307 ierr = VecViewFromOptions(solution, ((PetscObject) ts)->prefix, "-ts_view_solution");CHKERRQ(ierr); 3308 } 3309 3310 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 3311 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 3312 if (ts->adjoint_solve) { 3313 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 3314 } 3315 PetscFunctionReturn(0); 3316 } 3317 3318 #undef __FUNCT__ 3319 #define __FUNCT__ "TSAdjointSolve" 3320 /*@ 3321 TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE 3322 3323 Collective on TS 3324 3325 Input Parameter: 3326 . ts - the TS context obtained from TSCreate() 3327 3328 Options Database: 3329 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial conditions 3330 3331 Level: intermediate 3332 3333 Notes: 3334 This must be called after a call to TSSolve() that solves the forward problem 3335 3336 By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time 3337 3338 .keywords: TS, timestep, solve 3339 3340 .seealso: TSCreate(), TSSetSolution(), TSStep() 3341 @*/ 3342 PetscErrorCode TSAdjointSolve(TS ts) 3343 { 3344 PetscErrorCode ierr; 3345 3346 PetscFunctionBegin; 3347 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3348 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 3349 /* reset time step and iteration counters */ 3350 ts->steps = 0; 3351 ts->ksp_its = 0; 3352 ts->snes_its = 0; 3353 ts->num_snes_failures = 0; 3354 ts->reject = 0; 3355 ts->reason = TS_CONVERGED_ITERATING; 3356 3357 if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->total_steps; 3358 3359 if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 3360 while (!ts->reason) { 3361 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->adjoint_max_steps-ts->steps,ts->ptime);CHKERRQ(ierr); 3362 ierr = TSMonitor(ts,ts->adjoint_max_steps-ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3363 ierr = TSAdjointStep(ts);CHKERRQ(ierr); 3364 if (ts->event) { 3365 ierr = TSAdjointEventMonitor(ts);CHKERRQ(ierr); 3366 } 3367 3368 #if 0 /* I don't think PostStep is needed in AdjointSolve */ 3369 if (ts->event->status != TSEVENT_PROCESSING) { 3370 ierr = TSPostStep(ts);CHKERRQ(ierr); 3371 } 3372 } else { 3373 ierr = TSPostStep(ts);CHKERRQ(ierr); 3374 } 3375 #endif 3376 } 3377 ts->solvetime = ts->ptime; 3378 ierr = VecViewFromOptions(ts->vecs_sensi[0], ((PetscObject) ts)->prefix, "-ts_adjoint_view_solution");CHKERRQ(ierr); 3379 PetscFunctionReturn(0); 3380 } 3381 3382 #undef __FUNCT__ 3383 #define __FUNCT__ "TSMonitor" 3384 /*@ 3385 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 3386 3387 Collective on TS 3388 3389 Input Parameters: 3390 + ts - time stepping context obtained from TSCreate() 3391 . step - step number that has just completed 3392 . ptime - model time of the state 3393 - u - state at the current model time 3394 3395 Notes: 3396 TSMonitor() is typically used within the time stepping implementations. 3397 Users might call this function when using the TSStep() interface instead of TSSolve(). 3398 3399 Level: advanced 3400 3401 .keywords: TS, timestep 3402 @*/ 3403 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 3404 { 3405 PetscErrorCode ierr; 3406 PetscInt i,n = ts->numbermonitors; 3407 3408 PetscFunctionBegin; 3409 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3410 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 3411 ierr = VecLockPush(u);CHKERRQ(ierr); 3412 for (i=0; i<n; i++) { 3413 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 3414 } 3415 ierr = VecLockPop(u);CHKERRQ(ierr); 3416 PetscFunctionReturn(0); 3417 } 3418 3419 /* ------------------------------------------------------------------------*/ 3420 #undef __FUNCT__ 3421 #define __FUNCT__ "TSMonitorLGCtxCreate" 3422 /*@C 3423 TSMonitorLGCtxCreate - Creates a line graph context for use with 3424 TS to monitor the solution process graphically in various ways 3425 3426 Collective on TS 3427 3428 Input Parameters: 3429 + host - the X display to open, or null for the local machine 3430 . label - the title to put in the title bar 3431 . x, y - the screen coordinates of the upper left coordinate of the window 3432 . m, n - the screen width and height in pixels 3433 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 3434 3435 Output Parameter: 3436 . ctx - the context 3437 3438 Options Database Key: 3439 + -ts_monitor_lg_timestep - automatically sets line graph monitor 3440 . -ts_monitor_lg_solution - 3441 . -ts_monitor_lg_error - 3442 . -ts_monitor_lg_ksp_iterations - 3443 . -ts_monitor_lg_snes_iterations - 3444 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 3445 3446 Notes: 3447 Use TSMonitorLGCtxDestroy() to destroy. 3448 3449 Level: intermediate 3450 3451 .keywords: TS, monitor, line graph, residual, seealso 3452 3453 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 3454 3455 @*/ 3456 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 3457 { 3458 PetscDraw win; 3459 PetscErrorCode ierr; 3460 3461 PetscFunctionBegin; 3462 ierr = PetscNew(ctx);CHKERRQ(ierr); 3463 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 3464 ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr); 3465 ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr); 3466 ierr = PetscLogObjectParent((PetscObject)(*ctx)->lg,(PetscObject)win);CHKERRQ(ierr); 3467 ierr = PetscDrawLGSetUseMarkers((*ctx)->lg,PETSC_TRUE);CHKERRQ(ierr); 3468 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 3469 (*ctx)->howoften = howoften; 3470 PetscFunctionReturn(0); 3471 } 3472 3473 #undef __FUNCT__ 3474 #define __FUNCT__ "TSMonitorLGTimeStep" 3475 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 3476 { 3477 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 3478 PetscReal x = ptime,y; 3479 PetscErrorCode ierr; 3480 3481 PetscFunctionBegin; 3482 if (!step) { 3483 PetscDrawAxis axis; 3484 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 3485 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr); 3486 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 3487 } 3488 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 3489 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 3490 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 3491 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 3492 } 3493 PetscFunctionReturn(0); 3494 } 3495 3496 #undef __FUNCT__ 3497 #define __FUNCT__ "TSMonitorLGCtxDestroy" 3498 /*@C 3499 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 3500 with TSMonitorLGCtxCreate(). 3501 3502 Collective on TSMonitorLGCtx 3503 3504 Input Parameter: 3505 . ctx - the monitor context 3506 3507 Level: intermediate 3508 3509 .keywords: TS, monitor, line graph, destroy 3510 3511 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 3512 @*/ 3513 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 3514 { 3515 PetscDraw draw; 3516 PetscErrorCode ierr; 3517 3518 PetscFunctionBegin; 3519 if ((*ctx)->transformdestroy) { 3520 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 3521 } 3522 ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr); 3523 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 3524 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 3525 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 3526 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 3527 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 3528 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 3529 ierr = PetscFree(*ctx);CHKERRQ(ierr); 3530 PetscFunctionReturn(0); 3531 } 3532 3533 #undef __FUNCT__ 3534 #define __FUNCT__ "TSGetTime" 3535 /*@ 3536 TSGetTime - Gets the time of the most recently completed step. 3537 3538 Not Collective 3539 3540 Input Parameter: 3541 . ts - the TS context obtained from TSCreate() 3542 3543 Output Parameter: 3544 . t - the current time 3545 3546 Level: beginner 3547 3548 Note: 3549 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 3550 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 3551 3552 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 3553 3554 .keywords: TS, get, time 3555 @*/ 3556 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 3557 { 3558 PetscFunctionBegin; 3559 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3560 PetscValidRealPointer(t,2); 3561 *t = ts->ptime; 3562 PetscFunctionReturn(0); 3563 } 3564 3565 #undef __FUNCT__ 3566 #define __FUNCT__ "TSGetPrevTime" 3567 /*@ 3568 TSGetPrevTime - Gets the starting time of the previously completed step. 3569 3570 Not Collective 3571 3572 Input Parameter: 3573 . ts - the TS context obtained from TSCreate() 3574 3575 Output Parameter: 3576 . t - the previous time 3577 3578 Level: beginner 3579 3580 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 3581 3582 .keywords: TS, get, time 3583 @*/ 3584 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 3585 { 3586 PetscFunctionBegin; 3587 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3588 PetscValidRealPointer(t,2); 3589 *t = ts->ptime_prev; 3590 PetscFunctionReturn(0); 3591 } 3592 3593 #undef __FUNCT__ 3594 #define __FUNCT__ "TSSetTime" 3595 /*@ 3596 TSSetTime - Allows one to reset the time. 3597 3598 Logically Collective on TS 3599 3600 Input Parameters: 3601 + ts - the TS context obtained from TSCreate() 3602 - time - the time 3603 3604 Level: intermediate 3605 3606 .seealso: TSGetTime(), TSSetDuration() 3607 3608 .keywords: TS, set, time 3609 @*/ 3610 PetscErrorCode TSSetTime(TS ts, PetscReal t) 3611 { 3612 PetscFunctionBegin; 3613 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3614 PetscValidLogicalCollectiveReal(ts,t,2); 3615 ts->ptime = t; 3616 PetscFunctionReturn(0); 3617 } 3618 3619 #undef __FUNCT__ 3620 #define __FUNCT__ "TSSetOptionsPrefix" 3621 /*@C 3622 TSSetOptionsPrefix - Sets the prefix used for searching for all 3623 TS options in the database. 3624 3625 Logically Collective on TS 3626 3627 Input Parameter: 3628 + ts - The TS context 3629 - prefix - The prefix to prepend to all option names 3630 3631 Notes: 3632 A hyphen (-) must NOT be given at the beginning of the prefix name. 3633 The first character of all runtime options is AUTOMATICALLY the 3634 hyphen. 3635 3636 Level: advanced 3637 3638 .keywords: TS, set, options, prefix, database 3639 3640 .seealso: TSSetFromOptions() 3641 3642 @*/ 3643 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 3644 { 3645 PetscErrorCode ierr; 3646 SNES snes; 3647 3648 PetscFunctionBegin; 3649 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3650 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 3651 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3652 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 3653 PetscFunctionReturn(0); 3654 } 3655 3656 3657 #undef __FUNCT__ 3658 #define __FUNCT__ "TSAppendOptionsPrefix" 3659 /*@C 3660 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 3661 TS options in the database. 3662 3663 Logically Collective on TS 3664 3665 Input Parameter: 3666 + ts - The TS context 3667 - prefix - The prefix to prepend to all option names 3668 3669 Notes: 3670 A hyphen (-) must NOT be given at the beginning of the prefix name. 3671 The first character of all runtime options is AUTOMATICALLY the 3672 hyphen. 3673 3674 Level: advanced 3675 3676 .keywords: TS, append, options, prefix, database 3677 3678 .seealso: TSGetOptionsPrefix() 3679 3680 @*/ 3681 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 3682 { 3683 PetscErrorCode ierr; 3684 SNES snes; 3685 3686 PetscFunctionBegin; 3687 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3688 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 3689 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3690 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 3691 PetscFunctionReturn(0); 3692 } 3693 3694 #undef __FUNCT__ 3695 #define __FUNCT__ "TSGetOptionsPrefix" 3696 /*@C 3697 TSGetOptionsPrefix - Sets the prefix used for searching for all 3698 TS options in the database. 3699 3700 Not Collective 3701 3702 Input Parameter: 3703 . ts - The TS context 3704 3705 Output Parameter: 3706 . prefix - A pointer to the prefix string used 3707 3708 Notes: On the fortran side, the user should pass in a string 'prifix' of 3709 sufficient length to hold the prefix. 3710 3711 Level: intermediate 3712 3713 .keywords: TS, get, options, prefix, database 3714 3715 .seealso: TSAppendOptionsPrefix() 3716 @*/ 3717 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 3718 { 3719 PetscErrorCode ierr; 3720 3721 PetscFunctionBegin; 3722 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3723 PetscValidPointer(prefix,2); 3724 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 3725 PetscFunctionReturn(0); 3726 } 3727 3728 #undef __FUNCT__ 3729 #define __FUNCT__ "TSGetRHSJacobian" 3730 /*@C 3731 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 3732 3733 Not Collective, but parallel objects are returned if TS is parallel 3734 3735 Input Parameter: 3736 . ts - The TS context obtained from TSCreate() 3737 3738 Output Parameters: 3739 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 3740 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 3741 . func - Function to compute the Jacobian of the RHS (or NULL) 3742 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 3743 3744 Notes: You can pass in NULL for any return argument you do not need. 3745 3746 Level: intermediate 3747 3748 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 3749 3750 .keywords: TS, timestep, get, matrix, Jacobian 3751 @*/ 3752 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 3753 { 3754 PetscErrorCode ierr; 3755 SNES snes; 3756 DM dm; 3757 3758 PetscFunctionBegin; 3759 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3760 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 3761 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3762 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 3763 PetscFunctionReturn(0); 3764 } 3765 3766 #undef __FUNCT__ 3767 #define __FUNCT__ "TSGetIJacobian" 3768 /*@C 3769 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 3770 3771 Not Collective, but parallel objects are returned if TS is parallel 3772 3773 Input Parameter: 3774 . ts - The TS context obtained from TSCreate() 3775 3776 Output Parameters: 3777 + Amat - The (approximate) Jacobian of F(t,U,U_t) 3778 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 3779 . f - The function to compute the matrices 3780 - ctx - User-defined context for Jacobian evaluation routine 3781 3782 Notes: You can pass in NULL for any return argument you do not need. 3783 3784 Level: advanced 3785 3786 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 3787 3788 .keywords: TS, timestep, get, matrix, Jacobian 3789 @*/ 3790 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 3791 { 3792 PetscErrorCode ierr; 3793 SNES snes; 3794 DM dm; 3795 3796 PetscFunctionBegin; 3797 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3798 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 3799 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 3800 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3801 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 3802 PetscFunctionReturn(0); 3803 } 3804 3805 3806 #undef __FUNCT__ 3807 #define __FUNCT__ "TSMonitorDrawSolution" 3808 /*@C 3809 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 3810 VecView() for the solution at each timestep 3811 3812 Collective on TS 3813 3814 Input Parameters: 3815 + ts - the TS context 3816 . step - current time-step 3817 . ptime - current time 3818 - dummy - either a viewer or NULL 3819 3820 Options Database: 3821 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 3822 3823 Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 3824 will look bad 3825 3826 Level: intermediate 3827 3828 .keywords: TS, vector, monitor, view 3829 3830 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3831 @*/ 3832 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3833 { 3834 PetscErrorCode ierr; 3835 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 3836 PetscDraw draw; 3837 3838 PetscFunctionBegin; 3839 if (!step && ictx->showinitial) { 3840 if (!ictx->initialsolution) { 3841 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 3842 } 3843 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 3844 } 3845 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 3846 3847 if (ictx->showinitial) { 3848 PetscReal pause; 3849 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 3850 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 3851 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 3852 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 3853 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 3854 } 3855 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 3856 if (ictx->showtimestepandtime) { 3857 PetscReal xl,yl,xr,yr,h; 3858 char time[32]; 3859 3860 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 3861 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 3862 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 3863 h = yl + .95*(yr - yl); 3864 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 3865 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 3866 } 3867 3868 if (ictx->showinitial) { 3869 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 3870 } 3871 PetscFunctionReturn(0); 3872 } 3873 3874 #undef __FUNCT__ 3875 #define __FUNCT__ "TSMonitorDrawSolutionPhase" 3876 /*@C 3877 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 3878 3879 Collective on TS 3880 3881 Input Parameters: 3882 + ts - the TS context 3883 . step - current time-step 3884 . ptime - current time 3885 - dummy - either a viewer or NULL 3886 3887 Level: intermediate 3888 3889 .keywords: TS, vector, monitor, view 3890 3891 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3892 @*/ 3893 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3894 { 3895 PetscErrorCode ierr; 3896 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 3897 PetscDraw draw; 3898 MPI_Comm comm; 3899 PetscInt n; 3900 PetscMPIInt size; 3901 PetscReal xl,yl,xr,yr,h; 3902 char time[32]; 3903 const PetscScalar *U; 3904 3905 PetscFunctionBegin; 3906 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 3907 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 3908 if (size != 1) SETERRQ(comm,PETSC_ERR_SUP,"Only allowed for sequential runs"); 3909 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 3910 if (n != 2) SETERRQ(comm,PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 3911 3912 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 3913 3914 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 3915 ierr = PetscDrawAxisGetLimits(ictx->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 3916 if ((PetscRealPart(U[0]) < xl) || (PetscRealPart(U[1]) < yl) || (PetscRealPart(U[0]) > xr) || (PetscRealPart(U[1]) > yr)) { 3917 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 3918 PetscFunctionReturn(0); 3919 } 3920 if (!step) ictx->color++; 3921 ierr = PetscDrawPoint(draw,PetscRealPart(U[0]),PetscRealPart(U[1]),ictx->color);CHKERRQ(ierr); 3922 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 3923 3924 if (ictx->showtimestepandtime) { 3925 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 3926 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 3927 h = yl + .95*(yr - yl); 3928 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 3929 } 3930 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 3931 PetscFunctionReturn(0); 3932 } 3933 3934 3935 #undef __FUNCT__ 3936 #define __FUNCT__ "TSMonitorDrawCtxDestroy" 3937 /*@C 3938 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 3939 3940 Collective on TS 3941 3942 Input Parameters: 3943 . ctx - the monitor context 3944 3945 Level: intermediate 3946 3947 .keywords: TS, vector, monitor, view 3948 3949 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 3950 @*/ 3951 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 3952 { 3953 PetscErrorCode ierr; 3954 3955 PetscFunctionBegin; 3956 ierr = PetscDrawAxisDestroy(&(*ictx)->axis);CHKERRQ(ierr); 3957 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 3958 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 3959 ierr = PetscFree(*ictx);CHKERRQ(ierr); 3960 PetscFunctionReturn(0); 3961 } 3962 3963 #undef __FUNCT__ 3964 #define __FUNCT__ "TSMonitorDrawCtxCreate" 3965 /*@C 3966 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 3967 3968 Collective on TS 3969 3970 Input Parameter: 3971 . ts - time-step context 3972 3973 Output Patameter: 3974 . ctx - the monitor context 3975 3976 Options Database: 3977 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 3978 3979 Level: intermediate 3980 3981 .keywords: TS, vector, monitor, view 3982 3983 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 3984 @*/ 3985 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 3986 { 3987 PetscErrorCode ierr; 3988 3989 PetscFunctionBegin; 3990 ierr = PetscNew(ctx);CHKERRQ(ierr); 3991 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 3992 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 3993 3994 (*ctx)->howoften = howoften; 3995 (*ctx)->showinitial = PETSC_FALSE; 3996 ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 3997 3998 (*ctx)->showtimestepandtime = PETSC_FALSE; 3999 ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 4000 (*ctx)->color = PETSC_DRAW_WHITE; 4001 PetscFunctionReturn(0); 4002 } 4003 4004 #undef __FUNCT__ 4005 #define __FUNCT__ "TSMonitorDrawError" 4006 /*@C 4007 TSMonitorDrawError - Monitors progress of the TS solvers by calling 4008 VecView() for the error at each timestep 4009 4010 Collective on TS 4011 4012 Input Parameters: 4013 + ts - the TS context 4014 . step - current time-step 4015 . ptime - current time 4016 - dummy - either a viewer or NULL 4017 4018 Level: intermediate 4019 4020 .keywords: TS, vector, monitor, view 4021 4022 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4023 @*/ 4024 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4025 { 4026 PetscErrorCode ierr; 4027 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4028 PetscViewer viewer = ctx->viewer; 4029 Vec work; 4030 4031 PetscFunctionBegin; 4032 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4033 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4034 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4035 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 4036 ierr = VecView(work,viewer);CHKERRQ(ierr); 4037 ierr = VecDestroy(&work);CHKERRQ(ierr); 4038 PetscFunctionReturn(0); 4039 } 4040 4041 #include <petsc-private/dmimpl.h> 4042 #undef __FUNCT__ 4043 #define __FUNCT__ "TSSetDM" 4044 /*@ 4045 TSSetDM - Sets the DM that may be used by some preconditioners 4046 4047 Logically Collective on TS and DM 4048 4049 Input Parameters: 4050 + ts - the preconditioner context 4051 - dm - the dm 4052 4053 Level: intermediate 4054 4055 4056 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4057 @*/ 4058 PetscErrorCode TSSetDM(TS ts,DM dm) 4059 { 4060 PetscErrorCode ierr; 4061 SNES snes; 4062 DMTS tsdm; 4063 4064 PetscFunctionBegin; 4065 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4066 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4067 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4068 if (ts->dm->dmts && !dm->dmts) { 4069 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4070 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4071 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4072 tsdm->originaldm = dm; 4073 } 4074 } 4075 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4076 } 4077 ts->dm = dm; 4078 4079 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4080 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4081 PetscFunctionReturn(0); 4082 } 4083 4084 #undef __FUNCT__ 4085 #define __FUNCT__ "TSGetDM" 4086 /*@ 4087 TSGetDM - Gets the DM that may be used by some preconditioners 4088 4089 Not Collective 4090 4091 Input Parameter: 4092 . ts - the preconditioner context 4093 4094 Output Parameter: 4095 . dm - the dm 4096 4097 Level: intermediate 4098 4099 4100 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4101 @*/ 4102 PetscErrorCode TSGetDM(TS ts,DM *dm) 4103 { 4104 PetscErrorCode ierr; 4105 4106 PetscFunctionBegin; 4107 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4108 if (!ts->dm) { 4109 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 4110 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 4111 } 4112 *dm = ts->dm; 4113 PetscFunctionReturn(0); 4114 } 4115 4116 #undef __FUNCT__ 4117 #define __FUNCT__ "SNESTSFormFunction" 4118 /*@ 4119 SNESTSFormFunction - Function to evaluate nonlinear residual 4120 4121 Logically Collective on SNES 4122 4123 Input Parameter: 4124 + snes - nonlinear solver 4125 . U - the current state at which to evaluate the residual 4126 - ctx - user context, must be a TS 4127 4128 Output Parameter: 4129 . F - the nonlinear residual 4130 4131 Notes: 4132 This function is not normally called by users and is automatically registered with the SNES used by TS. 4133 It is most frequently passed to MatFDColoringSetFunction(). 4134 4135 Level: advanced 4136 4137 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 4138 @*/ 4139 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 4140 { 4141 TS ts = (TS)ctx; 4142 PetscErrorCode ierr; 4143 4144 PetscFunctionBegin; 4145 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4146 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4147 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 4148 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 4149 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 4150 PetscFunctionReturn(0); 4151 } 4152 4153 #undef __FUNCT__ 4154 #define __FUNCT__ "SNESTSFormJacobian" 4155 /*@ 4156 SNESTSFormJacobian - Function to evaluate the Jacobian 4157 4158 Collective on SNES 4159 4160 Input Parameter: 4161 + snes - nonlinear solver 4162 . U - the current state at which to evaluate the residual 4163 - ctx - user context, must be a TS 4164 4165 Output Parameter: 4166 + A - the Jacobian 4167 . B - the preconditioning matrix (may be the same as A) 4168 - flag - indicates any structure change in the matrix 4169 4170 Notes: 4171 This function is not normally called by users and is automatically registered with the SNES used by TS. 4172 4173 Level: developer 4174 4175 .seealso: SNESSetJacobian() 4176 @*/ 4177 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 4178 { 4179 TS ts = (TS)ctx; 4180 PetscErrorCode ierr; 4181 4182 PetscFunctionBegin; 4183 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4184 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4185 PetscValidPointer(A,3); 4186 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 4187 PetscValidPointer(B,4); 4188 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 4189 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 4190 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 4191 PetscFunctionReturn(0); 4192 } 4193 4194 #undef __FUNCT__ 4195 #define __FUNCT__ "TSComputeRHSFunctionLinear" 4196 /*@C 4197 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only 4198 4199 Collective on TS 4200 4201 Input Arguments: 4202 + ts - time stepping context 4203 . t - time at which to evaluate 4204 . U - state at which to evaluate 4205 - ctx - context 4206 4207 Output Arguments: 4208 . F - right hand side 4209 4210 Level: intermediate 4211 4212 Notes: 4213 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 4214 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 4215 4216 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 4217 @*/ 4218 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 4219 { 4220 PetscErrorCode ierr; 4221 Mat Arhs,Brhs; 4222 4223 PetscFunctionBegin; 4224 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 4225 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 4226 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 4227 PetscFunctionReturn(0); 4228 } 4229 4230 #undef __FUNCT__ 4231 #define __FUNCT__ "TSComputeRHSJacobianConstant" 4232 /*@C 4233 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 4234 4235 Collective on TS 4236 4237 Input Arguments: 4238 + ts - time stepping context 4239 . t - time at which to evaluate 4240 . U - state at which to evaluate 4241 - ctx - context 4242 4243 Output Arguments: 4244 + A - pointer to operator 4245 . B - pointer to preconditioning matrix 4246 - flg - matrix structure flag 4247 4248 Level: intermediate 4249 4250 Notes: 4251 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 4252 4253 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 4254 @*/ 4255 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 4256 { 4257 PetscFunctionBegin; 4258 PetscFunctionReturn(0); 4259 } 4260 4261 #undef __FUNCT__ 4262 #define __FUNCT__ "TSComputeIFunctionLinear" 4263 /*@C 4264 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 4265 4266 Collective on TS 4267 4268 Input Arguments: 4269 + ts - time stepping context 4270 . t - time at which to evaluate 4271 . U - state at which to evaluate 4272 . Udot - time derivative of state vector 4273 - ctx - context 4274 4275 Output Arguments: 4276 . F - left hand side 4277 4278 Level: intermediate 4279 4280 Notes: 4281 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 4282 user is required to write their own TSComputeIFunction. 4283 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 4284 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 4285 4286 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant() 4287 @*/ 4288 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 4289 { 4290 PetscErrorCode ierr; 4291 Mat A,B; 4292 4293 PetscFunctionBegin; 4294 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 4295 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 4296 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 4297 PetscFunctionReturn(0); 4298 } 4299 4300 #undef __FUNCT__ 4301 #define __FUNCT__ "TSComputeIJacobianConstant" 4302 /*@C 4303 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 4304 4305 Collective on TS 4306 4307 Input Arguments: 4308 + ts - time stepping context 4309 . t - time at which to evaluate 4310 . U - state at which to evaluate 4311 . Udot - time derivative of state vector 4312 . shift - shift to apply 4313 - ctx - context 4314 4315 Output Arguments: 4316 + A - pointer to operator 4317 . B - pointer to preconditioning matrix 4318 - flg - matrix structure flag 4319 4320 Level: advanced 4321 4322 Notes: 4323 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 4324 4325 It is only appropriate for problems of the form 4326 4327 $ M Udot = F(U,t) 4328 4329 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 4330 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 4331 an implicit operator of the form 4332 4333 $ shift*M + J 4334 4335 where J is the Jacobian of -F(U). Support may be added in a future version of PETSc, but for now, the user must store 4336 a copy of M or reassemble it when requested. 4337 4338 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 4339 @*/ 4340 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 4341 { 4342 PetscErrorCode ierr; 4343 4344 PetscFunctionBegin; 4345 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 4346 ts->ijacobian.shift = shift; 4347 PetscFunctionReturn(0); 4348 } 4349 4350 #undef __FUNCT__ 4351 #define __FUNCT__ "TSGetEquationType" 4352 /*@ 4353 TSGetEquationType - Gets the type of the equation that TS is solving. 4354 4355 Not Collective 4356 4357 Input Parameter: 4358 . ts - the TS context 4359 4360 Output Parameter: 4361 . equation_type - see TSEquationType 4362 4363 Level: beginner 4364 4365 .keywords: TS, equation type 4366 4367 .seealso: TSSetEquationType(), TSEquationType 4368 @*/ 4369 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 4370 { 4371 PetscFunctionBegin; 4372 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4373 PetscValidPointer(equation_type,2); 4374 *equation_type = ts->equation_type; 4375 PetscFunctionReturn(0); 4376 } 4377 4378 #undef __FUNCT__ 4379 #define __FUNCT__ "TSSetEquationType" 4380 /*@ 4381 TSSetEquationType - Sets the type of the equation that TS is solving. 4382 4383 Not Collective 4384 4385 Input Parameter: 4386 + ts - the TS context 4387 . equation_type - see TSEquationType 4388 4389 Level: advanced 4390 4391 .keywords: TS, equation type 4392 4393 .seealso: TSGetEquationType(), TSEquationType 4394 @*/ 4395 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 4396 { 4397 PetscFunctionBegin; 4398 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4399 ts->equation_type = equation_type; 4400 PetscFunctionReturn(0); 4401 } 4402 4403 #undef __FUNCT__ 4404 #define __FUNCT__ "TSGetConvergedReason" 4405 /*@ 4406 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 4407 4408 Not Collective 4409 4410 Input Parameter: 4411 . ts - the TS context 4412 4413 Output Parameter: 4414 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4415 manual pages for the individual convergence tests for complete lists 4416 4417 Level: beginner 4418 4419 Notes: 4420 Can only be called after the call to TSSolve() is complete. 4421 4422 .keywords: TS, nonlinear, set, convergence, test 4423 4424 .seealso: TSSetConvergenceTest(), TSConvergedReason 4425 @*/ 4426 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 4427 { 4428 PetscFunctionBegin; 4429 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4430 PetscValidPointer(reason,2); 4431 *reason = ts->reason; 4432 PetscFunctionReturn(0); 4433 } 4434 4435 #undef __FUNCT__ 4436 #define __FUNCT__ "TSSetConvergedReason" 4437 /*@ 4438 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 4439 4440 Not Collective 4441 4442 Input Parameter: 4443 + ts - the TS context 4444 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4445 manual pages for the individual convergence tests for complete lists 4446 4447 Level: advanced 4448 4449 Notes: 4450 Can only be called during TSSolve() is active. 4451 4452 .keywords: TS, nonlinear, set, convergence, test 4453 4454 .seealso: TSConvergedReason 4455 @*/ 4456 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 4457 { 4458 PetscFunctionBegin; 4459 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4460 ts->reason = reason; 4461 PetscFunctionReturn(0); 4462 } 4463 4464 #undef __FUNCT__ 4465 #define __FUNCT__ "TSGetSolveTime" 4466 /*@ 4467 TSGetSolveTime - Gets the time after a call to TSSolve() 4468 4469 Not Collective 4470 4471 Input Parameter: 4472 . ts - the TS context 4473 4474 Output Parameter: 4475 . ftime - the final time. This time should correspond to the final time set with TSSetDuration() 4476 4477 Level: beginner 4478 4479 Notes: 4480 Can only be called after the call to TSSolve() is complete. 4481 4482 .keywords: TS, nonlinear, set, convergence, test 4483 4484 .seealso: TSSetConvergenceTest(), TSConvergedReason 4485 @*/ 4486 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 4487 { 4488 PetscFunctionBegin; 4489 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4490 PetscValidPointer(ftime,2); 4491 *ftime = ts->solvetime; 4492 PetscFunctionReturn(0); 4493 } 4494 4495 #undef __FUNCT__ 4496 #define __FUNCT__ "TSGetTotalSteps" 4497 /*@ 4498 TSGetTotalSteps - Gets the total number of steps done since the last call to TSSetUp() or TSCreate() 4499 4500 Not Collective 4501 4502 Input Parameter: 4503 . ts - the TS context 4504 4505 Output Parameter: 4506 . steps - the number of steps 4507 4508 Level: beginner 4509 4510 Notes: 4511 Includes the number of steps for all calls to TSSolve() since TSSetUp() was called 4512 4513 .keywords: TS, nonlinear, set, convergence, test 4514 4515 .seealso: TSSetConvergenceTest(), TSConvergedReason 4516 @*/ 4517 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) 4518 { 4519 PetscFunctionBegin; 4520 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4521 PetscValidPointer(steps,2); 4522 *steps = ts->total_steps; 4523 PetscFunctionReturn(0); 4524 } 4525 4526 #undef __FUNCT__ 4527 #define __FUNCT__ "TSGetSNESIterations" 4528 /*@ 4529 TSGetSNESIterations - Gets the total number of nonlinear iterations 4530 used by the time integrator. 4531 4532 Not Collective 4533 4534 Input Parameter: 4535 . ts - TS context 4536 4537 Output Parameter: 4538 . nits - number of nonlinear iterations 4539 4540 Notes: 4541 This counter is reset to zero for each successive call to TSSolve(). 4542 4543 Level: intermediate 4544 4545 .keywords: TS, get, number, nonlinear, iterations 4546 4547 .seealso: TSGetKSPIterations() 4548 @*/ 4549 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 4550 { 4551 PetscFunctionBegin; 4552 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4553 PetscValidIntPointer(nits,2); 4554 *nits = ts->snes_its; 4555 PetscFunctionReturn(0); 4556 } 4557 4558 #undef __FUNCT__ 4559 #define __FUNCT__ "TSGetKSPIterations" 4560 /*@ 4561 TSGetKSPIterations - Gets the total number of linear iterations 4562 used by the time integrator. 4563 4564 Not Collective 4565 4566 Input Parameter: 4567 . ts - TS context 4568 4569 Output Parameter: 4570 . lits - number of linear iterations 4571 4572 Notes: 4573 This counter is reset to zero for each successive call to TSSolve(). 4574 4575 Level: intermediate 4576 4577 .keywords: TS, get, number, linear, iterations 4578 4579 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 4580 @*/ 4581 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 4582 { 4583 PetscFunctionBegin; 4584 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4585 PetscValidIntPointer(lits,2); 4586 *lits = ts->ksp_its; 4587 PetscFunctionReturn(0); 4588 } 4589 4590 #undef __FUNCT__ 4591 #define __FUNCT__ "TSGetStepRejections" 4592 /*@ 4593 TSGetStepRejections - Gets the total number of rejected steps. 4594 4595 Not Collective 4596 4597 Input Parameter: 4598 . ts - TS context 4599 4600 Output Parameter: 4601 . rejects - number of steps rejected 4602 4603 Notes: 4604 This counter is reset to zero for each successive call to TSSolve(). 4605 4606 Level: intermediate 4607 4608 .keywords: TS, get, number 4609 4610 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 4611 @*/ 4612 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 4613 { 4614 PetscFunctionBegin; 4615 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4616 PetscValidIntPointer(rejects,2); 4617 *rejects = ts->reject; 4618 PetscFunctionReturn(0); 4619 } 4620 4621 #undef __FUNCT__ 4622 #define __FUNCT__ "TSGetSNESFailures" 4623 /*@ 4624 TSGetSNESFailures - Gets the total number of failed SNES solves 4625 4626 Not Collective 4627 4628 Input Parameter: 4629 . ts - TS context 4630 4631 Output Parameter: 4632 . fails - number of failed nonlinear solves 4633 4634 Notes: 4635 This counter is reset to zero for each successive call to TSSolve(). 4636 4637 Level: intermediate 4638 4639 .keywords: TS, get, number 4640 4641 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 4642 @*/ 4643 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 4644 { 4645 PetscFunctionBegin; 4646 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4647 PetscValidIntPointer(fails,2); 4648 *fails = ts->num_snes_failures; 4649 PetscFunctionReturn(0); 4650 } 4651 4652 #undef __FUNCT__ 4653 #define __FUNCT__ "TSSetMaxStepRejections" 4654 /*@ 4655 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 4656 4657 Not Collective 4658 4659 Input Parameter: 4660 + ts - TS context 4661 - rejects - maximum number of rejected steps, pass -1 for unlimited 4662 4663 Notes: 4664 The counter is reset to zero for each step 4665 4666 Options Database Key: 4667 . -ts_max_reject - Maximum number of step rejections before a step fails 4668 4669 Level: intermediate 4670 4671 .keywords: TS, set, maximum, number 4672 4673 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 4674 @*/ 4675 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 4676 { 4677 PetscFunctionBegin; 4678 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4679 ts->max_reject = rejects; 4680 PetscFunctionReturn(0); 4681 } 4682 4683 #undef __FUNCT__ 4684 #define __FUNCT__ "TSSetMaxSNESFailures" 4685 /*@ 4686 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 4687 4688 Not Collective 4689 4690 Input Parameter: 4691 + ts - TS context 4692 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 4693 4694 Notes: 4695 The counter is reset to zero for each successive call to TSSolve(). 4696 4697 Options Database Key: 4698 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 4699 4700 Level: intermediate 4701 4702 .keywords: TS, set, maximum, number 4703 4704 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 4705 @*/ 4706 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 4707 { 4708 PetscFunctionBegin; 4709 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4710 ts->max_snes_failures = fails; 4711 PetscFunctionReturn(0); 4712 } 4713 4714 #undef __FUNCT__ 4715 #define __FUNCT__ "TSSetErrorIfStepFails" 4716 /*@ 4717 TSSetErrorIfStepFails - Error if no step succeeds 4718 4719 Not Collective 4720 4721 Input Parameter: 4722 + ts - TS context 4723 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 4724 4725 Options Database Key: 4726 . -ts_error_if_step_fails - Error if no step succeeds 4727 4728 Level: intermediate 4729 4730 .keywords: TS, set, error 4731 4732 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 4733 @*/ 4734 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 4735 { 4736 PetscFunctionBegin; 4737 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4738 ts->errorifstepfailed = err; 4739 PetscFunctionReturn(0); 4740 } 4741 4742 #undef __FUNCT__ 4743 #define __FUNCT__ "TSMonitorSolutionBinary" 4744 /*@C 4745 TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file 4746 4747 Collective on TS 4748 4749 Input Parameters: 4750 + ts - the TS context 4751 . step - current time-step 4752 . ptime - current time 4753 . u - current state 4754 - viewer - binary viewer 4755 4756 Level: intermediate 4757 4758 .keywords: TS, vector, monitor, view 4759 4760 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4761 @*/ 4762 PetscErrorCode TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer) 4763 { 4764 PetscErrorCode ierr; 4765 PetscViewer v = (PetscViewer)viewer; 4766 4767 PetscFunctionBegin; 4768 ierr = VecView(u,v);CHKERRQ(ierr); 4769 PetscFunctionReturn(0); 4770 } 4771 4772 #undef __FUNCT__ 4773 #define __FUNCT__ "TSMonitorSolutionVTK" 4774 /*@C 4775 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 4776 4777 Collective on TS 4778 4779 Input Parameters: 4780 + ts - the TS context 4781 . step - current time-step 4782 . ptime - current time 4783 . u - current state 4784 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 4785 4786 Level: intermediate 4787 4788 Notes: 4789 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. 4790 These are named according to the file name template. 4791 4792 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 4793 4794 .keywords: TS, vector, monitor, view 4795 4796 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4797 @*/ 4798 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 4799 { 4800 PetscErrorCode ierr; 4801 char filename[PETSC_MAX_PATH_LEN]; 4802 PetscViewer viewer; 4803 4804 PetscFunctionBegin; 4805 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 4806 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 4807 ierr = VecView(u,viewer);CHKERRQ(ierr); 4808 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4809 PetscFunctionReturn(0); 4810 } 4811 4812 #undef __FUNCT__ 4813 #define __FUNCT__ "TSMonitorSolutionVTKDestroy" 4814 /*@C 4815 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 4816 4817 Collective on TS 4818 4819 Input Parameters: 4820 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 4821 4822 Level: intermediate 4823 4824 Note: 4825 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 4826 4827 .keywords: TS, vector, monitor, view 4828 4829 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 4830 @*/ 4831 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 4832 { 4833 PetscErrorCode ierr; 4834 4835 PetscFunctionBegin; 4836 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 4837 PetscFunctionReturn(0); 4838 } 4839 4840 #undef __FUNCT__ 4841 #define __FUNCT__ "TSGetAdapt" 4842 /*@ 4843 TSGetAdapt - Get the adaptive controller context for the current method 4844 4845 Collective on TS if controller has not been created yet 4846 4847 Input Arguments: 4848 . ts - time stepping context 4849 4850 Output Arguments: 4851 . adapt - adaptive controller 4852 4853 Level: intermediate 4854 4855 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 4856 @*/ 4857 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 4858 { 4859 PetscErrorCode ierr; 4860 4861 PetscFunctionBegin; 4862 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4863 PetscValidPointer(adapt,2); 4864 if (!ts->adapt) { 4865 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 4866 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 4867 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 4868 } 4869 *adapt = ts->adapt; 4870 PetscFunctionReturn(0); 4871 } 4872 4873 #undef __FUNCT__ 4874 #define __FUNCT__ "TSSetTolerances" 4875 /*@ 4876 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 4877 4878 Logically Collective 4879 4880 Input Arguments: 4881 + ts - time integration context 4882 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 4883 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 4884 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 4885 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 4886 4887 Options Database keys: 4888 + -ts_rtol <rtol> - relative tolerance for local truncation error 4889 - -ts_atol <atol> Absolute tolerance for local truncation error 4890 4891 Level: beginner 4892 4893 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 4894 @*/ 4895 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 4896 { 4897 PetscErrorCode ierr; 4898 4899 PetscFunctionBegin; 4900 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 4901 if (vatol) { 4902 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 4903 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 4904 4905 ts->vatol = vatol; 4906 } 4907 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 4908 if (vrtol) { 4909 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 4910 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 4911 4912 ts->vrtol = vrtol; 4913 } 4914 PetscFunctionReturn(0); 4915 } 4916 4917 #undef __FUNCT__ 4918 #define __FUNCT__ "TSGetTolerances" 4919 /*@ 4920 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 4921 4922 Logically Collective 4923 4924 Input Arguments: 4925 . ts - time integration context 4926 4927 Output Arguments: 4928 + atol - scalar absolute tolerances, NULL to ignore 4929 . vatol - vector of absolute tolerances, NULL to ignore 4930 . rtol - scalar relative tolerances, NULL to ignore 4931 - vrtol - vector of relative tolerances, NULL to ignore 4932 4933 Level: beginner 4934 4935 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 4936 @*/ 4937 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 4938 { 4939 PetscFunctionBegin; 4940 if (atol) *atol = ts->atol; 4941 if (vatol) *vatol = ts->vatol; 4942 if (rtol) *rtol = ts->rtol; 4943 if (vrtol) *vrtol = ts->vrtol; 4944 PetscFunctionReturn(0); 4945 } 4946 4947 #undef __FUNCT__ 4948 #define __FUNCT__ "TSSetDifferentialEquationsIS" 4949 /*@ 4950 TSSetDifferentialEquationsIS - Sets an IS containing locations of differential equations in a DAE 4951 4952 Not Collective 4953 4954 Input Arguments: 4955 + ts - time stepping context 4956 - is_diff - Index set for differential equations 4957 4958 Level: advanced 4959 4960 @*/ 4961 PetscErrorCode TSSetDifferentialEquationsIS(TS ts, IS is_diff) 4962 { 4963 PetscErrorCode ierr; 4964 4965 PetscFunctionBegin; 4966 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4967 PetscValidHeaderSpecific(is_diff,IS_CLASSID,2); 4968 PetscCheckSameComm(ts,1,is_diff,2); 4969 ierr = PetscObjectReference((PetscObject)is_diff);CHKERRQ(ierr); 4970 ierr = ISDestroy(&ts->is_diff);CHKERRQ(ierr); 4971 ts->is_diff = is_diff; 4972 PetscFunctionReturn(0); 4973 } 4974 4975 #undef __FUNCT__ 4976 #define __FUNCT__ "TSErrorWeightedNorm2" 4977 /*@ 4978 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 4979 4980 Collective on TS 4981 4982 Input Arguments: 4983 + ts - time stepping context 4984 . U - state vector, usually ts->vec_sol 4985 - Y - state vector to be compared to U 4986 4987 Output Arguments: 4988 . norm - weighted norm, a value of 1.0 is considered small 4989 4990 Level: developer 4991 4992 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 4993 @*/ 4994 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm) 4995 { 4996 PetscErrorCode ierr; 4997 PetscInt i,n,N,rstart; 4998 const PetscScalar *u,*y; 4999 PetscReal sum,gsum; 5000 PetscReal tol; 5001 5002 PetscFunctionBegin; 5003 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5004 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5005 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5006 PetscValidType(U,2); 5007 PetscValidType(Y,3); 5008 PetscCheckSameComm(U,2,Y,3); 5009 PetscValidPointer(norm,4); 5010 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5011 5012 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5013 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5014 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5015 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5016 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5017 sum = 0.; 5018 if (ts->vatol && ts->vrtol) { 5019 const PetscScalar *atol,*rtol; 5020 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5021 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5022 if(ts->is_diff) { 5023 const PetscInt *idx; 5024 PetscInt k; 5025 ierr = ISGetIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5026 ierr = ISGetLocalSize(ts->is_diff,&n);CHKERRQ(ierr); 5027 for(i=0; i < n; i++) { 5028 k = idx[i] - rstart; 5029 tol = PetscRealPart(atol[k]) + PetscRealPart(rtol[k])*PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5030 sum += PetscSqr(PetscAbsScalar(y[k] - u[k]) / tol); 5031 } 5032 ierr = ISRestoreIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5033 } else { 5034 for (i=0; i<n; i++) { 5035 tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5036 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 5037 } 5038 } 5039 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5040 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5041 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5042 const PetscScalar *atol; 5043 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5044 if(ts->is_diff) { 5045 const PetscInt *idx; 5046 PetscInt k; 5047 ierr = ISGetIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5048 ierr = ISGetLocalSize(ts->is_diff,&n);CHKERRQ(ierr); 5049 for(i=0; i < n; i++) { 5050 k = idx[i] - rstart; 5051 tol = PetscRealPart(atol[k]) + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5052 sum += PetscSqr(PetscAbsScalar(y[k] - u[k]) / tol); 5053 } 5054 ierr = ISRestoreIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5055 } else { 5056 for (i=0; i<n; i++) { 5057 tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5058 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 5059 } 5060 } 5061 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5062 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5063 const PetscScalar *rtol; 5064 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5065 if(ts->is_diff) { 5066 const PetscInt *idx; 5067 PetscInt k; 5068 ierr = ISGetIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5069 ierr = ISGetLocalSize(ts->is_diff,&n);CHKERRQ(ierr); 5070 for(i=0; i < n; i++) { 5071 k = idx[i] - rstart; 5072 tol = ts->atol + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5073 sum += PetscSqr(PetscAbsScalar(y[k] - u[k]) / tol); 5074 } 5075 ierr = ISRestoreIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5076 } else { 5077 for (i=0; i<n; i++) { 5078 tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5079 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 5080 } 5081 } 5082 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5083 } else { /* scalar atol, scalar rtol */ 5084 if (ts->is_diff) { 5085 const PetscInt *idx; 5086 PetscInt k; 5087 ierr = ISGetIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5088 ierr = ISGetLocalSize(ts->is_diff,&n);CHKERRQ(ierr); 5089 for (i=0; i<n; i++) { 5090 k = idx[i] - rstart; 5091 tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5092 sum += PetscSqr(PetscAbsScalar(y[k] - u[k]) / tol); 5093 } 5094 } else { 5095 for (i=0; i<n; i++) { 5096 tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5097 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 5098 } 5099 } 5100 } 5101 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5102 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5103 5104 ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5105 *norm = PetscSqrtReal(gsum / N); 5106 5107 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5108 PetscFunctionReturn(0); 5109 } 5110 5111 #undef __FUNCT__ 5112 #define __FUNCT__ "TSErrorWeightedNormInfinity" 5113 /*@ 5114 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5115 5116 Collective on TS 5117 5118 Input Arguments: 5119 + ts - time stepping context 5120 . U - state vector, usually ts->vec_sol 5121 - Y - state vector to be compared to U 5122 5123 Output Arguments: 5124 . norm - weighted norm, a value of 1.0 is considered small 5125 5126 Level: developer 5127 5128 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5129 @*/ 5130 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm) 5131 { 5132 PetscErrorCode ierr; 5133 PetscInt i,n,N,rstart,k; 5134 const PetscScalar *u,*y; 5135 PetscReal max,gmax; 5136 PetscReal tol; 5137 5138 PetscFunctionBegin; 5139 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5140 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5141 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5142 PetscValidType(U,2); 5143 PetscValidType(Y,3); 5144 PetscCheckSameComm(U,2,Y,3); 5145 PetscValidPointer(norm,4); 5146 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5147 5148 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5149 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5150 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5151 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5152 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5153 if (ts->vatol && ts->vrtol) { 5154 const PetscScalar *atol,*rtol; 5155 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5156 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5157 if(ts->is_diff) { 5158 const PetscInt *idx; 5159 ierr = ISGetIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5160 ierr = ISGetLocalSize(ts->is_diff,&n);CHKERRQ(ierr); 5161 5162 k = idx[0]; 5163 tol = PetscRealPart(atol[k]) + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5164 max = PetscAbsScalar(y[k] - u[k]) / tol; 5165 for(i=1; i < n; i++) { 5166 k = idx[i] - rstart; 5167 tol = PetscRealPart(atol[k]) + PetscRealPart(rtol[k])*PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5168 max = PetscMax(max,PetscAbsScalar(y[k] - u[k]) / tol); 5169 } 5170 ierr = ISRestoreIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5171 } else { 5172 k = 0; 5173 tol = PetscRealPart(atol[k]) + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5174 max = PetscAbsScalar(y[k] - u[k]) / tol; 5175 for (i=1; i<n; i++) { 5176 tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5177 max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol); 5178 } 5179 } 5180 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5181 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5182 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5183 const PetscScalar *atol; 5184 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5185 if(ts->is_diff) { 5186 const PetscInt *idx; 5187 ierr = ISGetIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5188 ierr = ISGetLocalSize(ts->is_diff,&n);CHKERRQ(ierr); 5189 5190 k = idx[0]; 5191 tol = PetscRealPart(atol[k]) + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5192 max = PetscAbsScalar(y[k] - u[k]) / tol; 5193 for(i=1; i < n; i++) { 5194 k = idx[i] - rstart; 5195 tol = PetscRealPart(atol[k]) + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5196 max = PetscMax(max,PetscAbsScalar(y[k] - u[k]) / tol); 5197 } 5198 ierr = ISRestoreIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5199 } else { 5200 k = 0; 5201 tol = PetscRealPart(atol[k]) + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5202 max = PetscAbsScalar(y[k] - u[k]) / tol; 5203 for (i=1; i<n; i++) { 5204 tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5205 max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol); 5206 } 5207 } 5208 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5209 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5210 const PetscScalar *rtol; 5211 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5212 if(ts->is_diff) { 5213 const PetscInt *idx; 5214 ierr = ISGetIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5215 ierr = ISGetLocalSize(ts->is_diff,&n);CHKERRQ(ierr); 5216 5217 k = idx[0]; 5218 tol = ts->atol + PetscRealPart(rtol[k])*PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5219 max = PetscAbsScalar(y[k] - u[k]) / tol; 5220 for(i=1; i < n; i++) { 5221 k = idx[i] - rstart; 5222 tol = ts->atol + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5223 max = PetscMax(max,PetscAbsScalar(y[k] - u[k]) / tol); 5224 } 5225 ierr = ISRestoreIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5226 } else { 5227 k = 0; 5228 tol = ts->atol + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5229 max = PetscAbsScalar(y[k] - u[k]) / tol; 5230 for (i=1; i<n; i++) { 5231 tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5232 max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol); 5233 } 5234 } 5235 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5236 } else { /* scalar atol, scalar rtol */ 5237 if (ts->is_diff) { 5238 const PetscInt *idx; 5239 ierr = ISGetIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5240 ierr = ISGetLocalSize(ts->is_diff,&n);CHKERRQ(ierr); 5241 5242 k = idx[0]; 5243 tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5244 max = PetscAbsScalar(y[k] - u[k]) / tol; 5245 for (i=1; i<n; i++) { 5246 k = idx[i] - rstart; 5247 tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5248 max = PetscMax(max,PetscAbsScalar(y[k] - u[k]) / tol); 5249 } 5250 ierr = ISRestoreIndices(ts->is_diff,&idx);CHKERRQ(ierr); 5251 } else { 5252 k = 0; 5253 tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 5254 max = PetscAbsScalar(y[k] - u[k]) / tol; 5255 for (i=1; i<n; i++) { 5256 tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5257 max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol); 5258 } 5259 } 5260 } 5261 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5262 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5263 5264 ierr = MPI_Allreduce(&max,&gmax,1,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5265 *norm = gmax; 5266 5267 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5268 PetscFunctionReturn(0); 5269 } 5270 5271 #undef __FUNCT__ 5272 #define __FUNCT__ "TSErrorWeightedNorm" 5273 /*@ 5274 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors 5275 5276 Collective on TS 5277 5278 Input Arguments: 5279 + ts - time stepping context 5280 . U - state vector, usually ts->vec_sol 5281 . Y - state vector to be compared to U 5282 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 5283 5284 Output Arguments: 5285 . norm - weighted norm, a value of 1.0 is considered small 5286 5287 5288 Options Database Keys: 5289 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 5290 5291 Level: developer 5292 5293 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 5294 @*/ 5295 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm) 5296 { 5297 PetscErrorCode ierr; 5298 5299 PetscFunctionBegin; 5300 if (wnormtype == NORM_2) { 5301 ierr = TSErrorWeightedNorm2(ts,U,Y,norm);CHKERRQ(ierr); 5302 } else if(wnormtype == NORM_INFINITY) { 5303 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm);CHKERRQ(ierr); 5304 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 5305 PetscFunctionReturn(0); 5306 } 5307 5308 #undef __FUNCT__ 5309 #define __FUNCT__ "TSSetCFLTimeLocal" 5310 /*@ 5311 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 5312 5313 Logically Collective on TS 5314 5315 Input Arguments: 5316 + ts - time stepping context 5317 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 5318 5319 Note: 5320 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 5321 5322 Level: intermediate 5323 5324 .seealso: TSGetCFLTime(), TSADAPTCFL 5325 @*/ 5326 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 5327 { 5328 PetscFunctionBegin; 5329 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5330 ts->cfltime_local = cfltime; 5331 ts->cfltime = -1.; 5332 PetscFunctionReturn(0); 5333 } 5334 5335 #undef __FUNCT__ 5336 #define __FUNCT__ "TSGetCFLTime" 5337 /*@ 5338 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 5339 5340 Collective on TS 5341 5342 Input Arguments: 5343 . ts - time stepping context 5344 5345 Output Arguments: 5346 . cfltime - maximum stable time step for forward Euler 5347 5348 Level: advanced 5349 5350 .seealso: TSSetCFLTimeLocal() 5351 @*/ 5352 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 5353 { 5354 PetscErrorCode ierr; 5355 5356 PetscFunctionBegin; 5357 if (ts->cfltime < 0) { 5358 ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5359 } 5360 *cfltime = ts->cfltime; 5361 PetscFunctionReturn(0); 5362 } 5363 5364 #undef __FUNCT__ 5365 #define __FUNCT__ "TSVISetVariableBounds" 5366 /*@ 5367 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 5368 5369 Input Parameters: 5370 . ts - the TS context. 5371 . xl - lower bound. 5372 . xu - upper bound. 5373 5374 Notes: 5375 If this routine is not called then the lower and upper bounds are set to 5376 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 5377 5378 Level: advanced 5379 5380 @*/ 5381 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 5382 { 5383 PetscErrorCode ierr; 5384 SNES snes; 5385 5386 PetscFunctionBegin; 5387 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 5388 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 5389 PetscFunctionReturn(0); 5390 } 5391 5392 #if defined(PETSC_HAVE_MATLAB_ENGINE) 5393 #include <mex.h> 5394 5395 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 5396 5397 #undef __FUNCT__ 5398 #define __FUNCT__ "TSComputeFunction_Matlab" 5399 /* 5400 TSComputeFunction_Matlab - Calls the function that has been set with 5401 TSSetFunctionMatlab(). 5402 5403 Collective on TS 5404 5405 Input Parameters: 5406 + snes - the TS context 5407 - u - input vector 5408 5409 Output Parameter: 5410 . y - function vector, as set by TSSetFunction() 5411 5412 Notes: 5413 TSComputeFunction() is typically used within nonlinear solvers 5414 implementations, so most users would not generally call this routine 5415 themselves. 5416 5417 Level: developer 5418 5419 .keywords: TS, nonlinear, compute, function 5420 5421 .seealso: TSSetFunction(), TSGetFunction() 5422 */ 5423 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 5424 { 5425 PetscErrorCode ierr; 5426 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 5427 int nlhs = 1,nrhs = 7; 5428 mxArray *plhs[1],*prhs[7]; 5429 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 5430 5431 PetscFunctionBegin; 5432 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 5433 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 5434 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 5435 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 5436 PetscCheckSameComm(snes,1,u,3); 5437 PetscCheckSameComm(snes,1,y,5); 5438 5439 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5440 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 5441 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 5442 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 5443 5444 prhs[0] = mxCreateDoubleScalar((double)ls); 5445 prhs[1] = mxCreateDoubleScalar(time); 5446 prhs[2] = mxCreateDoubleScalar((double)lx); 5447 prhs[3] = mxCreateDoubleScalar((double)lxdot); 5448 prhs[4] = mxCreateDoubleScalar((double)ly); 5449 prhs[5] = mxCreateString(sctx->funcname); 5450 prhs[6] = sctx->ctx; 5451 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 5452 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5453 mxDestroyArray(prhs[0]); 5454 mxDestroyArray(prhs[1]); 5455 mxDestroyArray(prhs[2]); 5456 mxDestroyArray(prhs[3]); 5457 mxDestroyArray(prhs[4]); 5458 mxDestroyArray(prhs[5]); 5459 mxDestroyArray(plhs[0]); 5460 PetscFunctionReturn(0); 5461 } 5462 5463 5464 #undef __FUNCT__ 5465 #define __FUNCT__ "TSSetFunctionMatlab" 5466 /* 5467 TSSetFunctionMatlab - Sets the function evaluation routine and function 5468 vector for use by the TS routines in solving ODEs 5469 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 5470 5471 Logically Collective on TS 5472 5473 Input Parameters: 5474 + ts - the TS context 5475 - func - function evaluation routine 5476 5477 Calling sequence of func: 5478 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 5479 5480 Level: beginner 5481 5482 .keywords: TS, nonlinear, set, function 5483 5484 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 5485 */ 5486 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 5487 { 5488 PetscErrorCode ierr; 5489 TSMatlabContext *sctx; 5490 5491 PetscFunctionBegin; 5492 /* currently sctx is memory bleed */ 5493 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 5494 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 5495 /* 5496 This should work, but it doesn't 5497 sctx->ctx = ctx; 5498 mexMakeArrayPersistent(sctx->ctx); 5499 */ 5500 sctx->ctx = mxDuplicateArray(ctx); 5501 5502 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 5503 PetscFunctionReturn(0); 5504 } 5505 5506 #undef __FUNCT__ 5507 #define __FUNCT__ "TSComputeJacobian_Matlab" 5508 /* 5509 TSComputeJacobian_Matlab - Calls the function that has been set with 5510 TSSetJacobianMatlab(). 5511 5512 Collective on TS 5513 5514 Input Parameters: 5515 + ts - the TS context 5516 . u - input vector 5517 . A, B - the matrices 5518 - ctx - user context 5519 5520 Level: developer 5521 5522 .keywords: TS, nonlinear, compute, function 5523 5524 .seealso: TSSetFunction(), TSGetFunction() 5525 @*/ 5526 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx) 5527 { 5528 PetscErrorCode ierr; 5529 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 5530 int nlhs = 2,nrhs = 9; 5531 mxArray *plhs[2],*prhs[9]; 5532 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 5533 5534 PetscFunctionBegin; 5535 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5536 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 5537 5538 /* call Matlab function in ctx with arguments u and y */ 5539 5540 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 5541 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 5542 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 5543 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 5544 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 5545 5546 prhs[0] = mxCreateDoubleScalar((double)ls); 5547 prhs[1] = mxCreateDoubleScalar((double)time); 5548 prhs[2] = mxCreateDoubleScalar((double)lx); 5549 prhs[3] = mxCreateDoubleScalar((double)lxdot); 5550 prhs[4] = mxCreateDoubleScalar((double)shift); 5551 prhs[5] = mxCreateDoubleScalar((double)lA); 5552 prhs[6] = mxCreateDoubleScalar((double)lB); 5553 prhs[7] = mxCreateString(sctx->funcname); 5554 prhs[8] = sctx->ctx; 5555 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 5556 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5557 mxDestroyArray(prhs[0]); 5558 mxDestroyArray(prhs[1]); 5559 mxDestroyArray(prhs[2]); 5560 mxDestroyArray(prhs[3]); 5561 mxDestroyArray(prhs[4]); 5562 mxDestroyArray(prhs[5]); 5563 mxDestroyArray(prhs[6]); 5564 mxDestroyArray(prhs[7]); 5565 mxDestroyArray(plhs[0]); 5566 mxDestroyArray(plhs[1]); 5567 PetscFunctionReturn(0); 5568 } 5569 5570 5571 #undef __FUNCT__ 5572 #define __FUNCT__ "TSSetJacobianMatlab" 5573 /* 5574 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 5575 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 5576 5577 Logically Collective on TS 5578 5579 Input Parameters: 5580 + ts - the TS context 5581 . A,B - Jacobian matrices 5582 . func - function evaluation routine 5583 - ctx - user context 5584 5585 Calling sequence of func: 5586 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 5587 5588 5589 Level: developer 5590 5591 .keywords: TS, nonlinear, set, function 5592 5593 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 5594 */ 5595 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 5596 { 5597 PetscErrorCode ierr; 5598 TSMatlabContext *sctx; 5599 5600 PetscFunctionBegin; 5601 /* currently sctx is memory bleed */ 5602 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 5603 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 5604 /* 5605 This should work, but it doesn't 5606 sctx->ctx = ctx; 5607 mexMakeArrayPersistent(sctx->ctx); 5608 */ 5609 sctx->ctx = mxDuplicateArray(ctx); 5610 5611 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 5612 PetscFunctionReturn(0); 5613 } 5614 5615 #undef __FUNCT__ 5616 #define __FUNCT__ "TSMonitor_Matlab" 5617 /* 5618 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 5619 5620 Collective on TS 5621 5622 .seealso: TSSetFunction(), TSGetFunction() 5623 @*/ 5624 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 5625 { 5626 PetscErrorCode ierr; 5627 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 5628 int nlhs = 1,nrhs = 6; 5629 mxArray *plhs[1],*prhs[6]; 5630 long long int lx = 0,ls = 0; 5631 5632 PetscFunctionBegin; 5633 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5634 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 5635 5636 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 5637 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 5638 5639 prhs[0] = mxCreateDoubleScalar((double)ls); 5640 prhs[1] = mxCreateDoubleScalar((double)it); 5641 prhs[2] = mxCreateDoubleScalar((double)time); 5642 prhs[3] = mxCreateDoubleScalar((double)lx); 5643 prhs[4] = mxCreateString(sctx->funcname); 5644 prhs[5] = sctx->ctx; 5645 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 5646 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5647 mxDestroyArray(prhs[0]); 5648 mxDestroyArray(prhs[1]); 5649 mxDestroyArray(prhs[2]); 5650 mxDestroyArray(prhs[3]); 5651 mxDestroyArray(prhs[4]); 5652 mxDestroyArray(plhs[0]); 5653 PetscFunctionReturn(0); 5654 } 5655 5656 5657 #undef __FUNCT__ 5658 #define __FUNCT__ "TSMonitorSetMatlab" 5659 /* 5660 TSMonitorSetMatlab - Sets the monitor function from Matlab 5661 5662 Level: developer 5663 5664 .keywords: TS, nonlinear, set, function 5665 5666 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 5667 */ 5668 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 5669 { 5670 PetscErrorCode ierr; 5671 TSMatlabContext *sctx; 5672 5673 PetscFunctionBegin; 5674 /* currently sctx is memory bleed */ 5675 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 5676 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 5677 /* 5678 This should work, but it doesn't 5679 sctx->ctx = ctx; 5680 mexMakeArrayPersistent(sctx->ctx); 5681 */ 5682 sctx->ctx = mxDuplicateArray(ctx); 5683 5684 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 5685 PetscFunctionReturn(0); 5686 } 5687 #endif 5688 5689 #undef __FUNCT__ 5690 #define __FUNCT__ "TSMonitorLGSolution" 5691 /*@C 5692 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 5693 in a time based line graph 5694 5695 Collective on TS 5696 5697 Input Parameters: 5698 + ts - the TS context 5699 . step - current time-step 5700 . ptime - current time 5701 - lg - a line graph object 5702 5703 Options Database: 5704 . -ts_monitor_lg_solution_variables 5705 5706 Level: intermediate 5707 5708 Notes: each process in a parallel run displays its component solutions in a separate window 5709 5710 .keywords: TS, vector, monitor, view 5711 5712 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5713 @*/ 5714 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 5715 { 5716 PetscErrorCode ierr; 5717 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 5718 const PetscScalar *yy; 5719 PetscInt dim; 5720 Vec v; 5721 5722 PetscFunctionBegin; 5723 if (!step) { 5724 PetscDrawAxis axis; 5725 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 5726 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 5727 if (ctx->names && !ctx->displaynames) { 5728 char **displaynames; 5729 PetscBool flg; 5730 5731 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 5732 ierr = PetscMalloc((dim+1)*sizeof(char*),&displaynames);CHKERRQ(ierr); 5733 ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr); 5734 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 5735 if (flg) { 5736 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 5737 } 5738 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 5739 } 5740 if (ctx->displaynames) { 5741 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 5742 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 5743 } else if (ctx->names) { 5744 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 5745 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 5746 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 5747 } 5748 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 5749 } 5750 if (ctx->transform) { 5751 ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr); 5752 } else { 5753 v = u; 5754 } 5755 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 5756 #if defined(PETSC_USE_COMPLEX) 5757 { 5758 PetscReal *yreal; 5759 PetscInt i,n; 5760 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 5761 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 5762 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 5763 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 5764 ierr = PetscFree(yreal);CHKERRQ(ierr); 5765 } 5766 #else 5767 if (ctx->displaynames) { 5768 PetscInt i; 5769 for (i=0; i<ctx->ndisplayvariables; i++) { 5770 ctx->displayvalues[i] = yy[ctx->displayvariables[i]]; 5771 } 5772 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 5773 } else { 5774 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 5775 } 5776 #endif 5777 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 5778 if (ctx->transform) { 5779 ierr = VecDestroy(&v);CHKERRQ(ierr); 5780 } 5781 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 5782 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 5783 } 5784 PetscFunctionReturn(0); 5785 } 5786 5787 5788 #undef __FUNCT__ 5789 #define __FUNCT__ "TSMonitorLGSetVariableNames" 5790 /*@C 5791 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 5792 5793 Collective on TS 5794 5795 Input Parameters: 5796 + ts - the TS context 5797 - names - the names of the components, final string must be NULL 5798 5799 Level: intermediate 5800 5801 .keywords: TS, vector, monitor, view 5802 5803 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 5804 @*/ 5805 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 5806 { 5807 PetscErrorCode ierr; 5808 PetscInt i; 5809 5810 PetscFunctionBegin; 5811 for (i=0; i<ts->numbermonitors; i++) { 5812 if (ts->monitor[i] == TSMonitorLGSolution) { 5813 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 5814 break; 5815 } 5816 } 5817 PetscFunctionReturn(0); 5818 } 5819 5820 #undef __FUNCT__ 5821 #define __FUNCT__ "TSMonitorLGCtxSetVariableNames" 5822 /*@C 5823 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 5824 5825 Collective on TS 5826 5827 Input Parameters: 5828 + ts - the TS context 5829 - names - the names of the components, final string must be NULL 5830 5831 Level: intermediate 5832 5833 .keywords: TS, vector, monitor, view 5834 5835 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 5836 @*/ 5837 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 5838 { 5839 PetscErrorCode ierr; 5840 5841 PetscFunctionBegin; 5842 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 5843 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 5844 PetscFunctionReturn(0); 5845 } 5846 5847 #undef __FUNCT__ 5848 #define __FUNCT__ "TSMonitorLGGetVariableNames" 5849 /*@C 5850 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 5851 5852 Collective on TS 5853 5854 Input Parameter: 5855 . ts - the TS context 5856 5857 Output Parameter: 5858 . names - the names of the components, final string must be NULL 5859 5860 Level: intermediate 5861 5862 .keywords: TS, vector, monitor, view 5863 5864 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 5865 @*/ 5866 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 5867 { 5868 PetscInt i; 5869 5870 PetscFunctionBegin; 5871 *names = NULL; 5872 for (i=0; i<ts->numbermonitors; i++) { 5873 if (ts->monitor[i] == TSMonitorLGSolution) { 5874 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 5875 *names = (const char *const *)ctx->names; 5876 break; 5877 } 5878 } 5879 PetscFunctionReturn(0); 5880 } 5881 5882 #undef __FUNCT__ 5883 #define __FUNCT__ "TSMonitorLGCtxSetDisplayVariables" 5884 /*@C 5885 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 5886 5887 Collective on TS 5888 5889 Input Parameters: 5890 + ctx - the TSMonitorLG context 5891 . displaynames - the names of the components, final string must be NULL 5892 5893 Level: intermediate 5894 5895 .keywords: TS, vector, monitor, view 5896 5897 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 5898 @*/ 5899 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 5900 { 5901 PetscInt j = 0,k; 5902 PetscErrorCode ierr; 5903 5904 PetscFunctionBegin; 5905 if (!ctx->names) PetscFunctionReturn(0); 5906 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 5907 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 5908 while (displaynames[j]) j++; 5909 ctx->ndisplayvariables = j; 5910 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 5911 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 5912 j = 0; 5913 while (displaynames[j]) { 5914 k = 0; 5915 while (ctx->names[k]) { 5916 PetscBool flg; 5917 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 5918 if (flg) { 5919 ctx->displayvariables[j] = k; 5920 break; 5921 } 5922 k++; 5923 } 5924 j++; 5925 } 5926 PetscFunctionReturn(0); 5927 } 5928 5929 5930 #undef __FUNCT__ 5931 #define __FUNCT__ "TSMonitorLGSetDisplayVariables" 5932 /*@C 5933 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 5934 5935 Collective on TS 5936 5937 Input Parameters: 5938 + ts - the TS context 5939 . displaynames - the names of the components, final string must be NULL 5940 5941 Level: intermediate 5942 5943 .keywords: TS, vector, monitor, view 5944 5945 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 5946 @*/ 5947 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 5948 { 5949 PetscInt i; 5950 PetscErrorCode ierr; 5951 5952 PetscFunctionBegin; 5953 for (i=0; i<ts->numbermonitors; i++) { 5954 if (ts->monitor[i] == TSMonitorLGSolution) { 5955 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 5956 break; 5957 } 5958 } 5959 PetscFunctionReturn(0); 5960 } 5961 5962 #undef __FUNCT__ 5963 #define __FUNCT__ "TSMonitorLGSetTransform" 5964 /*@C 5965 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 5966 5967 Collective on TS 5968 5969 Input Parameters: 5970 + ts - the TS context 5971 . transform - the transform function 5972 . destroy - function to destroy the optional context 5973 - ctx - optional context used by transform function 5974 5975 Level: intermediate 5976 5977 .keywords: TS, vector, monitor, view 5978 5979 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 5980 @*/ 5981 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 5982 { 5983 PetscInt i; 5984 PetscErrorCode ierr; 5985 5986 PetscFunctionBegin; 5987 for (i=0; i<ts->numbermonitors; i++) { 5988 if (ts->monitor[i] == TSMonitorLGSolution) { 5989 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 5990 } 5991 } 5992 PetscFunctionReturn(0); 5993 } 5994 5995 #undef __FUNCT__ 5996 #define __FUNCT__ "TSMonitorLGCtxSetTransform" 5997 /*@C 5998 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 5999 6000 Collective on TSLGCtx 6001 6002 Input Parameters: 6003 + ts - the TS context 6004 . transform - the transform function 6005 . destroy - function to destroy the optional context 6006 - ctx - optional context used by transform function 6007 6008 Level: intermediate 6009 6010 .keywords: TS, vector, monitor, view 6011 6012 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 6013 @*/ 6014 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6015 { 6016 PetscFunctionBegin; 6017 ctx->transform = transform; 6018 ctx->transformdestroy = destroy; 6019 ctx->transformctx = tctx; 6020 PetscFunctionReturn(0); 6021 } 6022 6023 #undef __FUNCT__ 6024 #define __FUNCT__ "TSMonitorLGError" 6025 /*@C 6026 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector 6027 in a time based line graph 6028 6029 Collective on TS 6030 6031 Input Parameters: 6032 + ts - the TS context 6033 . step - current time-step 6034 . ptime - current time 6035 - lg - a line graph object 6036 6037 Level: intermediate 6038 6039 Notes: 6040 Only for sequential solves. 6041 6042 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6043 6044 Options Database Keys: 6045 . -ts_monitor_lg_error - create a graphical monitor of error history 6046 6047 .keywords: TS, vector, monitor, view 6048 6049 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6050 @*/ 6051 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 6052 { 6053 PetscErrorCode ierr; 6054 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 6055 const PetscScalar *yy; 6056 Vec y; 6057 PetscInt dim; 6058 6059 PetscFunctionBegin; 6060 if (!step) { 6061 PetscDrawAxis axis; 6062 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6063 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr); 6064 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6065 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6066 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6067 } 6068 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6069 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6070 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6071 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 6072 #if defined(PETSC_USE_COMPLEX) 6073 { 6074 PetscReal *yreal; 6075 PetscInt i,n; 6076 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 6077 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6078 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6079 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6080 ierr = PetscFree(yreal);CHKERRQ(ierr); 6081 } 6082 #else 6083 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6084 #endif 6085 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 6086 ierr = VecDestroy(&y);CHKERRQ(ierr); 6087 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6088 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6089 } 6090 PetscFunctionReturn(0); 6091 } 6092 6093 #undef __FUNCT__ 6094 #define __FUNCT__ "TSMonitorLGSNESIterations" 6095 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 6096 { 6097 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 6098 PetscReal x = ptime,y; 6099 PetscErrorCode ierr; 6100 PetscInt its; 6101 6102 PetscFunctionBegin; 6103 if (!n) { 6104 PetscDrawAxis axis; 6105 6106 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6107 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 6108 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6109 6110 ctx->snes_its = 0; 6111 } 6112 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 6113 y = its - ctx->snes_its; 6114 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 6115 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 6116 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6117 } 6118 ctx->snes_its = its; 6119 PetscFunctionReturn(0); 6120 } 6121 6122 #undef __FUNCT__ 6123 #define __FUNCT__ "TSMonitorLGKSPIterations" 6124 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 6125 { 6126 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 6127 PetscReal x = ptime,y; 6128 PetscErrorCode ierr; 6129 PetscInt its; 6130 6131 PetscFunctionBegin; 6132 if (!n) { 6133 PetscDrawAxis axis; 6134 6135 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6136 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 6137 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6138 6139 ctx->ksp_its = 0; 6140 } 6141 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 6142 y = its - ctx->ksp_its; 6143 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 6144 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 6145 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6146 } 6147 ctx->ksp_its = its; 6148 PetscFunctionReturn(0); 6149 } 6150 6151 #undef __FUNCT__ 6152 #define __FUNCT__ "TSComputeLinearStability" 6153 /*@ 6154 TSComputeLinearStability - computes the linear stability function at a point 6155 6156 Collective on TS and Vec 6157 6158 Input Parameters: 6159 + ts - the TS context 6160 - xr,xi - real and imaginary part of input arguments 6161 6162 Output Parameters: 6163 . yr,yi - real and imaginary part of function value 6164 6165 Level: developer 6166 6167 .keywords: TS, compute 6168 6169 .seealso: TSSetRHSFunction(), TSComputeIFunction() 6170 @*/ 6171 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 6172 { 6173 PetscErrorCode ierr; 6174 6175 PetscFunctionBegin; 6176 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6177 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 6178 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 6179 PetscFunctionReturn(0); 6180 } 6181 6182 /* ------------------------------------------------------------------------*/ 6183 #undef __FUNCT__ 6184 #define __FUNCT__ "TSMonitorEnvelopeCtxCreate" 6185 /*@C 6186 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 6187 6188 Collective on TS 6189 6190 Input Parameters: 6191 . ts - the ODE solver object 6192 6193 Output Parameter: 6194 . ctx - the context 6195 6196 Level: intermediate 6197 6198 .keywords: TS, monitor, line graph, residual, seealso 6199 6200 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 6201 6202 @*/ 6203 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 6204 { 6205 PetscErrorCode ierr; 6206 6207 PetscFunctionBegin; 6208 ierr = PetscNew(ctx);CHKERRQ(ierr); 6209 PetscFunctionReturn(0); 6210 } 6211 6212 #undef __FUNCT__ 6213 #define __FUNCT__ "TSMonitorEnvelope" 6214 /*@C 6215 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 6216 6217 Collective on TS 6218 6219 Input Parameters: 6220 + ts - the TS context 6221 . step - current time-step 6222 . ptime - current time 6223 - ctx - the envelope context 6224 6225 Options Database: 6226 . -ts_monitor_envelope 6227 6228 Level: intermediate 6229 6230 Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 6231 6232 .keywords: TS, vector, monitor, view 6233 6234 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds() 6235 @*/ 6236 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 6237 { 6238 PetscErrorCode ierr; 6239 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dummy; 6240 6241 PetscFunctionBegin; 6242 if (!ctx->max) { 6243 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 6244 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 6245 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 6246 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 6247 } else { 6248 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 6249 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 6250 } 6251 PetscFunctionReturn(0); 6252 } 6253 6254 6255 #undef __FUNCT__ 6256 #define __FUNCT__ "TSMonitorEnvelopeGetBounds" 6257 /*@C 6258 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 6259 6260 Collective on TS 6261 6262 Input Parameter: 6263 . ts - the TS context 6264 6265 Output Parameter: 6266 + max - the maximum values 6267 - min - the minimum values 6268 6269 Level: intermediate 6270 6271 .keywords: TS, vector, monitor, view 6272 6273 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 6274 @*/ 6275 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 6276 { 6277 PetscInt i; 6278 6279 PetscFunctionBegin; 6280 if (max) *max = NULL; 6281 if (min) *min = NULL; 6282 for (i=0; i<ts->numbermonitors; i++) { 6283 if (ts->monitor[i] == TSMonitorEnvelope) { 6284 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 6285 if (max) *max = ctx->max; 6286 if (min) *min = ctx->min; 6287 break; 6288 } 6289 } 6290 PetscFunctionReturn(0); 6291 } 6292 6293 #undef __FUNCT__ 6294 #define __FUNCT__ "TSMonitorEnvelopeCtxDestroy" 6295 /*@C 6296 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 6297 6298 Collective on TSMonitorEnvelopeCtx 6299 6300 Input Parameter: 6301 . ctx - the monitor context 6302 6303 Level: intermediate 6304 6305 .keywords: TS, monitor, line graph, destroy 6306 6307 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 6308 @*/ 6309 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 6310 { 6311 PetscErrorCode ierr; 6312 6313 PetscFunctionBegin; 6314 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 6315 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 6316 ierr = PetscFree(*ctx);CHKERRQ(ierr); 6317 PetscFunctionReturn(0); 6318 } 6319 6320 #undef __FUNCT__ 6321 #define __FUNCT__ "TSRollBack" 6322 /*@ 6323 TSRollBack - Rolls back one time step 6324 6325 Collective on TS 6326 6327 Input Parameter: 6328 . ts - the TS context obtained from TSCreate() 6329 6330 Level: advanced 6331 6332 .keywords: TS, timestep, rollback 6333 6334 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 6335 @*/ 6336 PetscErrorCode TSRollBack(TS ts) 6337 { 6338 PetscErrorCode ierr; 6339 6340 PetscFunctionBegin; 6341 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 6342 6343 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 6344 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 6345 ts->time_step = ts->ptime - ts->ptime_prev; 6346 ts->ptime = ts->ptime_prev; 6347 ts->steprollback = PETSC_TRUE; /* Flag to indicate that the step is rollbacked */ 6348 PetscFunctionReturn(0); 6349 } 6350 6351 #undef __FUNCT__ 6352 #define __FUNCT__ "TSGetStages" 6353 /*@ 6354 TSGetStages - Get the number of stages and stage values 6355 6356 Input Parameter: 6357 . ts - the TS context obtained from TSCreate() 6358 6359 Level: advanced 6360 6361 .keywords: TS, getstages 6362 6363 .seealso: TSCreate() 6364 @*/ 6365 PetscErrorCode TSGetStages(TS ts,PetscInt *ns, Vec **Y) 6366 { 6367 PetscErrorCode ierr; 6368 6369 PetscFunctionBegin; 6370 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 6371 PetscValidPointer(ns,2); 6372 6373 if (!ts->ops->getstages) *ns=0; 6374 else { 6375 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 6376 } 6377 PetscFunctionReturn(0); 6378 } 6379 6380 6381 #undef __FUNCT__ 6382 #define __FUNCT__ "TSComputeIJacobianDefaultColor" 6383 /*@C 6384 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 6385 6386 Collective on SNES 6387 6388 Input Parameters: 6389 + ts - the TS context 6390 . t - current timestep 6391 . U - state vector 6392 . Udot - time derivative of state vector 6393 . shift - shift to apply, see note below 6394 - ctx - an optional user context 6395 6396 Output Parameters: 6397 + J - Jacobian matrix (not altered in this routine) 6398 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 6399 6400 Level: intermediate 6401 6402 Notes: 6403 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 6404 6405 dF/dU + shift*dF/dUdot 6406 6407 Most users should not need to explicitly call this routine, as it 6408 is used internally within the nonlinear solvers. 6409 6410 This will first try to get the coloring from the DM. If the DM type has no coloring 6411 routine, then it will try to get the coloring from the matrix. This requires that the 6412 matrix have nonzero entries precomputed. 6413 6414 .keywords: TS, finite differences, Jacobian, coloring, sparse 6415 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 6416 @*/ 6417 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 6418 { 6419 SNES snes; 6420 MatFDColoring color; 6421 PetscBool hascolor, matcolor = PETSC_FALSE; 6422 PetscErrorCode ierr; 6423 6424 PetscFunctionBegin; 6425 ierr = PetscOptionsGetBool(((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 6426 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 6427 if (!color) { 6428 DM dm; 6429 ISColoring iscoloring; 6430 6431 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 6432 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 6433 if (hascolor && !matcolor) { 6434 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 6435 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 6436 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 6437 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 6438 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 6439 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 6440 } else { 6441 MatColoring mc; 6442 6443 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 6444 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 6445 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 6446 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 6447 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 6448 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 6449 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 6450 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 6451 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 6452 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 6453 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 6454 } 6455 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 6456 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 6457 } 6458 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 6459 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 6460 if (J != B) { 6461 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6462 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6463 } 6464 PetscFunctionReturn(0); 6465 } 6466