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 PetscErrorCode ierr; 3265 3266 PetscFunctionBegin; 3267 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3268 if (ts->prestage) { 3269 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 3270 } 3271 PetscFunctionReturn(0); 3272 } 3273 3274 /*@ 3275 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 3276 3277 Collective on TS 3278 3279 Input Parameters: 3280 . ts - The TS context obtained from TSCreate() 3281 stagetime - The absolute time of the current stage 3282 stageindex - Stage number 3283 Y - Array of vectors (of size = total number 3284 of stages) with the stage solutions 3285 3286 Notes: 3287 TSPostStage() is typically used within time stepping implementations, 3288 most users would not generally call this routine themselves. 3289 3290 Level: developer 3291 3292 .keywords: TS, timestep 3293 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3294 @*/ 3295 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 3296 { 3297 PetscErrorCode ierr; 3298 3299 PetscFunctionBegin; 3300 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3301 if (ts->poststage) { 3302 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 3303 } 3304 PetscFunctionReturn(0); 3305 } 3306 3307 /*@ 3308 TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate() 3309 3310 Collective on TS 3311 3312 Input Parameters: 3313 . ts - The TS context obtained from TSCreate() 3314 3315 Notes: 3316 TSPostEvaluate() is typically used within time stepping implementations, 3317 most users would not generally call this routine themselves. 3318 3319 Level: developer 3320 3321 .keywords: TS, timestep 3322 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep() 3323 @*/ 3324 PetscErrorCode TSPostEvaluate(TS ts) 3325 { 3326 PetscErrorCode ierr; 3327 3328 PetscFunctionBegin; 3329 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3330 if (ts->postevaluate) { 3331 Vec U; 3332 PetscObjectState sprev,spost; 3333 3334 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3335 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3336 PetscStackCallStandard((*ts->postevaluate),(ts)); 3337 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3338 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3339 } 3340 PetscFunctionReturn(0); 3341 } 3342 3343 /*@C 3344 TSSetPostStep - Sets the general-purpose function 3345 called once at the end of each time step. 3346 3347 Logically Collective on TS 3348 3349 Input Parameters: 3350 + ts - The TS context obtained from TSCreate() 3351 - func - The function 3352 3353 Calling sequence of func: 3354 $ func (TS ts); 3355 3356 Notes: 3357 The function set by TSSetPostStep() is called after each successful step. The solution vector X 3358 obtained by TSGetSolution() may be different than that computed at the step end if the event handler 3359 locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead. 3360 3361 Level: intermediate 3362 3363 .keywords: TS, timestep 3364 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetStepNumber(), TSGetTime(), TSRestartStep() 3365 @*/ 3366 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 3367 { 3368 PetscFunctionBegin; 3369 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3370 ts->poststep = func; 3371 PetscFunctionReturn(0); 3372 } 3373 3374 /*@ 3375 TSPostStep - Runs the user-defined post-step function. 3376 3377 Collective on TS 3378 3379 Input Parameters: 3380 . ts - The TS context obtained from TSCreate() 3381 3382 Notes: 3383 TSPostStep() is typically used within time stepping implementations, 3384 so most users would not generally call this routine themselves. 3385 3386 Level: developer 3387 3388 .keywords: TS, timestep 3389 @*/ 3390 PetscErrorCode TSPostStep(TS ts) 3391 { 3392 PetscErrorCode ierr; 3393 3394 PetscFunctionBegin; 3395 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3396 if (ts->poststep) { 3397 Vec U; 3398 PetscObjectState sprev,spost; 3399 3400 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3401 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3402 PetscStackCallStandard((*ts->poststep),(ts)); 3403 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3404 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3405 } 3406 PetscFunctionReturn(0); 3407 } 3408 3409 /* ------------ Routines to set performance monitoring options ----------- */ 3410 3411 /*@C 3412 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 3413 timestep to display the iteration's progress. 3414 3415 Logically Collective on TS 3416 3417 Input Parameters: 3418 + ts - the TS context obtained from TSCreate() 3419 . monitor - monitoring routine 3420 . mctx - [optional] user-defined context for private data for the 3421 monitor routine (use NULL if no context is desired) 3422 - monitordestroy - [optional] routine that frees monitor context 3423 (may be NULL) 3424 3425 Calling sequence of monitor: 3426 $ PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 3427 3428 + ts - the TS context 3429 . 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) 3430 . time - current time 3431 . u - current iterate 3432 - mctx - [optional] monitoring context 3433 3434 Notes: 3435 This routine adds an additional monitor to the list of monitors that 3436 already has been loaded. 3437 3438 Fortran Notes: 3439 Only a single monitor function can be set for each TS object 3440 3441 Level: intermediate 3442 3443 .keywords: TS, timestep, set, monitor 3444 3445 .seealso: TSMonitorDefault(), TSMonitorCancel() 3446 @*/ 3447 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 3448 { 3449 PetscErrorCode ierr; 3450 PetscInt i; 3451 PetscBool identical; 3452 3453 PetscFunctionBegin; 3454 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3455 for (i=0; i<ts->numbermonitors;i++) { 3456 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr); 3457 if (identical) PetscFunctionReturn(0); 3458 } 3459 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3460 ts->monitor[ts->numbermonitors] = monitor; 3461 ts->monitordestroy[ts->numbermonitors] = mdestroy; 3462 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 3463 PetscFunctionReturn(0); 3464 } 3465 3466 /*@C 3467 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 3468 3469 Logically Collective on TS 3470 3471 Input Parameters: 3472 . ts - the TS context obtained from TSCreate() 3473 3474 Notes: 3475 There is no way to remove a single, specific monitor. 3476 3477 Level: intermediate 3478 3479 .keywords: TS, timestep, set, monitor 3480 3481 .seealso: TSMonitorDefault(), TSMonitorSet() 3482 @*/ 3483 PetscErrorCode TSMonitorCancel(TS ts) 3484 { 3485 PetscErrorCode ierr; 3486 PetscInt i; 3487 3488 PetscFunctionBegin; 3489 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3490 for (i=0; i<ts->numbermonitors; i++) { 3491 if (ts->monitordestroy[i]) { 3492 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 3493 } 3494 } 3495 ts->numbermonitors = 0; 3496 PetscFunctionReturn(0); 3497 } 3498 3499 /*@C 3500 TSMonitorDefault - The Default monitor, prints the timestep and time for each step 3501 3502 Level: intermediate 3503 3504 .keywords: TS, set, monitor 3505 3506 .seealso: TSMonitorSet() 3507 @*/ 3508 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3509 { 3510 PetscErrorCode ierr; 3511 PetscViewer viewer = vf->viewer; 3512 PetscBool iascii,ibinary; 3513 3514 PetscFunctionBegin; 3515 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3516 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3517 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 3518 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3519 if (iascii) { 3520 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3521 if (step == -1){ /* this indicates it is an interpolated solution */ 3522 ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr); 3523 } else { 3524 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3525 } 3526 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3527 } else if (ibinary) { 3528 PetscMPIInt rank; 3529 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 3530 if (!rank) { 3531 PetscBool skipHeader; 3532 PetscInt classid = REAL_FILE_CLASSID; 3533 3534 ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 3535 if (!skipHeader) { 3536 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 3537 } 3538 ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr); 3539 } else { 3540 ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr); 3541 } 3542 } 3543 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3544 PetscFunctionReturn(0); 3545 } 3546 3547 /*@C 3548 TSMonitorExtreme - Prints the extreme values of the solution at each timestep 3549 3550 Level: intermediate 3551 3552 .keywords: TS, set, monitor 3553 3554 .seealso: TSMonitorSet() 3555 @*/ 3556 PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3557 { 3558 PetscErrorCode ierr; 3559 PetscViewer viewer = vf->viewer; 3560 PetscBool iascii; 3561 PetscReal max,min; 3562 3563 3564 PetscFunctionBegin; 3565 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3566 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3567 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3568 if (iascii) { 3569 ierr = VecMax(v,NULL,&max);CHKERRQ(ierr); 3570 ierr = VecMin(v,NULL,&min);CHKERRQ(ierr); 3571 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3572 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); 3573 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3574 } 3575 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3576 PetscFunctionReturn(0); 3577 } 3578 3579 /*@ 3580 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 3581 3582 Collective on TS 3583 3584 Input Argument: 3585 + ts - time stepping context 3586 - t - time to interpolate to 3587 3588 Output Argument: 3589 . U - state at given time 3590 3591 Level: intermediate 3592 3593 Developer Notes: 3594 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3595 3596 .keywords: TS, set 3597 3598 .seealso: TSSetExactFinalTime(), TSSolve() 3599 @*/ 3600 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3601 { 3602 PetscErrorCode ierr; 3603 3604 PetscFunctionBegin; 3605 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3606 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3607 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); 3608 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3609 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3610 PetscFunctionReturn(0); 3611 } 3612 3613 /*@ 3614 TSStep - Steps one time step 3615 3616 Collective on TS 3617 3618 Input Parameter: 3619 . ts - the TS context obtained from TSCreate() 3620 3621 Level: developer 3622 3623 Notes: 3624 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3625 3626 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3627 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3628 3629 This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the 3630 time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3631 3632 .keywords: TS, timestep, solve 3633 3634 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3635 @*/ 3636 PetscErrorCode TSStep(TS ts) 3637 { 3638 PetscErrorCode ierr; 3639 static PetscBool cite = PETSC_FALSE; 3640 PetscReal ptime; 3641 3642 PetscFunctionBegin; 3643 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3644 ierr = PetscCitationsRegister("@techreport{tspaper,\n" 3645 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3646 " author = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n" 3647 " type = {Preprint},\n" 3648 " number = {ANL/MCS-P5061-0114},\n" 3649 " institution = {Argonne National Laboratory},\n" 3650 " year = {2014}\n}\n",&cite);CHKERRQ(ierr); 3651 3652 ierr = TSSetUp(ts);CHKERRQ(ierr); 3653 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3654 3655 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>"); 3656 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()"); 3657 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"); 3658 3659 if (!ts->steps) ts->ptime_prev = ts->ptime; 3660 ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev; 3661 ts->reason = TS_CONVERGED_ITERATING; 3662 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3663 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3664 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3665 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3666 ts->ptime_prev = ptime; 3667 ts->steps++; 3668 ts->steprollback = PETSC_FALSE; 3669 ts->steprestart = PETSC_FALSE; 3670 3671 if (ts->reason < 0) { 3672 if (ts->errorifstepfailed) { 3673 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]); 3674 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3675 } 3676 } else if (!ts->reason) { 3677 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3678 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3679 } 3680 PetscFunctionReturn(0); 3681 } 3682 3683 /*@ 3684 TSEvaluateWLTE - Evaluate the weighted local truncation error norm 3685 at the end of a time step with a given order of accuracy. 3686 3687 Collective on TS 3688 3689 Input Arguments: 3690 + ts - time stepping context 3691 . wnormtype - norm type, either NORM_2 or NORM_INFINITY 3692 - order - optional, desired order for the error evaluation or PETSC_DECIDE 3693 3694 Output Arguments: 3695 + order - optional, the actual order of the error evaluation 3696 - wlte - the weighted local truncation error norm 3697 3698 Level: advanced 3699 3700 Notes: 3701 If the timestepper cannot evaluate the error in a particular step 3702 (eg. in the first step or restart steps after event handling), 3703 this routine returns wlte=-1.0 . 3704 3705 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm() 3706 @*/ 3707 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte) 3708 { 3709 PetscErrorCode ierr; 3710 3711 PetscFunctionBegin; 3712 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3713 PetscValidType(ts,1); 3714 PetscValidLogicalCollectiveEnum(ts,wnormtype,4); 3715 if (order) PetscValidIntPointer(order,3); 3716 if (order) PetscValidLogicalCollectiveInt(ts,*order,3); 3717 PetscValidRealPointer(wlte,4); 3718 if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 3719 if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name); 3720 ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr); 3721 PetscFunctionReturn(0); 3722 } 3723 3724 /*@ 3725 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 3726 3727 Collective on TS 3728 3729 Input Arguments: 3730 + ts - time stepping context 3731 . order - desired order of accuracy 3732 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 3733 3734 Output Arguments: 3735 . U - state at the end of the current step 3736 3737 Level: advanced 3738 3739 Notes: 3740 This function cannot be called until all stages have been evaluated. 3741 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. 3742 3743 .seealso: TSStep(), TSAdapt 3744 @*/ 3745 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 3746 { 3747 PetscErrorCode ierr; 3748 3749 PetscFunctionBegin; 3750 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3751 PetscValidType(ts,1); 3752 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3753 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3754 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 3755 PetscFunctionReturn(0); 3756 } 3757 3758 /*@ 3759 TSSolve - Steps the requested number of timesteps. 3760 3761 Collective on TS 3762 3763 Input Parameter: 3764 + ts - the TS context obtained from TSCreate() 3765 - u - the solution vector (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used, 3766 otherwise must contain the initial conditions and will contain the solution at the final requested time 3767 3768 Level: beginner 3769 3770 Notes: 3771 The final time returned by this function may be different from the time of the internally 3772 held state accessible by TSGetSolution() and TSGetTime() because the method may have 3773 stepped over the final time. 3774 3775 .keywords: TS, timestep, solve 3776 3777 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime() 3778 @*/ 3779 PetscErrorCode TSSolve(TS ts,Vec u) 3780 { 3781 Vec solution; 3782 PetscErrorCode ierr; 3783 3784 PetscFunctionBegin; 3785 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3786 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3787 3788 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 */ 3789 if (!ts->vec_sol || u == ts->vec_sol) { 3790 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 3791 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 3792 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 3793 } 3794 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 3795 if (ts->forward_solve) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE"); 3796 } else if (u) { 3797 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 3798 } 3799 ierr = TSSetUp(ts);CHKERRQ(ierr); 3800 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3801 3802 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>"); 3803 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()"); 3804 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"); 3805 3806 if (ts->forward_solve) { 3807 ierr = TSForwardSetUp(ts);CHKERRQ(ierr); 3808 } 3809 3810 /* reset number of steps only when the step is not restarted. ARKIMEX 3811 restarts the step after an event. Resetting these counters in such case causes 3812 TSTrajectory to incorrectly save the output files 3813 */ 3814 /* reset time step and iteration counters */ 3815 if (!ts->steps) { 3816 ts->ksp_its = 0; 3817 ts->snes_its = 0; 3818 ts->num_snes_failures = 0; 3819 ts->reject = 0; 3820 ts->steprestart = PETSC_TRUE; 3821 ts->steprollback = PETSC_FALSE; 3822 } 3823 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && ts->ptime + ts->time_step > ts->max_time) ts->time_step = ts->max_time - ts->ptime; 3824 ts->reason = TS_CONVERGED_ITERATING; 3825 3826 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 3827 3828 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 3829 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 3830 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 3831 ts->solvetime = ts->ptime; 3832 solution = ts->vec_sol; 3833 } else { /* Step the requested number of timesteps. */ 3834 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3835 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3836 3837 if (!ts->steps) { 3838 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3839 ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3840 } 3841 3842 while (!ts->reason) { 3843 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3844 if (!ts->steprollback) { 3845 ierr = TSPreStep(ts);CHKERRQ(ierr); 3846 } 3847 ierr = TSStep(ts);CHKERRQ(ierr); 3848 if (ts->testjacobian) { 3849 ierr = TSRHSJacobianTest(ts,NULL);CHKERRQ(ierr); 3850 } 3851 if (ts->testjacobiantranspose) { 3852 ierr = TSRHSJacobianTestTranspose(ts,NULL);CHKERRQ(ierr); 3853 } 3854 if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */ 3855 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 3856 } 3857 if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */ 3858 ierr = TSForwardStep(ts);CHKERRQ(ierr); 3859 } 3860 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 3861 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. */ 3862 if (ts->steprollback) { 3863 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 3864 } 3865 if (!ts->steprollback) { 3866 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3867 ierr = TSPostStep(ts);CHKERRQ(ierr); 3868 } 3869 } 3870 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3871 3872 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 3873 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 3874 ts->solvetime = ts->max_time; 3875 solution = u; 3876 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 3877 } else { 3878 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 3879 ts->solvetime = ts->ptime; 3880 solution = ts->vec_sol; 3881 } 3882 } 3883 3884 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 3885 ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr); 3886 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 3887 if (ts->adjoint_solve) { 3888 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 3889 } 3890 PetscFunctionReturn(0); 3891 } 3892 3893 /*@C 3894 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 3895 3896 Collective on TS 3897 3898 Input Parameters: 3899 + ts - time stepping context obtained from TSCreate() 3900 . step - step number that has just completed 3901 . ptime - model time of the state 3902 - u - state at the current model time 3903 3904 Notes: 3905 TSMonitor() is typically used automatically within the time stepping implementations. 3906 Users would almost never call this routine directly. 3907 3908 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 3909 3910 Level: developer 3911 3912 .keywords: TS, timestep 3913 @*/ 3914 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 3915 { 3916 DM dm; 3917 PetscInt i,n = ts->numbermonitors; 3918 PetscErrorCode ierr; 3919 3920 PetscFunctionBegin; 3921 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3922 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 3923 3924 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3925 ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr); 3926 3927 ierr = VecLockPush(u);CHKERRQ(ierr); 3928 for (i=0; i<n; i++) { 3929 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 3930 } 3931 ierr = VecLockPop(u);CHKERRQ(ierr); 3932 PetscFunctionReturn(0); 3933 } 3934 3935 /* ------------------------------------------------------------------------*/ 3936 /*@C 3937 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 3938 TS to monitor the solution process graphically in various ways 3939 3940 Collective on TS 3941 3942 Input Parameters: 3943 + host - the X display to open, or null for the local machine 3944 . label - the title to put in the title bar 3945 . x, y - the screen coordinates of the upper left coordinate of the window 3946 . m, n - the screen width and height in pixels 3947 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 3948 3949 Output Parameter: 3950 . ctx - the context 3951 3952 Options Database Key: 3953 + -ts_monitor_lg_timestep - automatically sets line graph monitor 3954 + -ts_monitor_lg_timestep_log - automatically sets line graph monitor 3955 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 3956 . -ts_monitor_lg_error - monitor the error 3957 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 3958 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 3959 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 3960 3961 Notes: 3962 Use TSMonitorLGCtxDestroy() to destroy. 3963 3964 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 3965 3966 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 3967 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 3968 as the first argument. 3969 3970 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 3971 3972 Level: intermediate 3973 3974 .keywords: TS, monitor, line graph, residual 3975 3976 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 3977 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 3978 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 3979 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 3980 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 3981 3982 @*/ 3983 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 3984 { 3985 PetscDraw draw; 3986 PetscErrorCode ierr; 3987 3988 PetscFunctionBegin; 3989 ierr = PetscNew(ctx);CHKERRQ(ierr); 3990 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 3991 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 3992 ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr); 3993 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 3994 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 3995 (*ctx)->howoften = howoften; 3996 PetscFunctionReturn(0); 3997 } 3998 3999 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 4000 { 4001 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4002 PetscReal x = ptime,y; 4003 PetscErrorCode ierr; 4004 4005 PetscFunctionBegin; 4006 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 4007 if (!step) { 4008 PetscDrawAxis axis; 4009 const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step"; 4010 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4011 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr); 4012 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4013 } 4014 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 4015 if (ctx->semilogy) y = PetscLog10Real(y); 4016 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4017 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4018 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4019 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 4020 } 4021 PetscFunctionReturn(0); 4022 } 4023 4024 /*@C 4025 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 4026 with TSMonitorLGCtxCreate(). 4027 4028 Collective on TSMonitorLGCtx 4029 4030 Input Parameter: 4031 . ctx - the monitor context 4032 4033 Level: intermediate 4034 4035 .keywords: TS, monitor, line graph, destroy 4036 4037 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 4038 @*/ 4039 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 4040 { 4041 PetscErrorCode ierr; 4042 4043 PetscFunctionBegin; 4044 if ((*ctx)->transformdestroy) { 4045 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 4046 } 4047 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 4048 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 4049 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 4050 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 4051 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 4052 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4053 PetscFunctionReturn(0); 4054 } 4055 4056 /*@ 4057 TSGetTime - Gets the time of the most recently completed step. 4058 4059 Not Collective 4060 4061 Input Parameter: 4062 . ts - the TS context obtained from TSCreate() 4063 4064 Output Parameter: 4065 . t - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime(). 4066 4067 Level: beginner 4068 4069 Note: 4070 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 4071 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 4072 4073 .seealso: TSGetSolveTime(), TSSetTime(), TSGetTimeStep() 4074 4075 .keywords: TS, get, time 4076 @*/ 4077 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 4078 { 4079 PetscFunctionBegin; 4080 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4081 PetscValidRealPointer(t,2); 4082 *t = ts->ptime; 4083 PetscFunctionReturn(0); 4084 } 4085 4086 /*@ 4087 TSGetPrevTime - Gets the starting time of the previously completed step. 4088 4089 Not Collective 4090 4091 Input Parameter: 4092 . ts - the TS context obtained from TSCreate() 4093 4094 Output Parameter: 4095 . t - the previous time 4096 4097 Level: beginner 4098 4099 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep() 4100 4101 .keywords: TS, get, time 4102 @*/ 4103 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 4104 { 4105 PetscFunctionBegin; 4106 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4107 PetscValidRealPointer(t,2); 4108 *t = ts->ptime_prev; 4109 PetscFunctionReturn(0); 4110 } 4111 4112 /*@ 4113 TSSetTime - Allows one to reset the time. 4114 4115 Logically Collective on TS 4116 4117 Input Parameters: 4118 + ts - the TS context obtained from TSCreate() 4119 - time - the time 4120 4121 Level: intermediate 4122 4123 .seealso: TSGetTime(), TSSetMaxSteps() 4124 4125 .keywords: TS, set, time 4126 @*/ 4127 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4128 { 4129 PetscFunctionBegin; 4130 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4131 PetscValidLogicalCollectiveReal(ts,t,2); 4132 ts->ptime = t; 4133 PetscFunctionReturn(0); 4134 } 4135 4136 /*@C 4137 TSSetOptionsPrefix - Sets the prefix used for searching for all 4138 TS options in the database. 4139 4140 Logically Collective on TS 4141 4142 Input Parameter: 4143 + ts - The TS context 4144 - prefix - The prefix to prepend to all option names 4145 4146 Notes: 4147 A hyphen (-) must NOT be given at the beginning of the prefix name. 4148 The first character of all runtime options is AUTOMATICALLY the 4149 hyphen. 4150 4151 Level: advanced 4152 4153 .keywords: TS, set, options, prefix, database 4154 4155 .seealso: TSSetFromOptions() 4156 4157 @*/ 4158 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4159 { 4160 PetscErrorCode ierr; 4161 SNES snes; 4162 4163 PetscFunctionBegin; 4164 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4165 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4166 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4167 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4168 PetscFunctionReturn(0); 4169 } 4170 4171 /*@C 4172 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4173 TS options in the database. 4174 4175 Logically Collective on TS 4176 4177 Input Parameter: 4178 + ts - The TS context 4179 - prefix - The prefix to prepend to all option names 4180 4181 Notes: 4182 A hyphen (-) must NOT be given at the beginning of the prefix name. 4183 The first character of all runtime options is AUTOMATICALLY the 4184 hyphen. 4185 4186 Level: advanced 4187 4188 .keywords: TS, append, options, prefix, database 4189 4190 .seealso: TSGetOptionsPrefix() 4191 4192 @*/ 4193 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4194 { 4195 PetscErrorCode ierr; 4196 SNES snes; 4197 4198 PetscFunctionBegin; 4199 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4200 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4201 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4202 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4203 PetscFunctionReturn(0); 4204 } 4205 4206 /*@C 4207 TSGetOptionsPrefix - Sets the prefix used for searching for all 4208 TS options in the database. 4209 4210 Not Collective 4211 4212 Input Parameter: 4213 . ts - The TS context 4214 4215 Output Parameter: 4216 . prefix - A pointer to the prefix string used 4217 4218 Notes: 4219 On the fortran side, the user should pass in a string 'prifix' of 4220 sufficient length to hold the prefix. 4221 4222 Level: intermediate 4223 4224 .keywords: TS, get, options, prefix, database 4225 4226 .seealso: TSAppendOptionsPrefix() 4227 @*/ 4228 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4229 { 4230 PetscErrorCode ierr; 4231 4232 PetscFunctionBegin; 4233 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4234 PetscValidPointer(prefix,2); 4235 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4236 PetscFunctionReturn(0); 4237 } 4238 4239 /*@C 4240 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4241 4242 Not Collective, but parallel objects are returned if TS is parallel 4243 4244 Input Parameter: 4245 . ts - The TS context obtained from TSCreate() 4246 4247 Output Parameters: 4248 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4249 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4250 . func - Function to compute the Jacobian of the RHS (or NULL) 4251 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4252 4253 Notes: 4254 You can pass in NULL for any return argument you do not need. 4255 4256 Level: intermediate 4257 4258 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4259 4260 .keywords: TS, timestep, get, matrix, Jacobian 4261 @*/ 4262 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4263 { 4264 PetscErrorCode ierr; 4265 DM dm; 4266 4267 PetscFunctionBegin; 4268 if (Amat || Pmat) { 4269 SNES snes; 4270 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4271 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4272 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4273 } 4274 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4275 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4276 PetscFunctionReturn(0); 4277 } 4278 4279 /*@C 4280 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4281 4282 Not Collective, but parallel objects are returned if TS is parallel 4283 4284 Input Parameter: 4285 . ts - The TS context obtained from TSCreate() 4286 4287 Output Parameters: 4288 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4289 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4290 . f - The function to compute the matrices 4291 - ctx - User-defined context for Jacobian evaluation routine 4292 4293 Notes: 4294 You can pass in NULL for any return argument you do not need. 4295 4296 Level: advanced 4297 4298 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4299 4300 .keywords: TS, timestep, get, matrix, Jacobian 4301 @*/ 4302 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4303 { 4304 PetscErrorCode ierr; 4305 DM dm; 4306 4307 PetscFunctionBegin; 4308 if (Amat || Pmat) { 4309 SNES snes; 4310 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4311 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4312 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4313 } 4314 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4315 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4316 PetscFunctionReturn(0); 4317 } 4318 4319 /*@C 4320 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4321 VecView() for the solution at each timestep 4322 4323 Collective on TS 4324 4325 Input Parameters: 4326 + ts - the TS context 4327 . step - current time-step 4328 . ptime - current time 4329 - dummy - either a viewer or NULL 4330 4331 Options Database: 4332 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4333 4334 Notes: 4335 the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4336 will look bad 4337 4338 Level: intermediate 4339 4340 .keywords: TS, vector, monitor, view 4341 4342 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4343 @*/ 4344 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4345 { 4346 PetscErrorCode ierr; 4347 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4348 PetscDraw draw; 4349 4350 PetscFunctionBegin; 4351 if (!step && ictx->showinitial) { 4352 if (!ictx->initialsolution) { 4353 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 4354 } 4355 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 4356 } 4357 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4358 4359 if (ictx->showinitial) { 4360 PetscReal pause; 4361 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 4362 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 4363 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 4364 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 4365 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 4366 } 4367 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 4368 if (ictx->showtimestepandtime) { 4369 PetscReal xl,yl,xr,yr,h; 4370 char time[32]; 4371 4372 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4373 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4374 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4375 h = yl + .95*(yr - yl); 4376 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4377 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4378 } 4379 4380 if (ictx->showinitial) { 4381 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 4382 } 4383 PetscFunctionReturn(0); 4384 } 4385 4386 /*@C 4387 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 4388 4389 Collective on TS 4390 4391 Input Parameters: 4392 + ts - the TS context 4393 . step - current time-step 4394 . ptime - current time 4395 - dummy - either a viewer or NULL 4396 4397 Level: intermediate 4398 4399 .keywords: TS, vector, monitor, view 4400 4401 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4402 @*/ 4403 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4404 { 4405 PetscErrorCode ierr; 4406 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4407 PetscDraw draw; 4408 PetscDrawAxis axis; 4409 PetscInt n; 4410 PetscMPIInt size; 4411 PetscReal U0,U1,xl,yl,xr,yr,h; 4412 char time[32]; 4413 const PetscScalar *U; 4414 4415 PetscFunctionBegin; 4416 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 4417 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 4418 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 4419 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 4420 4421 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4422 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 4423 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 4424 if (!step) { 4425 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 4426 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 4427 } 4428 4429 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 4430 U0 = PetscRealPart(U[0]); 4431 U1 = PetscRealPart(U[1]); 4432 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 4433 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 4434 4435 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4436 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 4437 if (ictx->showtimestepandtime) { 4438 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4439 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4440 h = yl + .95*(yr - yl); 4441 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4442 } 4443 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4444 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4445 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 4446 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 4447 PetscFunctionReturn(0); 4448 } 4449 4450 /*@C 4451 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 4452 4453 Collective on TS 4454 4455 Input Parameters: 4456 . ctx - the monitor context 4457 4458 Level: intermediate 4459 4460 .keywords: TS, vector, monitor, view 4461 4462 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 4463 @*/ 4464 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 4465 { 4466 PetscErrorCode ierr; 4467 4468 PetscFunctionBegin; 4469 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 4470 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 4471 ierr = PetscFree(*ictx);CHKERRQ(ierr); 4472 PetscFunctionReturn(0); 4473 } 4474 4475 /*@C 4476 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 4477 4478 Collective on TS 4479 4480 Input Parameter: 4481 . ts - time-step context 4482 4483 Output Patameter: 4484 . ctx - the monitor context 4485 4486 Options Database: 4487 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4488 4489 Level: intermediate 4490 4491 .keywords: TS, vector, monitor, view 4492 4493 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 4494 @*/ 4495 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 4496 { 4497 PetscErrorCode ierr; 4498 4499 PetscFunctionBegin; 4500 ierr = PetscNew(ctx);CHKERRQ(ierr); 4501 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 4502 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 4503 4504 (*ctx)->howoften = howoften; 4505 (*ctx)->showinitial = PETSC_FALSE; 4506 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 4507 4508 (*ctx)->showtimestepandtime = PETSC_FALSE; 4509 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 4510 PetscFunctionReturn(0); 4511 } 4512 4513 /*@C 4514 TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling 4515 VecView() for the solution provided by TSSetSolutionFunction() at each timestep 4516 4517 Collective on TS 4518 4519 Input Parameters: 4520 + ts - the TS context 4521 . step - current time-step 4522 . ptime - current time 4523 - dummy - either a viewer or NULL 4524 4525 Options Database: 4526 . -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4527 4528 Level: intermediate 4529 4530 .keywords: TS, vector, monitor, view 4531 4532 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4533 @*/ 4534 PetscErrorCode TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4535 { 4536 PetscErrorCode ierr; 4537 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4538 PetscViewer viewer = ctx->viewer; 4539 Vec work; 4540 4541 PetscFunctionBegin; 4542 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4543 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4544 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4545 ierr = VecView(work,viewer);CHKERRQ(ierr); 4546 ierr = VecDestroy(&work);CHKERRQ(ierr); 4547 PetscFunctionReturn(0); 4548 } 4549 4550 /*@C 4551 TSMonitorDrawError - Monitors progress of the TS solvers by calling 4552 VecView() for the error at each timestep 4553 4554 Collective on TS 4555 4556 Input Parameters: 4557 + ts - the TS context 4558 . step - current time-step 4559 . ptime - current time 4560 - dummy - either a viewer or NULL 4561 4562 Options Database: 4563 . -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4564 4565 Level: intermediate 4566 4567 .keywords: TS, vector, monitor, view 4568 4569 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4570 @*/ 4571 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4572 { 4573 PetscErrorCode ierr; 4574 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4575 PetscViewer viewer = ctx->viewer; 4576 Vec work; 4577 4578 PetscFunctionBegin; 4579 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4580 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4581 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4582 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 4583 ierr = VecView(work,viewer);CHKERRQ(ierr); 4584 ierr = VecDestroy(&work);CHKERRQ(ierr); 4585 PetscFunctionReturn(0); 4586 } 4587 4588 #include <petsc/private/dmimpl.h> 4589 /*@ 4590 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 4591 4592 Logically Collective on TS and DM 4593 4594 Input Parameters: 4595 + ts - the ODE integrator object 4596 - dm - the dm, cannot be NULL 4597 4598 Notes: 4599 A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 4600 even when not using interfaces like DMTSSetIFunction(). Use DMClone() to get a distinct DM when solving 4601 different problems using the same function space. 4602 4603 Level: intermediate 4604 4605 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4606 @*/ 4607 PetscErrorCode TSSetDM(TS ts,DM dm) 4608 { 4609 PetscErrorCode ierr; 4610 SNES snes; 4611 DMTS tsdm; 4612 4613 PetscFunctionBegin; 4614 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4615 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4616 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4617 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4618 if (ts->dm->dmts && !dm->dmts) { 4619 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4620 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4621 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4622 tsdm->originaldm = dm; 4623 } 4624 } 4625 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4626 } 4627 ts->dm = dm; 4628 4629 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4630 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4631 PetscFunctionReturn(0); 4632 } 4633 4634 /*@ 4635 TSGetDM - Gets the DM that may be used by some preconditioners 4636 4637 Not Collective 4638 4639 Input Parameter: 4640 . ts - the preconditioner context 4641 4642 Output Parameter: 4643 . dm - the dm 4644 4645 Level: intermediate 4646 4647 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4648 @*/ 4649 PetscErrorCode TSGetDM(TS ts,DM *dm) 4650 { 4651 PetscErrorCode ierr; 4652 4653 PetscFunctionBegin; 4654 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4655 if (!ts->dm) { 4656 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 4657 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 4658 } 4659 *dm = ts->dm; 4660 PetscFunctionReturn(0); 4661 } 4662 4663 /*@ 4664 SNESTSFormFunction - Function to evaluate nonlinear residual 4665 4666 Logically Collective on SNES 4667 4668 Input Parameter: 4669 + snes - nonlinear solver 4670 . U - the current state at which to evaluate the residual 4671 - ctx - user context, must be a TS 4672 4673 Output Parameter: 4674 . F - the nonlinear residual 4675 4676 Notes: 4677 This function is not normally called by users and is automatically registered with the SNES used by TS. 4678 It is most frequently passed to MatFDColoringSetFunction(). 4679 4680 Level: advanced 4681 4682 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 4683 @*/ 4684 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 4685 { 4686 TS ts = (TS)ctx; 4687 PetscErrorCode ierr; 4688 4689 PetscFunctionBegin; 4690 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4691 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4692 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 4693 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 4694 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 4695 PetscFunctionReturn(0); 4696 } 4697 4698 /*@ 4699 SNESTSFormJacobian - Function to evaluate the Jacobian 4700 4701 Collective on SNES 4702 4703 Input Parameter: 4704 + snes - nonlinear solver 4705 . U - the current state at which to evaluate the residual 4706 - ctx - user context, must be a TS 4707 4708 Output Parameter: 4709 + A - the Jacobian 4710 . B - the preconditioning matrix (may be the same as A) 4711 - flag - indicates any structure change in the matrix 4712 4713 Notes: 4714 This function is not normally called by users and is automatically registered with the SNES used by TS. 4715 4716 Level: developer 4717 4718 .seealso: SNESSetJacobian() 4719 @*/ 4720 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 4721 { 4722 TS ts = (TS)ctx; 4723 PetscErrorCode ierr; 4724 4725 PetscFunctionBegin; 4726 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4727 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4728 PetscValidPointer(A,3); 4729 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 4730 PetscValidPointer(B,4); 4731 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 4732 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 4733 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 4734 PetscFunctionReturn(0); 4735 } 4736 4737 /*@C 4738 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 4739 4740 Collective on TS 4741 4742 Input Arguments: 4743 + ts - time stepping context 4744 . t - time at which to evaluate 4745 . U - state at which to evaluate 4746 - ctx - context 4747 4748 Output Arguments: 4749 . F - right hand side 4750 4751 Level: intermediate 4752 4753 Notes: 4754 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 4755 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 4756 4757 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 4758 @*/ 4759 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 4760 { 4761 PetscErrorCode ierr; 4762 Mat Arhs,Brhs; 4763 4764 PetscFunctionBegin; 4765 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 4766 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 4767 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 4768 PetscFunctionReturn(0); 4769 } 4770 4771 /*@C 4772 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 4773 4774 Collective on TS 4775 4776 Input Arguments: 4777 + ts - time stepping context 4778 . t - time at which to evaluate 4779 . U - state at which to evaluate 4780 - ctx - context 4781 4782 Output Arguments: 4783 + A - pointer to operator 4784 . B - pointer to preconditioning matrix 4785 - flg - matrix structure flag 4786 4787 Level: intermediate 4788 4789 Notes: 4790 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 4791 4792 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 4793 @*/ 4794 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 4795 { 4796 PetscFunctionBegin; 4797 PetscFunctionReturn(0); 4798 } 4799 4800 /*@C 4801 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 4802 4803 Collective on TS 4804 4805 Input Arguments: 4806 + ts - time stepping context 4807 . t - time at which to evaluate 4808 . U - state at which to evaluate 4809 . Udot - time derivative of state vector 4810 - ctx - context 4811 4812 Output Arguments: 4813 . F - left hand side 4814 4815 Level: intermediate 4816 4817 Notes: 4818 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 4819 user is required to write their own TSComputeIFunction. 4820 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 4821 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 4822 4823 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 4824 4825 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 4826 @*/ 4827 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 4828 { 4829 PetscErrorCode ierr; 4830 Mat A,B; 4831 4832 PetscFunctionBegin; 4833 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 4834 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 4835 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 4836 PetscFunctionReturn(0); 4837 } 4838 4839 /*@C 4840 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 4841 4842 Collective on TS 4843 4844 Input Arguments: 4845 + ts - time stepping context 4846 . t - time at which to evaluate 4847 . U - state at which to evaluate 4848 . Udot - time derivative of state vector 4849 . shift - shift to apply 4850 - ctx - context 4851 4852 Output Arguments: 4853 + A - pointer to operator 4854 . B - pointer to preconditioning matrix 4855 - flg - matrix structure flag 4856 4857 Level: advanced 4858 4859 Notes: 4860 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 4861 4862 It is only appropriate for problems of the form 4863 4864 $ M Udot = F(U,t) 4865 4866 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 4867 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 4868 an implicit operator of the form 4869 4870 $ shift*M + J 4871 4872 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 4873 a copy of M or reassemble it when requested. 4874 4875 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 4876 @*/ 4877 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 4878 { 4879 PetscErrorCode ierr; 4880 4881 PetscFunctionBegin; 4882 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 4883 ts->ijacobian.shift = shift; 4884 PetscFunctionReturn(0); 4885 } 4886 4887 /*@ 4888 TSGetEquationType - Gets the type of the equation that TS is solving. 4889 4890 Not Collective 4891 4892 Input Parameter: 4893 . ts - the TS context 4894 4895 Output Parameter: 4896 . equation_type - see TSEquationType 4897 4898 Level: beginner 4899 4900 .keywords: TS, equation type 4901 4902 .seealso: TSSetEquationType(), TSEquationType 4903 @*/ 4904 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 4905 { 4906 PetscFunctionBegin; 4907 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4908 PetscValidPointer(equation_type,2); 4909 *equation_type = ts->equation_type; 4910 PetscFunctionReturn(0); 4911 } 4912 4913 /*@ 4914 TSSetEquationType - Sets the type of the equation that TS is solving. 4915 4916 Not Collective 4917 4918 Input Parameter: 4919 + ts - the TS context 4920 - equation_type - see TSEquationType 4921 4922 Level: advanced 4923 4924 .keywords: TS, equation type 4925 4926 .seealso: TSGetEquationType(), TSEquationType 4927 @*/ 4928 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 4929 { 4930 PetscFunctionBegin; 4931 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4932 ts->equation_type = equation_type; 4933 PetscFunctionReturn(0); 4934 } 4935 4936 /*@ 4937 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 4938 4939 Not Collective 4940 4941 Input Parameter: 4942 . ts - the TS context 4943 4944 Output Parameter: 4945 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4946 manual pages for the individual convergence tests for complete lists 4947 4948 Level: beginner 4949 4950 Notes: 4951 Can only be called after the call to TSSolve() is complete. 4952 4953 .keywords: TS, nonlinear, set, convergence, test 4954 4955 .seealso: TSSetConvergenceTest(), TSConvergedReason 4956 @*/ 4957 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 4958 { 4959 PetscFunctionBegin; 4960 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4961 PetscValidPointer(reason,2); 4962 *reason = ts->reason; 4963 PetscFunctionReturn(0); 4964 } 4965 4966 /*@ 4967 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 4968 4969 Not Collective 4970 4971 Input Parameter: 4972 + ts - the TS context 4973 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4974 manual pages for the individual convergence tests for complete lists 4975 4976 Level: advanced 4977 4978 Notes: 4979 Can only be called during TSSolve() is active. 4980 4981 .keywords: TS, nonlinear, set, convergence, test 4982 4983 .seealso: TSConvergedReason 4984 @*/ 4985 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 4986 { 4987 PetscFunctionBegin; 4988 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4989 ts->reason = reason; 4990 PetscFunctionReturn(0); 4991 } 4992 4993 /*@ 4994 TSGetSolveTime - Gets the time after a call to TSSolve() 4995 4996 Not Collective 4997 4998 Input Parameter: 4999 . ts - the TS context 5000 5001 Output Parameter: 5002 . ftime - the final time. This time corresponds to the final time set with TSSetMaxTime() 5003 5004 Level: beginner 5005 5006 Notes: 5007 Can only be called after the call to TSSolve() is complete. 5008 5009 .keywords: TS, nonlinear, set, convergence, test 5010 5011 .seealso: TSSetConvergenceTest(), TSConvergedReason 5012 @*/ 5013 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 5014 { 5015 PetscFunctionBegin; 5016 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5017 PetscValidPointer(ftime,2); 5018 *ftime = ts->solvetime; 5019 PetscFunctionReturn(0); 5020 } 5021 5022 /*@ 5023 TSGetSNESIterations - Gets the total number of nonlinear iterations 5024 used by the time integrator. 5025 5026 Not Collective 5027 5028 Input Parameter: 5029 . ts - TS context 5030 5031 Output Parameter: 5032 . nits - number of nonlinear iterations 5033 5034 Notes: 5035 This counter is reset to zero for each successive call to TSSolve(). 5036 5037 Level: intermediate 5038 5039 .keywords: TS, get, number, nonlinear, iterations 5040 5041 .seealso: TSGetKSPIterations() 5042 @*/ 5043 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 5044 { 5045 PetscFunctionBegin; 5046 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5047 PetscValidIntPointer(nits,2); 5048 *nits = ts->snes_its; 5049 PetscFunctionReturn(0); 5050 } 5051 5052 /*@ 5053 TSGetKSPIterations - Gets the total number of linear iterations 5054 used by the time integrator. 5055 5056 Not Collective 5057 5058 Input Parameter: 5059 . ts - TS context 5060 5061 Output Parameter: 5062 . lits - number of linear iterations 5063 5064 Notes: 5065 This counter is reset to zero for each successive call to TSSolve(). 5066 5067 Level: intermediate 5068 5069 .keywords: TS, get, number, linear, iterations 5070 5071 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 5072 @*/ 5073 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 5074 { 5075 PetscFunctionBegin; 5076 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5077 PetscValidIntPointer(lits,2); 5078 *lits = ts->ksp_its; 5079 PetscFunctionReturn(0); 5080 } 5081 5082 /*@ 5083 TSGetStepRejections - Gets the total number of rejected steps. 5084 5085 Not Collective 5086 5087 Input Parameter: 5088 . ts - TS context 5089 5090 Output Parameter: 5091 . rejects - number of steps rejected 5092 5093 Notes: 5094 This counter is reset to zero for each successive call to TSSolve(). 5095 5096 Level: intermediate 5097 5098 .keywords: TS, get, number 5099 5100 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 5101 @*/ 5102 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 5103 { 5104 PetscFunctionBegin; 5105 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5106 PetscValidIntPointer(rejects,2); 5107 *rejects = ts->reject; 5108 PetscFunctionReturn(0); 5109 } 5110 5111 /*@ 5112 TSGetSNESFailures - Gets the total number of failed SNES solves 5113 5114 Not Collective 5115 5116 Input Parameter: 5117 . ts - TS context 5118 5119 Output Parameter: 5120 . fails - number of failed nonlinear solves 5121 5122 Notes: 5123 This counter is reset to zero for each successive call to TSSolve(). 5124 5125 Level: intermediate 5126 5127 .keywords: TS, get, number 5128 5129 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5130 @*/ 5131 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5132 { 5133 PetscFunctionBegin; 5134 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5135 PetscValidIntPointer(fails,2); 5136 *fails = ts->num_snes_failures; 5137 PetscFunctionReturn(0); 5138 } 5139 5140 /*@ 5141 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5142 5143 Not Collective 5144 5145 Input Parameter: 5146 + ts - TS context 5147 - rejects - maximum number of rejected steps, pass -1 for unlimited 5148 5149 Notes: 5150 The counter is reset to zero for each step 5151 5152 Options Database Key: 5153 . -ts_max_reject - Maximum number of step rejections before a step fails 5154 5155 Level: intermediate 5156 5157 .keywords: TS, set, maximum, number 5158 5159 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5160 @*/ 5161 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5162 { 5163 PetscFunctionBegin; 5164 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5165 ts->max_reject = rejects; 5166 PetscFunctionReturn(0); 5167 } 5168 5169 /*@ 5170 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5171 5172 Not Collective 5173 5174 Input Parameter: 5175 + ts - TS context 5176 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5177 5178 Notes: 5179 The counter is reset to zero for each successive call to TSSolve(). 5180 5181 Options Database Key: 5182 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5183 5184 Level: intermediate 5185 5186 .keywords: TS, set, maximum, number 5187 5188 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5189 @*/ 5190 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5191 { 5192 PetscFunctionBegin; 5193 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5194 ts->max_snes_failures = fails; 5195 PetscFunctionReturn(0); 5196 } 5197 5198 /*@ 5199 TSSetErrorIfStepFails - Error if no step succeeds 5200 5201 Not Collective 5202 5203 Input Parameter: 5204 + ts - TS context 5205 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5206 5207 Options Database Key: 5208 . -ts_error_if_step_fails - Error if no step succeeds 5209 5210 Level: intermediate 5211 5212 .keywords: TS, set, error 5213 5214 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5215 @*/ 5216 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5217 { 5218 PetscFunctionBegin; 5219 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5220 ts->errorifstepfailed = err; 5221 PetscFunctionReturn(0); 5222 } 5223 5224 /*@C 5225 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 5226 5227 Collective on TS 5228 5229 Input Parameters: 5230 + ts - the TS context 5231 . step - current time-step 5232 . ptime - current time 5233 . u - current state 5234 - vf - viewer and its format 5235 5236 Level: intermediate 5237 5238 .keywords: TS, vector, monitor, view 5239 5240 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5241 @*/ 5242 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5243 { 5244 PetscErrorCode ierr; 5245 5246 PetscFunctionBegin; 5247 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5248 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5249 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5250 PetscFunctionReturn(0); 5251 } 5252 5253 /*@C 5254 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5255 5256 Collective on TS 5257 5258 Input Parameters: 5259 + ts - the TS context 5260 . step - current time-step 5261 . ptime - current time 5262 . u - current state 5263 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5264 5265 Level: intermediate 5266 5267 Notes: 5268 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. 5269 These are named according to the file name template. 5270 5271 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5272 5273 .keywords: TS, vector, monitor, view 5274 5275 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5276 @*/ 5277 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5278 { 5279 PetscErrorCode ierr; 5280 char filename[PETSC_MAX_PATH_LEN]; 5281 PetscViewer viewer; 5282 5283 PetscFunctionBegin; 5284 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5285 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5286 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5287 ierr = VecView(u,viewer);CHKERRQ(ierr); 5288 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5289 PetscFunctionReturn(0); 5290 } 5291 5292 /*@C 5293 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5294 5295 Collective on TS 5296 5297 Input Parameters: 5298 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5299 5300 Level: intermediate 5301 5302 Note: 5303 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 5304 5305 .keywords: TS, vector, monitor, view 5306 5307 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 5308 @*/ 5309 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 5310 { 5311 PetscErrorCode ierr; 5312 5313 PetscFunctionBegin; 5314 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 5315 PetscFunctionReturn(0); 5316 } 5317 5318 /*@ 5319 TSGetAdapt - Get the adaptive controller context for the current method 5320 5321 Collective on TS if controller has not been created yet 5322 5323 Input Arguments: 5324 . ts - time stepping context 5325 5326 Output Arguments: 5327 . adapt - adaptive controller 5328 5329 Level: intermediate 5330 5331 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 5332 @*/ 5333 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 5334 { 5335 PetscErrorCode ierr; 5336 5337 PetscFunctionBegin; 5338 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5339 PetscValidPointer(adapt,2); 5340 if (!ts->adapt) { 5341 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 5342 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 5343 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 5344 } 5345 *adapt = ts->adapt; 5346 PetscFunctionReturn(0); 5347 } 5348 5349 /*@ 5350 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 5351 5352 Logically Collective 5353 5354 Input Arguments: 5355 + ts - time integration context 5356 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 5357 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 5358 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 5359 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 5360 5361 Options Database keys: 5362 + -ts_rtol <rtol> - relative tolerance for local truncation error 5363 - -ts_atol <atol> Absolute tolerance for local truncation error 5364 5365 Notes: 5366 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 5367 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 5368 computed only for the differential or the algebraic part then this can be done using the vector of 5369 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 5370 differential part and infinity for the algebraic part, the LTE calculation will include only the 5371 differential variables. 5372 5373 Level: beginner 5374 5375 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 5376 @*/ 5377 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 5378 { 5379 PetscErrorCode ierr; 5380 5381 PetscFunctionBegin; 5382 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 5383 if (vatol) { 5384 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 5385 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 5386 ts->vatol = vatol; 5387 } 5388 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 5389 if (vrtol) { 5390 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 5391 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 5392 ts->vrtol = vrtol; 5393 } 5394 PetscFunctionReturn(0); 5395 } 5396 5397 /*@ 5398 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5399 5400 Logically Collective 5401 5402 Input Arguments: 5403 . ts - time integration context 5404 5405 Output Arguments: 5406 + atol - scalar absolute tolerances, NULL to ignore 5407 . vatol - vector of absolute tolerances, NULL to ignore 5408 . rtol - scalar relative tolerances, NULL to ignore 5409 - vrtol - vector of relative tolerances, NULL to ignore 5410 5411 Level: beginner 5412 5413 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 5414 @*/ 5415 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 5416 { 5417 PetscFunctionBegin; 5418 if (atol) *atol = ts->atol; 5419 if (vatol) *vatol = ts->vatol; 5420 if (rtol) *rtol = ts->rtol; 5421 if (vrtol) *vrtol = ts->vrtol; 5422 PetscFunctionReturn(0); 5423 } 5424 5425 /*@ 5426 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 5427 5428 Collective on TS 5429 5430 Input Arguments: 5431 + ts - time stepping context 5432 . U - state vector, usually ts->vec_sol 5433 - Y - state vector to be compared to U 5434 5435 Output Arguments: 5436 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5437 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5438 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5439 5440 Level: developer 5441 5442 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 5443 @*/ 5444 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5445 { 5446 PetscErrorCode ierr; 5447 PetscInt i,n,N,rstart; 5448 PetscInt n_loc,na_loc,nr_loc; 5449 PetscReal n_glb,na_glb,nr_glb; 5450 const PetscScalar *u,*y; 5451 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 5452 PetscReal tol,tola,tolr; 5453 PetscReal err_loc[6],err_glb[6]; 5454 5455 PetscFunctionBegin; 5456 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5457 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5458 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5459 PetscValidType(U,2); 5460 PetscValidType(Y,3); 5461 PetscCheckSameComm(U,2,Y,3); 5462 PetscValidPointer(norm,4); 5463 PetscValidPointer(norma,5); 5464 PetscValidPointer(normr,6); 5465 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5466 5467 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5468 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5469 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5470 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5471 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5472 sum = 0.; n_loc = 0; 5473 suma = 0.; na_loc = 0; 5474 sumr = 0.; nr_loc = 0; 5475 if (ts->vatol && ts->vrtol) { 5476 const PetscScalar *atol,*rtol; 5477 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5478 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5479 for (i=0; i<n; i++) { 5480 diff = PetscAbsScalar(y[i] - u[i]); 5481 tola = PetscRealPart(atol[i]); 5482 if(tola>0.){ 5483 suma += PetscSqr(diff/tola); 5484 na_loc++; 5485 } 5486 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5487 if(tolr>0.){ 5488 sumr += PetscSqr(diff/tolr); 5489 nr_loc++; 5490 } 5491 tol=tola+tolr; 5492 if(tol>0.){ 5493 sum += PetscSqr(diff/tol); 5494 n_loc++; 5495 } 5496 } 5497 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5498 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5499 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5500 const PetscScalar *atol; 5501 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5502 for (i=0; i<n; i++) { 5503 diff = PetscAbsScalar(y[i] - u[i]); 5504 tola = PetscRealPart(atol[i]); 5505 if(tola>0.){ 5506 suma += PetscSqr(diff/tola); 5507 na_loc++; 5508 } 5509 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5510 if(tolr>0.){ 5511 sumr += PetscSqr(diff/tolr); 5512 nr_loc++; 5513 } 5514 tol=tola+tolr; 5515 if(tol>0.){ 5516 sum += PetscSqr(diff/tol); 5517 n_loc++; 5518 } 5519 } 5520 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5521 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5522 const PetscScalar *rtol; 5523 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5524 for (i=0; i<n; i++) { 5525 diff = PetscAbsScalar(y[i] - u[i]); 5526 tola = ts->atol; 5527 if(tola>0.){ 5528 suma += PetscSqr(diff/tola); 5529 na_loc++; 5530 } 5531 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5532 if(tolr>0.){ 5533 sumr += PetscSqr(diff/tolr); 5534 nr_loc++; 5535 } 5536 tol=tola+tolr; 5537 if(tol>0.){ 5538 sum += PetscSqr(diff/tol); 5539 n_loc++; 5540 } 5541 } 5542 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5543 } else { /* scalar atol, scalar rtol */ 5544 for (i=0; i<n; i++) { 5545 diff = PetscAbsScalar(y[i] - u[i]); 5546 tola = ts->atol; 5547 if(tola>0.){ 5548 suma += PetscSqr(diff/tola); 5549 na_loc++; 5550 } 5551 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5552 if(tolr>0.){ 5553 sumr += PetscSqr(diff/tolr); 5554 nr_loc++; 5555 } 5556 tol=tola+tolr; 5557 if(tol>0.){ 5558 sum += PetscSqr(diff/tol); 5559 n_loc++; 5560 } 5561 } 5562 } 5563 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5564 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5565 5566 err_loc[0] = sum; 5567 err_loc[1] = suma; 5568 err_loc[2] = sumr; 5569 err_loc[3] = (PetscReal)n_loc; 5570 err_loc[4] = (PetscReal)na_loc; 5571 err_loc[5] = (PetscReal)nr_loc; 5572 5573 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5574 5575 gsum = err_glb[0]; 5576 gsuma = err_glb[1]; 5577 gsumr = err_glb[2]; 5578 n_glb = err_glb[3]; 5579 na_glb = err_glb[4]; 5580 nr_glb = err_glb[5]; 5581 5582 *norm = 0.; 5583 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 5584 *norma = 0.; 5585 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5586 *normr = 0.; 5587 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5588 5589 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5590 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5591 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5592 PetscFunctionReturn(0); 5593 } 5594 5595 /*@ 5596 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5597 5598 Collective on TS 5599 5600 Input Arguments: 5601 + ts - time stepping context 5602 . U - state vector, usually ts->vec_sol 5603 - Y - state vector to be compared to U 5604 5605 Output Arguments: 5606 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5607 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5608 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5609 5610 Level: developer 5611 5612 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5613 @*/ 5614 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5615 { 5616 PetscErrorCode ierr; 5617 PetscInt i,n,N,rstart; 5618 const PetscScalar *u,*y; 5619 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 5620 PetscReal tol,tola,tolr,diff; 5621 PetscReal err_loc[3],err_glb[3]; 5622 5623 PetscFunctionBegin; 5624 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5625 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5626 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5627 PetscValidType(U,2); 5628 PetscValidType(Y,3); 5629 PetscCheckSameComm(U,2,Y,3); 5630 PetscValidPointer(norm,4); 5631 PetscValidPointer(norma,5); 5632 PetscValidPointer(normr,6); 5633 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5634 5635 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5636 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5637 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5638 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5639 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5640 5641 max=0.; 5642 maxa=0.; 5643 maxr=0.; 5644 5645 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5646 const PetscScalar *atol,*rtol; 5647 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5648 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5649 5650 for (i=0; i<n; i++) { 5651 diff = PetscAbsScalar(y[i] - u[i]); 5652 tola = PetscRealPart(atol[i]); 5653 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5654 tol = tola+tolr; 5655 if(tola>0.){ 5656 maxa = PetscMax(maxa,diff / tola); 5657 } 5658 if(tolr>0.){ 5659 maxr = PetscMax(maxr,diff / tolr); 5660 } 5661 if(tol>0.){ 5662 max = PetscMax(max,diff / tol); 5663 } 5664 } 5665 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5666 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5667 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5668 const PetscScalar *atol; 5669 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5670 for (i=0; i<n; i++) { 5671 diff = PetscAbsScalar(y[i] - u[i]); 5672 tola = PetscRealPart(atol[i]); 5673 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5674 tol = tola+tolr; 5675 if(tola>0.){ 5676 maxa = PetscMax(maxa,diff / tola); 5677 } 5678 if(tolr>0.){ 5679 maxr = PetscMax(maxr,diff / tolr); 5680 } 5681 if(tol>0.){ 5682 max = PetscMax(max,diff / tol); 5683 } 5684 } 5685 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5686 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5687 const PetscScalar *rtol; 5688 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5689 5690 for (i=0; i<n; i++) { 5691 diff = PetscAbsScalar(y[i] - u[i]); 5692 tola = ts->atol; 5693 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5694 tol = tola+tolr; 5695 if(tola>0.){ 5696 maxa = PetscMax(maxa,diff / tola); 5697 } 5698 if(tolr>0.){ 5699 maxr = PetscMax(maxr,diff / tolr); 5700 } 5701 if(tol>0.){ 5702 max = PetscMax(max,diff / tol); 5703 } 5704 } 5705 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5706 } else { /* scalar atol, scalar rtol */ 5707 5708 for (i=0; i<n; i++) { 5709 diff = PetscAbsScalar(y[i] - u[i]); 5710 tola = ts->atol; 5711 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5712 tol = tola+tolr; 5713 if(tola>0.){ 5714 maxa = PetscMax(maxa,diff / tola); 5715 } 5716 if(tolr>0.){ 5717 maxr = PetscMax(maxr,diff / tolr); 5718 } 5719 if(tol>0.){ 5720 max = PetscMax(max,diff / tol); 5721 } 5722 } 5723 } 5724 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5725 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5726 err_loc[0] = max; 5727 err_loc[1] = maxa; 5728 err_loc[2] = maxr; 5729 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5730 gmax = err_glb[0]; 5731 gmaxa = err_glb[1]; 5732 gmaxr = err_glb[2]; 5733 5734 *norm = gmax; 5735 *norma = gmaxa; 5736 *normr = gmaxr; 5737 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5738 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5739 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5740 PetscFunctionReturn(0); 5741 } 5742 5743 /*@ 5744 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 5745 5746 Collective on TS 5747 5748 Input Arguments: 5749 + ts - time stepping context 5750 . U - state vector, usually ts->vec_sol 5751 . Y - state vector to be compared to U 5752 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 5753 5754 Output Arguments: 5755 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 5756 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 5757 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 5758 5759 Options Database Keys: 5760 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 5761 5762 Level: developer 5763 5764 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 5765 @*/ 5766 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5767 { 5768 PetscErrorCode ierr; 5769 5770 PetscFunctionBegin; 5771 if (wnormtype == NORM_2) { 5772 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 5773 } else if(wnormtype == NORM_INFINITY) { 5774 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 5775 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 5776 PetscFunctionReturn(0); 5777 } 5778 5779 5780 /*@ 5781 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 5782 5783 Collective on TS 5784 5785 Input Arguments: 5786 + ts - time stepping context 5787 . E - error vector 5788 . U - state vector, usually ts->vec_sol 5789 - Y - state vector, previous time step 5790 5791 Output Arguments: 5792 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5793 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5794 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5795 5796 Level: developer 5797 5798 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 5799 @*/ 5800 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5801 { 5802 PetscErrorCode ierr; 5803 PetscInt i,n,N,rstart; 5804 PetscInt n_loc,na_loc,nr_loc; 5805 PetscReal n_glb,na_glb,nr_glb; 5806 const PetscScalar *e,*u,*y; 5807 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 5808 PetscReal tol,tola,tolr; 5809 PetscReal err_loc[6],err_glb[6]; 5810 5811 PetscFunctionBegin; 5812 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5813 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 5814 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 5815 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 5816 PetscValidType(E,2); 5817 PetscValidType(U,3); 5818 PetscValidType(Y,4); 5819 PetscCheckSameComm(E,2,U,3); 5820 PetscCheckSameComm(U,2,Y,3); 5821 PetscValidPointer(norm,5); 5822 PetscValidPointer(norma,6); 5823 PetscValidPointer(normr,7); 5824 5825 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 5826 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 5827 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 5828 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 5829 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5830 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5831 sum = 0.; n_loc = 0; 5832 suma = 0.; na_loc = 0; 5833 sumr = 0.; nr_loc = 0; 5834 if (ts->vatol && ts->vrtol) { 5835 const PetscScalar *atol,*rtol; 5836 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5837 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5838 for (i=0; i<n; i++) { 5839 err = PetscAbsScalar(e[i]); 5840 tola = PetscRealPart(atol[i]); 5841 if(tola>0.){ 5842 suma += PetscSqr(err/tola); 5843 na_loc++; 5844 } 5845 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5846 if(tolr>0.){ 5847 sumr += PetscSqr(err/tolr); 5848 nr_loc++; 5849 } 5850 tol=tola+tolr; 5851 if(tol>0.){ 5852 sum += PetscSqr(err/tol); 5853 n_loc++; 5854 } 5855 } 5856 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5857 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5858 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5859 const PetscScalar *atol; 5860 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5861 for (i=0; i<n; i++) { 5862 err = PetscAbsScalar(e[i]); 5863 tola = PetscRealPart(atol[i]); 5864 if(tola>0.){ 5865 suma += PetscSqr(err/tola); 5866 na_loc++; 5867 } 5868 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5869 if(tolr>0.){ 5870 sumr += PetscSqr(err/tolr); 5871 nr_loc++; 5872 } 5873 tol=tola+tolr; 5874 if(tol>0.){ 5875 sum += PetscSqr(err/tol); 5876 n_loc++; 5877 } 5878 } 5879 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5880 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5881 const PetscScalar *rtol; 5882 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5883 for (i=0; i<n; i++) { 5884 err = PetscAbsScalar(e[i]); 5885 tola = ts->atol; 5886 if(tola>0.){ 5887 suma += PetscSqr(err/tola); 5888 na_loc++; 5889 } 5890 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5891 if(tolr>0.){ 5892 sumr += PetscSqr(err/tolr); 5893 nr_loc++; 5894 } 5895 tol=tola+tolr; 5896 if(tol>0.){ 5897 sum += PetscSqr(err/tol); 5898 n_loc++; 5899 } 5900 } 5901 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5902 } else { /* scalar atol, scalar rtol */ 5903 for (i=0; i<n; i++) { 5904 err = PetscAbsScalar(e[i]); 5905 tola = ts->atol; 5906 if(tola>0.){ 5907 suma += PetscSqr(err/tola); 5908 na_loc++; 5909 } 5910 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5911 if(tolr>0.){ 5912 sumr += PetscSqr(err/tolr); 5913 nr_loc++; 5914 } 5915 tol=tola+tolr; 5916 if(tol>0.){ 5917 sum += PetscSqr(err/tol); 5918 n_loc++; 5919 } 5920 } 5921 } 5922 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 5923 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5924 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5925 5926 err_loc[0] = sum; 5927 err_loc[1] = suma; 5928 err_loc[2] = sumr; 5929 err_loc[3] = (PetscReal)n_loc; 5930 err_loc[4] = (PetscReal)na_loc; 5931 err_loc[5] = (PetscReal)nr_loc; 5932 5933 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5934 5935 gsum = err_glb[0]; 5936 gsuma = err_glb[1]; 5937 gsumr = err_glb[2]; 5938 n_glb = err_glb[3]; 5939 na_glb = err_glb[4]; 5940 nr_glb = err_glb[5]; 5941 5942 *norm = 0.; 5943 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 5944 *norma = 0.; 5945 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5946 *normr = 0.; 5947 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5948 5949 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5950 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5951 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5952 PetscFunctionReturn(0); 5953 } 5954 5955 /*@ 5956 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 5957 Collective on TS 5958 5959 Input Arguments: 5960 + ts - time stepping context 5961 . E - error vector 5962 . U - state vector, usually ts->vec_sol 5963 - Y - state vector, previous time step 5964 5965 Output Arguments: 5966 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5967 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5968 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5969 5970 Level: developer 5971 5972 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 5973 @*/ 5974 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5975 { 5976 PetscErrorCode ierr; 5977 PetscInt i,n,N,rstart; 5978 const PetscScalar *e,*u,*y; 5979 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 5980 PetscReal tol,tola,tolr; 5981 PetscReal err_loc[3],err_glb[3]; 5982 5983 PetscFunctionBegin; 5984 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5985 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 5986 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 5987 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 5988 PetscValidType(E,2); 5989 PetscValidType(U,3); 5990 PetscValidType(Y,4); 5991 PetscCheckSameComm(E,2,U,3); 5992 PetscCheckSameComm(U,2,Y,3); 5993 PetscValidPointer(norm,5); 5994 PetscValidPointer(norma,6); 5995 PetscValidPointer(normr,7); 5996 5997 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 5998 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 5999 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6000 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6001 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6002 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6003 6004 max=0.; 6005 maxa=0.; 6006 maxr=0.; 6007 6008 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6009 const PetscScalar *atol,*rtol; 6010 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6011 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6012 6013 for (i=0; i<n; i++) { 6014 err = PetscAbsScalar(e[i]); 6015 tola = PetscRealPart(atol[i]); 6016 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6017 tol = tola+tolr; 6018 if(tola>0.){ 6019 maxa = PetscMax(maxa,err / tola); 6020 } 6021 if(tolr>0.){ 6022 maxr = PetscMax(maxr,err / tolr); 6023 } 6024 if(tol>0.){ 6025 max = PetscMax(max,err / tol); 6026 } 6027 } 6028 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6029 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6030 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6031 const PetscScalar *atol; 6032 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6033 for (i=0; i<n; i++) { 6034 err = PetscAbsScalar(e[i]); 6035 tola = PetscRealPart(atol[i]); 6036 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6037 tol = tola+tolr; 6038 if(tola>0.){ 6039 maxa = PetscMax(maxa,err / tola); 6040 } 6041 if(tolr>0.){ 6042 maxr = PetscMax(maxr,err / tolr); 6043 } 6044 if(tol>0.){ 6045 max = PetscMax(max,err / tol); 6046 } 6047 } 6048 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6049 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6050 const PetscScalar *rtol; 6051 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6052 6053 for (i=0; i<n; i++) { 6054 err = PetscAbsScalar(e[i]); 6055 tola = ts->atol; 6056 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6057 tol = tola+tolr; 6058 if(tola>0.){ 6059 maxa = PetscMax(maxa,err / tola); 6060 } 6061 if(tolr>0.){ 6062 maxr = PetscMax(maxr,err / tolr); 6063 } 6064 if(tol>0.){ 6065 max = PetscMax(max,err / tol); 6066 } 6067 } 6068 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6069 } else { /* scalar atol, scalar rtol */ 6070 6071 for (i=0; i<n; i++) { 6072 err = PetscAbsScalar(e[i]); 6073 tola = ts->atol; 6074 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6075 tol = tola+tolr; 6076 if(tola>0.){ 6077 maxa = PetscMax(maxa,err / tola); 6078 } 6079 if(tolr>0.){ 6080 maxr = PetscMax(maxr,err / tolr); 6081 } 6082 if(tol>0.){ 6083 max = PetscMax(max,err / tol); 6084 } 6085 } 6086 } 6087 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6088 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6089 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6090 err_loc[0] = max; 6091 err_loc[1] = maxa; 6092 err_loc[2] = maxr; 6093 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6094 gmax = err_glb[0]; 6095 gmaxa = err_glb[1]; 6096 gmaxr = err_glb[2]; 6097 6098 *norm = gmax; 6099 *norma = gmaxa; 6100 *normr = gmaxr; 6101 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6102 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6103 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6104 PetscFunctionReturn(0); 6105 } 6106 6107 /*@ 6108 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 6109 6110 Collective on TS 6111 6112 Input Arguments: 6113 + ts - time stepping context 6114 . E - error vector 6115 . U - state vector, usually ts->vec_sol 6116 . Y - state vector, previous time step 6117 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6118 6119 Output Arguments: 6120 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6121 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6122 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6123 6124 Options Database Keys: 6125 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6126 6127 Level: developer 6128 6129 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6130 @*/ 6131 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6132 { 6133 PetscErrorCode ierr; 6134 6135 PetscFunctionBegin; 6136 if (wnormtype == NORM_2) { 6137 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6138 } else if(wnormtype == NORM_INFINITY) { 6139 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6140 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6141 PetscFunctionReturn(0); 6142 } 6143 6144 6145 /*@ 6146 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6147 6148 Logically Collective on TS 6149 6150 Input Arguments: 6151 + ts - time stepping context 6152 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6153 6154 Note: 6155 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6156 6157 Level: intermediate 6158 6159 .seealso: TSGetCFLTime(), TSADAPTCFL 6160 @*/ 6161 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6162 { 6163 PetscFunctionBegin; 6164 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6165 ts->cfltime_local = cfltime; 6166 ts->cfltime = -1.; 6167 PetscFunctionReturn(0); 6168 } 6169 6170 /*@ 6171 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6172 6173 Collective on TS 6174 6175 Input Arguments: 6176 . ts - time stepping context 6177 6178 Output Arguments: 6179 . cfltime - maximum stable time step for forward Euler 6180 6181 Level: advanced 6182 6183 .seealso: TSSetCFLTimeLocal() 6184 @*/ 6185 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6186 { 6187 PetscErrorCode ierr; 6188 6189 PetscFunctionBegin; 6190 if (ts->cfltime < 0) { 6191 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6192 } 6193 *cfltime = ts->cfltime; 6194 PetscFunctionReturn(0); 6195 } 6196 6197 /*@ 6198 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6199 6200 Input Parameters: 6201 . ts - the TS context. 6202 . xl - lower bound. 6203 . xu - upper bound. 6204 6205 Notes: 6206 If this routine is not called then the lower and upper bounds are set to 6207 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6208 6209 Level: advanced 6210 6211 @*/ 6212 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6213 { 6214 PetscErrorCode ierr; 6215 SNES snes; 6216 6217 PetscFunctionBegin; 6218 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6219 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6220 PetscFunctionReturn(0); 6221 } 6222 6223 #if defined(PETSC_HAVE_MATLAB_ENGINE) 6224 #include <mex.h> 6225 6226 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 6227 6228 /* 6229 TSComputeFunction_Matlab - Calls the function that has been set with 6230 TSSetFunctionMatlab(). 6231 6232 Collective on TS 6233 6234 Input Parameters: 6235 + snes - the TS context 6236 - u - input vector 6237 6238 Output Parameter: 6239 . y - function vector, as set by TSSetFunction() 6240 6241 Notes: 6242 TSComputeFunction() is typically used within nonlinear solvers 6243 implementations, so most users would not generally call this routine 6244 themselves. 6245 6246 Level: developer 6247 6248 .keywords: TS, nonlinear, compute, function 6249 6250 .seealso: TSSetFunction(), TSGetFunction() 6251 */ 6252 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 6253 { 6254 PetscErrorCode ierr; 6255 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6256 int nlhs = 1,nrhs = 7; 6257 mxArray *plhs[1],*prhs[7]; 6258 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 6259 6260 PetscFunctionBegin; 6261 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 6262 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6263 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 6264 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 6265 PetscCheckSameComm(snes,1,u,3); 6266 PetscCheckSameComm(snes,1,y,5); 6267 6268 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 6269 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6270 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 6271 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 6272 6273 prhs[0] = mxCreateDoubleScalar((double)ls); 6274 prhs[1] = mxCreateDoubleScalar(time); 6275 prhs[2] = mxCreateDoubleScalar((double)lx); 6276 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6277 prhs[4] = mxCreateDoubleScalar((double)ly); 6278 prhs[5] = mxCreateString(sctx->funcname); 6279 prhs[6] = sctx->ctx; 6280 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 6281 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6282 mxDestroyArray(prhs[0]); 6283 mxDestroyArray(prhs[1]); 6284 mxDestroyArray(prhs[2]); 6285 mxDestroyArray(prhs[3]); 6286 mxDestroyArray(prhs[4]); 6287 mxDestroyArray(prhs[5]); 6288 mxDestroyArray(plhs[0]); 6289 PetscFunctionReturn(0); 6290 } 6291 6292 /* 6293 TSSetFunctionMatlab - Sets the function evaluation routine and function 6294 vector for use by the TS routines in solving ODEs 6295 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 6296 6297 Logically Collective on TS 6298 6299 Input Parameters: 6300 + ts - the TS context 6301 - func - function evaluation routine 6302 6303 Calling sequence of func: 6304 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 6305 6306 Level: beginner 6307 6308 .keywords: TS, nonlinear, set, function 6309 6310 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6311 */ 6312 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 6313 { 6314 PetscErrorCode ierr; 6315 TSMatlabContext *sctx; 6316 6317 PetscFunctionBegin; 6318 /* currently sctx is memory bleed */ 6319 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6320 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6321 /* 6322 This should work, but it doesn't 6323 sctx->ctx = ctx; 6324 mexMakeArrayPersistent(sctx->ctx); 6325 */ 6326 sctx->ctx = mxDuplicateArray(ctx); 6327 6328 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 6329 PetscFunctionReturn(0); 6330 } 6331 6332 /* 6333 TSComputeJacobian_Matlab - Calls the function that has been set with 6334 TSSetJacobianMatlab(). 6335 6336 Collective on TS 6337 6338 Input Parameters: 6339 + ts - the TS context 6340 . u - input vector 6341 . A, B - the matrices 6342 - ctx - user context 6343 6344 Level: developer 6345 6346 .keywords: TS, nonlinear, compute, function 6347 6348 .seealso: TSSetFunction(), TSGetFunction() 6349 @*/ 6350 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx) 6351 { 6352 PetscErrorCode ierr; 6353 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6354 int nlhs = 2,nrhs = 9; 6355 mxArray *plhs[2],*prhs[9]; 6356 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 6357 6358 PetscFunctionBegin; 6359 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6360 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6361 6362 /* call Matlab function in ctx with arguments u and y */ 6363 6364 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6365 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6366 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 6367 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 6368 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 6369 6370 prhs[0] = mxCreateDoubleScalar((double)ls); 6371 prhs[1] = mxCreateDoubleScalar((double)time); 6372 prhs[2] = mxCreateDoubleScalar((double)lx); 6373 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6374 prhs[4] = mxCreateDoubleScalar((double)shift); 6375 prhs[5] = mxCreateDoubleScalar((double)lA); 6376 prhs[6] = mxCreateDoubleScalar((double)lB); 6377 prhs[7] = mxCreateString(sctx->funcname); 6378 prhs[8] = sctx->ctx; 6379 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 6380 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6381 mxDestroyArray(prhs[0]); 6382 mxDestroyArray(prhs[1]); 6383 mxDestroyArray(prhs[2]); 6384 mxDestroyArray(prhs[3]); 6385 mxDestroyArray(prhs[4]); 6386 mxDestroyArray(prhs[5]); 6387 mxDestroyArray(prhs[6]); 6388 mxDestroyArray(prhs[7]); 6389 mxDestroyArray(plhs[0]); 6390 mxDestroyArray(plhs[1]); 6391 PetscFunctionReturn(0); 6392 } 6393 6394 /* 6395 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 6396 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 6397 6398 Logically Collective on TS 6399 6400 Input Parameters: 6401 + ts - the TS context 6402 . A,B - Jacobian matrices 6403 . func - function evaluation routine 6404 - ctx - user context 6405 6406 Calling sequence of func: 6407 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 6408 6409 Level: developer 6410 6411 .keywords: TS, nonlinear, set, function 6412 6413 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6414 */ 6415 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 6416 { 6417 PetscErrorCode ierr; 6418 TSMatlabContext *sctx; 6419 6420 PetscFunctionBegin; 6421 /* currently sctx is memory bleed */ 6422 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6423 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6424 /* 6425 This should work, but it doesn't 6426 sctx->ctx = ctx; 6427 mexMakeArrayPersistent(sctx->ctx); 6428 */ 6429 sctx->ctx = mxDuplicateArray(ctx); 6430 6431 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 6432 PetscFunctionReturn(0); 6433 } 6434 6435 /* 6436 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 6437 6438 Collective on TS 6439 6440 .seealso: TSSetFunction(), TSGetFunction() 6441 @*/ 6442 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 6443 { 6444 PetscErrorCode ierr; 6445 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6446 int nlhs = 1,nrhs = 6; 6447 mxArray *plhs[1],*prhs[6]; 6448 long long int lx = 0,ls = 0; 6449 6450 PetscFunctionBegin; 6451 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6452 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 6453 6454 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6455 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6456 6457 prhs[0] = mxCreateDoubleScalar((double)ls); 6458 prhs[1] = mxCreateDoubleScalar((double)it); 6459 prhs[2] = mxCreateDoubleScalar((double)time); 6460 prhs[3] = mxCreateDoubleScalar((double)lx); 6461 prhs[4] = mxCreateString(sctx->funcname); 6462 prhs[5] = sctx->ctx; 6463 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 6464 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6465 mxDestroyArray(prhs[0]); 6466 mxDestroyArray(prhs[1]); 6467 mxDestroyArray(prhs[2]); 6468 mxDestroyArray(prhs[3]); 6469 mxDestroyArray(prhs[4]); 6470 mxDestroyArray(plhs[0]); 6471 PetscFunctionReturn(0); 6472 } 6473 6474 /* 6475 TSMonitorSetMatlab - Sets the monitor function from Matlab 6476 6477 Level: developer 6478 6479 .keywords: TS, nonlinear, set, function 6480 6481 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6482 */ 6483 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 6484 { 6485 PetscErrorCode ierr; 6486 TSMatlabContext *sctx; 6487 6488 PetscFunctionBegin; 6489 /* currently sctx is memory bleed */ 6490 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6491 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6492 /* 6493 This should work, but it doesn't 6494 sctx->ctx = ctx; 6495 mexMakeArrayPersistent(sctx->ctx); 6496 */ 6497 sctx->ctx = mxDuplicateArray(ctx); 6498 6499 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 6500 PetscFunctionReturn(0); 6501 } 6502 #endif 6503 6504 /*@C 6505 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 6506 in a time based line graph 6507 6508 Collective on TS 6509 6510 Input Parameters: 6511 + ts - the TS context 6512 . step - current time-step 6513 . ptime - current time 6514 . u - current solution 6515 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 6516 6517 Options Database: 6518 . -ts_monitor_lg_solution_variables 6519 6520 Level: intermediate 6521 6522 Notes: 6523 Each process in a parallel run displays its component solutions in a separate window 6524 6525 .keywords: TS, vector, monitor, view 6526 6527 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 6528 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 6529 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 6530 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 6531 @*/ 6532 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6533 { 6534 PetscErrorCode ierr; 6535 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 6536 const PetscScalar *yy; 6537 Vec v; 6538 6539 PetscFunctionBegin; 6540 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6541 if (!step) { 6542 PetscDrawAxis axis; 6543 PetscInt dim; 6544 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6545 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 6546 if (!ctx->names) { 6547 PetscBool flg; 6548 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 6549 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 6550 if (flg) { 6551 PetscInt i,n; 6552 char **names; 6553 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 6554 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 6555 for (i=0; i<n; i++) { 6556 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 6557 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 6558 } 6559 names[n] = NULL; 6560 ctx->names = names; 6561 } 6562 } 6563 if (ctx->names && !ctx->displaynames) { 6564 char **displaynames; 6565 PetscBool flg; 6566 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6567 ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr); 6568 ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr); 6569 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 6570 if (flg) { 6571 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 6572 } 6573 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 6574 } 6575 if (ctx->displaynames) { 6576 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 6577 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 6578 } else if (ctx->names) { 6579 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6580 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6581 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 6582 } else { 6583 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6584 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6585 } 6586 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6587 } 6588 6589 if (!ctx->transform) v = u; 6590 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 6591 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 6592 if (ctx->displaynames) { 6593 PetscInt i; 6594 for (i=0; i<ctx->ndisplayvariables; i++) 6595 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 6596 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 6597 } else { 6598 #if defined(PETSC_USE_COMPLEX) 6599 PetscInt i,n; 6600 PetscReal *yreal; 6601 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 6602 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6603 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6604 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6605 ierr = PetscFree(yreal);CHKERRQ(ierr); 6606 #else 6607 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6608 #endif 6609 } 6610 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 6611 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 6612 6613 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6614 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6615 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6616 } 6617 PetscFunctionReturn(0); 6618 } 6619 6620 /*@C 6621 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6622 6623 Collective on TS 6624 6625 Input Parameters: 6626 + ts - the TS context 6627 - names - the names of the components, final string must be NULL 6628 6629 Level: intermediate 6630 6631 Notes: 6632 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6633 6634 .keywords: TS, vector, monitor, view 6635 6636 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 6637 @*/ 6638 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 6639 { 6640 PetscErrorCode ierr; 6641 PetscInt i; 6642 6643 PetscFunctionBegin; 6644 for (i=0; i<ts->numbermonitors; i++) { 6645 if (ts->monitor[i] == TSMonitorLGSolution) { 6646 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 6647 break; 6648 } 6649 } 6650 PetscFunctionReturn(0); 6651 } 6652 6653 /*@C 6654 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6655 6656 Collective on TS 6657 6658 Input Parameters: 6659 + ts - the TS context 6660 - names - the names of the components, final string must be NULL 6661 6662 Level: intermediate 6663 6664 .keywords: TS, vector, monitor, view 6665 6666 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 6667 @*/ 6668 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 6669 { 6670 PetscErrorCode ierr; 6671 6672 PetscFunctionBegin; 6673 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 6674 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 6675 PetscFunctionReturn(0); 6676 } 6677 6678 /*@C 6679 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 6680 6681 Collective on TS 6682 6683 Input Parameter: 6684 . ts - the TS context 6685 6686 Output Parameter: 6687 . names - the names of the components, final string must be NULL 6688 6689 Level: intermediate 6690 6691 Notes: 6692 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6693 6694 .keywords: TS, vector, monitor, view 6695 6696 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 6697 @*/ 6698 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 6699 { 6700 PetscInt i; 6701 6702 PetscFunctionBegin; 6703 *names = NULL; 6704 for (i=0; i<ts->numbermonitors; i++) { 6705 if (ts->monitor[i] == TSMonitorLGSolution) { 6706 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 6707 *names = (const char *const *)ctx->names; 6708 break; 6709 } 6710 } 6711 PetscFunctionReturn(0); 6712 } 6713 6714 /*@C 6715 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 6716 6717 Collective on TS 6718 6719 Input Parameters: 6720 + ctx - the TSMonitorLG context 6721 . displaynames - the names of the components, final string must be NULL 6722 6723 Level: intermediate 6724 6725 .keywords: TS, vector, monitor, view 6726 6727 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6728 @*/ 6729 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 6730 { 6731 PetscInt j = 0,k; 6732 PetscErrorCode ierr; 6733 6734 PetscFunctionBegin; 6735 if (!ctx->names) PetscFunctionReturn(0); 6736 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 6737 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 6738 while (displaynames[j]) j++; 6739 ctx->ndisplayvariables = j; 6740 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 6741 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 6742 j = 0; 6743 while (displaynames[j]) { 6744 k = 0; 6745 while (ctx->names[k]) { 6746 PetscBool flg; 6747 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 6748 if (flg) { 6749 ctx->displayvariables[j] = k; 6750 break; 6751 } 6752 k++; 6753 } 6754 j++; 6755 } 6756 PetscFunctionReturn(0); 6757 } 6758 6759 /*@C 6760 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 6761 6762 Collective on TS 6763 6764 Input Parameters: 6765 + ts - the TS context 6766 . displaynames - the names of the components, final string must be NULL 6767 6768 Notes: 6769 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6770 6771 Level: intermediate 6772 6773 .keywords: TS, vector, monitor, view 6774 6775 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6776 @*/ 6777 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 6778 { 6779 PetscInt i; 6780 PetscErrorCode ierr; 6781 6782 PetscFunctionBegin; 6783 for (i=0; i<ts->numbermonitors; i++) { 6784 if (ts->monitor[i] == TSMonitorLGSolution) { 6785 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 6786 break; 6787 } 6788 } 6789 PetscFunctionReturn(0); 6790 } 6791 6792 /*@C 6793 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 6794 6795 Collective on TS 6796 6797 Input Parameters: 6798 + ts - the TS context 6799 . transform - the transform function 6800 . destroy - function to destroy the optional context 6801 - ctx - optional context used by transform function 6802 6803 Notes: 6804 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6805 6806 Level: intermediate 6807 6808 .keywords: TS, vector, monitor, view 6809 6810 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 6811 @*/ 6812 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6813 { 6814 PetscInt i; 6815 PetscErrorCode ierr; 6816 6817 PetscFunctionBegin; 6818 for (i=0; i<ts->numbermonitors; i++) { 6819 if (ts->monitor[i] == TSMonitorLGSolution) { 6820 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 6821 } 6822 } 6823 PetscFunctionReturn(0); 6824 } 6825 6826 /*@C 6827 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 6828 6829 Collective on TSLGCtx 6830 6831 Input Parameters: 6832 + ts - the TS context 6833 . transform - the transform function 6834 . destroy - function to destroy the optional context 6835 - ctx - optional context used by transform function 6836 6837 Level: intermediate 6838 6839 .keywords: TS, vector, monitor, view 6840 6841 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 6842 @*/ 6843 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6844 { 6845 PetscFunctionBegin; 6846 ctx->transform = transform; 6847 ctx->transformdestroy = destroy; 6848 ctx->transformctx = tctx; 6849 PetscFunctionReturn(0); 6850 } 6851 6852 /*@C 6853 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error 6854 in a time based line graph 6855 6856 Collective on TS 6857 6858 Input Parameters: 6859 + ts - the TS context 6860 . step - current time-step 6861 . ptime - current time 6862 . u - current solution 6863 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 6864 6865 Level: intermediate 6866 6867 Notes: 6868 Each process in a parallel run displays its component errors in a separate window 6869 6870 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6871 6872 Options Database Keys: 6873 . -ts_monitor_lg_error - create a graphical monitor of error history 6874 6875 .keywords: TS, vector, monitor, view 6876 6877 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6878 @*/ 6879 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 6880 { 6881 PetscErrorCode ierr; 6882 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 6883 const PetscScalar *yy; 6884 Vec y; 6885 6886 PetscFunctionBegin; 6887 if (!step) { 6888 PetscDrawAxis axis; 6889 PetscInt dim; 6890 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6891 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr); 6892 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6893 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6894 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6895 } 6896 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6897 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6898 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6899 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 6900 #if defined(PETSC_USE_COMPLEX) 6901 { 6902 PetscReal *yreal; 6903 PetscInt i,n; 6904 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 6905 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6906 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6907 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6908 ierr = PetscFree(yreal);CHKERRQ(ierr); 6909 } 6910 #else 6911 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6912 #endif 6913 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 6914 ierr = VecDestroy(&y);CHKERRQ(ierr); 6915 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6916 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6917 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6918 } 6919 PetscFunctionReturn(0); 6920 } 6921 6922 /*@C 6923 TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep 6924 6925 Collective on TS 6926 6927 Input Parameters: 6928 + ts - the TS context 6929 . step - current time-step 6930 . ptime - current time 6931 . u - current solution 6932 - dctx - unused context 6933 6934 Level: intermediate 6935 6936 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6937 6938 Options Database Keys: 6939 . -ts_monitor_error - create a graphical monitor of error history 6940 6941 .keywords: TS, vector, monitor, view 6942 6943 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6944 @*/ 6945 PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 6946 { 6947 PetscErrorCode ierr; 6948 Vec y; 6949 PetscReal nrm; 6950 PetscBool flg; 6951 6952 PetscFunctionBegin; 6953 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6954 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6955 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6956 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg);CHKERRQ(ierr); 6957 if (flg) { 6958 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 6959 ierr = PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm);CHKERRQ(ierr); 6960 } 6961 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg);CHKERRQ(ierr); 6962 if (flg) { 6963 ierr = VecView(y,vf->viewer);CHKERRQ(ierr); 6964 } 6965 ierr = VecDestroy(&y);CHKERRQ(ierr); 6966 PetscFunctionReturn(0); 6967 } 6968 6969 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 6970 { 6971 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 6972 PetscReal x = ptime,y; 6973 PetscErrorCode ierr; 6974 PetscInt its; 6975 6976 PetscFunctionBegin; 6977 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6978 if (!n) { 6979 PetscDrawAxis axis; 6980 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6981 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 6982 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6983 ctx->snes_its = 0; 6984 } 6985 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 6986 y = its - ctx->snes_its; 6987 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 6988 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 6989 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6990 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6991 } 6992 ctx->snes_its = its; 6993 PetscFunctionReturn(0); 6994 } 6995 6996 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 6997 { 6998 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 6999 PetscReal x = ptime,y; 7000 PetscErrorCode ierr; 7001 PetscInt its; 7002 7003 PetscFunctionBegin; 7004 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7005 if (!n) { 7006 PetscDrawAxis axis; 7007 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7008 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 7009 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7010 ctx->ksp_its = 0; 7011 } 7012 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 7013 y = its - ctx->ksp_its; 7014 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7015 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7016 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7017 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7018 } 7019 ctx->ksp_its = its; 7020 PetscFunctionReturn(0); 7021 } 7022 7023 /*@ 7024 TSComputeLinearStability - computes the linear stability function at a point 7025 7026 Collective on TS and Vec 7027 7028 Input Parameters: 7029 + ts - the TS context 7030 - xr,xi - real and imaginary part of input arguments 7031 7032 Output Parameters: 7033 . yr,yi - real and imaginary part of function value 7034 7035 Level: developer 7036 7037 .keywords: TS, compute 7038 7039 .seealso: TSSetRHSFunction(), TSComputeIFunction() 7040 @*/ 7041 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 7042 { 7043 PetscErrorCode ierr; 7044 7045 PetscFunctionBegin; 7046 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7047 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 7048 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 7049 PetscFunctionReturn(0); 7050 } 7051 7052 /* ------------------------------------------------------------------------*/ 7053 /*@C 7054 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 7055 7056 Collective on TS 7057 7058 Input Parameters: 7059 . ts - the ODE solver object 7060 7061 Output Parameter: 7062 . ctx - the context 7063 7064 Level: intermediate 7065 7066 .keywords: TS, monitor, line graph, residual, seealso 7067 7068 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 7069 7070 @*/ 7071 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 7072 { 7073 PetscErrorCode ierr; 7074 7075 PetscFunctionBegin; 7076 ierr = PetscNew(ctx);CHKERRQ(ierr); 7077 PetscFunctionReturn(0); 7078 } 7079 7080 /*@C 7081 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 7082 7083 Collective on TS 7084 7085 Input Parameters: 7086 + ts - the TS context 7087 . step - current time-step 7088 . ptime - current time 7089 . u - current solution 7090 - dctx - the envelope context 7091 7092 Options Database: 7093 . -ts_monitor_envelope 7094 7095 Level: intermediate 7096 7097 Notes: 7098 after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 7099 7100 .keywords: TS, vector, monitor, view 7101 7102 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 7103 @*/ 7104 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 7105 { 7106 PetscErrorCode ierr; 7107 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 7108 7109 PetscFunctionBegin; 7110 if (!ctx->max) { 7111 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 7112 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 7113 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 7114 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 7115 } else { 7116 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 7117 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 7118 } 7119 PetscFunctionReturn(0); 7120 } 7121 7122 /*@C 7123 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 7124 7125 Collective on TS 7126 7127 Input Parameter: 7128 . ts - the TS context 7129 7130 Output Parameter: 7131 + max - the maximum values 7132 - min - the minimum values 7133 7134 Notes: 7135 If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7136 7137 Level: intermediate 7138 7139 .keywords: TS, vector, monitor, view 7140 7141 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7142 @*/ 7143 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7144 { 7145 PetscInt i; 7146 7147 PetscFunctionBegin; 7148 if (max) *max = NULL; 7149 if (min) *min = NULL; 7150 for (i=0; i<ts->numbermonitors; i++) { 7151 if (ts->monitor[i] == TSMonitorEnvelope) { 7152 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7153 if (max) *max = ctx->max; 7154 if (min) *min = ctx->min; 7155 break; 7156 } 7157 } 7158 PetscFunctionReturn(0); 7159 } 7160 7161 /*@C 7162 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7163 7164 Collective on TSMonitorEnvelopeCtx 7165 7166 Input Parameter: 7167 . ctx - the monitor context 7168 7169 Level: intermediate 7170 7171 .keywords: TS, monitor, line graph, destroy 7172 7173 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7174 @*/ 7175 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7176 { 7177 PetscErrorCode ierr; 7178 7179 PetscFunctionBegin; 7180 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7181 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7182 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7183 PetscFunctionReturn(0); 7184 } 7185 7186 /*@ 7187 TSRestartStep - Flags the solver to restart the next step 7188 7189 Collective on TS 7190 7191 Input Parameter: 7192 . ts - the TS context obtained from TSCreate() 7193 7194 Level: advanced 7195 7196 Notes: 7197 Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of 7198 discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution 7199 vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For 7200 the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce 7201 discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with 7202 discontinuous source terms). 7203 7204 .keywords: TS, timestep, restart 7205 7206 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep() 7207 @*/ 7208 PetscErrorCode TSRestartStep(TS ts) 7209 { 7210 PetscFunctionBegin; 7211 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7212 ts->steprestart = PETSC_TRUE; 7213 PetscFunctionReturn(0); 7214 } 7215 7216 /*@ 7217 TSRollBack - Rolls back one time step 7218 7219 Collective on TS 7220 7221 Input Parameter: 7222 . ts - the TS context obtained from TSCreate() 7223 7224 Level: advanced 7225 7226 .keywords: TS, timestep, rollback 7227 7228 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7229 @*/ 7230 PetscErrorCode TSRollBack(TS ts) 7231 { 7232 PetscErrorCode ierr; 7233 7234 PetscFunctionBegin; 7235 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7236 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7237 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7238 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7239 ts->time_step = ts->ptime - ts->ptime_prev; 7240 ts->ptime = ts->ptime_prev; 7241 ts->ptime_prev = ts->ptime_prev_rollback; 7242 ts->steps--; 7243 ts->steprollback = PETSC_TRUE; 7244 PetscFunctionReturn(0); 7245 } 7246 7247 /*@ 7248 TSGetStages - Get the number of stages and stage values 7249 7250 Input Parameter: 7251 . ts - the TS context obtained from TSCreate() 7252 7253 Output Parameters: 7254 + ns - the number of stages 7255 - Y - the current stage vectors 7256 7257 Level: advanced 7258 7259 Notes: Both ns and Y can be NULL. 7260 7261 .keywords: TS, getstages 7262 7263 .seealso: TSCreate() 7264 @*/ 7265 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7266 { 7267 PetscErrorCode ierr; 7268 7269 PetscFunctionBegin; 7270 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7271 if (ns) PetscValidPointer(ns,2); 7272 if (Y) PetscValidPointer(Y,3); 7273 if (!ts->ops->getstages) { 7274 if (ns) *ns = 0; 7275 if (Y) *Y = NULL; 7276 } else { 7277 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7278 } 7279 PetscFunctionReturn(0); 7280 } 7281 7282 /*@C 7283 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7284 7285 Collective on SNES 7286 7287 Input Parameters: 7288 + ts - the TS context 7289 . t - current timestep 7290 . U - state vector 7291 . Udot - time derivative of state vector 7292 . shift - shift to apply, see note below 7293 - ctx - an optional user context 7294 7295 Output Parameters: 7296 + J - Jacobian matrix (not altered in this routine) 7297 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7298 7299 Level: intermediate 7300 7301 Notes: 7302 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7303 7304 dF/dU + shift*dF/dUdot 7305 7306 Most users should not need to explicitly call this routine, as it 7307 is used internally within the nonlinear solvers. 7308 7309 This will first try to get the coloring from the DM. If the DM type has no coloring 7310 routine, then it will try to get the coloring from the matrix. This requires that the 7311 matrix have nonzero entries precomputed. 7312 7313 .keywords: TS, finite differences, Jacobian, coloring, sparse 7314 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7315 @*/ 7316 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7317 { 7318 SNES snes; 7319 MatFDColoring color; 7320 PetscBool hascolor, matcolor = PETSC_FALSE; 7321 PetscErrorCode ierr; 7322 7323 PetscFunctionBegin; 7324 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7325 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7326 if (!color) { 7327 DM dm; 7328 ISColoring iscoloring; 7329 7330 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 7331 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 7332 if (hascolor && !matcolor) { 7333 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 7334 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7335 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7336 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7337 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7338 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7339 } else { 7340 MatColoring mc; 7341 7342 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 7343 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 7344 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 7345 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 7346 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 7347 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 7348 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7349 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7350 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7351 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7352 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7353 } 7354 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 7355 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 7356 } 7357 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 7358 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 7359 if (J != B) { 7360 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7361 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7362 } 7363 PetscFunctionReturn(0); 7364 } 7365 7366 /*@ 7367 TSSetFunctionDomainError - Set the function testing if the current state vector is valid 7368 7369 Input Parameters: 7370 ts - the TS context 7371 func - function called within TSFunctionDomainError 7372 7373 Level: intermediate 7374 7375 .keywords: TS, state, domain 7376 .seealso: TSAdaptCheckStage(), TSFunctionDomainError() 7377 @*/ 7378 7379 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 7380 { 7381 PetscFunctionBegin; 7382 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7383 ts->functiondomainerror = func; 7384 PetscFunctionReturn(0); 7385 } 7386 7387 /*@ 7388 TSFunctionDomainError - Check if the current state is valid 7389 7390 Input Parameters: 7391 ts - the TS context 7392 stagetime - time of the simulation 7393 Y - state vector to check. 7394 7395 Output Parameter: 7396 accept - Set to PETSC_FALSE if the current state vector is valid. 7397 7398 Note: 7399 This function should be used to ensure the state is in a valid part of the space. 7400 For example, one can ensure here all values are positive. 7401 7402 Level: advanced 7403 @*/ 7404 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 7405 { 7406 PetscErrorCode ierr; 7407 7408 PetscFunctionBegin; 7409 7410 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7411 *accept = PETSC_TRUE; 7412 if (ts->functiondomainerror) { 7413 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 7414 } 7415 PetscFunctionReturn(0); 7416 } 7417 7418 /*@C 7419 TSClone - This function clones a time step object. 7420 7421 Collective on MPI_Comm 7422 7423 Input Parameter: 7424 . tsin - The input TS 7425 7426 Output Parameter: 7427 . tsout - The output TS (cloned) 7428 7429 Notes: 7430 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. 7431 7432 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); 7433 7434 Level: developer 7435 7436 .keywords: TS, clone 7437 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 7438 @*/ 7439 PetscErrorCode TSClone(TS tsin, TS *tsout) 7440 { 7441 TS t; 7442 PetscErrorCode ierr; 7443 SNES snes_start; 7444 DM dm; 7445 TSType type; 7446 7447 PetscFunctionBegin; 7448 PetscValidPointer(tsin,1); 7449 *tsout = NULL; 7450 7451 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 7452 7453 /* General TS description */ 7454 t->numbermonitors = 0; 7455 t->setupcalled = 0; 7456 t->ksp_its = 0; 7457 t->snes_its = 0; 7458 t->nwork = 0; 7459 t->rhsjacobian.time = -1e20; 7460 t->rhsjacobian.scale = 1.; 7461 t->ijacobian.shift = 1.; 7462 7463 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 7464 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 7465 7466 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 7467 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 7468 7469 t->adapt = tsin->adapt; 7470 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 7471 7472 t->trajectory = tsin->trajectory; 7473 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 7474 7475 t->event = tsin->event; 7476 if (t->event) t->event->refct++; 7477 7478 t->problem_type = tsin->problem_type; 7479 t->ptime = tsin->ptime; 7480 t->ptime_prev = tsin->ptime_prev; 7481 t->time_step = tsin->time_step; 7482 t->max_time = tsin->max_time; 7483 t->steps = tsin->steps; 7484 t->max_steps = tsin->max_steps; 7485 t->equation_type = tsin->equation_type; 7486 t->atol = tsin->atol; 7487 t->rtol = tsin->rtol; 7488 t->max_snes_failures = tsin->max_snes_failures; 7489 t->max_reject = tsin->max_reject; 7490 t->errorifstepfailed = tsin->errorifstepfailed; 7491 7492 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 7493 ierr = TSSetType(t,type);CHKERRQ(ierr); 7494 7495 t->vec_sol = NULL; 7496 7497 t->cfltime = tsin->cfltime; 7498 t->cfltime_local = tsin->cfltime_local; 7499 t->exact_final_time = tsin->exact_final_time; 7500 7501 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 7502 7503 if (((PetscObject)tsin)->fortran_func_pointers) { 7504 PetscInt i; 7505 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 7506 for (i=0; i<10; i++) { 7507 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 7508 } 7509 } 7510 *tsout = t; 7511 PetscFunctionReturn(0); 7512 } 7513 7514 static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void* ctx,Vec x,Vec y) 7515 { 7516 PetscErrorCode ierr; 7517 TS ts = (TS) ctx; 7518 7519 PetscFunctionBegin; 7520 ierr = TSComputeRHSFunction(ts,0,x,y);CHKERRQ(ierr); 7521 PetscFunctionReturn(0); 7522 } 7523 7524 /*@ 7525 TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function. 7526 7527 Logically Collective on TS and Mat 7528 7529 Input Parameters: 7530 TS - the time stepping routine 7531 7532 Output Parameter: 7533 . flg - PETSC_TRUE if the multiply is likely correct 7534 7535 Options Database: 7536 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator 7537 7538 Level: advanced 7539 7540 Notes: 7541 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7542 7543 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTestTranspose() 7544 @*/ 7545 PetscErrorCode TSRHSJacobianTest(TS ts,PetscBool *flg) 7546 { 7547 Mat J,B; 7548 PetscErrorCode ierr; 7549 TSRHSJacobian func; 7550 void* ctx; 7551 7552 PetscFunctionBegin; 7553 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7554 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7555 ierr = MatShellTestMult(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7556 PetscFunctionReturn(0); 7557 } 7558 7559 /*@C 7560 TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function. 7561 7562 Logically Collective on TS and Mat 7563 7564 Input Parameters: 7565 TS - the time stepping routine 7566 7567 Output Parameter: 7568 . flg - PETSC_TRUE if the multiply is likely correct 7569 7570 Options Database: 7571 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator 7572 7573 Notes: 7574 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7575 7576 Level: advanced 7577 7578 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTest() 7579 @*/ 7580 PetscErrorCode TSRHSJacobianTestTranspose(TS ts,PetscBool *flg) 7581 { 7582 Mat J,B; 7583 PetscErrorCode ierr; 7584 void *ctx; 7585 TSRHSJacobian func; 7586 7587 PetscFunctionBegin; 7588 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7589 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7590 ierr = MatShellTestMultTranspose(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7591 PetscFunctionReturn(0); 7592 } 7593