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