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