1c4762a1bSJed Brown static char help[] = "Second Order TVD Finite Volume Example.\n"; 2c4762a1bSJed Brown /*F 3c4762a1bSJed Brown 4c4762a1bSJed Brown We use a second order TVD finite volume method to evolve a system of PDEs. Our simple upwinded residual evaluation loops 5c4762a1bSJed Brown over all mesh faces and uses a Riemann solver to produce the flux given the face geometry and cell values, 6c4762a1bSJed Brown \begin{equation} 7c4762a1bSJed Brown f_i = \mathrm{riemann}(\mathrm{phys}, p_\mathrm{centroid}, \hat n, x^L, x^R) 8c4762a1bSJed Brown \end{equation} 9c4762a1bSJed Brown and then update the cell values given the cell volume. 10c4762a1bSJed Brown \begin{eqnarray} 11c4762a1bSJed Brown f^L_i &-=& \frac{f_i}{vol^L} \\ 12c4762a1bSJed Brown f^R_i &+=& \frac{f_i}{vol^R} 13c4762a1bSJed Brown \end{eqnarray} 14c4762a1bSJed Brown 15c4762a1bSJed Brown As an example, we can consider the shallow water wave equation, 16c4762a1bSJed Brown \begin{eqnarray} 17c4762a1bSJed Brown h_t + \nabla\cdot \left( uh \right) &=& 0 \\ 18c4762a1bSJed Brown (uh)_t + \nabla\cdot \left( u\otimes uh + \frac{g h^2}{2} I \right) &=& 0 19c4762a1bSJed Brown \end{eqnarray} 20c4762a1bSJed Brown where $h$ is wave height, $u$ is wave velocity, and $g$ is the acceleration due to gravity. 21c4762a1bSJed Brown 22c4762a1bSJed Brown A representative Riemann solver for the shallow water equations is given in the PhysicsRiemann_SW() function, 23c4762a1bSJed Brown \begin{eqnarray} 24c4762a1bSJed Brown f^{L,R}_h &=& uh^{L,R} \cdot \hat n \\ 25c4762a1bSJed Brown f^{L,R}_{uh} &=& \frac{f^{L,R}_h}{h^{L,R}} uh^{L,R} + g (h^{L,R})^2 \hat n \\ 26c4762a1bSJed Brown c^{L,R} &=& \sqrt{g h^{L,R}} \\ 27c4762a1bSJed Brown s &=& \max\left( \left|\frac{uh^L \cdot \hat n}{h^L}\right| + c^L, \left|\frac{uh^R \cdot \hat n}{h^R}\right| + c^R \right) \\ 28c4762a1bSJed Brown f_i &=& \frac{A_\mathrm{face}}{2} \left( f^L_i + f^R_i + s \left( x^L_i - x^R_i \right) \right) 29c4762a1bSJed Brown \end{eqnarray} 30c4762a1bSJed Brown where $c$ is the local gravity wave speed and $f_i$ is a Rusanov flux. 31c4762a1bSJed Brown 32c4762a1bSJed Brown The more sophisticated residual evaluation in RHSFunctionLocal_LS() uses a least-squares fit to a quadratic polynomial 33c4762a1bSJed Brown over a neighborhood of the given element. 34c4762a1bSJed Brown 35c4762a1bSJed Brown The mesh is read in from an ExodusII file, usually generated by Cubit. 3652115386SStefano Zampini 3752115386SStefano Zampini The example also shows how to handle AMR in a time-dependent TS solver. 38c4762a1bSJed Brown F*/ 39c4762a1bSJed Brown #include <petscdmplex.h> 40c4762a1bSJed Brown #include <petscdmforest.h> 41c4762a1bSJed Brown #include <petscds.h> 42c4762a1bSJed Brown #include <petscts.h> 43c4762a1bSJed Brown 44c4762a1bSJed Brown #define DIM 2 /* Geometric dimension */ 45c4762a1bSJed Brown 468d2c18caSMukkund Sunjii static PetscFunctionList PhysicsList, PhysicsRiemannList_SW; 47c4762a1bSJed Brown 48c4762a1bSJed Brown /* Represents continuum physical equations. */ 49c4762a1bSJed Brown typedef struct _n_Physics *Physics; 50c4762a1bSJed Brown 51c4762a1bSJed Brown /* Physical model includes boundary conditions, initial conditions, and functionals of interest. It is 52c4762a1bSJed Brown * discretization-independent, but its members depend on the scenario being solved. */ 53c4762a1bSJed Brown typedef struct _n_Model *Model; 54c4762a1bSJed Brown 55c4762a1bSJed Brown /* 'User' implements a discretization of a continuous model. */ 56c4762a1bSJed Brown typedef struct _n_User *User; 57c4762a1bSJed Brown typedef PetscErrorCode (*SolutionFunction)(Model, PetscReal, const PetscReal *, PetscScalar *, void *); 5845480ffeSMatthew G. Knepley typedef PetscErrorCode (*SetUpBCFunction)(DM, PetscDS, Physics); 59c4762a1bSJed Brown typedef PetscErrorCode (*FunctionalFunction)(Model, PetscReal, const PetscReal *, const PetscScalar *, PetscReal *, void *); 60c4762a1bSJed Brown typedef PetscErrorCode (*SetupFields)(Physics, PetscSection); 61c4762a1bSJed Brown static PetscErrorCode ModelSolutionSetDefault(Model, SolutionFunction, void *); 62c4762a1bSJed Brown static PetscErrorCode ModelFunctionalRegister(Model, const char *, PetscInt *, FunctionalFunction, void *); 63c4762a1bSJed Brown static PetscErrorCode OutputVTK(DM, const char *, PetscViewer *); 64c4762a1bSJed Brown 65c4762a1bSJed Brown struct FieldDescription { 66c4762a1bSJed Brown const char *name; 67c4762a1bSJed Brown PetscInt dof; 68c4762a1bSJed Brown }; 69c4762a1bSJed Brown 70c4762a1bSJed Brown typedef struct _n_FunctionalLink *FunctionalLink; 71c4762a1bSJed Brown struct _n_FunctionalLink { 72c4762a1bSJed Brown char *name; 73c4762a1bSJed Brown FunctionalFunction func; 74c4762a1bSJed Brown void *ctx; 75c4762a1bSJed Brown PetscInt offset; 76c4762a1bSJed Brown FunctionalLink next; 77c4762a1bSJed Brown }; 78c4762a1bSJed Brown 79c4762a1bSJed Brown struct _n_Physics { 80c4762a1bSJed Brown PetscRiemannFunc riemann; 81c4762a1bSJed Brown PetscInt dof; /* number of degrees of freedom per cell */ 82c4762a1bSJed Brown PetscReal maxspeed; /* kludge to pick initial time step, need to add monitoring and step control */ 83c4762a1bSJed Brown void *data; 84c4762a1bSJed Brown PetscInt nfields; 85c4762a1bSJed Brown const struct FieldDescription *field_desc; 86c4762a1bSJed Brown }; 87c4762a1bSJed Brown 88c4762a1bSJed Brown struct _n_Model { 89da81f932SPierre Jolivet MPI_Comm comm; /* Does not do collective communication, but some error conditions can be collective */ 90c4762a1bSJed Brown Physics physics; 91c4762a1bSJed Brown FunctionalLink functionalRegistry; 92c4762a1bSJed Brown PetscInt maxComputed; 93c4762a1bSJed Brown PetscInt numMonitored; 94c4762a1bSJed Brown FunctionalLink *functionalMonitored; 95c4762a1bSJed Brown PetscInt numCall; 96c4762a1bSJed Brown FunctionalLink *functionalCall; 97c4762a1bSJed Brown SolutionFunction solution; 98c4762a1bSJed Brown SetUpBCFunction setupbc; 99c4762a1bSJed Brown void *solutionctx; 100c4762a1bSJed Brown PetscReal maxspeed; /* estimate of global maximum speed (for CFL calculation) */ 101c4762a1bSJed Brown PetscReal bounds[2 * DIM]; 102c4762a1bSJed Brown PetscErrorCode (*errorIndicator)(PetscInt, PetscReal, PetscInt, const PetscScalar[], const PetscScalar[], PetscReal *, void *); 103c4762a1bSJed Brown void *errorCtx; 104c4762a1bSJed Brown }; 105c4762a1bSJed Brown 106c4762a1bSJed Brown struct _n_User { 107c4762a1bSJed Brown PetscInt vtkInterval; /* For monitor */ 108c4762a1bSJed Brown char outputBasename[PETSC_MAX_PATH_LEN]; /* Basename for output files */ 109c4762a1bSJed Brown PetscInt monitorStepOffset; 110c4762a1bSJed Brown Model model; 111c4762a1bSJed Brown PetscBool vtkmon; 112c4762a1bSJed Brown }; 113c4762a1bSJed Brown 114d71ae5a4SJacob Faibussowitsch static inline PetscReal DotDIMReal(const PetscReal *x, const PetscReal *y) 115d71ae5a4SJacob Faibussowitsch { 116c4762a1bSJed Brown PetscInt i; 117c4762a1bSJed Brown PetscReal prod = 0.0; 118c4762a1bSJed Brown 119c4762a1bSJed Brown for (i = 0; i < DIM; i++) prod += x[i] * y[i]; 120c4762a1bSJed Brown return prod; 121c4762a1bSJed Brown } 122d71ae5a4SJacob Faibussowitsch static inline PetscReal NormDIM(const PetscReal *x) 123d71ae5a4SJacob Faibussowitsch { 1249371c9d4SSatish Balay return PetscSqrtReal(PetscAbsReal(DotDIMReal(x, x))); 1259371c9d4SSatish Balay } 126c4762a1bSJed Brown 127d71ae5a4SJacob Faibussowitsch static inline PetscReal Dot2Real(const PetscReal *x, const PetscReal *y) 128d71ae5a4SJacob Faibussowitsch { 1299371c9d4SSatish Balay return x[0] * y[0] + x[1] * y[1]; 1309371c9d4SSatish Balay } 131d71ae5a4SJacob Faibussowitsch static inline PetscReal Norm2Real(const PetscReal *x) 132d71ae5a4SJacob Faibussowitsch { 1339371c9d4SSatish Balay return PetscSqrtReal(PetscAbsReal(Dot2Real(x, x))); 1349371c9d4SSatish Balay } 135d71ae5a4SJacob Faibussowitsch static inline void Normalize2Real(PetscReal *x) 136d71ae5a4SJacob Faibussowitsch { 1379371c9d4SSatish Balay PetscReal a = 1. / Norm2Real(x); 1389371c9d4SSatish Balay x[0] *= a; 1399371c9d4SSatish Balay x[1] *= a; 1409371c9d4SSatish Balay } 141d71ae5a4SJacob Faibussowitsch static inline void Waxpy2Real(PetscReal a, const PetscReal *x, const PetscReal *y, PetscReal *w) 142d71ae5a4SJacob Faibussowitsch { 1439371c9d4SSatish Balay w[0] = a * x[0] + y[0]; 1449371c9d4SSatish Balay w[1] = a * x[1] + y[1]; 1459371c9d4SSatish Balay } 146d71ae5a4SJacob Faibussowitsch static inline void Scale2Real(PetscReal a, const PetscReal *x, PetscReal *y) 147d71ae5a4SJacob Faibussowitsch { 1489371c9d4SSatish Balay y[0] = a * x[0]; 1499371c9d4SSatish Balay y[1] = a * x[1]; 1509371c9d4SSatish Balay } 151c4762a1bSJed Brown 152c4762a1bSJed Brown /******************* Advect ********************/ 1539371c9d4SSatish Balay typedef enum { 1549371c9d4SSatish Balay ADVECT_SOL_TILTED, 1559371c9d4SSatish Balay ADVECT_SOL_BUMP, 1569371c9d4SSatish Balay ADVECT_SOL_BUMP_CAVITY 1579371c9d4SSatish Balay } AdvectSolType; 158c4762a1bSJed Brown static const char *const AdvectSolTypes[] = {"TILTED", "BUMP", "BUMP_CAVITY", "AdvectSolType", "ADVECT_SOL_", 0}; 1599371c9d4SSatish Balay typedef enum { 1609371c9d4SSatish Balay ADVECT_SOL_BUMP_CONE, 1619371c9d4SSatish Balay ADVECT_SOL_BUMP_COS 1629371c9d4SSatish Balay } AdvectSolBumpType; 163c4762a1bSJed Brown static const char *const AdvectSolBumpTypes[] = {"CONE", "COS", "AdvectSolBumpType", "ADVECT_SOL_BUMP_", 0}; 164c4762a1bSJed Brown 165c4762a1bSJed Brown typedef struct { 166c4762a1bSJed Brown PetscReal wind[DIM]; 167c4762a1bSJed Brown } Physics_Advect_Tilted; 168c4762a1bSJed Brown typedef struct { 169c4762a1bSJed Brown PetscReal center[DIM]; 170c4762a1bSJed Brown PetscReal radius; 171c4762a1bSJed Brown AdvectSolBumpType type; 172c4762a1bSJed Brown } Physics_Advect_Bump; 173c4762a1bSJed Brown 174c4762a1bSJed Brown typedef struct { 175c4762a1bSJed Brown PetscReal inflowState; 176c4762a1bSJed Brown AdvectSolType soltype; 1779371c9d4SSatish Balay union 1789371c9d4SSatish Balay { 179c4762a1bSJed Brown Physics_Advect_Tilted tilted; 180c4762a1bSJed Brown Physics_Advect_Bump bump; 181c4762a1bSJed Brown } sol; 182c4762a1bSJed Brown struct { 183c4762a1bSJed Brown PetscInt Solution; 184c4762a1bSJed Brown PetscInt Error; 185c4762a1bSJed Brown } functional; 186c4762a1bSJed Brown } Physics_Advect; 187c4762a1bSJed Brown 1889371c9d4SSatish Balay static const struct FieldDescription PhysicsFields_Advect[] = { 1899371c9d4SSatish Balay {"U", 1}, 1909371c9d4SSatish Balay {NULL, 0} 1919371c9d4SSatish Balay }; 192c4762a1bSJed Brown 193d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsBoundary_Advect_Inflow(PetscReal time, const PetscReal *c, const PetscReal *n, const PetscScalar *xI, PetscScalar *xG, void *ctx) 194d71ae5a4SJacob Faibussowitsch { 195c4762a1bSJed Brown Physics phys = (Physics)ctx; 196c4762a1bSJed Brown Physics_Advect *advect = (Physics_Advect *)phys->data; 197c4762a1bSJed Brown 198c4762a1bSJed Brown PetscFunctionBeginUser; 199c4762a1bSJed Brown xG[0] = advect->inflowState; 2003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 201c4762a1bSJed Brown } 202c4762a1bSJed Brown 203d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsBoundary_Advect_Outflow(PetscReal time, const PetscReal *c, const PetscReal *n, const PetscScalar *xI, PetscScalar *xG, void *ctx) 204d71ae5a4SJacob Faibussowitsch { 205c4762a1bSJed Brown PetscFunctionBeginUser; 206c4762a1bSJed Brown xG[0] = xI[0]; 2073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208c4762a1bSJed Brown } 209c4762a1bSJed Brown 210d71ae5a4SJacob Faibussowitsch static void PhysicsRiemann_Advect(PetscInt dim, PetscInt Nf, const PetscReal *qp, const PetscReal *n, const PetscScalar *xL, const PetscScalar *xR, PetscInt numConstants, const PetscScalar constants[], PetscScalar *flux, Physics phys) 211d71ae5a4SJacob Faibussowitsch { 212c4762a1bSJed Brown Physics_Advect *advect = (Physics_Advect *)phys->data; 213c4762a1bSJed Brown PetscReal wind[DIM], wn; 214c4762a1bSJed Brown 215c4762a1bSJed Brown switch (advect->soltype) { 216c4762a1bSJed Brown case ADVECT_SOL_TILTED: { 217c4762a1bSJed Brown Physics_Advect_Tilted *tilted = &advect->sol.tilted; 218c4762a1bSJed Brown wind[0] = tilted->wind[0]; 219c4762a1bSJed Brown wind[1] = tilted->wind[1]; 220c4762a1bSJed Brown } break; 221c4762a1bSJed Brown case ADVECT_SOL_BUMP: 222c4762a1bSJed Brown wind[0] = -qp[1]; 223c4762a1bSJed Brown wind[1] = qp[0]; 224c4762a1bSJed Brown break; 2259371c9d4SSatish Balay case ADVECT_SOL_BUMP_CAVITY: { 226c4762a1bSJed Brown PetscInt i; 227c4762a1bSJed Brown PetscReal comp2[3] = {0., 0., 0.}, rad2; 228c4762a1bSJed Brown 229c4762a1bSJed Brown rad2 = 0.; 230c4762a1bSJed Brown for (i = 0; i < dim; i++) { 231c4762a1bSJed Brown comp2[i] = qp[i] * qp[i]; 232c4762a1bSJed Brown rad2 += comp2[i]; 233c4762a1bSJed Brown } 234c4762a1bSJed Brown 235c4762a1bSJed Brown wind[0] = -qp[1]; 236c4762a1bSJed Brown wind[1] = qp[0]; 237c4762a1bSJed Brown if (rad2 > 1.) { 238c4762a1bSJed Brown PetscInt maxI = 0; 239c4762a1bSJed Brown PetscReal maxComp2 = comp2[0]; 240c4762a1bSJed Brown 241c4762a1bSJed Brown for (i = 1; i < dim; i++) { 242c4762a1bSJed Brown if (comp2[i] > maxComp2) { 243c4762a1bSJed Brown maxI = i; 244c4762a1bSJed Brown maxComp2 = comp2[i]; 245c4762a1bSJed Brown } 246c4762a1bSJed Brown } 247c4762a1bSJed Brown wind[maxI] = 0.; 248c4762a1bSJed Brown } 2499371c9d4SSatish Balay } break; 2509371c9d4SSatish Balay default: { 251c4762a1bSJed Brown PetscInt i; 252c4762a1bSJed Brown for (i = 0; i < DIM; ++i) wind[i] = 0.0; 253c4762a1bSJed Brown } 25498921bdaSJacob Faibussowitsch /* default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for solution type %s",AdvectSolBumpTypes[advect->soltype]); */ 255c4762a1bSJed Brown } 256c4762a1bSJed Brown wn = Dot2Real(wind, n); 257c4762a1bSJed Brown flux[0] = (wn > 0 ? xL[0] : xR[0]) * wn; 258c4762a1bSJed Brown } 259c4762a1bSJed Brown 260d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsSolution_Advect(Model mod, PetscReal time, const PetscReal *x, PetscScalar *u, void *ctx) 261d71ae5a4SJacob Faibussowitsch { 262c4762a1bSJed Brown Physics phys = (Physics)ctx; 263c4762a1bSJed Brown Physics_Advect *advect = (Physics_Advect *)phys->data; 264c4762a1bSJed Brown 265c4762a1bSJed Brown PetscFunctionBeginUser; 266c4762a1bSJed Brown switch (advect->soltype) { 267c4762a1bSJed Brown case ADVECT_SOL_TILTED: { 268c4762a1bSJed Brown PetscReal x0[DIM]; 269c4762a1bSJed Brown Physics_Advect_Tilted *tilted = &advect->sol.tilted; 270c4762a1bSJed Brown Waxpy2Real(-time, tilted->wind, x, x0); 271c4762a1bSJed Brown if (x0[1] > 0) u[0] = 1. * x[0] + 3. * x[1]; 272c4762a1bSJed Brown else u[0] = advect->inflowState; 273c4762a1bSJed Brown } break; 274c4762a1bSJed Brown case ADVECT_SOL_BUMP_CAVITY: 275c4762a1bSJed Brown case ADVECT_SOL_BUMP: { 276c4762a1bSJed Brown Physics_Advect_Bump *bump = &advect->sol.bump; 277c4762a1bSJed Brown PetscReal x0[DIM], v[DIM], r, cost, sint; 278c4762a1bSJed Brown cost = PetscCosReal(time); 279c4762a1bSJed Brown sint = PetscSinReal(time); 280c4762a1bSJed Brown x0[0] = cost * x[0] + sint * x[1]; 281c4762a1bSJed Brown x0[1] = -sint * x[0] + cost * x[1]; 282c4762a1bSJed Brown Waxpy2Real(-1, bump->center, x0, v); 283c4762a1bSJed Brown r = Norm2Real(v); 284c4762a1bSJed Brown switch (bump->type) { 285d71ae5a4SJacob Faibussowitsch case ADVECT_SOL_BUMP_CONE: 286d71ae5a4SJacob Faibussowitsch u[0] = PetscMax(1 - r / bump->radius, 0); 287d71ae5a4SJacob Faibussowitsch break; 288d71ae5a4SJacob Faibussowitsch case ADVECT_SOL_BUMP_COS: 289d71ae5a4SJacob Faibussowitsch u[0] = 0.5 + 0.5 * PetscCosReal(PetscMin(r / bump->radius, 1) * PETSC_PI); 290d71ae5a4SJacob Faibussowitsch break; 291c4762a1bSJed Brown } 292c4762a1bSJed Brown } break; 293d71ae5a4SJacob Faibussowitsch default: 294d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unknown solution type"); 295c4762a1bSJed Brown } 2963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 297c4762a1bSJed Brown } 298c4762a1bSJed Brown 299d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsFunctional_Advect(Model mod, PetscReal time, const PetscReal *x, const PetscScalar *y, PetscReal *f, void *ctx) 300d71ae5a4SJacob Faibussowitsch { 301c4762a1bSJed Brown Physics phys = (Physics)ctx; 302c4762a1bSJed Brown Physics_Advect *advect = (Physics_Advect *)phys->data; 303391faea4SSatish Balay PetscScalar yexact[1] = {0.0}; 304c4762a1bSJed Brown 305c4762a1bSJed Brown PetscFunctionBeginUser; 3069566063dSJacob Faibussowitsch PetscCall(PhysicsSolution_Advect(mod, time, x, yexact, phys)); 307c4762a1bSJed Brown f[advect->functional.Solution] = PetscRealPart(y[0]); 308c4762a1bSJed Brown f[advect->functional.Error] = PetscAbsScalar(y[0] - yexact[0]); 3093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 310c4762a1bSJed Brown } 311c4762a1bSJed Brown 312d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetUpBC_Advect(DM dm, PetscDS prob, Physics phys) 313d71ae5a4SJacob Faibussowitsch { 314c4762a1bSJed Brown const PetscInt inflowids[] = {100, 200, 300}, outflowids[] = {101}; 31545480ffeSMatthew G. Knepley DMLabel label; 316c4762a1bSJed Brown 317c4762a1bSJed Brown PetscFunctionBeginUser; 318c4762a1bSJed Brown /* Register "canned" boundary conditions and defaults for where to apply. */ 3199566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "Face Sets", &label)); 320dd39110bSPierre Jolivet PetscCall(PetscDSAddBoundary(prob, DM_BC_NATURAL_RIEMANN, "inflow", label, PETSC_STATIC_ARRAY_LENGTH(inflowids), inflowids, 0, 0, NULL, (void (*)(void))PhysicsBoundary_Advect_Inflow, NULL, phys, NULL)); 321dd39110bSPierre Jolivet PetscCall(PetscDSAddBoundary(prob, DM_BC_NATURAL_RIEMANN, "outflow", label, PETSC_STATIC_ARRAY_LENGTH(outflowids), outflowids, 0, 0, NULL, (void (*)(void))PhysicsBoundary_Advect_Outflow, NULL, phys, NULL)); 3223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 323c4762a1bSJed Brown } 324c4762a1bSJed Brown 325d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsCreate_Advect(Model mod, Physics phys, PetscOptionItems *PetscOptionsObject) 326d71ae5a4SJacob Faibussowitsch { 327c4762a1bSJed Brown Physics_Advect *advect; 328c4762a1bSJed Brown 329c4762a1bSJed Brown PetscFunctionBeginUser; 330c4762a1bSJed Brown phys->field_desc = PhysicsFields_Advect; 331c4762a1bSJed Brown phys->riemann = (PetscRiemannFunc)PhysicsRiemann_Advect; 3329566063dSJacob Faibussowitsch PetscCall(PetscNew(&advect)); 333c4762a1bSJed Brown phys->data = advect; 334c4762a1bSJed Brown mod->setupbc = SetUpBC_Advect; 335c4762a1bSJed Brown 336d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "Advect options"); 337c4762a1bSJed Brown { 338c4762a1bSJed Brown PetscInt two = 2, dof = 1; 339c4762a1bSJed Brown advect->soltype = ADVECT_SOL_TILTED; 3409566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-advect_sol_type", "solution type", "", AdvectSolTypes, (PetscEnum)advect->soltype, (PetscEnum *)&advect->soltype, NULL)); 341c4762a1bSJed Brown switch (advect->soltype) { 342c4762a1bSJed Brown case ADVECT_SOL_TILTED: { 343c4762a1bSJed Brown Physics_Advect_Tilted *tilted = &advect->sol.tilted; 344c4762a1bSJed Brown two = 2; 345c4762a1bSJed Brown tilted->wind[0] = 0.0; 346c4762a1bSJed Brown tilted->wind[1] = 1.0; 3479566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-advect_tilted_wind", "background wind vx,vy", "", tilted->wind, &two, NULL)); 348c4762a1bSJed Brown advect->inflowState = -2.0; 3499566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-advect_tilted_inflow", "Inflow state", "", &advect->inflowState, &dof, NULL)); 350c4762a1bSJed Brown phys->maxspeed = Norm2Real(tilted->wind); 351c4762a1bSJed Brown } break; 352c4762a1bSJed Brown case ADVECT_SOL_BUMP_CAVITY: 353c4762a1bSJed Brown case ADVECT_SOL_BUMP: { 354c4762a1bSJed Brown Physics_Advect_Bump *bump = &advect->sol.bump; 355c4762a1bSJed Brown two = 2; 356c4762a1bSJed Brown bump->center[0] = 2.; 357c4762a1bSJed Brown bump->center[1] = 0.; 3589566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-advect_bump_center", "location of center of bump x,y", "", bump->center, &two, NULL)); 359c4762a1bSJed Brown bump->radius = 0.9; 3609566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-advect_bump_radius", "radius of bump", "", bump->radius, &bump->radius, NULL)); 361c4762a1bSJed Brown bump->type = ADVECT_SOL_BUMP_CONE; 3629566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-advect_bump_type", "type of bump", "", AdvectSolBumpTypes, (PetscEnum)bump->type, (PetscEnum *)&bump->type, NULL)); 363c4762a1bSJed Brown phys->maxspeed = 3.; /* radius of mesh, kludge */ 364c4762a1bSJed Brown } break; 365c4762a1bSJed Brown } 366c4762a1bSJed Brown } 367d0609cedSBarry Smith PetscOptionsHeadEnd(); 368c4762a1bSJed Brown /* Initial/transient solution with default boundary conditions */ 3699566063dSJacob Faibussowitsch PetscCall(ModelSolutionSetDefault(mod, PhysicsSolution_Advect, phys)); 370c4762a1bSJed Brown /* Register "canned" functionals */ 3719566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Solution", &advect->functional.Solution, PhysicsFunctional_Advect, phys)); 3729566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Error", &advect->functional.Error, PhysicsFunctional_Advect, phys)); 3733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 374c4762a1bSJed Brown } 375c4762a1bSJed Brown 376c4762a1bSJed Brown /******************* Shallow Water ********************/ 377c4762a1bSJed Brown typedef struct { 378c4762a1bSJed Brown PetscReal gravity; 379c4762a1bSJed Brown PetscReal boundaryHeight; 380c4762a1bSJed Brown struct { 381c4762a1bSJed Brown PetscInt Height; 382c4762a1bSJed Brown PetscInt Speed; 383c4762a1bSJed Brown PetscInt Energy; 384c4762a1bSJed Brown } functional; 385c4762a1bSJed Brown } Physics_SW; 386c4762a1bSJed Brown typedef struct { 387c4762a1bSJed Brown PetscReal h; 388c4762a1bSJed Brown PetscReal uh[DIM]; 389c4762a1bSJed Brown } SWNode; 3909371c9d4SSatish Balay typedef union 3919371c9d4SSatish Balay { 392c4762a1bSJed Brown SWNode swnode; 393c4762a1bSJed Brown PetscReal vals[DIM + 1]; 394c4762a1bSJed Brown } SWNodeUnion; 395c4762a1bSJed Brown 3969371c9d4SSatish Balay static const struct FieldDescription PhysicsFields_SW[] = { 3979371c9d4SSatish Balay {"Height", 1 }, 3989371c9d4SSatish Balay {"Momentum", DIM}, 3999371c9d4SSatish Balay {NULL, 0 } 4009371c9d4SSatish Balay }; 401c4762a1bSJed Brown 402c4762a1bSJed Brown /* 403c4762a1bSJed Brown * h_t + div(uh) = 0 404c4762a1bSJed Brown * (uh)_t + div (u\otimes uh + g h^2 / 2 I) = 0 405c4762a1bSJed Brown * 406c4762a1bSJed Brown * */ 407d71ae5a4SJacob Faibussowitsch static PetscErrorCode SWFlux(Physics phys, const PetscReal *n, const SWNode *x, SWNode *f) 408d71ae5a4SJacob Faibussowitsch { 409c4762a1bSJed Brown Physics_SW *sw = (Physics_SW *)phys->data; 410c4762a1bSJed Brown PetscReal uhn, u[DIM]; 411c4762a1bSJed Brown PetscInt i; 412c4762a1bSJed Brown 413c4762a1bSJed Brown PetscFunctionBeginUser; 414c4762a1bSJed Brown Scale2Real(1. / x->h, x->uh, u); 415c4762a1bSJed Brown uhn = x->uh[0] * n[0] + x->uh[1] * n[1]; 416c4762a1bSJed Brown f->h = uhn; 417c4762a1bSJed Brown for (i = 0; i < DIM; i++) f->uh[i] = u[i] * uhn + sw->gravity * PetscSqr(x->h) * n[i]; 4183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 419c4762a1bSJed Brown } 420c4762a1bSJed Brown 421d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsBoundary_SW_Wall(PetscReal time, const PetscReal *c, const PetscReal *n, const PetscScalar *xI, PetscScalar *xG, void *ctx) 422d71ae5a4SJacob Faibussowitsch { 423c4762a1bSJed Brown PetscFunctionBeginUser; 424c4762a1bSJed Brown xG[0] = xI[0]; 425c4762a1bSJed Brown xG[1] = -xI[1]; 426c4762a1bSJed Brown xG[2] = -xI[2]; 4273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 428c4762a1bSJed Brown } 429c4762a1bSJed Brown 430d71ae5a4SJacob Faibussowitsch static void PhysicsRiemann_SW_HLL(PetscInt dim, PetscInt Nf, const PetscReal *qp, const PetscReal *n, const PetscScalar *xL, const PetscScalar *xR, PetscInt numConstants, const PetscScalar constants[], PetscScalar *flux, Physics phys) 431d71ae5a4SJacob Faibussowitsch { 4328d2c18caSMukkund Sunjii Physics_SW *sw = (Physics_SW *)phys->data; 4338d2c18caSMukkund Sunjii PetscReal aL, aR; 4348d2c18caSMukkund Sunjii PetscReal nn[DIM]; 4358d2c18caSMukkund Sunjii #if !defined(PETSC_USE_COMPLEX) 4368d2c18caSMukkund Sunjii const SWNode *uL = (const SWNode *)xL, *uR = (const SWNode *)xR; 4378d2c18caSMukkund Sunjii #else 4388d2c18caSMukkund Sunjii SWNodeUnion uLreal, uRreal; 4398d2c18caSMukkund Sunjii const SWNode *uL = &uLreal.swnode; 4408d2c18caSMukkund Sunjii const SWNode *uR = &uRreal.swnode; 4418d2c18caSMukkund Sunjii #endif 4428d2c18caSMukkund Sunjii SWNodeUnion fL, fR; 4438d2c18caSMukkund Sunjii PetscInt i; 4448d2c18caSMukkund Sunjii PetscReal zero = 0.; 4458d2c18caSMukkund Sunjii 4468d2c18caSMukkund Sunjii #if defined(PETSC_USE_COMPLEX) 4479371c9d4SSatish Balay uLreal.swnode.h = 0; 4489371c9d4SSatish Balay uRreal.swnode.h = 0; 4498d2c18caSMukkund Sunjii for (i = 0; i < 1 + dim; i++) uLreal.vals[i] = PetscRealPart(xL[i]); 4508d2c18caSMukkund Sunjii for (i = 0; i < 1 + dim; i++) uRreal.vals[i] = PetscRealPart(xR[i]); 4518d2c18caSMukkund Sunjii #endif 4528d2c18caSMukkund Sunjii if (uL->h <= 0 || uR->h <= 0) { 4538d2c18caSMukkund Sunjii for (i = 0; i < 1 + dim; i++) flux[i] = zero; 4548d2c18caSMukkund Sunjii return; 4558d2c18caSMukkund Sunjii } /* SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Reconstructed thickness is negative"); */ 4568d2c18caSMukkund Sunjii nn[0] = n[0]; 4578d2c18caSMukkund Sunjii nn[1] = n[1]; 4588d2c18caSMukkund Sunjii Normalize2Real(nn); 4593ba16761SJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF, SWFlux(phys, nn, uL, &(fL.swnode))); 4603ba16761SJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF, SWFlux(phys, nn, uR, &(fR.swnode))); 4618d2c18caSMukkund Sunjii /* gravity wave speed */ 4628d2c18caSMukkund Sunjii aL = PetscSqrtReal(sw->gravity * uL->h); 4638d2c18caSMukkund Sunjii aR = PetscSqrtReal(sw->gravity * uR->h); 4648d2c18caSMukkund Sunjii // Defining u_tilda and v_tilda as u and v 4658d2c18caSMukkund Sunjii PetscReal u_L, u_R; 4668d2c18caSMukkund Sunjii u_L = Dot2Real(uL->uh, nn) / uL->h; 4678d2c18caSMukkund Sunjii u_R = Dot2Real(uR->uh, nn) / uR->h; 4688d2c18caSMukkund Sunjii PetscReal sL, sR; 4698d2c18caSMukkund Sunjii sL = PetscMin(u_L - aL, u_R - aR); 4708d2c18caSMukkund Sunjii sR = PetscMax(u_L + aL, u_R + aR); 4718d2c18caSMukkund Sunjii if (sL > zero) { 472ad540459SPierre Jolivet for (i = 0; i < dim + 1; i++) flux[i] = fL.vals[i] * Norm2Real(n); 4738d2c18caSMukkund Sunjii } else if (sR < zero) { 474ad540459SPierre Jolivet for (i = 0; i < dim + 1; i++) flux[i] = fR.vals[i] * Norm2Real(n); 4758d2c18caSMukkund Sunjii } else { 476ad540459SPierre Jolivet for (i = 0; i < dim + 1; i++) flux[i] = ((sR * fL.vals[i] - sL * fR.vals[i] + sR * sL * (xR[i] - xL[i])) / (sR - sL)) * Norm2Real(n); 4778d2c18caSMukkund Sunjii } 4788d2c18caSMukkund Sunjii } 4798d2c18caSMukkund Sunjii 480d71ae5a4SJacob Faibussowitsch static void PhysicsRiemann_SW_Rusanov(PetscInt dim, PetscInt Nf, const PetscReal *qp, const PetscReal *n, const PetscScalar *xL, const PetscScalar *xR, PetscInt numConstants, const PetscScalar constants[], PetscScalar *flux, Physics phys) 481d71ae5a4SJacob Faibussowitsch { 482c4762a1bSJed Brown Physics_SW *sw = (Physics_SW *)phys->data; 483c4762a1bSJed Brown PetscReal cL, cR, speed; 484c4762a1bSJed Brown PetscReal nn[DIM]; 485c4762a1bSJed Brown #if !defined(PETSC_USE_COMPLEX) 486c4762a1bSJed Brown const SWNode *uL = (const SWNode *)xL, *uR = (const SWNode *)xR; 487c4762a1bSJed Brown #else 488c4762a1bSJed Brown SWNodeUnion uLreal, uRreal; 489c4762a1bSJed Brown const SWNode *uL = &uLreal.swnode; 490c4762a1bSJed Brown const SWNode *uR = &uRreal.swnode; 491c4762a1bSJed Brown #endif 492c4762a1bSJed Brown SWNodeUnion fL, fR; 493c4762a1bSJed Brown PetscInt i; 494c4762a1bSJed Brown PetscReal zero = 0.; 495c4762a1bSJed Brown 496c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX) 4979371c9d4SSatish Balay uLreal.swnode.h = 0; 4989371c9d4SSatish Balay uRreal.swnode.h = 0; 499c4762a1bSJed Brown for (i = 0; i < 1 + dim; i++) uLreal.vals[i] = PetscRealPart(xL[i]); 500c4762a1bSJed Brown for (i = 0; i < 1 + dim; i++) uRreal.vals[i] = PetscRealPart(xR[i]); 501c4762a1bSJed Brown #endif 5029371c9d4SSatish Balay if (uL->h < 0 || uR->h < 0) { 5039371c9d4SSatish Balay for (i = 0; i < 1 + dim; i++) flux[i] = zero / zero; 5049371c9d4SSatish Balay return; 5059371c9d4SSatish Balay } /* reconstructed thickness is negative */ 506c4762a1bSJed Brown nn[0] = n[0]; 507c4762a1bSJed Brown nn[1] = n[1]; 508c4762a1bSJed Brown Normalize2Real(nn); 5093ba16761SJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF, SWFlux(phys, nn, uL, &(fL.swnode))); 5103ba16761SJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF, SWFlux(phys, nn, uR, &(fR.swnode))); 511c4762a1bSJed Brown cL = PetscSqrtReal(sw->gravity * uL->h); 512c4762a1bSJed Brown cR = PetscSqrtReal(sw->gravity * uR->h); /* gravity wave speed */ 513c4762a1bSJed Brown speed = PetscMax(PetscAbsReal(Dot2Real(uL->uh, nn) / uL->h) + cL, PetscAbsReal(Dot2Real(uR->uh, nn) / uR->h) + cR); 514c4762a1bSJed Brown for (i = 0; i < 1 + dim; i++) flux[i] = (0.5 * (fL.vals[i] + fR.vals[i]) + 0.5 * speed * (xL[i] - xR[i])) * Norm2Real(n); 515c4762a1bSJed Brown } 516c4762a1bSJed Brown 517d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsSolution_SW(Model mod, PetscReal time, const PetscReal *x, PetscScalar *u, void *ctx) 518d71ae5a4SJacob Faibussowitsch { 519c4762a1bSJed Brown PetscReal dx[2], r, sigma; 520c4762a1bSJed Brown 521c4762a1bSJed Brown PetscFunctionBeginUser; 52254c59aa7SJacob Faibussowitsch PetscCheck(time == 0.0, mod->comm, PETSC_ERR_SUP, "No solution known for time %g", (double)time); 523c4762a1bSJed Brown dx[0] = x[0] - 1.5; 524c4762a1bSJed Brown dx[1] = x[1] - 1.0; 525c4762a1bSJed Brown r = Norm2Real(dx); 526c4762a1bSJed Brown sigma = 0.5; 527c4762a1bSJed Brown u[0] = 1 + 2 * PetscExpReal(-PetscSqr(r) / (2 * PetscSqr(sigma))); 528c4762a1bSJed Brown u[1] = 0.0; 529c4762a1bSJed Brown u[2] = 0.0; 5303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 531c4762a1bSJed Brown } 532c4762a1bSJed Brown 533d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsFunctional_SW(Model mod, PetscReal time, const PetscReal *coord, const PetscScalar *xx, PetscReal *f, void *ctx) 534d71ae5a4SJacob Faibussowitsch { 535c4762a1bSJed Brown Physics phys = (Physics)ctx; 536c4762a1bSJed Brown Physics_SW *sw = (Physics_SW *)phys->data; 537c4762a1bSJed Brown const SWNode *x = (const SWNode *)xx; 538c4762a1bSJed Brown PetscReal u[2]; 539c4762a1bSJed Brown PetscReal h; 540c4762a1bSJed Brown 541c4762a1bSJed Brown PetscFunctionBeginUser; 542c4762a1bSJed Brown h = x->h; 543c4762a1bSJed Brown Scale2Real(1. / x->h, x->uh, u); 544c4762a1bSJed Brown f[sw->functional.Height] = h; 545c4762a1bSJed Brown f[sw->functional.Speed] = Norm2Real(u) + PetscSqrtReal(sw->gravity * h); 546c4762a1bSJed Brown f[sw->functional.Energy] = 0.5 * (Dot2Real(x->uh, u) + sw->gravity * PetscSqr(h)); 5473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 548c4762a1bSJed Brown } 549c4762a1bSJed Brown 550d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetUpBC_SW(DM dm, PetscDS prob, Physics phys) 551d71ae5a4SJacob Faibussowitsch { 552c4762a1bSJed Brown const PetscInt wallids[] = {100, 101, 200, 300}; 55345480ffeSMatthew G. Knepley DMLabel label; 55445480ffeSMatthew G. Knepley 555c4762a1bSJed Brown PetscFunctionBeginUser; 5569566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "Face Sets", &label)); 557dd39110bSPierre Jolivet PetscCall(PetscDSAddBoundary(prob, DM_BC_NATURAL_RIEMANN, "wall", label, PETSC_STATIC_ARRAY_LENGTH(wallids), wallids, 0, 0, NULL, (void (*)(void))PhysicsBoundary_SW_Wall, NULL, phys, NULL)); 5583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 559c4762a1bSJed Brown } 560c4762a1bSJed Brown 561d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsCreate_SW(Model mod, Physics phys, PetscOptionItems *PetscOptionsObject) 562d71ae5a4SJacob Faibussowitsch { 563c4762a1bSJed Brown Physics_SW *sw; 5648d2c18caSMukkund Sunjii char sw_riemann[64] = "rusanov"; 565c4762a1bSJed Brown 566c4762a1bSJed Brown PetscFunctionBeginUser; 567c4762a1bSJed Brown phys->field_desc = PhysicsFields_SW; 5689566063dSJacob Faibussowitsch PetscCall(PetscNew(&sw)); 569c4762a1bSJed Brown phys->data = sw; 570c4762a1bSJed Brown mod->setupbc = SetUpBC_SW; 571c4762a1bSJed Brown 5723ba16761SJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PhysicsRiemannList_SW, "rusanov", PhysicsRiemann_SW_Rusanov)); 5733ba16761SJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PhysicsRiemannList_SW, "hll", PhysicsRiemann_SW_HLL)); 5748d2c18caSMukkund Sunjii 575d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SW options"); 576c4762a1bSJed Brown { 5778d2c18caSMukkund Sunjii void (*PhysicsRiemann_SW)(PetscInt, PetscInt, const PetscReal *, const PetscReal *, const PetscScalar *, const PetscScalar *, PetscInt, const PetscScalar, PetscScalar *, Physics); 578c4762a1bSJed Brown sw->gravity = 1.0; 5799566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-sw_gravity", "Gravitational constant", "", sw->gravity, &sw->gravity, NULL)); 5809566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-sw_riemann", "Riemann solver", "", PhysicsRiemannList_SW, sw_riemann, sw_riemann, sizeof sw_riemann, NULL)); 5819566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PhysicsRiemannList_SW, sw_riemann, &PhysicsRiemann_SW)); 5828d2c18caSMukkund Sunjii phys->riemann = (PetscRiemannFunc)PhysicsRiemann_SW; 583c4762a1bSJed Brown } 584d0609cedSBarry Smith PetscOptionsHeadEnd(); 585c4762a1bSJed Brown phys->maxspeed = PetscSqrtReal(2.0 * sw->gravity); /* Mach 1 for depth of 2 */ 586c4762a1bSJed Brown 5879566063dSJacob Faibussowitsch PetscCall(ModelSolutionSetDefault(mod, PhysicsSolution_SW, phys)); 5889566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Height", &sw->functional.Height, PhysicsFunctional_SW, phys)); 5899566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Speed", &sw->functional.Speed, PhysicsFunctional_SW, phys)); 5909566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Energy", &sw->functional.Energy, PhysicsFunctional_SW, phys)); 591c4762a1bSJed Brown 5923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 593c4762a1bSJed Brown } 594c4762a1bSJed Brown 595c4762a1bSJed Brown /******************* Euler Density Shock (EULER_IV_SHOCK,EULER_SS_SHOCK) ********************/ 596c4762a1bSJed Brown /* An initial-value and self-similar solutions of the compressible Euler equations */ 597c4762a1bSJed Brown /* Ravi Samtaney and D. I. Pullin */ 598c4762a1bSJed Brown /* Phys. Fluids 8, 2650 (1996); http://dx.doi.org/10.1063/1.869050 */ 5999371c9d4SSatish Balay typedef enum { 6009371c9d4SSatish Balay EULER_PAR_GAMMA, 6019371c9d4SSatish Balay EULER_PAR_RHOR, 6029371c9d4SSatish Balay EULER_PAR_AMACH, 6039371c9d4SSatish Balay EULER_PAR_ITANA, 6049371c9d4SSatish Balay EULER_PAR_SIZE 6059371c9d4SSatish Balay } EulerParamIdx; 6069371c9d4SSatish Balay typedef enum { 6079371c9d4SSatish Balay EULER_IV_SHOCK, 6089371c9d4SSatish Balay EULER_SS_SHOCK, 6099371c9d4SSatish Balay EULER_SHOCK_TUBE, 6109371c9d4SSatish Balay EULER_LINEAR_WAVE 6119371c9d4SSatish Balay } EulerType; 612c4762a1bSJed Brown typedef struct { 613c4762a1bSJed Brown PetscReal r; 614c4762a1bSJed Brown PetscReal ru[DIM]; 615c4762a1bSJed Brown PetscReal E; 616c4762a1bSJed Brown } EulerNode; 6179371c9d4SSatish Balay typedef union 6189371c9d4SSatish Balay { 619c4762a1bSJed Brown EulerNode eulernode; 620c4762a1bSJed Brown PetscReal vals[DIM + 2]; 621c4762a1bSJed Brown } EulerNodeUnion; 622c4762a1bSJed Brown typedef PetscErrorCode (*EquationOfState)(const PetscReal *, const EulerNode *, PetscReal *); 623c4762a1bSJed Brown typedef struct { 624c4762a1bSJed Brown EulerType type; 625c4762a1bSJed Brown PetscReal pars[EULER_PAR_SIZE]; 626c4762a1bSJed Brown EquationOfState sound; 627c4762a1bSJed Brown struct { 628c4762a1bSJed Brown PetscInt Density; 629c4762a1bSJed Brown PetscInt Momentum; 630c4762a1bSJed Brown PetscInt Energy; 631c4762a1bSJed Brown PetscInt Pressure; 632c4762a1bSJed Brown PetscInt Speed; 633c4762a1bSJed Brown } monitor; 634c4762a1bSJed Brown } Physics_Euler; 635c4762a1bSJed Brown 6369371c9d4SSatish Balay static const struct FieldDescription PhysicsFields_Euler[] = { 6379371c9d4SSatish Balay {"Density", 1 }, 6389371c9d4SSatish Balay {"Momentum", DIM}, 6399371c9d4SSatish Balay {"Energy", 1 }, 6409371c9d4SSatish Balay {NULL, 0 } 6419371c9d4SSatish Balay }; 642c4762a1bSJed Brown 643c4762a1bSJed Brown /* initial condition */ 644c4762a1bSJed Brown int initLinearWave(EulerNode *ux, const PetscReal gamma, const PetscReal coord[], const PetscReal Lx); 645d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsSolution_Euler(Model mod, PetscReal time, const PetscReal *x, PetscScalar *u, void *ctx) 646d71ae5a4SJacob Faibussowitsch { 647c4762a1bSJed Brown PetscInt i; 648c4762a1bSJed Brown Physics phys = (Physics)ctx; 649c4762a1bSJed Brown Physics_Euler *eu = (Physics_Euler *)phys->data; 650c4762a1bSJed Brown EulerNode *uu = (EulerNode *)u; 651c4762a1bSJed Brown PetscReal p0, gamma, c; 652c4762a1bSJed Brown PetscFunctionBeginUser; 65354c59aa7SJacob Faibussowitsch PetscCheck(time == 0.0, mod->comm, PETSC_ERR_SUP, "No solution known for time %g", (double)time); 654c4762a1bSJed Brown 655c4762a1bSJed Brown for (i = 0; i < DIM; i++) uu->ru[i] = 0.0; /* zero out initial velocity */ 656c4762a1bSJed Brown /* set E and rho */ 657c4762a1bSJed Brown gamma = eu->pars[EULER_PAR_GAMMA]; 658c4762a1bSJed Brown 659c4762a1bSJed Brown if (eu->type == EULER_IV_SHOCK || eu->type == EULER_SS_SHOCK) { 660c4762a1bSJed Brown /******************* Euler Density Shock ********************/ 661c4762a1bSJed Brown /* On initial-value and self-similar solutions of the compressible Euler equations */ 662c4762a1bSJed Brown /* Ravi Samtaney and D. I. Pullin */ 663c4762a1bSJed Brown /* Phys. Fluids 8, 2650 (1996); http://dx.doi.org/10.1063/1.869050 */ 664c4762a1bSJed Brown /* initial conditions 1: left of shock, 0: left of discontinuity 2: right of discontinuity, */ 665c4762a1bSJed Brown p0 = 1.; 666c4762a1bSJed Brown if (x[0] < 0.0 + x[1] * eu->pars[EULER_PAR_ITANA]) { 667c4762a1bSJed Brown if (x[0] < mod->bounds[0] * 0.5) { /* left of shock (1) */ 668c4762a1bSJed Brown PetscReal amach, rho, press, gas1, p1; 669c4762a1bSJed Brown amach = eu->pars[EULER_PAR_AMACH]; 670c4762a1bSJed Brown rho = 1.; 671c4762a1bSJed Brown press = p0; 672c4762a1bSJed Brown p1 = press * (1.0 + 2.0 * gamma / (gamma + 1.0) * (amach * amach - 1.0)); 673c4762a1bSJed Brown gas1 = (gamma - 1.0) / (gamma + 1.0); 674c4762a1bSJed Brown uu->r = rho * (p1 / press + gas1) / (gas1 * p1 / press + 1.0); 675c4762a1bSJed Brown uu->ru[0] = ((uu->r - rho) * PetscSqrtReal(gamma * press / rho) * amach); 676c4762a1bSJed Brown uu->E = p1 / (gamma - 1.0) + .5 / uu->r * uu->ru[0] * uu->ru[0]; 6779371c9d4SSatish Balay } else { /* left of discontinuity (0) */ 678c4762a1bSJed Brown uu->r = 1.; /* rho = 1 */ 679c4762a1bSJed Brown uu->E = p0 / (gamma - 1.0); 680c4762a1bSJed Brown } 6819371c9d4SSatish Balay } else { /* right of discontinuity (2) */ 682c4762a1bSJed Brown uu->r = eu->pars[EULER_PAR_RHOR]; 683c4762a1bSJed Brown uu->E = p0 / (gamma - 1.0); 684c4762a1bSJed Brown } 6859371c9d4SSatish Balay } else if (eu->type == EULER_SHOCK_TUBE) { 686c4762a1bSJed Brown /* For (x<x0) set (rho,u,p)=(8,0,10) and for (x>x0) set (rho,u,p)=(1,0,1). Choose x0 to the midpoint of the domain in the x-direction. */ 687c4762a1bSJed Brown if (x[0] < 0.0) { 688c4762a1bSJed Brown uu->r = 8.; 689c4762a1bSJed Brown uu->E = 10. / (gamma - 1.); 6909371c9d4SSatish Balay } else { 691c4762a1bSJed Brown uu->r = 1.; 692c4762a1bSJed Brown uu->E = 1. / (gamma - 1.); 693c4762a1bSJed Brown } 6949371c9d4SSatish Balay } else if (eu->type == EULER_LINEAR_WAVE) { 695c4762a1bSJed Brown initLinearWave(uu, gamma, x, mod->bounds[1] - mod->bounds[0]); 6969371c9d4SSatish Balay } else SETERRQ(mod->comm, PETSC_ERR_SUP, "Unknown type %d", eu->type); 697c4762a1bSJed Brown 698c4762a1bSJed Brown /* set phys->maxspeed: (mod->maxspeed = phys->maxspeed) in main; */ 6993ba16761SJacob Faibussowitsch PetscCall(eu->sound(&gamma, uu, &c)); 700c4762a1bSJed Brown c = (uu->ru[0] / uu->r) + c; 701c4762a1bSJed Brown if (c > phys->maxspeed) phys->maxspeed = c; 702c4762a1bSJed Brown 7033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 704c4762a1bSJed Brown } 705c4762a1bSJed Brown 706d71ae5a4SJacob Faibussowitsch static PetscErrorCode Pressure_PG(const PetscReal gamma, const EulerNode *x, PetscReal *p) 707d71ae5a4SJacob Faibussowitsch { 708c4762a1bSJed Brown PetscReal ru2; 709c4762a1bSJed Brown 710c4762a1bSJed Brown PetscFunctionBeginUser; 711c4762a1bSJed Brown ru2 = DotDIMReal(x->ru, x->ru); 712c4762a1bSJed Brown (*p) = (x->E - 0.5 * ru2 / x->r) * (gamma - 1.0); /* (E - rho V^2/2)(gamma-1) = e rho (gamma-1) */ 7133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 714c4762a1bSJed Brown } 715c4762a1bSJed Brown 716d71ae5a4SJacob Faibussowitsch static PetscErrorCode SpeedOfSound_PG(const PetscReal *gamma, const EulerNode *x, PetscReal *c) 717d71ae5a4SJacob Faibussowitsch { 718c4762a1bSJed Brown PetscReal p; 719c4762a1bSJed Brown 720c4762a1bSJed Brown PetscFunctionBeginUser; 7213ba16761SJacob Faibussowitsch PetscCall(Pressure_PG(*gamma, x, &p)); 72254c59aa7SJacob Faibussowitsch PetscCheck(p >= 0., PETSC_COMM_WORLD, PETSC_ERR_SUP, "negative pressure time %g -- NEED TO FIX!!!!!!", (double)p); 723c4762a1bSJed Brown /* pars[EULER_PAR_GAMMA] = heat capacity ratio */ 724c4762a1bSJed Brown (*c) = PetscSqrtReal(*gamma * p / x->r); 7253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 726c4762a1bSJed Brown } 727c4762a1bSJed Brown 728c4762a1bSJed Brown /* 729c4762a1bSJed Brown * x = (rho,rho*(u_1),...,rho*e)^T 730c4762a1bSJed Brown * x_t+div(f_1(x))+...+div(f_DIM(x)) = 0 731c4762a1bSJed Brown * 732c4762a1bSJed Brown * f_i(x) = u_i*x+(0,0,...,p,...,p*u_i)^T 733c4762a1bSJed Brown * 734c4762a1bSJed Brown */ 735d71ae5a4SJacob Faibussowitsch static PetscErrorCode EulerFlux(Physics phys, const PetscReal *n, const EulerNode *x, EulerNode *f) 736d71ae5a4SJacob Faibussowitsch { 737c4762a1bSJed Brown Physics_Euler *eu = (Physics_Euler *)phys->data; 738c4762a1bSJed Brown PetscReal nu, p; 739c4762a1bSJed Brown PetscInt i; 740c4762a1bSJed Brown 741c4762a1bSJed Brown PetscFunctionBeginUser; 7423ba16761SJacob Faibussowitsch PetscCall(Pressure_PG(eu->pars[EULER_PAR_GAMMA], x, &p)); 743c4762a1bSJed Brown nu = DotDIMReal(x->ru, n); 744c4762a1bSJed Brown f->r = nu; /* A rho u */ 745c4762a1bSJed Brown nu /= x->r; /* A u */ 746c4762a1bSJed Brown for (i = 0; i < DIM; i++) f->ru[i] = nu * x->ru[i] + n[i] * p; /* r u^2 + p */ 747c4762a1bSJed Brown f->E = nu * (x->E + p); /* u(e+p) */ 7483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 749c4762a1bSJed Brown } 750c4762a1bSJed Brown 751c4762a1bSJed Brown /* PetscReal* => EulerNode* conversion */ 752d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsBoundary_Euler_Wall(PetscReal time, const PetscReal *c, const PetscReal *n, const PetscScalar *a_xI, PetscScalar *a_xG, void *ctx) 753d71ae5a4SJacob Faibussowitsch { 754c4762a1bSJed Brown PetscInt i; 755c4762a1bSJed Brown const EulerNode *xI = (const EulerNode *)a_xI; 756c4762a1bSJed Brown EulerNode *xG = (EulerNode *)a_xG; 757c4762a1bSJed Brown Physics phys = (Physics)ctx; 758c4762a1bSJed Brown Physics_Euler *eu = (Physics_Euler *)phys->data; 759c4762a1bSJed Brown PetscFunctionBeginUser; 760c4762a1bSJed Brown xG->r = xI->r; /* ghost cell density - same */ 761c4762a1bSJed Brown xG->E = xI->E; /* ghost cell energy - same */ 762c4762a1bSJed Brown if (n[1] != 0.) { /* top and bottom */ 763c4762a1bSJed Brown xG->ru[0] = xI->ru[0]; /* copy tang to wall */ 764c4762a1bSJed Brown xG->ru[1] = -xI->ru[1]; /* reflect perp to t/b wall */ 7659371c9d4SSatish Balay } else { /* sides */ 766c4762a1bSJed Brown for (i = 0; i < DIM; i++) xG->ru[i] = xI->ru[i]; /* copy */ 767c4762a1bSJed Brown } 768c4762a1bSJed Brown if (eu->type == EULER_LINEAR_WAVE) { /* debug */ 769c4762a1bSJed Brown #if 0 77063a3b9bcSJacob Faibussowitsch PetscPrintf(PETSC_COMM_WORLD,"%s coord=%g,%g\n",PETSC_FUNCTION_NAME,(double)c[0],(double)c[1]); 771c4762a1bSJed Brown #endif 772c4762a1bSJed Brown } 7733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 774c4762a1bSJed Brown } 775c4762a1bSJed Brown int godunovflux(const PetscScalar *ul, const PetscScalar *ur, PetscScalar *flux, const PetscReal *nn, const int *ndim, const PetscReal *gamma); 776c4762a1bSJed Brown /* PetscReal* => EulerNode* conversion */ 777d71ae5a4SJacob Faibussowitsch static void PhysicsRiemann_Euler_Godunov(PetscInt dim, PetscInt Nf, const PetscReal *qp, const PetscReal *n, const PetscScalar *xL, const PetscScalar *xR, PetscInt numConstants, const PetscScalar constants[], PetscScalar *flux, Physics phys) 778d71ae5a4SJacob Faibussowitsch { 779c4762a1bSJed Brown Physics_Euler *eu = (Physics_Euler *)phys->data; 780c4762a1bSJed Brown PetscReal cL, cR, speed, velL, velR, nn[DIM], s2; 781c4762a1bSJed Brown PetscInt i; 782c4762a1bSJed Brown PetscErrorCode ierr; 783c4762a1bSJed Brown 784d0609cedSBarry Smith PetscFunctionBeginUser; 785c4762a1bSJed Brown for (i = 0, s2 = 0.; i < DIM; i++) { 786c4762a1bSJed Brown nn[i] = n[i]; 787c4762a1bSJed Brown s2 += nn[i] * nn[i]; 788c4762a1bSJed Brown } 789c4762a1bSJed Brown s2 = PetscSqrtReal(s2); /* |n|_2 = sum(n^2)^1/2 */ 790c4762a1bSJed Brown for (i = 0.; i < DIM; i++) nn[i] /= s2; 791c4762a1bSJed Brown if (0) { /* Rusanov */ 792c4762a1bSJed Brown const EulerNode *uL = (const EulerNode *)xL, *uR = (const EulerNode *)xR; 793c4762a1bSJed Brown EulerNodeUnion fL, fR; 7943ba16761SJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF, EulerFlux(phys, nn, uL, &(fL.eulernode))); 7953ba16761SJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF, EulerFlux(phys, nn, uR, &(fR.eulernode))); 7969371c9d4SSatish Balay ierr = eu->sound(&eu->pars[EULER_PAR_GAMMA], uL, &cL); 7979371c9d4SSatish Balay if (ierr) exit(13); 7989371c9d4SSatish Balay ierr = eu->sound(&eu->pars[EULER_PAR_GAMMA], uR, &cR); 7999371c9d4SSatish Balay if (ierr) exit(14); 800c4762a1bSJed Brown velL = DotDIMReal(uL->ru, nn) / uL->r; 801c4762a1bSJed Brown velR = DotDIMReal(uR->ru, nn) / uR->r; 802c4762a1bSJed Brown speed = PetscMax(velR + cR, velL + cL); 803c4762a1bSJed Brown for (i = 0; i < 2 + dim; i++) flux[i] = 0.5 * ((fL.vals[i] + fR.vals[i]) + speed * (xL[i] - xR[i])) * s2; 8049371c9d4SSatish Balay } else { 805c4762a1bSJed Brown int dim = DIM; 806c4762a1bSJed Brown /* int iwave = */ 807c4762a1bSJed Brown godunovflux(xL, xR, flux, nn, &dim, &eu->pars[EULER_PAR_GAMMA]); 808c4762a1bSJed Brown for (i = 0; i < 2 + dim; i++) flux[i] *= s2; 809c4762a1bSJed Brown } 810c4762a1bSJed Brown PetscFunctionReturnVoid(); 811c4762a1bSJed Brown } 812c4762a1bSJed Brown 813d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsFunctional_Euler(Model mod, PetscReal time, const PetscReal *coord, const PetscScalar *xx, PetscReal *f, void *ctx) 814d71ae5a4SJacob Faibussowitsch { 815c4762a1bSJed Brown Physics phys = (Physics)ctx; 816c4762a1bSJed Brown Physics_Euler *eu = (Physics_Euler *)phys->data; 817c4762a1bSJed Brown const EulerNode *x = (const EulerNode *)xx; 818c4762a1bSJed Brown PetscReal p; 819c4762a1bSJed Brown 820c4762a1bSJed Brown PetscFunctionBeginUser; 821c4762a1bSJed Brown f[eu->monitor.Density] = x->r; 822c4762a1bSJed Brown f[eu->monitor.Momentum] = NormDIM(x->ru); 823c4762a1bSJed Brown f[eu->monitor.Energy] = x->E; 824c4762a1bSJed Brown f[eu->monitor.Speed] = NormDIM(x->ru) / x->r; 8253ba16761SJacob Faibussowitsch PetscCall(Pressure_PG(eu->pars[EULER_PAR_GAMMA], x, &p)); 826c4762a1bSJed Brown f[eu->monitor.Pressure] = p; 8273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 828c4762a1bSJed Brown } 829c4762a1bSJed Brown 830d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetUpBC_Euler(DM dm, PetscDS prob, Physics phys) 831d71ae5a4SJacob Faibussowitsch { 832c4762a1bSJed Brown Physics_Euler *eu = (Physics_Euler *)phys->data; 83345480ffeSMatthew G. Knepley DMLabel label; 83445480ffeSMatthew G. Knepley 835362febeeSStefano Zampini PetscFunctionBeginUser; 8369566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "Face Sets", &label)); 837c4762a1bSJed Brown if (eu->type == EULER_LINEAR_WAVE) { 838c4762a1bSJed Brown const PetscInt wallids[] = {100, 101}; 839dd39110bSPierre Jolivet PetscCall(PetscDSAddBoundary(prob, DM_BC_NATURAL_RIEMANN, "wall", label, PETSC_STATIC_ARRAY_LENGTH(wallids), wallids, 0, 0, NULL, (void (*)(void))PhysicsBoundary_Euler_Wall, NULL, phys, NULL)); 8409371c9d4SSatish Balay } else { 841c4762a1bSJed Brown const PetscInt wallids[] = {100, 101, 200, 300}; 842dd39110bSPierre Jolivet PetscCall(PetscDSAddBoundary(prob, DM_BC_NATURAL_RIEMANN, "wall", label, PETSC_STATIC_ARRAY_LENGTH(wallids), wallids, 0, 0, NULL, (void (*)(void))PhysicsBoundary_Euler_Wall, NULL, phys, NULL)); 843c4762a1bSJed Brown } 8443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 845c4762a1bSJed Brown } 846c4762a1bSJed Brown 847d71ae5a4SJacob Faibussowitsch static PetscErrorCode PhysicsCreate_Euler(Model mod, Physics phys, PetscOptionItems *PetscOptionsObject) 848d71ae5a4SJacob Faibussowitsch { 849c4762a1bSJed Brown Physics_Euler *eu; 850c4762a1bSJed Brown 851c4762a1bSJed Brown PetscFunctionBeginUser; 852c4762a1bSJed Brown phys->field_desc = PhysicsFields_Euler; 853c4762a1bSJed Brown phys->riemann = (PetscRiemannFunc)PhysicsRiemann_Euler_Godunov; 8549566063dSJacob Faibussowitsch PetscCall(PetscNew(&eu)); 855c4762a1bSJed Brown phys->data = eu; 856c4762a1bSJed Brown mod->setupbc = SetUpBC_Euler; 857d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "Euler options"); 858c4762a1bSJed Brown { 859c4762a1bSJed Brown PetscReal alpha; 860c4762a1bSJed Brown char type[64] = "linear_wave"; 861c4762a1bSJed Brown PetscBool is; 862c4762a1bSJed Brown eu->pars[EULER_PAR_GAMMA] = 1.4; 863c4762a1bSJed Brown eu->pars[EULER_PAR_AMACH] = 2.02; 864c4762a1bSJed Brown eu->pars[EULER_PAR_RHOR] = 3.0; 865c4762a1bSJed Brown eu->pars[EULER_PAR_ITANA] = 0.57735026918963; /* angle of Euler self similar (SS) shock */ 8669566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-eu_gamma", "Heat capacity ratio", "", eu->pars[EULER_PAR_GAMMA], &eu->pars[EULER_PAR_GAMMA], NULL)); 8679566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-eu_amach", "Shock speed (Mach)", "", eu->pars[EULER_PAR_AMACH], &eu->pars[EULER_PAR_AMACH], NULL)); 8689566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-eu_rho2", "Density right of discontinuity", "", eu->pars[EULER_PAR_RHOR], &eu->pars[EULER_PAR_RHOR], NULL)); 869c4762a1bSJed Brown alpha = 60.; 8709566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-eu_alpha", "Angle of discontinuity", "", alpha, &alpha, NULL)); 87163a3b9bcSJacob Faibussowitsch PetscCheck(alpha > 0. && alpha <= 90., PETSC_COMM_WORLD, PETSC_ERR_SUP, "Alpha bust be > 0 and <= 90 (%g)", (double)alpha); 872c4762a1bSJed Brown eu->pars[EULER_PAR_ITANA] = 1. / PetscTanReal(alpha * PETSC_PI / 180.0); 8739566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-eu_type", "Type of Euler test", "", type, type, sizeof(type), NULL)); 8749566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, "linear_wave", &is)); 875c4762a1bSJed Brown if (is) { 87630602db0SMatthew G. Knepley /* Remember this should be periodic */ 877c4762a1bSJed Brown eu->type = EULER_LINEAR_WAVE; 8789566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%s set Euler type: %s\n", PETSC_FUNCTION_NAME, "linear_wave")); 8799371c9d4SSatish Balay } else { 88054c59aa7SJacob Faibussowitsch PetscCheck(DIM == 2, PETSC_COMM_WORLD, PETSC_ERR_SUP, "DIM must be 2 unless linear wave test %s", type); 8819566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, "iv_shock", &is)); 882c4762a1bSJed Brown if (is) { 883c4762a1bSJed Brown eu->type = EULER_IV_SHOCK; 8849566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%s set Euler type: %s\n", PETSC_FUNCTION_NAME, "iv_shock")); 8859371c9d4SSatish Balay } else { 8869566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, "ss_shock", &is)); 887c4762a1bSJed Brown if (is) { 888c4762a1bSJed Brown eu->type = EULER_SS_SHOCK; 8899566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%s set Euler type: %s\n", PETSC_FUNCTION_NAME, "ss_shock")); 8909371c9d4SSatish Balay } else { 8919566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, "shock_tube", &is)); 892c4762a1bSJed Brown if (is) eu->type = EULER_SHOCK_TUBE; 89398921bdaSJacob Faibussowitsch else SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "Unknown Euler type %s", type); 8949566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%s set Euler type: %s\n", PETSC_FUNCTION_NAME, "shock_tube")); 895c4762a1bSJed Brown } 896c4762a1bSJed Brown } 897c4762a1bSJed Brown } 898c4762a1bSJed Brown } 899d0609cedSBarry Smith PetscOptionsHeadEnd(); 900c4762a1bSJed Brown eu->sound = SpeedOfSound_PG; 901c4762a1bSJed Brown phys->maxspeed = 0.; /* will get set in solution */ 9029566063dSJacob Faibussowitsch PetscCall(ModelSolutionSetDefault(mod, PhysicsSolution_Euler, phys)); 9039566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Speed", &eu->monitor.Speed, PhysicsFunctional_Euler, phys)); 9049566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Energy", &eu->monitor.Energy, PhysicsFunctional_Euler, phys)); 9059566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Density", &eu->monitor.Density, PhysicsFunctional_Euler, phys)); 9069566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Momentum", &eu->monitor.Momentum, PhysicsFunctional_Euler, phys)); 9079566063dSJacob Faibussowitsch PetscCall(ModelFunctionalRegister(mod, "Pressure", &eu->monitor.Pressure, PhysicsFunctional_Euler, phys)); 908c4762a1bSJed Brown 9093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 910c4762a1bSJed Brown } 911c4762a1bSJed Brown 912d71ae5a4SJacob Faibussowitsch static PetscErrorCode ErrorIndicator_Simple(PetscInt dim, PetscReal volume, PetscInt numComps, const PetscScalar u[], const PetscScalar grad[], PetscReal *error, void *ctx) 913d71ae5a4SJacob Faibussowitsch { 914c4762a1bSJed Brown PetscReal err = 0.; 915c4762a1bSJed Brown PetscInt i, j; 916c4762a1bSJed Brown 917c4762a1bSJed Brown PetscFunctionBeginUser; 918c4762a1bSJed Brown for (i = 0; i < numComps; i++) { 919ad540459SPierre Jolivet for (j = 0; j < dim; j++) err += PetscSqr(PetscRealPart(grad[i * dim + j])); 920c4762a1bSJed Brown } 921c4762a1bSJed Brown *error = volume * err; 9223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 923c4762a1bSJed Brown } 924c4762a1bSJed Brown 925d71ae5a4SJacob Faibussowitsch PetscErrorCode CreatePartitionVec(DM dm, DM *dmCell, Vec *partition) 926d71ae5a4SJacob Faibussowitsch { 927c4762a1bSJed Brown PetscSF sfPoint; 928c4762a1bSJed Brown PetscSection coordSection; 929c4762a1bSJed Brown Vec coordinates; 930c4762a1bSJed Brown PetscSection sectionCell; 931c4762a1bSJed Brown PetscScalar *part; 932c4762a1bSJed Brown PetscInt cStart, cEnd, c; 933c4762a1bSJed Brown PetscMPIInt rank; 934c4762a1bSJed Brown 935c4762a1bSJed Brown PetscFunctionBeginUser; 9369566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateSection(dm, &coordSection)); 9379566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coordinates)); 9389566063dSJacob Faibussowitsch PetscCall(DMClone(dm, dmCell)); 9399566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm, &sfPoint)); 9409566063dSJacob Faibussowitsch PetscCall(DMSetPointSF(*dmCell, sfPoint)); 9419566063dSJacob Faibussowitsch PetscCall(DMSetCoordinateSection(*dmCell, PETSC_DETERMINE, coordSection)); 9429566063dSJacob Faibussowitsch PetscCall(DMSetCoordinatesLocal(*dmCell, coordinates)); 9439566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 9449566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ionCell)); 9459566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(*dmCell, 0, &cStart, &cEnd)); 9469566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(sectionCell, cStart, cEnd)); 94748a46eb9SPierre Jolivet for (c = cStart; c < cEnd; ++c) PetscCall(PetscSectionSetDof(sectionCell, c, 1)); 9489566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(sectionCell)); 9499566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(*dmCell, sectionCell)); 9509566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(§ionCell)); 9519566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(*dmCell, partition)); 9529566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*partition, "partition")); 9539566063dSJacob Faibussowitsch PetscCall(VecGetArray(*partition, &part)); 954c4762a1bSJed Brown for (c = cStart; c < cEnd; ++c) { 955c4762a1bSJed Brown PetscScalar *p; 956c4762a1bSJed Brown 9579566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRef(*dmCell, c, part, &p)); 958c4762a1bSJed Brown p[0] = rank; 959c4762a1bSJed Brown } 9609566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(*partition, &part)); 9613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 962c4762a1bSJed Brown } 963c4762a1bSJed Brown 964d71ae5a4SJacob Faibussowitsch PetscErrorCode CreateMassMatrix(DM dm, Vec *massMatrix, User user) 965d71ae5a4SJacob Faibussowitsch { 9663e9753d6SMatthew G. Knepley DM plex, dmMass, dmFace, dmCell, dmCoord; 967c4762a1bSJed Brown PetscSection coordSection; 968c4762a1bSJed Brown Vec coordinates, facegeom, cellgeom; 969c4762a1bSJed Brown PetscSection sectionMass; 970c4762a1bSJed Brown PetscScalar *m; 971c4762a1bSJed Brown const PetscScalar *fgeom, *cgeom, *coords; 972c4762a1bSJed Brown PetscInt vStart, vEnd, v; 973c4762a1bSJed Brown 974c4762a1bSJed Brown PetscFunctionBeginUser; 9759566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 9769566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateSection(dm, &coordSection)); 9779566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coordinates)); 9789566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dmMass)); 9799566063dSJacob Faibussowitsch PetscCall(DMSetCoordinateSection(dmMass, PETSC_DETERMINE, coordSection)); 9809566063dSJacob Faibussowitsch PetscCall(DMSetCoordinatesLocal(dmMass, coordinates)); 9819566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ionMass)); 9829566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 9839566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(sectionMass, vStart, vEnd)); 984c4762a1bSJed Brown for (v = vStart; v < vEnd; ++v) { 985c4762a1bSJed Brown PetscInt numFaces; 986c4762a1bSJed Brown 9879566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupportSize(dmMass, v, &numFaces)); 9889566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(sectionMass, v, numFaces * numFaces)); 989c4762a1bSJed Brown } 9909566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(sectionMass)); 9919566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dmMass, sectionMass)); 9929566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(§ionMass)); 9939566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dmMass, massMatrix)); 9949566063dSJacob Faibussowitsch PetscCall(VecGetArray(*massMatrix, &m)); 9959566063dSJacob Faibussowitsch PetscCall(DMPlexGetGeometryFVM(plex, &facegeom, &cellgeom, NULL)); 9969566063dSJacob Faibussowitsch PetscCall(VecGetDM(facegeom, &dmFace)); 9979566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(facegeom, &fgeom)); 9989566063dSJacob Faibussowitsch PetscCall(VecGetDM(cellgeom, &dmCell)); 9999566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(cellgeom, &cgeom)); 10009566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(dm, &dmCoord)); 10019566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(coordinates, &coords)); 1002c4762a1bSJed Brown for (v = vStart; v < vEnd; ++v) { 1003c4762a1bSJed Brown const PetscInt *faces; 1004c4762a1bSJed Brown PetscFVFaceGeom *fgA, *fgB, *cg; 1005c4762a1bSJed Brown PetscScalar *vertex; 1006c4762a1bSJed Brown PetscInt numFaces, sides[2], f, g; 1007c4762a1bSJed Brown 10089566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmCoord, v, coords, &vertex)); 10099566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupportSize(dmMass, v, &numFaces)); 10109566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dmMass, v, &faces)); 1011c4762a1bSJed Brown for (f = 0; f < numFaces; ++f) { 1012c4762a1bSJed Brown sides[0] = faces[f]; 10139566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fgA)); 1014c4762a1bSJed Brown for (g = 0; g < numFaces; ++g) { 1015c4762a1bSJed Brown const PetscInt *cells = NULL; 1016c4762a1bSJed Brown PetscReal area = 0.0; 1017c4762a1bSJed Brown PetscInt numCells; 1018c4762a1bSJed Brown 1019c4762a1bSJed Brown sides[1] = faces[g]; 10209566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmFace, faces[g], fgeom, &fgB)); 10219566063dSJacob Faibussowitsch PetscCall(DMPlexGetJoin(dmMass, 2, sides, &numCells, &cells)); 102254c59aa7SJacob Faibussowitsch PetscCheck(numCells == 1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Invalid join for faces"); 10239566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmCell, cells[0], cgeom, &cg)); 1024c4762a1bSJed Brown area += PetscAbsScalar((vertex[0] - cg->centroid[0]) * (fgA->centroid[1] - cg->centroid[1]) - (vertex[1] - cg->centroid[1]) * (fgA->centroid[0] - cg->centroid[0])); 1025c4762a1bSJed Brown area += PetscAbsScalar((vertex[0] - cg->centroid[0]) * (fgB->centroid[1] - cg->centroid[1]) - (vertex[1] - cg->centroid[1]) * (fgB->centroid[0] - cg->centroid[0])); 1026c4762a1bSJed Brown m[f * numFaces + g] = Dot2Real(fgA->normal, fgB->normal) * area * 0.5; 10279566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreJoin(dmMass, 2, sides, &numCells, &cells)); 1028c4762a1bSJed Brown } 1029c4762a1bSJed Brown } 1030c4762a1bSJed Brown } 10319566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(facegeom, &fgeom)); 10329566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(cellgeom, &cgeom)); 10339566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(coordinates, &coords)); 10349566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(*massMatrix, &m)); 10359566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmMass)); 10369566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 10373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1038c4762a1bSJed Brown } 1039c4762a1bSJed Brown 1040c4762a1bSJed Brown /* Behavior will be different for multi-physics or when using non-default boundary conditions */ 1041d71ae5a4SJacob Faibussowitsch static PetscErrorCode ModelSolutionSetDefault(Model mod, SolutionFunction func, void *ctx) 1042d71ae5a4SJacob Faibussowitsch { 1043c4762a1bSJed Brown PetscFunctionBeginUser; 1044c4762a1bSJed Brown mod->solution = func; 1045c4762a1bSJed Brown mod->solutionctx = ctx; 10463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1047c4762a1bSJed Brown } 1048c4762a1bSJed Brown 1049d71ae5a4SJacob Faibussowitsch static PetscErrorCode ModelFunctionalRegister(Model mod, const char *name, PetscInt *offset, FunctionalFunction func, void *ctx) 1050d71ae5a4SJacob Faibussowitsch { 1051c4762a1bSJed Brown FunctionalLink link, *ptr; 1052c4762a1bSJed Brown PetscInt lastoffset = -1; 1053c4762a1bSJed Brown 1054c4762a1bSJed Brown PetscFunctionBeginUser; 1055c4762a1bSJed Brown for (ptr = &mod->functionalRegistry; *ptr; ptr = &(*ptr)->next) lastoffset = (*ptr)->offset; 10569566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 10579566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &link->name)); 1058c4762a1bSJed Brown link->offset = lastoffset + 1; 1059c4762a1bSJed Brown link->func = func; 1060c4762a1bSJed Brown link->ctx = ctx; 1061c4762a1bSJed Brown link->next = NULL; 1062c4762a1bSJed Brown *ptr = link; 1063c4762a1bSJed Brown *offset = link->offset; 10643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1065c4762a1bSJed Brown } 1066c4762a1bSJed Brown 1067d71ae5a4SJacob Faibussowitsch static PetscErrorCode ModelFunctionalSetFromOptions(Model mod, PetscOptionItems *PetscOptionsObject) 1068d71ae5a4SJacob Faibussowitsch { 1069c4762a1bSJed Brown PetscInt i, j; 1070c4762a1bSJed Brown FunctionalLink link; 1071c4762a1bSJed Brown char *names[256]; 1072c4762a1bSJed Brown 1073c4762a1bSJed Brown PetscFunctionBeginUser; 1074dd39110bSPierre Jolivet mod->numMonitored = PETSC_STATIC_ARRAY_LENGTH(names); 10759566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringArray("-monitor", "list of functionals to monitor", "", names, &mod->numMonitored, NULL)); 1076c4762a1bSJed Brown /* Create list of functionals that will be computed somehow */ 10779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mod->numMonitored, &mod->functionalMonitored)); 1078c4762a1bSJed Brown /* Create index of calls that we will have to make to compute these functionals (over-allocation in general). */ 10799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mod->numMonitored, &mod->functionalCall)); 1080c4762a1bSJed Brown mod->numCall = 0; 1081c4762a1bSJed Brown for (i = 0; i < mod->numMonitored; i++) { 1082c4762a1bSJed Brown for (link = mod->functionalRegistry; link; link = link->next) { 1083c4762a1bSJed Brown PetscBool match; 10849566063dSJacob Faibussowitsch PetscCall(PetscStrcasecmp(names[i], link->name, &match)); 1085c4762a1bSJed Brown if (match) break; 1086c4762a1bSJed Brown } 108754c59aa7SJacob Faibussowitsch PetscCheck(link, mod->comm, PETSC_ERR_USER, "No known functional '%s'", names[i]); 1088c4762a1bSJed Brown mod->functionalMonitored[i] = link; 1089c4762a1bSJed Brown for (j = 0; j < i; j++) { 1090c4762a1bSJed Brown if (mod->functionalCall[j]->func == link->func && mod->functionalCall[j]->ctx == link->ctx) goto next_name; 1091c4762a1bSJed Brown } 1092c4762a1bSJed Brown mod->functionalCall[mod->numCall++] = link; /* Just points to the first link using the result. There may be more results. */ 1093c4762a1bSJed Brown next_name: 10949566063dSJacob Faibussowitsch PetscCall(PetscFree(names[i])); 1095c4762a1bSJed Brown } 1096c4762a1bSJed Brown 1097c4762a1bSJed Brown /* Find out the maximum index of any functional computed by a function we will be calling (even if we are not using it) */ 1098c4762a1bSJed Brown mod->maxComputed = -1; 1099c4762a1bSJed Brown for (link = mod->functionalRegistry; link; link = link->next) { 1100c4762a1bSJed Brown for (i = 0; i < mod->numCall; i++) { 1101c4762a1bSJed Brown FunctionalLink call = mod->functionalCall[i]; 1102ad540459SPierre Jolivet if (link->func == call->func && link->ctx == call->ctx) mod->maxComputed = PetscMax(mod->maxComputed, link->offset); 1103c4762a1bSJed Brown } 1104c4762a1bSJed Brown } 11053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1106c4762a1bSJed Brown } 1107c4762a1bSJed Brown 1108d71ae5a4SJacob Faibussowitsch static PetscErrorCode FunctionalLinkDestroy(FunctionalLink *link) 1109d71ae5a4SJacob Faibussowitsch { 1110c4762a1bSJed Brown FunctionalLink l, next; 1111c4762a1bSJed Brown 1112c4762a1bSJed Brown PetscFunctionBeginUser; 11133ba16761SJacob Faibussowitsch if (!link) PetscFunctionReturn(PETSC_SUCCESS); 1114c4762a1bSJed Brown l = *link; 1115c4762a1bSJed Brown *link = NULL; 1116c4762a1bSJed Brown for (; l; l = next) { 1117c4762a1bSJed Brown next = l->next; 11189566063dSJacob Faibussowitsch PetscCall(PetscFree(l->name)); 11199566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 1120c4762a1bSJed Brown } 11213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1122c4762a1bSJed Brown } 1123c4762a1bSJed Brown 1124c4762a1bSJed Brown /* put the solution callback into a functional callback */ 1125d71ae5a4SJacob Faibussowitsch static PetscErrorCode SolutionFunctional(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *modctx) 1126d71ae5a4SJacob Faibussowitsch { 1127c4762a1bSJed Brown Model mod; 11287510d9b0SBarry Smith PetscFunctionBeginUser; 1129c4762a1bSJed Brown mod = (Model)modctx; 11309566063dSJacob Faibussowitsch PetscCall((*mod->solution)(mod, time, x, u, mod->solutionctx)); 11313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1132c4762a1bSJed Brown } 1133c4762a1bSJed Brown 1134d71ae5a4SJacob Faibussowitsch PetscErrorCode SetInitialCondition(DM dm, Vec X, User user) 1135d71ae5a4SJacob Faibussowitsch { 1136c4762a1bSJed Brown PetscErrorCode (*func[1])(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 1137c4762a1bSJed Brown void *ctx[1]; 1138c4762a1bSJed Brown Model mod = user->model; 1139c4762a1bSJed Brown 1140c4762a1bSJed Brown PetscFunctionBeginUser; 1141c4762a1bSJed Brown func[0] = SolutionFunctional; 1142c4762a1bSJed Brown ctx[0] = (void *)mod; 11439566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, 0.0, func, ctx, INSERT_ALL_VALUES, X)); 11443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1145c4762a1bSJed Brown } 1146c4762a1bSJed Brown 1147d71ae5a4SJacob Faibussowitsch static PetscErrorCode OutputVTK(DM dm, const char *filename, PetscViewer *viewer) 1148d71ae5a4SJacob Faibussowitsch { 1149c4762a1bSJed Brown PetscFunctionBeginUser; 11509566063dSJacob Faibussowitsch PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)dm), viewer)); 11519566063dSJacob Faibussowitsch PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERVTK)); 11529566063dSJacob Faibussowitsch PetscCall(PetscViewerFileSetName(*viewer, filename)); 11533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1154c4762a1bSJed Brown } 1155c4762a1bSJed Brown 1156d71ae5a4SJacob Faibussowitsch static PetscErrorCode MonitorVTK(TS ts, PetscInt stepnum, PetscReal time, Vec X, void *ctx) 1157d71ae5a4SJacob Faibussowitsch { 1158c4762a1bSJed Brown User user = (User)ctx; 11593e9753d6SMatthew G. Knepley DM dm, plex; 1160c4762a1bSJed Brown PetscViewer viewer; 1161c4762a1bSJed Brown char filename[PETSC_MAX_PATH_LEN], *ftable = NULL; 1162c4762a1bSJed Brown PetscReal xnorm; 1163c4762a1bSJed Brown 1164c4762a1bSJed Brown PetscFunctionBeginUser; 11659566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)X, "u")); 11669566063dSJacob Faibussowitsch PetscCall(VecGetDM(X, &dm)); 11679566063dSJacob Faibussowitsch PetscCall(VecNorm(X, NORM_INFINITY, &xnorm)); 1168c4762a1bSJed Brown 1169ad540459SPierre Jolivet if (stepnum >= 0) stepnum += user->monitorStepOffset; 1170c4762a1bSJed Brown if (stepnum >= 0) { /* No summary for final time */ 1171c4762a1bSJed Brown Model mod = user->model; 11723e9753d6SMatthew G. Knepley Vec cellgeom; 1173c4762a1bSJed Brown PetscInt c, cStart, cEnd, fcount, i; 1174c4762a1bSJed Brown size_t ftableused, ftablealloc; 1175c4762a1bSJed Brown const PetscScalar *cgeom, *x; 1176c4762a1bSJed Brown DM dmCell; 1177c4762a1bSJed Brown DMLabel vtkLabel; 1178c4762a1bSJed Brown PetscReal *fmin, *fmax, *fintegral, *ftmp; 11793e9753d6SMatthew G. Knepley 11809566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 11819566063dSJacob Faibussowitsch PetscCall(DMPlexGetGeometryFVM(plex, NULL, &cellgeom, NULL)); 1182c4762a1bSJed Brown fcount = mod->maxComputed + 1; 11839566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(fcount, &fmin, fcount, &fmax, fcount, &fintegral, fcount, &ftmp)); 1184c4762a1bSJed Brown for (i = 0; i < fcount; i++) { 1185c4762a1bSJed Brown fmin[i] = PETSC_MAX_REAL; 1186c4762a1bSJed Brown fmax[i] = PETSC_MIN_REAL; 1187c4762a1bSJed Brown fintegral[i] = 0; 1188c4762a1bSJed Brown } 11899566063dSJacob Faibussowitsch PetscCall(VecGetDM(cellgeom, &dmCell)); 11909566063dSJacob Faibussowitsch PetscCall(DMPlexGetSimplexOrBoxCells(dmCell, 0, &cStart, &cEnd)); 11919566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(cellgeom, &cgeom)); 11929566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 11939566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "vtk", &vtkLabel)); 1194c4762a1bSJed Brown for (c = cStart; c < cEnd; ++c) { 1195c4762a1bSJed Brown PetscFVCellGeom *cg; 1196c4762a1bSJed Brown const PetscScalar *cx = NULL; 1197c4762a1bSJed Brown PetscInt vtkVal = 0; 1198c4762a1bSJed Brown 1199c4762a1bSJed Brown /* not that these two routines as currently implemented work for any dm with a 1200c4762a1bSJed Brown * localSection/globalSection */ 12019566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmCell, c, cgeom, &cg)); 12029566063dSJacob Faibussowitsch PetscCall(DMPlexPointGlobalRead(dm, c, x, &cx)); 12039566063dSJacob Faibussowitsch if (vtkLabel) PetscCall(DMLabelGetValue(vtkLabel, c, &vtkVal)); 1204c4762a1bSJed Brown if (!vtkVal || !cx) continue; /* ghost, or not a global cell */ 1205c4762a1bSJed Brown for (i = 0; i < mod->numCall; i++) { 1206c4762a1bSJed Brown FunctionalLink flink = mod->functionalCall[i]; 12079566063dSJacob Faibussowitsch PetscCall((*flink->func)(mod, time, cg->centroid, cx, ftmp, flink->ctx)); 1208c4762a1bSJed Brown } 1209c4762a1bSJed Brown for (i = 0; i < fcount; i++) { 1210c4762a1bSJed Brown fmin[i] = PetscMin(fmin[i], ftmp[i]); 1211c4762a1bSJed Brown fmax[i] = PetscMax(fmax[i], ftmp[i]); 1212c4762a1bSJed Brown fintegral[i] += cg->volume * ftmp[i]; 1213c4762a1bSJed Brown } 1214c4762a1bSJed Brown } 12159566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(cellgeom, &cgeom)); 12169566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 12179566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 1218712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, fmin, fcount, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject)ts))); 1219712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, fmax, fcount, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)ts))); 1220712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, fintegral, fcount, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)ts))); 1221c4762a1bSJed Brown 1222c4762a1bSJed Brown ftablealloc = fcount * 100; 1223c4762a1bSJed Brown ftableused = 0; 12249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ftablealloc, &ftable)); 1225c4762a1bSJed Brown for (i = 0; i < mod->numMonitored; i++) { 1226c4762a1bSJed Brown size_t countused; 1227c4762a1bSJed Brown char buffer[256], *p; 1228c4762a1bSJed Brown FunctionalLink flink = mod->functionalMonitored[i]; 1229c4762a1bSJed Brown PetscInt id = flink->offset; 1230c4762a1bSJed Brown if (i % 3) { 12319566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(buffer, " ", 2)); 1232c4762a1bSJed Brown p = buffer + 2; 1233c4762a1bSJed Brown } else if (i) { 1234c4762a1bSJed Brown char newline[] = "\n"; 12359566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(buffer, newline, sizeof(newline) - 1)); 1236c4762a1bSJed Brown p = buffer + sizeof(newline) - 1; 1237c4762a1bSJed Brown } else { 1238c4762a1bSJed Brown p = buffer; 1239c4762a1bSJed Brown } 12409566063dSJacob Faibussowitsch PetscCall(PetscSNPrintfCount(p, sizeof buffer - (p - buffer), "%12s [%10.7g,%10.7g] int %10.7g", &countused, flink->name, (double)fmin[id], (double)fmax[id], (double)fintegral[id])); 1241c4762a1bSJed Brown countused--; 1242c4762a1bSJed Brown countused += p - buffer; 1243c4762a1bSJed Brown if (countused > ftablealloc - ftableused - 1) { /* reallocate */ 1244c4762a1bSJed Brown char *ftablenew; 1245c4762a1bSJed Brown ftablealloc = 2 * ftablealloc + countused; 12469566063dSJacob Faibussowitsch PetscCall(PetscMalloc(ftablealloc, &ftablenew)); 12479566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(ftablenew, ftable, ftableused)); 12489566063dSJacob Faibussowitsch PetscCall(PetscFree(ftable)); 1249c4762a1bSJed Brown ftable = ftablenew; 1250c4762a1bSJed Brown } 12519566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(ftable + ftableused, buffer, countused)); 1252c4762a1bSJed Brown ftableused += countused; 1253c4762a1bSJed Brown ftable[ftableused] = 0; 1254c4762a1bSJed Brown } 12559566063dSJacob Faibussowitsch PetscCall(PetscFree4(fmin, fmax, fintegral, ftmp)); 1256c4762a1bSJed Brown 125763a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "% 3" PetscInt_FMT " time %8.4g |x| %8.4g %s\n", stepnum, (double)time, (double)xnorm, ftable ? ftable : "")); 12589566063dSJacob Faibussowitsch PetscCall(PetscFree(ftable)); 1259c4762a1bSJed Brown } 12603ba16761SJacob Faibussowitsch if (user->vtkInterval < 1) PetscFunctionReturn(PETSC_SUCCESS); 1261c4762a1bSJed Brown if ((stepnum == -1) ^ (stepnum % user->vtkInterval == 0)) { 1262c4762a1bSJed Brown if (stepnum == -1) { /* Final time is not multiple of normal time interval, write it anyway */ 12639566063dSJacob Faibussowitsch PetscCall(TSGetStepNumber(ts, &stepnum)); 1264c4762a1bSJed Brown } 126563a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(filename, sizeof filename, "%s-%03" PetscInt_FMT ".vtu", user->outputBasename, stepnum)); 12669566063dSJacob Faibussowitsch PetscCall(OutputVTK(dm, filename, &viewer)); 12679566063dSJacob Faibussowitsch PetscCall(VecView(X, viewer)); 12689566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 1269c4762a1bSJed Brown } 12703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1271c4762a1bSJed Brown } 1272c4762a1bSJed Brown 1273d71ae5a4SJacob Faibussowitsch static PetscErrorCode initializeTS(DM dm, User user, TS *ts) 1274d71ae5a4SJacob Faibussowitsch { 12757510d9b0SBarry Smith PetscFunctionBeginUser; 12769566063dSJacob Faibussowitsch PetscCall(TSCreate(PetscObjectComm((PetscObject)dm), ts)); 12779566063dSJacob Faibussowitsch PetscCall(TSSetType(*ts, TSSSP)); 12789566063dSJacob Faibussowitsch PetscCall(TSSetDM(*ts, dm)); 12791baa6e33SBarry Smith if (user->vtkmon) PetscCall(TSMonitorSet(*ts, MonitorVTK, user, NULL)); 12809566063dSJacob Faibussowitsch PetscCall(DMTSSetBoundaryLocal(dm, DMPlexTSComputeBoundary, user)); 12819566063dSJacob Faibussowitsch PetscCall(DMTSSetRHSFunctionLocal(dm, DMPlexTSComputeRHSFunctionFVM, user)); 12829566063dSJacob Faibussowitsch PetscCall(TSSetMaxTime(*ts, 2.0)); 12839566063dSJacob Faibussowitsch PetscCall(TSSetExactFinalTime(*ts, TS_EXACTFINALTIME_STEPOVER)); 12843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1285c4762a1bSJed Brown } 1286c4762a1bSJed Brown 128752115386SStefano Zampini typedef struct { 128852115386SStefano Zampini PetscFV fvm; 128952115386SStefano Zampini VecTagger refineTag; 129052115386SStefano Zampini VecTagger coarsenTag; 129152115386SStefano Zampini DM adaptedDM; 129252115386SStefano Zampini User user; 129352115386SStefano Zampini PetscReal cfl; 129452115386SStefano Zampini PetscLimiter limiter; 129552115386SStefano Zampini PetscLimiter noneLimiter; 129652115386SStefano Zampini } TransferCtx; 129752115386SStefano Zampini 129852115386SStefano Zampini static PetscErrorCode adaptToleranceFVMSetUp(TS ts, PetscInt nstep, PetscReal time, Vec sol, PetscBool *resize, void *ctx) 1299d71ae5a4SJacob Faibussowitsch { 130052115386SStefano Zampini TransferCtx *tctx = (TransferCtx *)ctx; 130152115386SStefano Zampini PetscFV fvm = tctx->fvm; 130252115386SStefano Zampini VecTagger refineTag = tctx->refineTag; 130352115386SStefano Zampini VecTagger coarsenTag = tctx->coarsenTag; 130452115386SStefano Zampini User user = tctx->user; 1305c4762a1bSJed Brown DM dm, gradDM, plex, cellDM, adaptedDM = NULL; 1306c4762a1bSJed Brown Vec cellGeom, faceGeom; 1307c4762a1bSJed Brown PetscBool isForest, computeGradient; 1308c4762a1bSJed Brown Vec grad, locGrad, locX, errVec; 1309c4762a1bSJed Brown PetscInt cStart, cEnd, c, dim, nRefine, nCoarsen; 131052115386SStefano Zampini PetscReal minMaxInd[2] = {PETSC_MAX_REAL, PETSC_MIN_REAL}, minMaxIndGlobal[2]; 1311c4762a1bSJed Brown PetscScalar *errArray; 1312c4762a1bSJed Brown const PetscScalar *pointVals; 1313c4762a1bSJed Brown const PetscScalar *pointGrads; 1314c4762a1bSJed Brown const PetscScalar *pointGeom; 1315c4762a1bSJed Brown DMLabel adaptLabel = NULL; 1316c4762a1bSJed Brown IS refineIS, coarsenIS; 1317c4762a1bSJed Brown 13187510d9b0SBarry Smith PetscFunctionBeginUser; 131952115386SStefano Zampini *resize = PETSC_FALSE; 13209566063dSJacob Faibussowitsch PetscCall(VecGetDM(sol, &dm)); 13219566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 132252115386SStefano Zampini PetscCall(PetscFVSetLimiter(fvm, tctx->noneLimiter)); 13239566063dSJacob Faibussowitsch PetscCall(PetscFVGetComputeGradients(fvm, &computeGradient)); 13249566063dSJacob Faibussowitsch PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE)); 13259566063dSJacob Faibussowitsch PetscCall(DMIsForest(dm, &isForest)); 13269566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 13279566063dSJacob Faibussowitsch PetscCall(DMPlexGetDataFVM(plex, fvm, &cellGeom, &faceGeom, &gradDM)); 13289566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(plex, &locX)); 13299566063dSJacob Faibussowitsch PetscCall(DMPlexInsertBoundaryValues(plex, PETSC_TRUE, locX, 0.0, faceGeom, cellGeom, NULL)); 13309566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(plex, sol, INSERT_VALUES, locX)); 13319566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(plex, sol, INSERT_VALUES, locX)); 13329566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(gradDM, &grad)); 13339566063dSJacob Faibussowitsch PetscCall(DMPlexReconstructGradientsFVM(plex, locX, grad)); 13349566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(gradDM, &locGrad)); 13359566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(gradDM, grad, INSERT_VALUES, locGrad)); 13369566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(gradDM, grad, INSERT_VALUES, locGrad)); 13379566063dSJacob Faibussowitsch PetscCall(VecDestroy(&grad)); 13389566063dSJacob Faibussowitsch PetscCall(DMPlexGetSimplexOrBoxCells(plex, 0, &cStart, &cEnd)); 13399566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(locGrad, &pointGrads)); 13409566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(cellGeom, &pointGeom)); 13419566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(locX, &pointVals)); 13429566063dSJacob Faibussowitsch PetscCall(VecGetDM(cellGeom, &cellDM)); 13439566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "adapt", &adaptLabel)); 134477433607SBarry Smith PetscCall(VecCreateFromOptions(PetscObjectComm((PetscObject)plex), NULL, 1, cEnd - cStart, PETSC_DETERMINE, &errVec)); 13459566063dSJacob Faibussowitsch PetscCall(VecSetUp(errVec)); 13469566063dSJacob Faibussowitsch PetscCall(VecGetArray(errVec, &errArray)); 1347c4762a1bSJed Brown for (c = cStart; c < cEnd; c++) { 1348c4762a1bSJed Brown PetscReal errInd = 0.; 1349c4762a1bSJed Brown PetscScalar *pointGrad; 1350c4762a1bSJed Brown PetscScalar *pointVal; 1351c4762a1bSJed Brown PetscFVCellGeom *cg; 1352c4762a1bSJed Brown 13539566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(gradDM, c, pointGrads, &pointGrad)); 13549566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(cellDM, c, pointGeom, &cg)); 13559566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(plex, c, pointVals, &pointVal)); 1356c4762a1bSJed Brown 13579566063dSJacob Faibussowitsch PetscCall((user->model->errorIndicator)(dim, cg->volume, user->model->physics->dof, pointVal, pointGrad, &errInd, user->model->errorCtx)); 1358c4762a1bSJed Brown errArray[c - cStart] = errInd; 1359c4762a1bSJed Brown minMaxInd[0] = PetscMin(minMaxInd[0], errInd); 1360c4762a1bSJed Brown minMaxInd[1] = PetscMax(minMaxInd[1], errInd); 1361c4762a1bSJed Brown } 13629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(errVec, &errArray)); 13639566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(locX, &pointVals)); 13649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(cellGeom, &pointGeom)); 13659566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(locGrad, &pointGrads)); 13669566063dSJacob Faibussowitsch PetscCall(VecDestroy(&locGrad)); 13679566063dSJacob Faibussowitsch PetscCall(VecDestroy(&locX)); 13689566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 1369c4762a1bSJed Brown 13709566063dSJacob Faibussowitsch PetscCall(VecTaggerComputeIS(refineTag, errVec, &refineIS, NULL)); 13719566063dSJacob Faibussowitsch PetscCall(VecTaggerComputeIS(coarsenTag, errVec, &coarsenIS, NULL)); 13729566063dSJacob Faibussowitsch PetscCall(ISGetSize(refineIS, &nRefine)); 13739566063dSJacob Faibussowitsch PetscCall(ISGetSize(coarsenIS, &nCoarsen)); 13749566063dSJacob Faibussowitsch if (nRefine) PetscCall(DMLabelSetStratumIS(adaptLabel, DM_ADAPT_REFINE, refineIS)); 13759566063dSJacob Faibussowitsch if (nCoarsen) PetscCall(DMLabelSetStratumIS(adaptLabel, DM_ADAPT_COARSEN, coarsenIS)); 13769566063dSJacob Faibussowitsch PetscCall(ISDestroy(&coarsenIS)); 13779566063dSJacob Faibussowitsch PetscCall(ISDestroy(&refineIS)); 13789566063dSJacob Faibussowitsch PetscCall(VecDestroy(&errVec)); 1379c4762a1bSJed Brown 13809566063dSJacob Faibussowitsch PetscCall(PetscFVSetComputeGradients(fvm, computeGradient)); 138152115386SStefano Zampini PetscCall(PetscFVSetLimiter(fvm, tctx->limiter)); 1382c4762a1bSJed Brown minMaxInd[1] = -minMaxInd[1]; 1383712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(minMaxInd, minMaxIndGlobal, 2, MPIU_REAL, MPI_MIN, PetscObjectComm((PetscObject)dm))); 138452115386SStefano Zampini PetscCall(PetscInfo(ts, "error indicator range (%E, %E)\n", (double)minMaxIndGlobal[0], (double)(-minMaxIndGlobal[1]))); 1385c4762a1bSJed Brown if (nRefine || nCoarsen) { /* at least one cell is over the refinement threshold */ 13869566063dSJacob Faibussowitsch PetscCall(DMAdaptLabel(dm, adaptLabel, &adaptedDM)); 1387c4762a1bSJed Brown } 13889566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&adaptLabel)); 1389c4762a1bSJed Brown if (adaptedDM) { 139052115386SStefano Zampini tctx->adaptedDM = adaptedDM; 139152115386SStefano Zampini PetscCall(PetscInfo(ts, "Step %" PetscInt_FMT " adapted mesh, marking %" PetscInt_FMT " cells for refinement, and %" PetscInt_FMT " cells for coarsening\n", nstep, nRefine, nCoarsen)); 139252115386SStefano Zampini *resize = PETSC_TRUE; 1393c4762a1bSJed Brown } else { 139452115386SStefano Zampini PetscCall(PetscInfo(ts, "Step %" PetscInt_FMT " no adaptation\n", nstep)); 1395c4762a1bSJed Brown } 13963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1397c4762a1bSJed Brown } 1398c4762a1bSJed Brown 139952115386SStefano Zampini static PetscErrorCode Transfer(TS ts, PetscInt nv, Vec vecsin[], Vec vecsout[], void *ctx) 140052115386SStefano Zampini { 140152115386SStefano Zampini TransferCtx *tctx = (TransferCtx *)ctx; 140252115386SStefano Zampini DM dm; 140352115386SStefano Zampini PetscReal time; 140452115386SStefano Zampini 140552115386SStefano Zampini PetscFunctionBeginUser; 140652115386SStefano Zampini PetscCall(TSGetDM(ts, &dm)); 140752115386SStefano Zampini PetscCall(TSGetTime(ts, &time)); 140852115386SStefano Zampini PetscCheck(tctx->adaptedDM, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "Missing adaptedDM"); 140952115386SStefano Zampini for (PetscInt i = 0; i < nv; i++) { 141052115386SStefano Zampini const char *name; 141152115386SStefano Zampini 141252115386SStefano Zampini PetscCall(DMCreateGlobalVector(tctx->adaptedDM, &vecsout[i])); 141352115386SStefano Zampini PetscCall(DMForestTransferVec(dm, vecsin[i], tctx->adaptedDM, vecsout[i], PETSC_TRUE, time)); 141452115386SStefano Zampini PetscCall(PetscObjectGetName((PetscObject)vecsin[i], &name)); 141552115386SStefano Zampini PetscCall(PetscObjectSetName((PetscObject)vecsout[i], name)); 141652115386SStefano Zampini } 141752115386SStefano Zampini PetscCall(DMForestSetAdaptivityForest(tctx->adaptedDM, NULL)); /* clear internal references to the previous dm */ 141852115386SStefano Zampini 141952115386SStefano Zampini Model mod = tctx->user->model; 142052115386SStefano Zampini Physics phys = mod->physics; 142152115386SStefano Zampini PetscReal minRadius; 142252115386SStefano Zampini 142352115386SStefano Zampini PetscCall(DMPlexGetGeometryFVM(tctx->adaptedDM, NULL, NULL, &minRadius)); 142452115386SStefano Zampini PetscCall(MPIU_Allreduce(&phys->maxspeed, &mod->maxspeed, 1, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)ts))); 142552115386SStefano Zampini PetscCheck(mod->maxspeed > 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "Physics did not set maxspeed"); 142652115386SStefano Zampini 142752115386SStefano Zampini PetscReal dt = tctx->cfl * minRadius / mod->maxspeed; 142852115386SStefano Zampini PetscCall(TSSetTimeStep(ts, dt)); 142952115386SStefano Zampini 143052115386SStefano Zampini PetscCall(TSSetDM(ts, tctx->adaptedDM)); 143152115386SStefano Zampini PetscCall(DMDestroy(&tctx->adaptedDM)); 143252115386SStefano Zampini 143352115386SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 143452115386SStefano Zampini } 143552115386SStefano Zampini 1436d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 1437d71ae5a4SJacob Faibussowitsch { 1438c4762a1bSJed Brown MPI_Comm comm; 1439c4762a1bSJed Brown PetscDS prob; 1440c4762a1bSJed Brown PetscFV fvm; 1441c4762a1bSJed Brown PetscLimiter limiter = NULL, noneLimiter = NULL; 1442c4762a1bSJed Brown User user; 1443c4762a1bSJed Brown Model mod; 1444c4762a1bSJed Brown Physics phys; 14453e9753d6SMatthew G. Knepley DM dm, plex; 1446c4762a1bSJed Brown PetscReal ftime, cfl, dt, minRadius; 1447c4762a1bSJed Brown PetscInt dim, nsteps; 1448c4762a1bSJed Brown TS ts; 1449c4762a1bSJed Brown TSConvergedReason reason; 1450c4762a1bSJed Brown Vec X; 1451c4762a1bSJed Brown PetscViewer viewer; 1452b5a892a1SMatthew G. Knepley PetscBool vtkCellGeom, useAMR; 145330602db0SMatthew G. Knepley PetscInt adaptInterval; 1454c4762a1bSJed Brown char physname[256] = "advect"; 1455c4762a1bSJed Brown VecTagger refineTag = NULL, coarsenTag = NULL; 145652115386SStefano Zampini TransferCtx tctx; 1457c4762a1bSJed Brown 1458327415f7SBarry Smith PetscFunctionBeginUser; 14599566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, (char *)0, help)); 1460c4762a1bSJed Brown comm = PETSC_COMM_WORLD; 1461c4762a1bSJed Brown 14629566063dSJacob Faibussowitsch PetscCall(PetscNew(&user)); 14639566063dSJacob Faibussowitsch PetscCall(PetscNew(&user->model)); 14649566063dSJacob Faibussowitsch PetscCall(PetscNew(&user->model->physics)); 1465c4762a1bSJed Brown mod = user->model; 1466c4762a1bSJed Brown phys = mod->physics; 1467c4762a1bSJed Brown mod->comm = comm; 1468c4762a1bSJed Brown useAMR = PETSC_FALSE; 1469c4762a1bSJed Brown adaptInterval = 1; 1470c4762a1bSJed Brown 1471c4762a1bSJed Brown /* Register physical models to be available on the command line */ 14729566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PhysicsList, "advect", PhysicsCreate_Advect)); 14739566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PhysicsList, "sw", PhysicsCreate_SW)); 14749566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PhysicsList, "euler", PhysicsCreate_Euler)); 1475c4762a1bSJed Brown 1476d0609cedSBarry Smith PetscOptionsBegin(comm, NULL, "Unstructured Finite Volume Mesh Options", ""); 1477c4762a1bSJed Brown { 1478c4762a1bSJed Brown cfl = 0.9 * 4; /* default SSPRKS2 with s=5 stages is stable for CFL number s-1 */ 14799566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-ufv_cfl", "CFL number per step", "", cfl, &cfl, NULL)); 1480c4762a1bSJed Brown user->vtkInterval = 1; 14819566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ufv_vtk_interval", "VTK output interval (0 to disable)", "", user->vtkInterval, &user->vtkInterval, NULL)); 1482c4762a1bSJed Brown user->vtkmon = PETSC_TRUE; 14839566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ufv_vtk_monitor", "Use VTKMonitor routine", "", user->vtkmon, &user->vtkmon, NULL)); 1484c4762a1bSJed Brown vtkCellGeom = PETSC_FALSE; 1485c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(user->outputBasename, "ex11", sizeof(user->outputBasename))); 14869566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-ufv_vtk_basename", "VTK output basename", "", user->outputBasename, user->outputBasename, sizeof(user->outputBasename), NULL)); 14879566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ufv_vtk_cellgeom", "Write cell geometry (for debugging)", "", vtkCellGeom, &vtkCellGeom, NULL)); 14889566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ufv_use_amr", "use local adaptive mesh refinement", "", useAMR, &useAMR, NULL)); 14899566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ufv_adapt_interval", "time steps between AMR", "", adaptInterval, &adaptInterval, NULL)); 1490c4762a1bSJed Brown } 1491d0609cedSBarry Smith PetscOptionsEnd(); 1492c4762a1bSJed Brown 1493c4762a1bSJed Brown if (useAMR) { 1494c4762a1bSJed Brown VecTaggerBox refineBox, coarsenBox; 1495c4762a1bSJed Brown 1496c4762a1bSJed Brown refineBox.min = refineBox.max = PETSC_MAX_REAL; 1497c4762a1bSJed Brown coarsenBox.min = coarsenBox.max = PETSC_MIN_REAL; 1498c4762a1bSJed Brown 14999566063dSJacob Faibussowitsch PetscCall(VecTaggerCreate(comm, &refineTag)); 15009566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)refineTag, "refine_")); 15019566063dSJacob Faibussowitsch PetscCall(VecTaggerSetType(refineTag, VECTAGGERABSOLUTE)); 15029566063dSJacob Faibussowitsch PetscCall(VecTaggerAbsoluteSetBox(refineTag, &refineBox)); 15039566063dSJacob Faibussowitsch PetscCall(VecTaggerSetFromOptions(refineTag)); 15049566063dSJacob Faibussowitsch PetscCall(VecTaggerSetUp(refineTag)); 15059566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)refineTag, NULL, "-tag_view")); 1506c4762a1bSJed Brown 15079566063dSJacob Faibussowitsch PetscCall(VecTaggerCreate(comm, &coarsenTag)); 15089566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)coarsenTag, "coarsen_")); 15099566063dSJacob Faibussowitsch PetscCall(VecTaggerSetType(coarsenTag, VECTAGGERABSOLUTE)); 15109566063dSJacob Faibussowitsch PetscCall(VecTaggerAbsoluteSetBox(coarsenTag, &coarsenBox)); 15119566063dSJacob Faibussowitsch PetscCall(VecTaggerSetFromOptions(coarsenTag)); 15129566063dSJacob Faibussowitsch PetscCall(VecTaggerSetUp(coarsenTag)); 15139566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)coarsenTag, NULL, "-tag_view")); 1514c4762a1bSJed Brown } 1515c4762a1bSJed Brown 1516d0609cedSBarry Smith PetscOptionsBegin(comm, NULL, "Unstructured Finite Volume Physics Options", ""); 1517c4762a1bSJed Brown { 1518c4762a1bSJed Brown PetscErrorCode (*physcreate)(Model, Physics, PetscOptionItems *); 15199566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-physics", "Physics module to solve", "", PhysicsList, physname, physname, sizeof physname, NULL)); 15209566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PhysicsList, physname, &physcreate)); 15219566063dSJacob Faibussowitsch PetscCall(PetscMemzero(phys, sizeof(struct _n_Physics))); 15229566063dSJacob Faibussowitsch PetscCall((*physcreate)(mod, phys, PetscOptionsObject)); 1523c4762a1bSJed Brown /* Count number of fields and dofs */ 1524c4762a1bSJed Brown for (phys->nfields = 0, phys->dof = 0; phys->field_desc[phys->nfields].name; phys->nfields++) phys->dof += phys->field_desc[phys->nfields].dof; 152554c59aa7SJacob Faibussowitsch PetscCheck(phys->dof > 0, comm, PETSC_ERR_ARG_WRONGSTATE, "Physics '%s' did not set dof", physname); 15269566063dSJacob Faibussowitsch PetscCall(ModelFunctionalSetFromOptions(mod, PetscOptionsObject)); 1527c4762a1bSJed Brown } 1528d0609cedSBarry Smith PetscOptionsEnd(); 1529c4762a1bSJed Brown 1530c4762a1bSJed Brown /* Create mesh */ 1531c4762a1bSJed Brown { 153230602db0SMatthew G. Knepley PetscInt i; 153330602db0SMatthew G. Knepley 15349566063dSJacob Faibussowitsch PetscCall(DMCreate(comm, &dm)); 15359566063dSJacob Faibussowitsch PetscCall(DMSetType(dm, DMPLEX)); 15369566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(dm)); 15379371c9d4SSatish Balay for (i = 0; i < DIM; i++) { 15389371c9d4SSatish Balay mod->bounds[2 * i] = 0.; 15399371c9d4SSatish Balay mod->bounds[2 * i + 1] = 1.; 15409371c9d4SSatish Balay }; 1541c4762a1bSJed Brown dim = DIM; 154230602db0SMatthew G. Knepley { /* a null name means just do a hex box */ 154330602db0SMatthew G. Knepley PetscInt cells[3] = {1, 1, 1}, n = 3; 154430602db0SMatthew G. Knepley PetscBool flg2, skew = PETSC_FALSE; 1545c4762a1bSJed Brown PetscInt nret2 = 2 * DIM; 1546d0609cedSBarry Smith PetscOptionsBegin(comm, NULL, "Rectangular mesh options", ""); 15479566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-grid_bounds", "bounds of the mesh in each direction (i.e., x_min,x_max,y_min,y_max", "", mod->bounds, &nret2, &flg2)); 15489566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-grid_skew_60", "Skew grid for 60 degree shock mesh", "", skew, &skew, NULL)); 15499566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-dm_plex_box_faces", "Number of faces along each dimension", "", cells, &n, NULL)); 1550d0609cedSBarry Smith PetscOptionsEnd(); 155130602db0SMatthew G. Knepley /* TODO Rewrite this with Mark, and remove grid_bounds at that time */ 1552c4762a1bSJed Brown if (flg2) { 1553c4762a1bSJed Brown PetscInt dimEmbed, i; 1554c4762a1bSJed Brown PetscInt nCoords; 1555c4762a1bSJed Brown PetscScalar *coords; 1556c4762a1bSJed Brown Vec coordinates; 1557c4762a1bSJed Brown 15589566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coordinates)); 15599566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &dimEmbed)); 15609566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(coordinates, &nCoords)); 156154c59aa7SJacob Faibussowitsch PetscCheck(!(nCoords % dimEmbed), PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Coordinate vector the wrong size"); 15629566063dSJacob Faibussowitsch PetscCall(VecGetArray(coordinates, &coords)); 1563c4762a1bSJed Brown for (i = 0; i < nCoords; i += dimEmbed) { 1564c4762a1bSJed Brown PetscInt j; 1565c4762a1bSJed Brown 1566c4762a1bSJed Brown PetscScalar *coord = &coords[i]; 1567c4762a1bSJed Brown for (j = 0; j < dimEmbed; j++) { 1568c4762a1bSJed Brown coord[j] = mod->bounds[2 * j] + coord[j] * (mod->bounds[2 * j + 1] - mod->bounds[2 * j]); 1569c4762a1bSJed Brown if (dim == 2 && cells[1] == 1 && j == 0 && skew) { 1570c4762a1bSJed Brown if (cells[0] == 2 && i == 8) { 1571c4762a1bSJed Brown coord[j] = .57735026918963; /* hack to get 60 deg skewed mesh */ 157230602db0SMatthew G. Knepley } else if (cells[0] == 3) { 1573c4762a1bSJed Brown if (i == 2 || i == 10) coord[j] = mod->bounds[1] / 4.; 1574c4762a1bSJed Brown else if (i == 4) coord[j] = mod->bounds[1] / 2.; 1575c4762a1bSJed Brown else if (i == 12) coord[j] = 1.57735026918963 * mod->bounds[1] / 2.; 1576c4762a1bSJed Brown } 1577c4762a1bSJed Brown } 1578c4762a1bSJed Brown } 1579c4762a1bSJed Brown } 15809566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(coordinates, &coords)); 15819566063dSJacob Faibussowitsch PetscCall(DMSetCoordinatesLocal(dm, coordinates)); 1582c4762a1bSJed Brown } 1583c4762a1bSJed Brown } 1584c4762a1bSJed Brown } 15859566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(dm, NULL, "-orig_dm_view")); 15869566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1587c4762a1bSJed Brown 1588c4762a1bSJed Brown /* set up BCs, functions, tags */ 15899566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, "Face Sets")); 1590c4762a1bSJed Brown mod->errorIndicator = ErrorIndicator_Simple; 1591c4762a1bSJed Brown 1592c4762a1bSJed Brown { 1593c4762a1bSJed Brown DM gdm; 1594c4762a1bSJed Brown 15959566063dSJacob Faibussowitsch PetscCall(DMPlexConstructGhostCells(dm, NULL, NULL, &gdm)); 15969566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 1597c4762a1bSJed Brown dm = gdm; 15989566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(dm, NULL, "-dm_view")); 1599c4762a1bSJed Brown } 1600c4762a1bSJed Brown 16019566063dSJacob Faibussowitsch PetscCall(PetscFVCreate(comm, &fvm)); 16029566063dSJacob Faibussowitsch PetscCall(PetscFVSetFromOptions(fvm)); 16039566063dSJacob Faibussowitsch PetscCall(PetscFVSetNumComponents(fvm, phys->dof)); 16049566063dSJacob Faibussowitsch PetscCall(PetscFVSetSpatialDimension(fvm, dim)); 16059566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fvm, "")); 1606c4762a1bSJed Brown { 1607c4762a1bSJed Brown PetscInt f, dof; 1608c4762a1bSJed Brown for (f = 0, dof = 0; f < phys->nfields; f++) { 1609c4762a1bSJed Brown PetscInt newDof = phys->field_desc[f].dof; 1610c4762a1bSJed Brown 1611c4762a1bSJed Brown if (newDof == 1) { 16129566063dSJacob Faibussowitsch PetscCall(PetscFVSetComponentName(fvm, dof, phys->field_desc[f].name)); 16139371c9d4SSatish Balay } else { 1614c4762a1bSJed Brown PetscInt j; 1615c4762a1bSJed Brown 1616c4762a1bSJed Brown for (j = 0; j < newDof; j++) { 1617c4762a1bSJed Brown char compName[256] = "Unknown"; 1618c4762a1bSJed Brown 161963a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(compName, sizeof(compName), "%s_%" PetscInt_FMT, phys->field_desc[f].name, j)); 16209566063dSJacob Faibussowitsch PetscCall(PetscFVSetComponentName(fvm, dof + j, compName)); 1621c4762a1bSJed Brown } 1622c4762a1bSJed Brown } 1623c4762a1bSJed Brown dof += newDof; 1624c4762a1bSJed Brown } 1625c4762a1bSJed Brown } 1626c4762a1bSJed Brown /* FV is now structured with one field having all physics as components */ 16279566063dSJacob Faibussowitsch PetscCall(DMAddField(dm, NULL, (PetscObject)fvm)); 16289566063dSJacob Faibussowitsch PetscCall(DMCreateDS(dm)); 16299566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 16309566063dSJacob Faibussowitsch PetscCall(PetscDSSetRiemannSolver(prob, 0, user->model->physics->riemann)); 16319566063dSJacob Faibussowitsch PetscCall(PetscDSSetContext(prob, 0, user->model->physics)); 16329566063dSJacob Faibussowitsch PetscCall((*mod->setupbc)(dm, prob, phys)); 16339566063dSJacob Faibussowitsch PetscCall(PetscDSSetFromOptions(prob)); 1634c4762a1bSJed Brown { 1635c4762a1bSJed Brown char convType[256]; 1636c4762a1bSJed Brown PetscBool flg; 1637c4762a1bSJed Brown 1638d0609cedSBarry Smith PetscOptionsBegin(comm, "", "Mesh conversion options", "DMPLEX"); 16399566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_type", "Convert DMPlex to another format", "ex12", DMList, DMPLEX, convType, 256, &flg)); 1640d0609cedSBarry Smith PetscOptionsEnd(); 1641c4762a1bSJed Brown if (flg) { 1642c4762a1bSJed Brown DM dmConv; 1643c4762a1bSJed Brown 16449566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, convType, &dmConv)); 1645c4762a1bSJed Brown if (dmConv) { 16469566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(dmConv, NULL, "-dm_conv_view")); 16479566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 1648c4762a1bSJed Brown dm = dmConv; 16499566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(dm)); 1650c4762a1bSJed Brown } 1651c4762a1bSJed Brown } 1652c4762a1bSJed Brown } 1653c4762a1bSJed Brown 16549566063dSJacob Faibussowitsch PetscCall(initializeTS(dm, user, &ts)); 1655c4762a1bSJed Brown 16569566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &X)); 16579566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)X, "solution")); 16589566063dSJacob Faibussowitsch PetscCall(SetInitialCondition(dm, X, user)); 1659c4762a1bSJed Brown if (useAMR) { 1660c4762a1bSJed Brown PetscInt adaptIter; 1661c4762a1bSJed Brown 1662c4762a1bSJed Brown /* use no limiting when reconstructing gradients for adaptivity */ 16639566063dSJacob Faibussowitsch PetscCall(PetscFVGetLimiter(fvm, &limiter)); 16649566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)limiter)); 16659566063dSJacob Faibussowitsch PetscCall(PetscLimiterCreate(PetscObjectComm((PetscObject)fvm), &noneLimiter)); 16669566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetType(noneLimiter, PETSCLIMITERNONE)); 1667c4762a1bSJed Brown 166852115386SStefano Zampini /* Refinement context */ 166952115386SStefano Zampini tctx.fvm = fvm; 167052115386SStefano Zampini tctx.refineTag = refineTag; 167152115386SStefano Zampini tctx.coarsenTag = coarsenTag; 167252115386SStefano Zampini tctx.adaptedDM = NULL; 167352115386SStefano Zampini tctx.user = user; 167452115386SStefano Zampini tctx.noneLimiter = noneLimiter; 167552115386SStefano Zampini tctx.limiter = limiter; 167652115386SStefano Zampini tctx.cfl = cfl; 167752115386SStefano Zampini 167852115386SStefano Zampini /* Do some initial refinement steps */ 1679c4762a1bSJed Brown for (adaptIter = 0;; ++adaptIter) { 1680c4762a1bSJed Brown PetscLogDouble bytes; 168152115386SStefano Zampini PetscBool resize; 1682c4762a1bSJed Brown 16839566063dSJacob Faibussowitsch PetscCall(PetscMemoryGetCurrentUsage(&bytes)); 168463a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(ts, "refinement loop %" PetscInt_FMT ": memory used %g\n", adaptIter, (double)bytes)); 16859566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(dm, NULL, "-initial_dm_view")); 16869566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(X, NULL, "-initial_vec_view")); 1687c4762a1bSJed Brown 168852115386SStefano Zampini PetscCall(adaptToleranceFVMSetUp(ts, -1, 0.0, X, &resize, &tctx)); 168952115386SStefano Zampini if (!resize) break; 16909566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 16919566063dSJacob Faibussowitsch PetscCall(VecDestroy(&X)); 169252115386SStefano Zampini dm = tctx.adaptedDM; 169352115386SStefano Zampini tctx.adaptedDM = NULL; 169452115386SStefano Zampini PetscCall(TSSetDM(ts, dm)); 16959566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &X)); 16969566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)X, "solution")); 16979566063dSJacob Faibussowitsch PetscCall(SetInitialCondition(dm, X, user)); 1698c4762a1bSJed Brown } 1699c4762a1bSJed Brown } 1700c4762a1bSJed Brown 17019566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 1702c4762a1bSJed Brown if (vtkCellGeom) { 1703c4762a1bSJed Brown DM dmCell; 1704c4762a1bSJed Brown Vec cellgeom, partition; 1705c4762a1bSJed Brown 17069566063dSJacob Faibussowitsch PetscCall(DMPlexGetGeometryFVM(plex, NULL, &cellgeom, NULL)); 17079566063dSJacob Faibussowitsch PetscCall(OutputVTK(dm, "ex11-cellgeom.vtk", &viewer)); 17089566063dSJacob Faibussowitsch PetscCall(VecView(cellgeom, viewer)); 17099566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 17109566063dSJacob Faibussowitsch PetscCall(CreatePartitionVec(dm, &dmCell, &partition)); 17119566063dSJacob Faibussowitsch PetscCall(OutputVTK(dmCell, "ex11-partition.vtk", &viewer)); 17129566063dSJacob Faibussowitsch PetscCall(VecView(partition, viewer)); 17139566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 17149566063dSJacob Faibussowitsch PetscCall(VecDestroy(&partition)); 17159566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmCell)); 1716c4762a1bSJed Brown } 1717c4762a1bSJed Brown /* collect max maxspeed from all processes -- todo */ 17189566063dSJacob Faibussowitsch PetscCall(DMPlexGetGeometryFVM(plex, NULL, NULL, &minRadius)); 17199566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 1720712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(&phys->maxspeed, &mod->maxspeed, 1, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)ts))); 172154c59aa7SJacob Faibussowitsch PetscCheck(mod->maxspeed > 0, comm, PETSC_ERR_ARG_WRONGSTATE, "Physics '%s' did not set maxspeed", physname); 1722c4762a1bSJed Brown dt = cfl * minRadius / mod->maxspeed; 17239566063dSJacob Faibussowitsch PetscCall(TSSetTimeStep(ts, dt)); 17249566063dSJacob Faibussowitsch PetscCall(TSSetFromOptions(ts)); 1725c4762a1bSJed Brown 172652115386SStefano Zampini /* When using adaptive mesh refinement 172752115386SStefano Zampini specify callbacks to refine the solution 172852115386SStefano Zampini and interpolate data from old to new mesh */ 172952115386SStefano Zampini if (useAMR) { PetscCall(TSSetResize(ts, adaptToleranceFVMSetUp, Transfer, &tctx)); } 173052115386SStefano Zampini PetscCall(TSSetSolution(ts, X)); 17319566063dSJacob Faibussowitsch PetscCall(VecDestroy(&X)); 173252115386SStefano Zampini PetscCall(TSSolve(ts, NULL)); 17339566063dSJacob Faibussowitsch PetscCall(TSGetSolveTime(ts, &ftime)); 17349566063dSJacob Faibussowitsch PetscCall(TSGetStepNumber(ts, &nsteps)); 17359566063dSJacob Faibussowitsch PetscCall(TSGetConvergedReason(ts, &reason)); 173663a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%s at time %g after %" PetscInt_FMT " steps\n", TSConvergedReasons[reason], (double)ftime, nsteps)); 17379566063dSJacob Faibussowitsch PetscCall(TSDestroy(&ts)); 1738c4762a1bSJed Brown 17399566063dSJacob Faibussowitsch PetscCall(VecTaggerDestroy(&refineTag)); 17409566063dSJacob Faibussowitsch PetscCall(VecTaggerDestroy(&coarsenTag)); 17419566063dSJacob Faibussowitsch PetscCall(PetscFunctionListDestroy(&PhysicsList)); 17429566063dSJacob Faibussowitsch PetscCall(PetscFunctionListDestroy(&PhysicsRiemannList_SW)); 17439566063dSJacob Faibussowitsch PetscCall(FunctionalLinkDestroy(&user->model->functionalRegistry)); 17449566063dSJacob Faibussowitsch PetscCall(PetscFree(user->model->functionalMonitored)); 17459566063dSJacob Faibussowitsch PetscCall(PetscFree(user->model->functionalCall)); 17469566063dSJacob Faibussowitsch PetscCall(PetscFree(user->model->physics->data)); 17479566063dSJacob Faibussowitsch PetscCall(PetscFree(user->model->physics)); 17489566063dSJacob Faibussowitsch PetscCall(PetscFree(user->model)); 17499566063dSJacob Faibussowitsch PetscCall(PetscFree(user)); 17509566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&limiter)); 17519566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&noneLimiter)); 17529566063dSJacob Faibussowitsch PetscCall(PetscFVDestroy(&fvm)); 17539566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 17549566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 1755b122ec5aSJacob Faibussowitsch return 0; 1756c4762a1bSJed Brown } 1757c4762a1bSJed Brown 1758c4762a1bSJed Brown /* Godunov fluxs */ 1759d71ae5a4SJacob Faibussowitsch PetscScalar cvmgp_(PetscScalar *a, PetscScalar *b, PetscScalar *test) 1760d71ae5a4SJacob Faibussowitsch { 1761c4762a1bSJed Brown /* System generated locals */ 1762c4762a1bSJed Brown PetscScalar ret_val; 1763c4762a1bSJed Brown 1764ad540459SPierre Jolivet if (PetscRealPart(*test) > 0.) goto L10; 1765c4762a1bSJed Brown ret_val = *b; 1766c4762a1bSJed Brown return ret_val; 1767c4762a1bSJed Brown L10: 1768c4762a1bSJed Brown ret_val = *a; 1769c4762a1bSJed Brown return ret_val; 1770c4762a1bSJed Brown } /* cvmgp_ */ 1771c4762a1bSJed Brown 1772d71ae5a4SJacob Faibussowitsch PetscScalar cvmgm_(PetscScalar *a, PetscScalar *b, PetscScalar *test) 1773d71ae5a4SJacob Faibussowitsch { 1774c4762a1bSJed Brown /* System generated locals */ 1775c4762a1bSJed Brown PetscScalar ret_val; 1776c4762a1bSJed Brown 1777ad540459SPierre Jolivet if (PetscRealPart(*test) < 0.) goto L10; 1778c4762a1bSJed Brown ret_val = *b; 1779c4762a1bSJed Brown return ret_val; 1780c4762a1bSJed Brown L10: 1781c4762a1bSJed Brown ret_val = *a; 1782c4762a1bSJed Brown return ret_val; 1783c4762a1bSJed Brown } /* cvmgm_ */ 1784c4762a1bSJed Brown 1785d71ae5a4SJacob Faibussowitsch int riem1mdt(PetscScalar *gaml, PetscScalar *gamr, PetscScalar *rl, PetscScalar *pl, PetscScalar *uxl, PetscScalar *rr, PetscScalar *pr, PetscScalar *uxr, PetscScalar *rstarl, PetscScalar *rstarr, PetscScalar *pstar, PetscScalar *ustar) 1786d71ae5a4SJacob Faibussowitsch { 1787c4762a1bSJed Brown /* Initialized data */ 1788c4762a1bSJed Brown 1789c4762a1bSJed Brown static PetscScalar smallp = 1e-8; 1790c4762a1bSJed Brown 1791c4762a1bSJed Brown /* System generated locals */ 1792c4762a1bSJed Brown int i__1; 1793c4762a1bSJed Brown PetscScalar d__1, d__2; 1794c4762a1bSJed Brown 1795c4762a1bSJed Brown /* Local variables */ 1796c4762a1bSJed Brown static int i0; 1797c4762a1bSJed Brown static PetscScalar cl, cr, wl, zl, wr, zr, pst, durl, skpr1, skpr2; 1798c4762a1bSJed Brown static int iwave; 1799c4762a1bSJed Brown static PetscScalar gascl4, gascr4, cstarl, dpstar, cstarr; 1800c4762a1bSJed Brown /* static PetscScalar csqrl, csqrr, gascl1, gascl2, gascl3, gascr1, gascr2, gascr3; */ 1801c4762a1bSJed Brown static int iterno; 1802c4762a1bSJed Brown static PetscScalar ustarl, ustarr, rarepr1, rarepr2; 1803c4762a1bSJed Brown 1804c4762a1bSJed Brown /* gascl1 = *gaml - 1.; */ 1805c4762a1bSJed Brown /* gascl2 = (*gaml + 1.) * .5; */ 1806c4762a1bSJed Brown /* gascl3 = gascl2 / *gaml; */ 1807c4762a1bSJed Brown gascl4 = 1. / (*gaml - 1.); 1808c4762a1bSJed Brown 1809c4762a1bSJed Brown /* gascr1 = *gamr - 1.; */ 1810c4762a1bSJed Brown /* gascr2 = (*gamr + 1.) * .5; */ 1811c4762a1bSJed Brown /* gascr3 = gascr2 / *gamr; */ 1812c4762a1bSJed Brown gascr4 = 1. / (*gamr - 1.); 1813c4762a1bSJed Brown iterno = 10; 1814c4762a1bSJed Brown /* find pstar: */ 1815c4762a1bSJed Brown cl = PetscSqrtScalar(*gaml * *pl / *rl); 1816c4762a1bSJed Brown cr = PetscSqrtScalar(*gamr * *pr / *rr); 1817c4762a1bSJed Brown wl = *rl * cl; 1818c4762a1bSJed Brown wr = *rr * cr; 1819c4762a1bSJed Brown /* csqrl = wl * wl; */ 1820c4762a1bSJed Brown /* csqrr = wr * wr; */ 1821c4762a1bSJed Brown *pstar = (wl * *pr + wr * *pl) / (wl + wr); 1822c4762a1bSJed Brown *pstar = PetscMax(PetscRealPart(*pstar), PetscRealPart(smallp)); 1823c4762a1bSJed Brown pst = *pl / *pr; 1824c4762a1bSJed Brown skpr1 = cr * (pst - 1.) * PetscSqrtScalar(2. / (*gamr * (*gamr - 1. + (*gamr + 1.) * pst))); 1825c4762a1bSJed Brown d__1 = (*gamr - 1.) / (*gamr * 2.); 1826c4762a1bSJed Brown rarepr2 = gascr4 * 2. * cr * (1. - PetscPowScalar(pst, d__1)); 1827c4762a1bSJed Brown pst = *pr / *pl; 1828c4762a1bSJed Brown skpr2 = cl * (pst - 1.) * PetscSqrtScalar(2. / (*gaml * (*gaml - 1. + (*gaml + 1.) * pst))); 1829c4762a1bSJed Brown d__1 = (*gaml - 1.) / (*gaml * 2.); 1830c4762a1bSJed Brown rarepr1 = gascl4 * 2. * cl * (1. - PetscPowScalar(pst, d__1)); 1831c4762a1bSJed Brown durl = *uxr - *uxl; 1832c4762a1bSJed Brown if (PetscRealPart(*pr) < PetscRealPart(*pl)) { 1833c4762a1bSJed Brown if (PetscRealPart(durl) >= PetscRealPart(rarepr1)) { 1834c4762a1bSJed Brown iwave = 100; 1835c4762a1bSJed Brown } else if (PetscRealPart(durl) <= PetscRealPart(-skpr1)) { 1836c4762a1bSJed Brown iwave = 300; 1837c4762a1bSJed Brown } else { 1838c4762a1bSJed Brown iwave = 400; 1839c4762a1bSJed Brown } 1840c4762a1bSJed Brown } else { 1841c4762a1bSJed Brown if (PetscRealPart(durl) >= PetscRealPart(rarepr2)) { 1842c4762a1bSJed Brown iwave = 100; 1843c4762a1bSJed Brown } else if (PetscRealPart(durl) <= PetscRealPart(-skpr2)) { 1844c4762a1bSJed Brown iwave = 300; 1845c4762a1bSJed Brown } else { 1846c4762a1bSJed Brown iwave = 200; 1847c4762a1bSJed Brown } 1848c4762a1bSJed Brown } 1849c4762a1bSJed Brown if (iwave == 100) { 1850c4762a1bSJed Brown /* 1-wave: rarefaction wave, 3-wave: rarefaction wave */ 1851c4762a1bSJed Brown /* case (100) */ 1852c4762a1bSJed Brown i__1 = iterno; 1853c4762a1bSJed Brown for (i0 = 1; i0 <= i__1; ++i0) { 1854c4762a1bSJed Brown d__1 = *pstar / *pl; 1855c4762a1bSJed Brown d__2 = 1. / *gaml; 1856c4762a1bSJed Brown *rstarl = *rl * PetscPowScalar(d__1, d__2); 1857c4762a1bSJed Brown cstarl = PetscSqrtScalar(*gaml * *pstar / *rstarl); 1858c4762a1bSJed Brown ustarl = *uxl - gascl4 * 2. * (cstarl - cl); 1859c4762a1bSJed Brown zl = *rstarl * cstarl; 1860c4762a1bSJed Brown d__1 = *pstar / *pr; 1861c4762a1bSJed Brown d__2 = 1. / *gamr; 1862c4762a1bSJed Brown *rstarr = *rr * PetscPowScalar(d__1, d__2); 1863c4762a1bSJed Brown cstarr = PetscSqrtScalar(*gamr * *pstar / *rstarr); 1864c4762a1bSJed Brown ustarr = *uxr + gascr4 * 2. * (cstarr - cr); 1865c4762a1bSJed Brown zr = *rstarr * cstarr; 1866c4762a1bSJed Brown dpstar = zl * zr * (ustarr - ustarl) / (zl + zr); 1867c4762a1bSJed Brown *pstar -= dpstar; 1868c4762a1bSJed Brown *pstar = PetscMax(PetscRealPart(*pstar), PetscRealPart(smallp)); 1869c4762a1bSJed Brown if (PetscAbsScalar(dpstar) / PetscRealPart(*pstar) <= 1e-8) { 1870c4762a1bSJed Brown #if 0 1871c4762a1bSJed Brown break; 1872c4762a1bSJed Brown #endif 1873c4762a1bSJed Brown } 1874c4762a1bSJed Brown } 1875c4762a1bSJed Brown /* 1-wave: shock wave, 3-wave: rarefaction wave */ 1876c4762a1bSJed Brown } else if (iwave == 200) { 1877c4762a1bSJed Brown /* case (200) */ 1878c4762a1bSJed Brown i__1 = iterno; 1879c4762a1bSJed Brown for (i0 = 1; i0 <= i__1; ++i0) { 1880c4762a1bSJed Brown pst = *pstar / *pl; 1881c4762a1bSJed Brown ustarl = *uxl - (pst - 1.) * cl * PetscSqrtScalar(2. / (*gaml * (*gaml - 1. + (*gaml + 1.) * pst))); 1882c4762a1bSJed Brown zl = *pl / cl * PetscSqrtScalar(*gaml * 2. * (*gaml - 1. + (*gaml + 1.) * pst)) * (*gaml - 1. + (*gaml + 1.) * pst) / (*gaml * 3. - 1. + (*gaml + 1.) * pst); 1883c4762a1bSJed Brown d__1 = *pstar / *pr; 1884c4762a1bSJed Brown d__2 = 1. / *gamr; 1885c4762a1bSJed Brown *rstarr = *rr * PetscPowScalar(d__1, d__2); 1886c4762a1bSJed Brown cstarr = PetscSqrtScalar(*gamr * *pstar / *rstarr); 1887c4762a1bSJed Brown zr = *rstarr * cstarr; 1888c4762a1bSJed Brown ustarr = *uxr + gascr4 * 2. * (cstarr - cr); 1889c4762a1bSJed Brown dpstar = zl * zr * (ustarr - ustarl) / (zl + zr); 1890c4762a1bSJed Brown *pstar -= dpstar; 1891c4762a1bSJed Brown *pstar = PetscMax(PetscRealPart(*pstar), PetscRealPart(smallp)); 1892c4762a1bSJed Brown if (PetscAbsScalar(dpstar) / PetscRealPart(*pstar) <= 1e-8) { 1893c4762a1bSJed Brown #if 0 1894c4762a1bSJed Brown break; 1895c4762a1bSJed Brown #endif 1896c4762a1bSJed Brown } 1897c4762a1bSJed Brown } 1898c4762a1bSJed Brown /* 1-wave: shock wave, 3-wave: shock */ 1899c4762a1bSJed Brown } else if (iwave == 300) { 1900c4762a1bSJed Brown /* case (300) */ 1901c4762a1bSJed Brown i__1 = iterno; 1902c4762a1bSJed Brown for (i0 = 1; i0 <= i__1; ++i0) { 1903c4762a1bSJed Brown pst = *pstar / *pl; 1904c4762a1bSJed Brown ustarl = *uxl - (pst - 1.) * cl * PetscSqrtScalar(2. / (*gaml * (*gaml - 1. + (*gaml + 1.) * pst))); 1905c4762a1bSJed Brown zl = *pl / cl * PetscSqrtScalar(*gaml * 2. * (*gaml - 1. + (*gaml + 1.) * pst)) * (*gaml - 1. + (*gaml + 1.) * pst) / (*gaml * 3. - 1. + (*gaml + 1.) * pst); 1906c4762a1bSJed Brown pst = *pstar / *pr; 1907c4762a1bSJed Brown ustarr = *uxr + (pst - 1.) * cr * PetscSqrtScalar(2. / (*gamr * (*gamr - 1. + (*gamr + 1.) * pst))); 1908c4762a1bSJed Brown zr = *pr / cr * PetscSqrtScalar(*gamr * 2. * (*gamr - 1. + (*gamr + 1.) * pst)) * (*gamr - 1. + (*gamr + 1.) * pst) / (*gamr * 3. - 1. + (*gamr + 1.) * pst); 1909c4762a1bSJed Brown dpstar = zl * zr * (ustarr - ustarl) / (zl + zr); 1910c4762a1bSJed Brown *pstar -= dpstar; 1911c4762a1bSJed Brown *pstar = PetscMax(PetscRealPart(*pstar), PetscRealPart(smallp)); 1912c4762a1bSJed Brown if (PetscAbsScalar(dpstar) / PetscRealPart(*pstar) <= 1e-8) { 1913c4762a1bSJed Brown #if 0 1914c4762a1bSJed Brown break; 1915c4762a1bSJed Brown #endif 1916c4762a1bSJed Brown } 1917c4762a1bSJed Brown } 1918c4762a1bSJed Brown /* 1-wave: rarefaction wave, 3-wave: shock */ 1919c4762a1bSJed Brown } else if (iwave == 400) { 1920c4762a1bSJed Brown /* case (400) */ 1921c4762a1bSJed Brown i__1 = iterno; 1922c4762a1bSJed Brown for (i0 = 1; i0 <= i__1; ++i0) { 1923c4762a1bSJed Brown d__1 = *pstar / *pl; 1924c4762a1bSJed Brown d__2 = 1. / *gaml; 1925c4762a1bSJed Brown *rstarl = *rl * PetscPowScalar(d__1, d__2); 1926c4762a1bSJed Brown cstarl = PetscSqrtScalar(*gaml * *pstar / *rstarl); 1927c4762a1bSJed Brown ustarl = *uxl - gascl4 * 2. * (cstarl - cl); 1928c4762a1bSJed Brown zl = *rstarl * cstarl; 1929c4762a1bSJed Brown pst = *pstar / *pr; 1930c4762a1bSJed Brown ustarr = *uxr + (pst - 1.) * cr * PetscSqrtScalar(2. / (*gamr * (*gamr - 1. + (*gamr + 1.) * pst))); 1931c4762a1bSJed Brown zr = *pr / cr * PetscSqrtScalar(*gamr * 2. * (*gamr - 1. + (*gamr + 1.) * pst)) * (*gamr - 1. + (*gamr + 1.) * pst) / (*gamr * 3. - 1. + (*gamr + 1.) * pst); 1932c4762a1bSJed Brown dpstar = zl * zr * (ustarr - ustarl) / (zl + zr); 1933c4762a1bSJed Brown *pstar -= dpstar; 1934c4762a1bSJed Brown *pstar = PetscMax(PetscRealPart(*pstar), PetscRealPart(smallp)); 1935c4762a1bSJed Brown if (PetscAbsScalar(dpstar) / PetscRealPart(*pstar) <= 1e-8) { 1936c4762a1bSJed Brown #if 0 1937c4762a1bSJed Brown break; 1938c4762a1bSJed Brown #endif 1939c4762a1bSJed Brown } 1940c4762a1bSJed Brown } 1941c4762a1bSJed Brown } 1942c4762a1bSJed Brown 1943c4762a1bSJed Brown *ustar = (zl * ustarr + zr * ustarl) / (zl + zr); 1944c4762a1bSJed Brown if (PetscRealPart(*pstar) > PetscRealPart(*pl)) { 1945c4762a1bSJed Brown pst = *pstar / *pl; 19469371c9d4SSatish Balay *rstarl = ((*gaml + 1.) * pst + *gaml - 1.) / ((*gaml - 1.) * pst + *gaml + 1.) * *rl; 1947c4762a1bSJed Brown } 1948c4762a1bSJed Brown if (PetscRealPart(*pstar) > PetscRealPart(*pr)) { 1949c4762a1bSJed Brown pst = *pstar / *pr; 19509371c9d4SSatish Balay *rstarr = ((*gamr + 1.) * pst + *gamr - 1.) / ((*gamr - 1.) * pst + *gamr + 1.) * *rr; 1951c4762a1bSJed Brown } 1952c4762a1bSJed Brown return iwave; 1953c4762a1bSJed Brown } 1954c4762a1bSJed Brown 1955d71ae5a4SJacob Faibussowitsch PetscScalar sign(PetscScalar x) 1956d71ae5a4SJacob Faibussowitsch { 1957c4762a1bSJed Brown if (PetscRealPart(x) > 0) return 1.0; 1958c4762a1bSJed Brown if (PetscRealPart(x) < 0) return -1.0; 1959c4762a1bSJed Brown return 0.0; 1960c4762a1bSJed Brown } 1961c4762a1bSJed Brown /* Riemann Solver */ 1962c4762a1bSJed Brown /* -------------------------------------------------------------------- */ 1963d71ae5a4SJacob Faibussowitsch int riemannsolver(PetscScalar *xcen, PetscScalar *xp, PetscScalar *dtt, PetscScalar *rl, PetscScalar *uxl, PetscScalar *pl, PetscScalar *utl, PetscScalar *ubl, PetscScalar *gaml, PetscScalar *rho1l, PetscScalar *rr, PetscScalar *uxr, PetscScalar *pr, PetscScalar *utr, PetscScalar *ubr, PetscScalar *gamr, PetscScalar *rho1r, PetscScalar *rx, PetscScalar *uxm, PetscScalar *px, PetscScalar *utx, PetscScalar *ubx, PetscScalar *gam, PetscScalar *rho1) 1964d71ae5a4SJacob Faibussowitsch { 1965c4762a1bSJed Brown /* System generated locals */ 1966c4762a1bSJed Brown PetscScalar d__1, d__2; 1967c4762a1bSJed Brown 1968c4762a1bSJed Brown /* Local variables */ 1969c4762a1bSJed Brown static PetscScalar s, c0, p0, r0, u0, w0, x0, x2, ri, cx, sgn0, wsp0, gasc1, gasc2, gasc3, gasc4; 1970c4762a1bSJed Brown static PetscScalar cstar, pstar, rstar, ustar, xstar, wspst, ushock, streng, rstarl, rstarr, rstars; 1971c4762a1bSJed Brown int iwave; 1972c4762a1bSJed Brown 1973c4762a1bSJed Brown if (*rl == *rr && *pr == *pl && *uxl == *uxr && *gaml == *gamr) { 1974c4762a1bSJed Brown *rx = *rl; 1975c4762a1bSJed Brown *px = *pl; 1976c4762a1bSJed Brown *uxm = *uxl; 1977c4762a1bSJed Brown *gam = *gaml; 1978c4762a1bSJed Brown x2 = *xcen + *uxm * *dtt; 1979c4762a1bSJed Brown 1980c4762a1bSJed Brown if (PetscRealPart(*xp) >= PetscRealPart(x2)) { 1981c4762a1bSJed Brown *utx = *utr; 1982c4762a1bSJed Brown *ubx = *ubr; 1983c4762a1bSJed Brown *rho1 = *rho1r; 1984c4762a1bSJed Brown } else { 1985c4762a1bSJed Brown *utx = *utl; 1986c4762a1bSJed Brown *ubx = *ubl; 1987c4762a1bSJed Brown *rho1 = *rho1l; 1988c4762a1bSJed Brown } 1989c4762a1bSJed Brown return 0; 1990c4762a1bSJed Brown } 1991c4762a1bSJed Brown iwave = riem1mdt(gaml, gamr, rl, pl, uxl, rr, pr, uxr, &rstarl, &rstarr, &pstar, &ustar); 1992c4762a1bSJed Brown 1993c4762a1bSJed Brown x2 = *xcen + ustar * *dtt; 1994c4762a1bSJed Brown d__1 = *xp - x2; 1995c4762a1bSJed Brown sgn0 = sign(d__1); 1996c4762a1bSJed Brown /* x is in 3-wave if sgn0 = 1 */ 1997c4762a1bSJed Brown /* x is in 1-wave if sgn0 = -1 */ 1998c4762a1bSJed Brown r0 = cvmgm_(rl, rr, &sgn0); 1999c4762a1bSJed Brown p0 = cvmgm_(pl, pr, &sgn0); 2000c4762a1bSJed Brown u0 = cvmgm_(uxl, uxr, &sgn0); 2001c4762a1bSJed Brown *gam = cvmgm_(gaml, gamr, &sgn0); 2002c4762a1bSJed Brown gasc1 = *gam - 1.; 2003c4762a1bSJed Brown gasc2 = (*gam + 1.) * .5; 2004c4762a1bSJed Brown gasc3 = gasc2 / *gam; 2005c4762a1bSJed Brown gasc4 = 1. / (*gam - 1.); 2006c4762a1bSJed Brown c0 = PetscSqrtScalar(*gam * p0 / r0); 2007c4762a1bSJed Brown streng = pstar - p0; 2008c4762a1bSJed Brown w0 = *gam * r0 * p0 * (gasc3 * streng / p0 + 1.); 2009c4762a1bSJed Brown rstars = r0 / (1. - r0 * streng / w0); 2010c4762a1bSJed Brown d__1 = p0 / pstar; 2011c4762a1bSJed Brown d__2 = -1. / *gam; 2012c4762a1bSJed Brown rstarr = r0 * PetscPowScalar(d__1, d__2); 2013c4762a1bSJed Brown rstar = cvmgm_(&rstarr, &rstars, &streng); 2014c4762a1bSJed Brown w0 = PetscSqrtScalar(w0); 2015c4762a1bSJed Brown cstar = PetscSqrtScalar(*gam * pstar / rstar); 2016c4762a1bSJed Brown wsp0 = u0 + sgn0 * c0; 2017c4762a1bSJed Brown wspst = ustar + sgn0 * cstar; 2018c4762a1bSJed Brown ushock = ustar + sgn0 * w0 / rstar; 2019c4762a1bSJed Brown wspst = cvmgp_(&ushock, &wspst, &streng); 2020c4762a1bSJed Brown wsp0 = cvmgp_(&ushock, &wsp0, &streng); 2021c4762a1bSJed Brown x0 = *xcen + wsp0 * *dtt; 2022c4762a1bSJed Brown xstar = *xcen + wspst * *dtt; 2023c4762a1bSJed Brown /* using gas formula to evaluate rarefaction wave */ 2024c4762a1bSJed Brown /* ri : reiman invariant */ 2025c4762a1bSJed Brown ri = u0 - sgn0 * 2. * gasc4 * c0; 2026c4762a1bSJed Brown cx = sgn0 * .5 * gasc1 / gasc2 * ((*xp - *xcen) / *dtt - ri); 2027c4762a1bSJed Brown *uxm = ri + sgn0 * 2. * gasc4 * cx; 2028c4762a1bSJed Brown s = p0 / PetscPowScalar(r0, *gam); 2029c4762a1bSJed Brown d__1 = cx * cx / (*gam * s); 2030c4762a1bSJed Brown *rx = PetscPowScalar(d__1, gasc4); 2031c4762a1bSJed Brown *px = cx * cx * *rx / *gam; 2032c4762a1bSJed Brown d__1 = sgn0 * (x0 - *xp); 2033c4762a1bSJed Brown *rx = cvmgp_(rx, &r0, &d__1); 2034c4762a1bSJed Brown d__1 = sgn0 * (x0 - *xp); 2035c4762a1bSJed Brown *px = cvmgp_(px, &p0, &d__1); 2036c4762a1bSJed Brown d__1 = sgn0 * (x0 - *xp); 2037c4762a1bSJed Brown *uxm = cvmgp_(uxm, &u0, &d__1); 2038c4762a1bSJed Brown d__1 = sgn0 * (xstar - *xp); 2039c4762a1bSJed Brown *rx = cvmgm_(rx, &rstar, &d__1); 2040c4762a1bSJed Brown d__1 = sgn0 * (xstar - *xp); 2041c4762a1bSJed Brown *px = cvmgm_(px, &pstar, &d__1); 2042c4762a1bSJed Brown d__1 = sgn0 * (xstar - *xp); 2043c4762a1bSJed Brown *uxm = cvmgm_(uxm, &ustar, &d__1); 2044c4762a1bSJed Brown if (PetscRealPart(*xp) >= PetscRealPart(x2)) { 2045c4762a1bSJed Brown *utx = *utr; 2046c4762a1bSJed Brown *ubx = *ubr; 2047c4762a1bSJed Brown *rho1 = *rho1r; 2048c4762a1bSJed Brown } else { 2049c4762a1bSJed Brown *utx = *utl; 2050c4762a1bSJed Brown *ubx = *ubl; 2051c4762a1bSJed Brown *rho1 = *rho1l; 2052c4762a1bSJed Brown } 2053c4762a1bSJed Brown return iwave; 2054c4762a1bSJed Brown } 2055d71ae5a4SJacob Faibussowitsch int godunovflux(const PetscScalar *ul, const PetscScalar *ur, PetscScalar *flux, const PetscReal *nn, const int *ndim, const PetscReal *gamma) 2056d71ae5a4SJacob Faibussowitsch { 2057c4762a1bSJed Brown /* System generated locals */ 2058c4762a1bSJed Brown int i__1, iwave; 2059c4762a1bSJed Brown PetscScalar d__1, d__2, d__3; 2060c4762a1bSJed Brown 2061c4762a1bSJed Brown /* Local variables */ 2062c4762a1bSJed Brown static int k; 20639371c9d4SSatish Balay static PetscScalar bn[3], fn, ft, tg[3], pl, rl, pm, pr, rr, xp, ubl, ubm, ubr, dtt, unm, tmp, utl, utm, uxl, utr, uxr, gaml, gamm, gamr, xcen, rhom, rho1l, rho1m, rho1r; 2064c4762a1bSJed Brown 2065c4762a1bSJed Brown /* Function Body */ 2066c4762a1bSJed Brown xcen = 0.; 2067c4762a1bSJed Brown xp = 0.; 2068c4762a1bSJed Brown i__1 = *ndim; 2069c4762a1bSJed Brown for (k = 1; k <= i__1; ++k) { 2070c4762a1bSJed Brown tg[k - 1] = 0.; 2071c4762a1bSJed Brown bn[k - 1] = 0.; 2072c4762a1bSJed Brown } 2073c4762a1bSJed Brown dtt = 1.; 2074c4762a1bSJed Brown if (*ndim == 3) { 2075a795f3e7SBarry Smith if (nn[0] == 0. && nn[1] == 0.) { 2076c4762a1bSJed Brown tg[0] = 1.; 2077c4762a1bSJed Brown } else { 2078a795f3e7SBarry Smith tg[0] = -nn[1]; 2079a795f3e7SBarry Smith tg[1] = nn[0]; 2080c4762a1bSJed Brown } 2081c4762a1bSJed Brown /* tmp=dsqrt(tg(1)**2+tg(2)**2) */ 2082c4762a1bSJed Brown /* tg=tg/tmp */ 2083a795f3e7SBarry Smith bn[0] = -nn[2] * tg[1]; 2084a795f3e7SBarry Smith bn[1] = nn[2] * tg[0]; 2085a795f3e7SBarry Smith bn[2] = nn[0] * tg[1] - nn[1] * tg[0]; 2086c4762a1bSJed Brown /* Computing 2nd power */ 2087c4762a1bSJed Brown d__1 = bn[0]; 2088c4762a1bSJed Brown /* Computing 2nd power */ 2089c4762a1bSJed Brown d__2 = bn[1]; 2090c4762a1bSJed Brown /* Computing 2nd power */ 2091c4762a1bSJed Brown d__3 = bn[2]; 2092c4762a1bSJed Brown tmp = PetscSqrtScalar(d__1 * d__1 + d__2 * d__2 + d__3 * d__3); 2093c4762a1bSJed Brown i__1 = *ndim; 2094ad540459SPierre Jolivet for (k = 1; k <= i__1; ++k) bn[k - 1] /= tmp; 2095c4762a1bSJed Brown } else if (*ndim == 2) { 2096a795f3e7SBarry Smith tg[0] = -nn[1]; 2097a795f3e7SBarry Smith tg[1] = nn[0]; 2098c4762a1bSJed Brown /* tmp=dsqrt(tg(1)**2+tg(2)**2) */ 2099c4762a1bSJed Brown /* tg=tg/tmp */ 2100c4762a1bSJed Brown bn[0] = 0.; 2101c4762a1bSJed Brown bn[1] = 0.; 2102c4762a1bSJed Brown bn[2] = 1.; 2103c4762a1bSJed Brown } 2104a795f3e7SBarry Smith rl = ul[0]; 2105a795f3e7SBarry Smith rr = ur[0]; 2106c4762a1bSJed Brown uxl = 0.; 2107c4762a1bSJed Brown uxr = 0.; 2108c4762a1bSJed Brown utl = 0.; 2109c4762a1bSJed Brown utr = 0.; 2110c4762a1bSJed Brown ubl = 0.; 2111c4762a1bSJed Brown ubr = 0.; 2112c4762a1bSJed Brown i__1 = *ndim; 2113c4762a1bSJed Brown for (k = 1; k <= i__1; ++k) { 2114a795f3e7SBarry Smith uxl += ul[k] * nn[k - 1]; 2115a795f3e7SBarry Smith uxr += ur[k] * nn[k - 1]; 2116a795f3e7SBarry Smith utl += ul[k] * tg[k - 1]; 2117a795f3e7SBarry Smith utr += ur[k] * tg[k - 1]; 2118a795f3e7SBarry Smith ubl += ul[k] * bn[k - 1]; 2119a795f3e7SBarry Smith ubr += ur[k] * bn[k - 1]; 2120c4762a1bSJed Brown } 2121c4762a1bSJed Brown uxl /= rl; 2122c4762a1bSJed Brown uxr /= rr; 2123c4762a1bSJed Brown utl /= rl; 2124c4762a1bSJed Brown utr /= rr; 2125c4762a1bSJed Brown ubl /= rl; 2126c4762a1bSJed Brown ubr /= rr; 2127c4762a1bSJed Brown 2128c4762a1bSJed Brown gaml = *gamma; 2129c4762a1bSJed Brown gamr = *gamma; 2130c4762a1bSJed Brown /* Computing 2nd power */ 2131c4762a1bSJed Brown d__1 = uxl; 2132c4762a1bSJed Brown /* Computing 2nd power */ 2133c4762a1bSJed Brown d__2 = utl; 2134c4762a1bSJed Brown /* Computing 2nd power */ 2135c4762a1bSJed Brown d__3 = ubl; 2136a795f3e7SBarry Smith pl = (*gamma - 1.) * (ul[*ndim + 1] - rl * .5 * (d__1 * d__1 + d__2 * d__2 + d__3 * d__3)); 2137c4762a1bSJed Brown /* Computing 2nd power */ 2138c4762a1bSJed Brown d__1 = uxr; 2139c4762a1bSJed Brown /* Computing 2nd power */ 2140c4762a1bSJed Brown d__2 = utr; 2141c4762a1bSJed Brown /* Computing 2nd power */ 2142c4762a1bSJed Brown d__3 = ubr; 2143a795f3e7SBarry Smith pr = (*gamma - 1.) * (ur[*ndim + 1] - rr * .5 * (d__1 * d__1 + d__2 * d__2 + d__3 * d__3)); 2144c4762a1bSJed Brown rho1l = rl; 2145c4762a1bSJed Brown rho1r = rr; 2146c4762a1bSJed Brown 21479371c9d4SSatish Balay iwave = riemannsolver(&xcen, &xp, &dtt, &rl, &uxl, &pl, &utl, &ubl, &gaml, &rho1l, &rr, &uxr, &pr, &utr, &ubr, &gamr, &rho1r, &rhom, &unm, &pm, &utm, &ubm, &gamm, &rho1m); 2148c4762a1bSJed Brown 2149a795f3e7SBarry Smith flux[0] = rhom * unm; 2150c4762a1bSJed Brown fn = rhom * unm * unm + pm; 2151c4762a1bSJed Brown ft = rhom * unm * utm; 2152c4762a1bSJed Brown /* flux(2)=fn*nn(1)+ft*nn(2) */ 2153c4762a1bSJed Brown /* flux(3)=fn*tg(1)+ft*tg(2) */ 2154a795f3e7SBarry Smith flux[1] = fn * nn[0] + ft * tg[0]; 2155a795f3e7SBarry Smith flux[2] = fn * nn[1] + ft * tg[1]; 2156c4762a1bSJed Brown /* flux(2)=rhom*unm*(unm)+pm */ 2157c4762a1bSJed Brown /* flux(3)=rhom*(unm)*utm */ 2158ad540459SPierre Jolivet if (*ndim == 3) flux[3] = rhom * unm * ubm; 2159a795f3e7SBarry Smith flux[*ndim + 1] = (rhom * .5 * (unm * unm + utm * utm + ubm * ubm) + gamm / (gamm - 1.) * pm) * unm; 2160c4762a1bSJed Brown return iwave; 2161c4762a1bSJed Brown } /* godunovflux_ */ 2162c4762a1bSJed Brown 2163c4762a1bSJed Brown /* Subroutine to set up the initial conditions for the */ 2164c4762a1bSJed Brown /* Shock Interface interaction or linear wave (Ravi Samtaney,Mark Adams). */ 2165c4762a1bSJed Brown /* ----------------------------------------------------------------------- */ 2166d71ae5a4SJacob Faibussowitsch int projecteqstate(PetscReal wc[], const PetscReal ueq[], PetscReal lv[][3]) 2167d71ae5a4SJacob Faibussowitsch { 2168c4762a1bSJed Brown int j, k; 2169c4762a1bSJed Brown /* Wc=matmul(lv,Ueq) 3 vars */ 2170c4762a1bSJed Brown for (k = 0; k < 3; ++k) { 2171c4762a1bSJed Brown wc[k] = 0.; 2172ad540459SPierre Jolivet for (j = 0; j < 3; ++j) wc[k] += lv[k][j] * ueq[j]; 2173c4762a1bSJed Brown } 2174c4762a1bSJed Brown return 0; 2175c4762a1bSJed Brown } 2176c4762a1bSJed Brown /* ----------------------------------------------------------------------- */ 2177d71ae5a4SJacob Faibussowitsch int projecttoprim(PetscReal v[], const PetscReal wc[], PetscReal rv[][3]) 2178d71ae5a4SJacob Faibussowitsch { 2179c4762a1bSJed Brown int k, j; 2180c4762a1bSJed Brown /* V=matmul(rv,WC) 3 vars */ 2181c4762a1bSJed Brown for (k = 0; k < 3; ++k) { 2182c4762a1bSJed Brown v[k] = 0.; 2183ad540459SPierre Jolivet for (j = 0; j < 3; ++j) v[k] += rv[k][j] * wc[j]; 2184c4762a1bSJed Brown } 2185c4762a1bSJed Brown return 0; 2186c4762a1bSJed Brown } 2187c4762a1bSJed Brown /* ---------------------------------------------------------------------- */ 2188d71ae5a4SJacob Faibussowitsch int eigenvectors(PetscReal rv[][3], PetscReal lv[][3], const PetscReal ueq[], PetscReal gamma) 2189d71ae5a4SJacob Faibussowitsch { 2190c4762a1bSJed Brown int j, k; 2191c4762a1bSJed Brown PetscReal rho, csnd, p0; 2192c4762a1bSJed Brown /* PetscScalar u; */ 2193c4762a1bSJed Brown 21949371c9d4SSatish Balay for (k = 0; k < 3; ++k) 21959371c9d4SSatish Balay for (j = 0; j < 3; ++j) { 21969371c9d4SSatish Balay lv[k][j] = 0.; 21979371c9d4SSatish Balay rv[k][j] = 0.; 21989371c9d4SSatish Balay } 2199c4762a1bSJed Brown rho = ueq[0]; 2200c4762a1bSJed Brown /* u = ueq[1]; */ 2201c4762a1bSJed Brown p0 = ueq[2]; 2202c4762a1bSJed Brown csnd = PetscSqrtReal(gamma * p0 / rho); 2203c4762a1bSJed Brown lv[0][1] = rho * .5; 2204c4762a1bSJed Brown lv[0][2] = -.5 / csnd; 2205c4762a1bSJed Brown lv[1][0] = csnd; 2206c4762a1bSJed Brown lv[1][2] = -1. / csnd; 2207c4762a1bSJed Brown lv[2][1] = rho * .5; 2208c4762a1bSJed Brown lv[2][2] = .5 / csnd; 2209c4762a1bSJed Brown rv[0][0] = -1. / csnd; 2210c4762a1bSJed Brown rv[1][0] = 1. / rho; 2211c4762a1bSJed Brown rv[2][0] = -csnd; 2212c4762a1bSJed Brown rv[0][1] = 1. / csnd; 2213c4762a1bSJed Brown rv[0][2] = 1. / csnd; 2214c4762a1bSJed Brown rv[1][2] = 1. / rho; 2215c4762a1bSJed Brown rv[2][2] = csnd; 2216c4762a1bSJed Brown return 0; 2217c4762a1bSJed Brown } 2218c4762a1bSJed Brown 2219d71ae5a4SJacob Faibussowitsch int initLinearWave(EulerNode *ux, const PetscReal gamma, const PetscReal coord[], const PetscReal Lx) 2220d71ae5a4SJacob Faibussowitsch { 2221c4762a1bSJed Brown PetscReal p0, u0, wcp[3], wc[3]; 2222c4762a1bSJed Brown PetscReal lv[3][3]; 2223c4762a1bSJed Brown PetscReal vp[3]; 2224c4762a1bSJed Brown PetscReal rv[3][3]; 2225c4762a1bSJed Brown PetscReal eps, ueq[3], rho0, twopi; 2226c4762a1bSJed Brown 2227c4762a1bSJed Brown /* Function Body */ 2228c4762a1bSJed Brown twopi = 2. * PETSC_PI; 2229c4762a1bSJed Brown eps = 1e-4; /* perturbation */ 2230c4762a1bSJed Brown rho0 = 1e3; /* density of water */ 2231c4762a1bSJed Brown p0 = 101325.; /* init pressure of 1 atm (?) */ 2232c4762a1bSJed Brown u0 = 0.; 2233c4762a1bSJed Brown ueq[0] = rho0; 2234c4762a1bSJed Brown ueq[1] = u0; 2235c4762a1bSJed Brown ueq[2] = p0; 2236c4762a1bSJed Brown /* Project initial state to characteristic variables */ 2237c4762a1bSJed Brown eigenvectors(rv, lv, ueq, gamma); 2238c4762a1bSJed Brown projecteqstate(wc, ueq, lv); 2239c4762a1bSJed Brown wcp[0] = wc[0]; 2240c4762a1bSJed Brown wcp[1] = wc[1]; 2241c4762a1bSJed Brown wcp[2] = wc[2] + eps * PetscCosReal(coord[0] * 2. * twopi / Lx); 2242c4762a1bSJed Brown projecttoprim(vp, wcp, rv); 2243c4762a1bSJed Brown ux->r = vp[0]; /* density */ 2244c4762a1bSJed Brown ux->ru[0] = vp[0] * vp[1]; /* x momentum */ 2245c4762a1bSJed Brown ux->ru[1] = 0.; 2246c4762a1bSJed Brown #if defined DIM > 2 2247c4762a1bSJed Brown if (dim > 2) ux->ru[2] = 0.; 2248c4762a1bSJed Brown #endif 2249c4762a1bSJed Brown /* E = rho * e + rho * v^2/2 = p/(gam-1) + rho*v^2/2 */ 2250c4762a1bSJed Brown ux->E = vp[2] / (gamma - 1.) + 0.5 * vp[0] * vp[1] * vp[1]; 2251c4762a1bSJed Brown return 0; 2252c4762a1bSJed Brown } 2253c4762a1bSJed Brown 2254c4762a1bSJed Brown /*TEST 2255c4762a1bSJed Brown 225630602db0SMatthew G. Knepley testset: 225730602db0SMatthew G. Knepley args: -dm_plex_adj_cone -dm_plex_adj_closure 0 225830602db0SMatthew G. Knepley 225930602db0SMatthew G. Knepley test: 226030602db0SMatthew G. Knepley suffix: adv_2d_tri_0 226130602db0SMatthew G. Knepley requires: triangle 226230602db0SMatthew G. Knepley TODO: how did this ever get in main when there is no support for this 226330602db0SMatthew G. Knepley args: -ufv_vtk_interval 0 -simplex -dm_refine 3 -dm_plex_faces 1,1 -dm_plex_separate_marker -bc_inflow 1,2,4 -bc_outflow 3 226430602db0SMatthew G. Knepley 226530602db0SMatthew G. Knepley test: 226630602db0SMatthew G. Knepley suffix: adv_2d_tri_1 226730602db0SMatthew G. Knepley requires: triangle 226830602db0SMatthew G. Knepley TODO: how did this ever get in main when there is no support for this 226930602db0SMatthew G. Knepley args: -ufv_vtk_interval 0 -simplex -dm_refine 5 -dm_plex_faces 1,1 -dm_plex_separate_marker -grid_bounds -0.5,0.5,-0.5,0.5 -bc_inflow 1,2,4 -bc_outflow 3 -advect_sol_type bump -advect_bump_center 0.25,0 -advect_bump_radius 0.1 227030602db0SMatthew G. Knepley 227130602db0SMatthew G. Knepley test: 227230602db0SMatthew G. Knepley suffix: tut_1 227330602db0SMatthew G. Knepley requires: exodusii 227430602db0SMatthew G. Knepley nsize: 1 2275*c14a7e84SMatthew G. Knepley args: -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside.exo -exodusii_check_reserved 0 227630602db0SMatthew G. Knepley 227730602db0SMatthew G. Knepley test: 227830602db0SMatthew G. Knepley suffix: tut_2 227930602db0SMatthew G. Knepley requires: exodusii 228030602db0SMatthew G. Knepley nsize: 1 2281*c14a7e84SMatthew G. Knepley args: -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside.exo -exodusii_check_reserved 0 -ts_type rosw 228230602db0SMatthew G. Knepley 228330602db0SMatthew G. Knepley test: 228430602db0SMatthew G. Knepley suffix: tut_3 228530602db0SMatthew G. Knepley requires: exodusii 228630602db0SMatthew G. Knepley nsize: 4 2287e600fa54SMatthew G. Knepley args: -dm_distribute_overlap 1 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/annulus-20.exo -monitor Error -advect_sol_type bump -petscfv_type leastsquares -petsclimiter_type sin 228830602db0SMatthew G. Knepley 228930602db0SMatthew G. Knepley test: 229030602db0SMatthew G. Knepley suffix: tut_4 229130602db0SMatthew G. Knepley requires: exodusii 229230602db0SMatthew G. Knepley nsize: 4 2293e600fa54SMatthew G. Knepley args: -dm_distribute_overlap 1 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/annulus-20.exo -physics sw -monitor Height,Energy -petscfv_type leastsquares -petsclimiter_type minmod 229430602db0SMatthew G. Knepley 229530602db0SMatthew G. Knepley testset: 229630602db0SMatthew G. Knepley args: -dm_plex_adj_cone -dm_plex_adj_closure 0 -dm_plex_simplex 0 -dm_plex_box_faces 1,1,1 229730602db0SMatthew G. Knepley 2298c4762a1bSJed Brown # 2D Advection 0-10 2299c4762a1bSJed Brown test: 2300c4762a1bSJed Brown suffix: 0 2301c4762a1bSJed Brown requires: exodusii 2302*c14a7e84SMatthew G. Knepley args: -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside.exo -exodusii_check_reserved 0 2303c4762a1bSJed Brown 2304c4762a1bSJed Brown test: 2305c4762a1bSJed Brown suffix: 1 2306c4762a1bSJed Brown requires: exodusii 230730602db0SMatthew G. Knepley args: -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside-quad-15.exo 2308c4762a1bSJed Brown 2309c4762a1bSJed Brown test: 2310c4762a1bSJed Brown suffix: 2 2311c4762a1bSJed Brown requires: exodusii 2312c4762a1bSJed Brown nsize: 2 2313*c14a7e84SMatthew G. Knepley args: -dm_distribute_overlap 1 -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside.exo -exodusii_check_reserved 0 2314c4762a1bSJed Brown 2315c4762a1bSJed Brown test: 2316c4762a1bSJed Brown suffix: 3 2317c4762a1bSJed Brown requires: exodusii 2318c4762a1bSJed Brown nsize: 2 2319e600fa54SMatthew G. Knepley args: -dm_distribute_overlap 1 -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside-quad-15.exo 2320c4762a1bSJed Brown 2321c4762a1bSJed Brown test: 2322c4762a1bSJed Brown suffix: 4 2323c4762a1bSJed Brown requires: exodusii 23246c2b77d5SStefano Zampini nsize: 4 23256c2b77d5SStefano Zampini args: -dm_distribute_overlap 1 -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside-quad.exo -petscpartitioner_type simple 2326c4762a1bSJed Brown 2327c4762a1bSJed Brown test: 2328c4762a1bSJed Brown suffix: 5 2329c4762a1bSJed Brown requires: exodusii 2330*c14a7e84SMatthew G. Knepley args: -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside.exo -exodusii_check_reserved 0 -ts_type rosw -ts_adapt_reject_safety 1 2331c4762a1bSJed Brown 2332c4762a1bSJed Brown test: 2333c4762a1bSJed Brown suffix: 7 2334c4762a1bSJed Brown requires: exodusii 233530602db0SMatthew G. Knepley args: -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside-quad-15.exo -dm_refine 1 2336c4762a1bSJed Brown 2337c4762a1bSJed Brown test: 2338c4762a1bSJed Brown suffix: 8 2339c4762a1bSJed Brown requires: exodusii 2340c4762a1bSJed Brown nsize: 2 2341e600fa54SMatthew G. Knepley args: -dm_distribute_overlap 1 -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside-quad-15.exo -dm_refine 1 2342c4762a1bSJed Brown 2343c4762a1bSJed Brown test: 2344c4762a1bSJed Brown suffix: 9 2345c4762a1bSJed Brown requires: exodusii 2346c4762a1bSJed Brown nsize: 8 2347e600fa54SMatthew G. Knepley args: -dm_distribute_overlap 1 -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside-quad-15.exo -dm_refine 1 2348c4762a1bSJed Brown 2349c4762a1bSJed Brown test: 2350c4762a1bSJed Brown suffix: 10 2351c4762a1bSJed Brown requires: exodusii 235230602db0SMatthew G. Knepley args: -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/sevenside-quad.exo 2353c4762a1bSJed Brown 2354c4762a1bSJed Brown # 2D Shallow water 2355993a5519SMatthew G. Knepley testset: 2356993a5519SMatthew G. Knepley args: -physics sw -ufv_vtk_interval 0 -dm_plex_adj_cone -dm_plex_adj_closure 0 2357993a5519SMatthew G. Knepley 2358c4762a1bSJed Brown test: 2359c4762a1bSJed Brown suffix: sw_0 2360c4762a1bSJed Brown requires: exodusii 2361993a5519SMatthew G. Knepley args: -bc_wall 100,101 -ufv_cfl 5 -petscfv_type leastsquares -petsclimiter_type sin \ 2362993a5519SMatthew G. Knepley -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/annulus-20.exo \ 2363993a5519SMatthew G. Knepley -ts_max_time 1 -ts_ssp_type rks2 -ts_ssp_nstages 10 \ 2364993a5519SMatthew G. Knepley -monitor height,energy 2365993a5519SMatthew G. Knepley 2366993a5519SMatthew G. Knepley test: 2367993a5519SMatthew G. Knepley suffix: sw_1 2368993a5519SMatthew G. Knepley nsize: 2 2369993a5519SMatthew G. Knepley args: -bc_wall 1,3 -ufv_cfl 5 -petsclimiter_type sin \ 2370993a5519SMatthew G. Knepley -dm_plex_shape annulus -dm_plex_simplex 0 -dm_plex_box_faces 24,12 -dm_plex_box_lower 0,1 -dm_plex_box_upper 1,3 -dm_distribute_overlap 1 \ 2371993a5519SMatthew G. Knepley -ts_max_time 1 -ts_ssp_type rks2 -ts_ssp_nstages 10 \ 2372993a5519SMatthew G. Knepley -monitor height,energy 2373c4762a1bSJed Brown 23748d2c18caSMukkund Sunjii test: 23758d2c18caSMukkund Sunjii suffix: sw_hll 2376993a5519SMatthew G. Knepley args: -sw_riemann hll -bc_wall 1,2,3,4 -ufv_cfl 3 -petscfv_type leastsquares -petsclimiter_type sin \ 2377993a5519SMatthew G. Knepley -grid_bounds 0,5,0,5 -dm_plex_simplex 0 -dm_plex_box_faces 25,25 \ 2378993a5519SMatthew G. Knepley -ts_max_steps 5 -ts_ssp_type rks2 -ts_ssp_nstages 10 \ 2379993a5519SMatthew G. Knepley -monitor height,energy 2380993a5519SMatthew G. Knepley 2381993a5519SMatthew G. Knepley testset: 2382993a5519SMatthew G. Knepley args: -dm_plex_adj_cone -dm_plex_adj_closure 0 -dm_plex_simplex 0 -dm_plex_box_faces 1,1,1 23838d2c18caSMukkund Sunjii 2384c4762a1bSJed Brown # 2D Advection: p4est 2385c4762a1bSJed Brown test: 2386c4762a1bSJed Brown suffix: p4est_advec_2d 2387c4762a1bSJed Brown requires: p4est 238830602db0SMatthew G. Knepley args: -ufv_vtk_interval 0 -dm_type p4est -dm_forest_minimum_refinement 1 -dm_forest_initial_refinement 2 -dm_p4est_refine_pattern hash -dm_forest_maximum_refinement 5 2389c4762a1bSJed Brown 2390c4762a1bSJed Brown # Advection in a box 2391c4762a1bSJed Brown test: 2392c4762a1bSJed Brown suffix: adv_2d_quad_0 2393c4762a1bSJed Brown args: -ufv_vtk_interval 0 -dm_refine 3 -dm_plex_separate_marker -bc_inflow 1,2,4 -bc_outflow 3 2394c4762a1bSJed Brown 2395c4762a1bSJed Brown test: 2396c4762a1bSJed Brown suffix: adv_2d_quad_1 2397c4762a1bSJed Brown args: -ufv_vtk_interval 0 -dm_refine 3 -dm_plex_separate_marker -grid_bounds -0.5,0.5,-0.5,0.5 -bc_inflow 1,2,4 -bc_outflow 3 -advect_sol_type bump -advect_bump_center 0.25,0 -advect_bump_radius 0.1 2398c4762a1bSJed Brown timeoutfactor: 3 2399c4762a1bSJed Brown 2400c4762a1bSJed Brown test: 2401c4762a1bSJed Brown suffix: adv_2d_quad_p4est_0 2402c4762a1bSJed Brown requires: p4est 2403c4762a1bSJed Brown args: -ufv_vtk_interval 0 -dm_refine 5 -dm_type p4est -dm_plex_separate_marker -bc_inflow 1,2,4 -bc_outflow 3 2404c4762a1bSJed Brown 2405c4762a1bSJed Brown test: 2406c4762a1bSJed Brown suffix: adv_2d_quad_p4est_1 2407c4762a1bSJed Brown requires: p4est 2408c4762a1bSJed Brown args: -ufv_vtk_interval 0 -dm_refine 5 -dm_type p4est -dm_plex_separate_marker -grid_bounds -0.5,0.5,-0.5,0.5 -bc_inflow 1,2,4 -bc_outflow 3 -advect_sol_type bump -advect_bump_center 0.25,0 -advect_bump_radius 0.1 2409c4762a1bSJed Brown timeoutfactor: 3 2410c4762a1bSJed Brown 2411c4762a1bSJed Brown test: 2412c4762a1bSJed Brown suffix: adv_2d_quad_p4est_adapt_0 2413c4762a1bSJed Brown requires: p4est !__float128 #broken for quad precision 2414c4762a1bSJed Brown args: -ufv_vtk_interval 0 -dm_refine 3 -dm_type p4est -dm_plex_separate_marker -grid_bounds -0.5,0.5,-0.5,0.5 -bc_inflow 1,2,4 -bc_outflow 3 -advect_sol_type bump -advect_bump_center 0.25,0 -advect_bump_radius 0.1 -ufv_use_amr -refine_vec_tagger_box 0.005,inf -coarsen_vec_tagger_box 0,1.e-5 -petscfv_type leastsquares -ts_max_time 0.01 2415c4762a1bSJed Brown timeoutfactor: 3 2416c4762a1bSJed Brown 2417c4762a1bSJed Brown test: 2418c4762a1bSJed Brown suffix: adv_0 2419c4762a1bSJed Brown requires: exodusii 2420*c14a7e84SMatthew G. Knepley args: -ufv_vtk_interval 0 -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/blockcylinder-50.exo -exodusii_check_reserved 0 -bc_inflow 100,101,200 -bc_outflow 201 2421c4762a1bSJed Brown 2422c4762a1bSJed Brown test: 2423c4762a1bSJed Brown suffix: shock_0 2424c4762a1bSJed Brown requires: p4est !single !complex 242530602db0SMatthew G. Knepley args: -dm_plex_box_faces 2,1 -grid_bounds -1,1.,0.,1 -grid_skew_60 \ 242630602db0SMatthew G. Knepley -dm_type p4est -dm_forest_partition_overlap 1 -dm_forest_maximum_refinement 6 -dm_forest_minimum_refinement 2 -dm_forest_initial_refinement 2 \ 242730602db0SMatthew G. Knepley -ufv_use_amr -refine_vec_tagger_box 0.5,inf -coarsen_vec_tagger_box 0,1.e-2 -refine_tag_view -coarsen_tag_view \ 242830602db0SMatthew G. Knepley -bc_wall 1,2,3,4 -physics euler -eu_type iv_shock -ufv_cfl 10 -eu_alpha 60. -eu_gamma 1.4 -eu_amach 2.02 -eu_rho2 3. \ 242930602db0SMatthew G. Knepley -petscfv_type leastsquares -petsclimiter_type minmod -petscfv_compute_gradients 0 \ 243030602db0SMatthew G. Knepley -ts_max_time 0.5 -ts_ssp_type rks2 -ts_ssp_nstages 10 \ 243130602db0SMatthew G. Knepley -ufv_vtk_basename ${wPETSC_DIR}/ex11 -ufv_vtk_interval 0 -monitor density,energy 2432c4762a1bSJed Brown timeoutfactor: 3 2433c4762a1bSJed Brown 2434c4762a1bSJed Brown # Test GLVis visualization of PetscFV fields 2435c4762a1bSJed Brown test: 2436c4762a1bSJed Brown suffix: glvis_adv_2d_tet 243730602db0SMatthew G. Knepley args: -ufv_vtk_interval 0 -ufv_vtk_monitor 0 \ 243830602db0SMatthew G. Knepley -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/square_periodic.msh -dm_plex_gmsh_periodic 0 \ 243930602db0SMatthew G. Knepley -ts_monitor_solution glvis: -ts_max_steps 0 2440c4762a1bSJed Brown 2441c4762a1bSJed Brown test: 2442c4762a1bSJed Brown suffix: glvis_adv_2d_quad 244330602db0SMatthew G. Knepley args: -ufv_vtk_interval 0 -ufv_vtk_monitor 0 -bc_inflow 1,2,4 -bc_outflow 3 \ 244430602db0SMatthew G. Knepley -dm_refine 5 -dm_plex_separate_marker \ 244530602db0SMatthew G. Knepley -ts_monitor_solution glvis: -ts_max_steps 0 2446c4762a1bSJed Brown 2447c4762a1bSJed Brown TEST*/ 2448