1649ef022SMatthew Knepley static char help[] = "Time-dependent Low Mach Flow in 2d and 3d channels with finite elements.\n\ 2444129b9SMatthew G. Knepley We solve the Low Mach flow problem for both conducting and non-conducting fluids,\n\ 3444129b9SMatthew G. Knepley using a parallel unstructured mesh (DMPLEX) to discretize it.\n\n\n"; 4649ef022SMatthew Knepley 5649ef022SMatthew Knepley /*F 6444129b9SMatthew G. Knepley The non-conducting Low Mach flow is time-dependent isoviscous Navier-Stokes flow. We discretize using the 7649ef022SMatthew Knepley finite element method on an unstructured mesh. The weak form equations are 8649ef022SMatthew Knepley 9649ef022SMatthew Knepley \begin{align*} 10649ef022SMatthew Knepley < q, \nabla\cdot u > = 0 11649ef022SMatthew Knepley <v, du/dt> + <v, u \cdot \nabla u> + < \nabla v, \nu (\nabla u + {\nabla u}^T) > - < \nabla\cdot v, p > - < v, f > = 0 12649ef022SMatthew Knepley < w, u \cdot \nabla T > + < \nabla w, \alpha \nabla T > - < w, Q > = 0 13649ef022SMatthew Knepley \end{align*} 14649ef022SMatthew Knepley 15649ef022SMatthew Knepley where $\nu$ is the kinematic viscosity and $\alpha$ is thermal diffusivity. 16649ef022SMatthew Knepley 17444129b9SMatthew G. Knepley The conducting form is given in the ABLATE documentation [1,2] and derived in Principe and Codina [2]. 18444129b9SMatthew G. Knepley 19649ef022SMatthew Knepley For visualization, use 20649ef022SMatthew Knepley 21649ef022SMatthew Knepley -dm_view hdf5:$PWD/sol.h5 -sol_vec_view hdf5:$PWD/sol.h5::append -exact_vec_view hdf5:$PWD/sol.h5::append 22444129b9SMatthew G. Knepley 234e6a9dc0SMatthew Knepley To look at nonlinear solver convergence, use 244e6a9dc0SMatthew Knepley 254e6a9dc0SMatthew Knepley -dm_refine <k> -ts_max_steps 1 \ 264e6a9dc0SMatthew Knepley -ts_view -ts_monitor -snes_monitor -snes_converged_reason -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason 274e6a9dc0SMatthew Knepley 28444129b9SMatthew G. Knepley [1] https://ubchrest.github.io/ablate/content/formulations/lowMachFlow/ 29444129b9SMatthew G. Knepley [2] https://github.com/UBCHREST/ablate/blob/main/ablateCore/flow/lowMachFlow.c 30444129b9SMatthew G. Knepley [3] J. Principe and R. Codina, "Mathematical models for thermally coupled low speed flows", Adv. in Theo. and App. Mech., 2(1), pp.93--112, 2009. 31649ef022SMatthew Knepley F*/ 32649ef022SMatthew Knepley 33649ef022SMatthew Knepley #include <petscdmplex.h> 34649ef022SMatthew Knepley #include <petscsnes.h> 35649ef022SMatthew Knepley #include <petscts.h> 36649ef022SMatthew Knepley #include <petscds.h> 37649ef022SMatthew Knepley #include <petscbag.h> 38649ef022SMatthew Knepley 399371c9d4SSatish Balay typedef enum { 409371c9d4SSatish Balay MOD_INCOMPRESSIBLE, 419371c9d4SSatish Balay MOD_CONDUCTING, 429371c9d4SSatish Balay NUM_MOD_TYPES 439371c9d4SSatish Balay } ModType; 44444129b9SMatthew G. Knepley const char *modTypes[NUM_MOD_TYPES + 1] = {"incompressible", "conducting", "unknown"}; 45444129b9SMatthew G. Knepley 469371c9d4SSatish Balay typedef enum { 479371c9d4SSatish Balay SOL_QUADRATIC, 489371c9d4SSatish Balay SOL_CUBIC, 499371c9d4SSatish Balay SOL_CUBIC_TRIG, 509371c9d4SSatish Balay SOL_TAYLOR_GREEN, 519371c9d4SSatish Balay SOL_PIPE, 529371c9d4SSatish Balay SOL_PIPE_WIGGLY, 539371c9d4SSatish Balay NUM_SOL_TYPES 549371c9d4SSatish Balay } SolType; 55367970cfSMatthew G. Knepley const char *solTypes[NUM_SOL_TYPES + 1] = {"quadratic", "cubic", "cubic_trig", "taylor_green", "pipe", "pipe_wiggly", "unknown"}; 56444129b9SMatthew G. Knepley 57444129b9SMatthew G. Knepley /* Fields */ 58444129b9SMatthew G. Knepley const PetscInt VEL = 0; 59444129b9SMatthew G. Knepley const PetscInt PRES = 1; 60444129b9SMatthew G. Knepley const PetscInt TEMP = 2; 61444129b9SMatthew G. Knepley /* Sources */ 62444129b9SMatthew G. Knepley const PetscInt MOMENTUM = 0; 63444129b9SMatthew G. Knepley const PetscInt MASS = 1; 64444129b9SMatthew G. Knepley const PetscInt ENERGY = 2; 65444129b9SMatthew G. Knepley /* Constants */ 66444129b9SMatthew G. Knepley const PetscInt STROUHAL = 0; 67444129b9SMatthew G. Knepley const PetscInt FROUDE = 1; 68444129b9SMatthew G. Knepley const PetscInt REYNOLDS = 2; 69444129b9SMatthew G. Knepley const PetscInt PECLET = 3; 70444129b9SMatthew G. Knepley const PetscInt P_TH = 4; 71444129b9SMatthew G. Knepley const PetscInt MU = 5; 72444129b9SMatthew G. Knepley const PetscInt NU = 6; 73444129b9SMatthew G. Knepley const PetscInt C_P = 7; 74444129b9SMatthew G. Knepley const PetscInt K = 8; 75444129b9SMatthew G. Knepley const PetscInt ALPHA = 9; 76444129b9SMatthew G. Knepley const PetscInt T_IN = 10; 77444129b9SMatthew G. Knepley const PetscInt G_DIR = 11; 78367970cfSMatthew G. Knepley const PetscInt EPSILON = 12; 79649ef022SMatthew Knepley 80649ef022SMatthew Knepley typedef struct { 81444129b9SMatthew G. Knepley PetscReal Strouhal; /* Strouhal number */ 82444129b9SMatthew G. Knepley PetscReal Froude; /* Froude number */ 83444129b9SMatthew G. Knepley PetscReal Reynolds; /* Reynolds number */ 84444129b9SMatthew G. Knepley PetscReal Peclet; /* Peclet number */ 85444129b9SMatthew G. Knepley PetscReal p_th; /* Thermodynamic pressure */ 86444129b9SMatthew G. Knepley PetscReal mu; /* Dynamic viscosity */ 87649ef022SMatthew Knepley PetscReal nu; /* Kinematic viscosity */ 88444129b9SMatthew G. Knepley PetscReal c_p; /* Specific heat at constant pressure */ 89444129b9SMatthew G. Knepley PetscReal k; /* Thermal conductivity */ 90649ef022SMatthew Knepley PetscReal alpha; /* Thermal diffusivity */ 91649ef022SMatthew Knepley PetscReal T_in; /* Inlet temperature */ 92444129b9SMatthew G. Knepley PetscReal g_dir; /* Gravity direction */ 93367970cfSMatthew G. Knepley PetscReal epsilon; /* Strength of perturbation */ 94649ef022SMatthew Knepley } Parameter; 95649ef022SMatthew Knepley 96649ef022SMatthew Knepley typedef struct { 97649ef022SMatthew Knepley /* Problem definition */ 98649ef022SMatthew Knepley PetscBag bag; /* Holds problem parameters */ 99444129b9SMatthew G. Knepley ModType modType; /* Model type */ 100649ef022SMatthew Knepley SolType solType; /* MMS solution type */ 101444129b9SMatthew G. Knepley PetscBool hasNullSpace; /* Problem has the constant null space for pressure */ 102a712f3bbSMatthew G. Knepley /* Flow diagnostics */ 103a712f3bbSMatthew G. Knepley DM dmCell; /* A DM with piecewise constant discretization */ 104649ef022SMatthew Knepley } AppCtx; 105649ef022SMatthew Knepley 106d71ae5a4SJacob Faibussowitsch static PetscErrorCode zero(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 107d71ae5a4SJacob Faibussowitsch { 108649ef022SMatthew Knepley PetscInt d; 109649ef022SMatthew Knepley for (d = 0; d < Nc; ++d) u[d] = 0.0; 1103ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 111649ef022SMatthew Knepley } 112649ef022SMatthew Knepley 113d71ae5a4SJacob Faibussowitsch static PetscErrorCode constant(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 114d71ae5a4SJacob Faibussowitsch { 115649ef022SMatthew Knepley PetscInt d; 116649ef022SMatthew Knepley for (d = 0; d < Nc; ++d) u[d] = 1.0; 1173ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 118649ef022SMatthew Knepley } 119649ef022SMatthew Knepley 120649ef022SMatthew Knepley /* 121649ef022SMatthew Knepley CASE: quadratic 122649ef022SMatthew Knepley In 2D we use exact solution: 123649ef022SMatthew Knepley 124649ef022SMatthew Knepley u = t + x^2 + y^2 125649ef022SMatthew Knepley v = t + 2x^2 - 2xy 126649ef022SMatthew Knepley p = x + y - 1 127444129b9SMatthew G. Knepley T = t + x + y + 1 128649ef022SMatthew Knepley f = <t (2x + 2y) + 2x^3 + 4x^2y - 2xy^2 -4\nu + 2, t (2x - 2y) + 4xy^2 + 2x^2y - 2y^3 -4\nu + 2> 129649ef022SMatthew Knepley Q = 1 + 2t + 3x^2 - 2xy + y^2 130649ef022SMatthew Knepley 131649ef022SMatthew Knepley so that 132649ef022SMatthew Knepley 133649ef022SMatthew Knepley \nabla \cdot u = 2x - 2x = 0 134649ef022SMatthew Knepley 135649ef022SMatthew Knepley f = du/dt + u \cdot \nabla u - \nu \Delta u + \nabla p 136649ef022SMatthew Knepley = <1, 1> + <t + x^2 + y^2, t + 2x^2 - 2xy> . <<2x, 4x - 2y>, <2y, -2x>> - \nu <4, 4> + <1, 1> 137649ef022SMatthew Knepley = <t (2x + 2y) + 2x^3 + 4x^2y - 2xy^2, t (2x - 2y) + 2x^2y + 4xy^2 - 2y^3> + <-4 \nu + 2, -4\nu + 2> 138649ef022SMatthew Knepley = <t (2x + 2y) + 2x^3 + 4x^2y - 2xy^2 - 4\nu + 2, t (2x - 2y) + 4xy^2 + 2x^2y - 2y^3 - 4\nu + 2> 139649ef022SMatthew Knepley 140649ef022SMatthew Knepley Q = dT/dt + u \cdot \nabla T - \alpha \Delta T 141649ef022SMatthew Knepley = 1 + <t + x^2 + y^2, t + 2x^2 - 2xy> . <1, 1> - \alpha 0 142649ef022SMatthew Knepley = 1 + 2t + 3x^2 - 2xy + y^2 143649ef022SMatthew Knepley */ 144649ef022SMatthew Knepley 145d71ae5a4SJacob Faibussowitsch static PetscErrorCode quadratic_u(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 146d71ae5a4SJacob Faibussowitsch { 147649ef022SMatthew Knepley u[0] = time + X[0] * X[0] + X[1] * X[1]; 148649ef022SMatthew Knepley u[1] = time + 2.0 * X[0] * X[0] - 2.0 * X[0] * X[1]; 1493ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 150649ef022SMatthew Knepley } 151d71ae5a4SJacob Faibussowitsch static PetscErrorCode quadratic_u_t(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 152d71ae5a4SJacob Faibussowitsch { 153649ef022SMatthew Knepley u[0] = 1.0; 154649ef022SMatthew Knepley u[1] = 1.0; 1553ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 156649ef022SMatthew Knepley } 157649ef022SMatthew Knepley 158d71ae5a4SJacob Faibussowitsch static PetscErrorCode quadratic_p(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *p, void *ctx) 159d71ae5a4SJacob Faibussowitsch { 160649ef022SMatthew Knepley p[0] = X[0] + X[1] - 1.0; 1613ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 162649ef022SMatthew Knepley } 163649ef022SMatthew Knepley 164d71ae5a4SJacob Faibussowitsch static PetscErrorCode quadratic_T(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 165d71ae5a4SJacob Faibussowitsch { 166444129b9SMatthew G. Knepley T[0] = time + X[0] + X[1] + 1.0; 1673ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 168649ef022SMatthew Knepley } 169d71ae5a4SJacob Faibussowitsch static PetscErrorCode quadratic_T_t(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 170d71ae5a4SJacob Faibussowitsch { 171649ef022SMatthew Knepley T[0] = 1.0; 1723ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 173649ef022SMatthew Knepley } 174649ef022SMatthew Knepley 175d71ae5a4SJacob Faibussowitsch static void f0_quadratic_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 176d71ae5a4SJacob Faibussowitsch { 177444129b9SMatthew G. Knepley const PetscReal nu = PetscRealPart(constants[NU]); 178649ef022SMatthew Knepley 179444129b9SMatthew G. Knepley f0[0] -= t * (2 * X[0] + 2 * X[1]) + 2 * X[0] * X[0] * X[0] + 4 * X[0] * X[0] * X[1] - 2 * X[0] * X[1] * X[1] - 4.0 * nu + 2; 180444129b9SMatthew G. Knepley f0[1] -= t * (2 * X[0] - 2 * X[1]) + 4 * X[0] * X[1] * X[1] + 2 * X[0] * X[0] * X[1] - 2 * X[1] * X[1] * X[1] - 4.0 * nu + 2; 181649ef022SMatthew Knepley } 182649ef022SMatthew Knepley 183d71ae5a4SJacob Faibussowitsch static void f0_quadratic_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 184d71ae5a4SJacob Faibussowitsch { 185444129b9SMatthew G. Knepley f0[0] -= 2 * t + 1 + 3 * X[0] * X[0] - 2 * X[0] * X[1] + X[1] * X[1]; 186444129b9SMatthew G. Knepley } 187444129b9SMatthew G. Knepley 188444129b9SMatthew G. Knepley /* 189444129b9SMatthew G. Knepley CASE: quadratic 190444129b9SMatthew G. Knepley In 2D we use exact solution: 191444129b9SMatthew G. Knepley 192444129b9SMatthew G. Knepley u = t + x^2 + y^2 193444129b9SMatthew G. Knepley v = t + 2x^2 - 2xy 194444129b9SMatthew G. Knepley p = x + y - 1 195444129b9SMatthew G. Knepley T = t + x + y + 1 196444129b9SMatthew G. Knepley rho = p^{th} / T 197444129b9SMatthew G. Knepley 198444129b9SMatthew G. Knepley so that 199444129b9SMatthew G. Knepley 200444129b9SMatthew G. Knepley \nabla \cdot u = 2x - 2x = 0 201444129b9SMatthew G. Knepley grad u = <<2 x, 4x - 2y>, <2 y, -2x>> 202444129b9SMatthew G. Knepley epsilon(u) = 1/2 (grad u + grad u^T) = <<2x, 2x>, <2x, -2x>> 203444129b9SMatthew G. Knepley epsilon'(u) = epsilon(u) - 1/3 (div u) I = epsilon(u) 204444129b9SMatthew G. Knepley div epsilon'(u) = <2, 2> 205444129b9SMatthew G. Knepley 206444129b9SMatthew G. Knepley f = rho S du/dt + rho u \cdot \nabla u - 2\mu/Re div \epsilon'(u) + \nabla p + rho / F^2 \hat y 207444129b9SMatthew G. Knepley = rho S <1, 1> + rho <t + x^2 + y^2, t + 2x^2 - 2xy> . <<2x, 4x - 2y>, <2y, -2x>> - 2\mu/Re <2, 2> + <1, 1> + rho/F^2 <0, 1> 208444129b9SMatthew G. Knepley = rho S <1, 1> + rho <t (2x + 2y) + 2x^3 + 4x^2y - 2xy^2, t (2x - 2y) + 2x^2y + 4xy^2 - 2y^3> - mu/Re <4, 4> + <1, 1> + rho/F^2 <0, 1> 209444129b9SMatthew G. Knepley 210444129b9SMatthew G. Knepley g = S rho_t + div (rho u) 211444129b9SMatthew G. Knepley = -S pth T_t/T^2 + rho div (u) + u . grad rho 212444129b9SMatthew G. Knepley = -S pth 1/T^2 - pth u . grad T / T^2 213444129b9SMatthew G. Knepley = -pth / T^2 (S + 2t + 3 x^2 - 2xy + y^2) 214444129b9SMatthew G. Knepley 215444129b9SMatthew G. Knepley Q = rho c_p S dT/dt + rho c_p u . grad T - 1/Pe div k grad T 216444129b9SMatthew G. Knepley = c_p S pth / T + c_p pth (2t + 3 x^2 - 2xy + y^2) / T - k/Pe 0 217444129b9SMatthew G. Knepley = c_p pth / T (S + 2t + 3 x^2 - 2xy + y^2) 218444129b9SMatthew G. Knepley */ 219d71ae5a4SJacob Faibussowitsch static void f0_conduct_quadratic_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 220d71ae5a4SJacob Faibussowitsch { 221444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 222444129b9SMatthew G. Knepley const PetscReal F = PetscRealPart(constants[FROUDE]); 223444129b9SMatthew G. Knepley const PetscReal Re = PetscRealPart(constants[REYNOLDS]); 224444129b9SMatthew G. Knepley const PetscReal mu = PetscRealPart(constants[MU]); 225444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 226444129b9SMatthew G. Knepley const PetscReal rho = p_th / (t + X[0] + X[1] + 1.); 227444129b9SMatthew G. Knepley const PetscInt gd = (PetscInt)PetscRealPart(constants[G_DIR]); 228444129b9SMatthew G. Knepley 229444129b9SMatthew G. Knepley f0[0] -= rho * S + rho * (2. * t * (X[0] + X[1]) + 2. * X[0] * X[0] * X[0] + 4. * X[0] * X[0] * X[1] - 2. * X[0] * X[1] * X[1]) - 4. * mu / Re + 1.; 230444129b9SMatthew G. Knepley f0[1] -= rho * S + rho * (2. * t * (X[0] - X[1]) + 2. * X[0] * X[0] * X[1] + 4. * X[0] * X[1] * X[1] - 2. * X[1] * X[1] * X[1]) - 4. * mu / Re + 1.; 231444129b9SMatthew G. Knepley f0[gd] -= rho / PetscSqr(F); 232444129b9SMatthew G. Knepley } 233444129b9SMatthew G. Knepley 234d71ae5a4SJacob Faibussowitsch static void f0_conduct_quadratic_q(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 235d71ae5a4SJacob Faibussowitsch { 236444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 237444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 238444129b9SMatthew G. Knepley 239444129b9SMatthew G. Knepley f0[0] += p_th * (S + 2. * t + 3. * X[0] * X[0] - 2. * X[0] * X[1] + X[1] * X[1]) / PetscSqr(t + X[0] + X[1] + 1.); 240444129b9SMatthew G. Knepley } 241444129b9SMatthew G. Knepley 242d71ae5a4SJacob Faibussowitsch static void f0_conduct_quadratic_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 243d71ae5a4SJacob Faibussowitsch { 244444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 245444129b9SMatthew G. Knepley const PetscReal c_p = PetscRealPart(constants[C_P]); 246444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 247444129b9SMatthew G. Knepley 248444129b9SMatthew G. Knepley f0[0] -= c_p * p_th * (S + 2. * t + 3. * X[0] * X[0] - 2. * X[0] * X[1] + X[1] * X[1]) / (t + X[0] + X[1] + 1.); 249649ef022SMatthew Knepley } 250649ef022SMatthew Knepley 251649ef022SMatthew Knepley /* 252649ef022SMatthew Knepley CASE: cubic 253649ef022SMatthew Knepley In 2D we use exact solution: 254649ef022SMatthew Knepley 255649ef022SMatthew Knepley u = t + x^3 + y^3 256649ef022SMatthew Knepley v = t + 2x^3 - 3x^2y 257649ef022SMatthew Knepley p = 3/2 x^2 + 3/2 y^2 - 1 258649ef022SMatthew Knepley T = t + 1/2 x^2 + 1/2 y^2 259649ef022SMatthew Knepley f = < t(3x^2 + 3y^2) + 3x^5 + 6x^3y^2 - 6x^2y^3 - \nu(6x + 6y) + 3x + 1, 260649ef022SMatthew Knepley t(3x^2 - 6xy) + 6x^2y^3 + 3x^4y - 6xy^4 - \nu(12x - 6y) + 3y + 1> 261649ef022SMatthew Knepley Q = x^4 + xy^3 + 2x^3y - 3x^2y^2 + xt + yt - 2\alpha + 1 262649ef022SMatthew Knepley 263649ef022SMatthew Knepley so that 264649ef022SMatthew Knepley 265649ef022SMatthew Knepley \nabla \cdot u = 3x^2 - 3x^2 = 0 266649ef022SMatthew Knepley 267649ef022SMatthew Knepley du/dt + u \cdot \nabla u - \nu \Delta u + \nabla p - f 268649ef022SMatthew Knepley = <1,1> + <t(3x^2 + 3y^2) + 3x^5 + 6x^3y^2 - 6x^2y^3, t(3x^2 - 6xy) + 6x^2y^3 + 3x^4y - 6xy^4> - \nu<6x + 6y, 12x - 6y> + <3x, 3y> - <t(3x^2 + 3y^2) + 3x^5 + 6x^3y^2 - 6x^2y^3 - \nu(6x + 6y) + 3x + 1, t(3x^2 - 6xy) + 6x^2y^3 + 3x^4y - 6xy^4 - \nu(12x - 6y) + 3y + 1> = 0 269649ef022SMatthew Knepley 270649ef022SMatthew Knepley dT/dt + u \cdot \nabla T - \alpha \Delta T - Q = 1 + (x^3 + y^3) x + (2x^3 - 3x^2y) y - 2*\alpha - (x^4 + xy^3 + 2x^3y - 3x^2y^2 - 2*\alpha +1) = 0 271649ef022SMatthew Knepley */ 272d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_u(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 273d71ae5a4SJacob Faibussowitsch { 274649ef022SMatthew Knepley u[0] = time + X[0] * X[0] * X[0] + X[1] * X[1] * X[1]; 275649ef022SMatthew Knepley u[1] = time + 2.0 * X[0] * X[0] * X[0] - 3.0 * X[0] * X[0] * X[1]; 2763ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 277649ef022SMatthew Knepley } 278d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_u_t(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 279d71ae5a4SJacob Faibussowitsch { 280649ef022SMatthew Knepley u[0] = 1.0; 281649ef022SMatthew Knepley u[1] = 1.0; 2823ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 283649ef022SMatthew Knepley } 284649ef022SMatthew Knepley 285d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_p(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *p, void *ctx) 286d71ae5a4SJacob Faibussowitsch { 287649ef022SMatthew Knepley p[0] = 3.0 * X[0] * X[0] / 2.0 + 3.0 * X[1] * X[1] / 2.0 - 1.0; 2883ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 289649ef022SMatthew Knepley } 290649ef022SMatthew Knepley 291d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_T(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 292d71ae5a4SJacob Faibussowitsch { 293649ef022SMatthew Knepley T[0] = time + X[0] * X[0] / 2.0 + X[1] * X[1] / 2.0; 2943ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 295649ef022SMatthew Knepley } 296d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_T_t(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 297d71ae5a4SJacob Faibussowitsch { 298649ef022SMatthew Knepley T[0] = 1.0; 2993ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 300649ef022SMatthew Knepley } 301649ef022SMatthew Knepley 302d71ae5a4SJacob Faibussowitsch static void f0_cubic_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 303d71ae5a4SJacob Faibussowitsch { 304444129b9SMatthew G. Knepley const PetscReal nu = PetscRealPart(constants[NU]); 305649ef022SMatthew Knepley 306649ef022SMatthew Knepley f0[0] -= (t * (3 * X[0] * X[0] + 3 * X[1] * X[1]) + 3 * X[0] * X[0] * X[0] * X[0] * X[0] + 6 * X[0] * X[0] * X[0] * X[1] * X[1] - 6 * X[0] * X[0] * X[1] * X[1] * X[1] - (6 * X[0] + 6 * X[1]) * nu + 3 * X[0] + 1); 307649ef022SMatthew Knepley f0[1] -= (t * (3 * X[0] * X[0] - 6 * X[0] * X[1]) + 3 * X[0] * X[0] * X[0] * X[0] * X[1] + 6 * X[0] * X[0] * X[1] * X[1] * X[1] - 6 * X[0] * X[1] * X[1] * X[1] * X[1] - (12 * X[0] - 6 * X[1]) * nu + 3 * X[1] + 1); 308649ef022SMatthew Knepley } 309649ef022SMatthew Knepley 310d71ae5a4SJacob Faibussowitsch static void f0_cubic_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 311d71ae5a4SJacob Faibussowitsch { 312444129b9SMatthew G. Knepley const PetscReal alpha = PetscRealPart(constants[ALPHA]); 313649ef022SMatthew Knepley 314444129b9SMatthew G. Knepley f0[0] -= X[0] * X[0] * X[0] * X[0] + 2.0 * X[0] * X[0] * X[0] * X[1] - 3.0 * X[0] * X[0] * X[1] * X[1] + X[0] * X[1] * X[1] * X[1] + X[0] * t + X[1] * t - 2.0 * alpha + 1; 315649ef022SMatthew Knepley } 316649ef022SMatthew Knepley 317649ef022SMatthew Knepley /* 318649ef022SMatthew Knepley CASE: cubic-trigonometric 319649ef022SMatthew Knepley In 2D we use exact solution: 320649ef022SMatthew Knepley 321649ef022SMatthew Knepley u = beta cos t + x^3 + y^3 322649ef022SMatthew Knepley v = beta sin t + 2x^3 - 3x^2y 323649ef022SMatthew Knepley p = 3/2 x^2 + 3/2 y^2 - 1 324649ef022SMatthew Knepley T = 20 cos t + 1/2 x^2 + 1/2 y^2 325649ef022SMatthew Knepley f = < beta cos t 3x^2 + beta sin t (3y^2 - 1) + 3x^5 + 6x^3y^2 - 6x^2y^3 - \nu(6x + 6y) + 3x, 326649ef022SMatthew Knepley beta cos t (6x^2 - 6xy) - beta sin t (3x^2) + 3x^4y + 6x^2y^3 - 6xy^4 - \nu(12x - 6y) + 3y> 327649ef022SMatthew Knepley Q = beta cos t x + beta sin t (y - 1) + x^4 + 2x^3y - 3x^2y^2 + xy^3 - 2\alpha 328649ef022SMatthew Knepley 329649ef022SMatthew Knepley so that 330649ef022SMatthew Knepley 331649ef022SMatthew Knepley \nabla \cdot u = 3x^2 - 3x^2 = 0 332649ef022SMatthew Knepley 333649ef022SMatthew Knepley f = du/dt + u \cdot \nabla u - \nu \Delta u + \nabla p 334649ef022SMatthew Knepley = <-sin t, cos t> + <cos t + x^3 + y^3, sin t + 2x^3 - 3x^2y> <<3x^2, 6x^2 - 6xy>, <3y^2, -3x^2>> - \nu <6x + 6y, 12x - 6y> + <3x, 3y> 335649ef022SMatthew Knepley = <-sin t, cos t> + <cos t 3x^2 + 3x^5 + 3x^2y^3 + sin t 3y^2 + 6x^3y^2 - 9x^2y^3, cos t (6x^2 - 6xy) + 6x^5 - 6x^4y + 6x^2y^3 - 6xy^4 + sin t (-3x^2) - 6x^5 + 9x^4y> - \nu <6x + 6y, 12x - 6y> + <3x, 3y> 336649ef022SMatthew Knepley = <cos t (3x^2) + sin t (3y^2 - 1) + 3x^5 + 6x^3y^2 - 6x^2y^3 - \nu (6x + 6y) + 3x, 337649ef022SMatthew Knepley cos t (6x^2 - 6xy) - sin t (3x^2) + 3x^4y + 6x^2y^3 - 6xy^4 - \nu (12x - 6y) + 3y> 338649ef022SMatthew Knepley 339649ef022SMatthew Knepley Q = dT/dt + u \cdot \nabla T - \alpha \Delta T 340649ef022SMatthew Knepley = -sin t + <cos t + x^3 + y^3, sin t + 2x^3 - 3x^2y> . <x, y> - 2 \alpha 341649ef022SMatthew Knepley = -sin t + cos t (x) + x^4 + xy^3 + sin t (y) + 2x^3y - 3x^2y^2 - 2 \alpha 342649ef022SMatthew Knepley = cos t x + sin t (y - 1) + (x^4 + 2x^3y - 3x^2y^2 + xy^3 - 2 \alpha) 343649ef022SMatthew Knepley */ 344d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_trig_u(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 345d71ae5a4SJacob Faibussowitsch { 346649ef022SMatthew Knepley u[0] = 100. * PetscCosReal(time) + X[0] * X[0] * X[0] + X[1] * X[1] * X[1]; 347649ef022SMatthew Knepley u[1] = 100. * PetscSinReal(time) + 2.0 * X[0] * X[0] * X[0] - 3.0 * X[0] * X[0] * X[1]; 3483ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 349649ef022SMatthew Knepley } 350d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_trig_u_t(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 351d71ae5a4SJacob Faibussowitsch { 352649ef022SMatthew Knepley u[0] = -100. * PetscSinReal(time); 353649ef022SMatthew Knepley u[1] = 100. * PetscCosReal(time); 3543ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 355649ef022SMatthew Knepley } 356649ef022SMatthew Knepley 357d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_trig_p(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *p, void *ctx) 358d71ae5a4SJacob Faibussowitsch { 359649ef022SMatthew Knepley p[0] = 3.0 * X[0] * X[0] / 2.0 + 3.0 * X[1] * X[1] / 2.0 - 1.0; 3603ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 361649ef022SMatthew Knepley } 362649ef022SMatthew Knepley 363d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_trig_T(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 364d71ae5a4SJacob Faibussowitsch { 365649ef022SMatthew Knepley T[0] = 100. * PetscCosReal(time) + X[0] * X[0] / 2.0 + X[1] * X[1] / 2.0; 3663ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 367649ef022SMatthew Knepley } 368d71ae5a4SJacob Faibussowitsch static PetscErrorCode cubic_trig_T_t(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 369d71ae5a4SJacob Faibussowitsch { 370649ef022SMatthew Knepley T[0] = -100. * PetscSinReal(time); 3713ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 372649ef022SMatthew Knepley } 373649ef022SMatthew Knepley 374d71ae5a4SJacob Faibussowitsch static void f0_cubic_trig_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 375d71ae5a4SJacob Faibussowitsch { 376444129b9SMatthew G. Knepley const PetscReal nu = PetscRealPart(constants[NU]); 377649ef022SMatthew Knepley 378649ef022SMatthew Knepley f0[0] -= 100. * PetscCosReal(t) * (3 * X[0] * X[0]) + 100. * PetscSinReal(t) * (3 * X[1] * X[1] - 1.) + 3 * X[0] * X[0] * X[0] * X[0] * X[0] + 6 * X[0] * X[0] * X[0] * X[1] * X[1] - 6 * X[0] * X[0] * X[1] * X[1] * X[1] - (6 * X[0] + 6 * X[1]) * nu + 3 * X[0]; 379649ef022SMatthew Knepley f0[1] -= 100. * PetscCosReal(t) * (6 * X[0] * X[0] - 6 * X[0] * X[1]) - 100. * PetscSinReal(t) * (3 * X[0] * X[0]) + 3 * X[0] * X[0] * X[0] * X[0] * X[1] + 6 * X[0] * X[0] * X[1] * X[1] * X[1] - 6 * X[0] * X[1] * X[1] * X[1] * X[1] - (12 * X[0] - 6 * X[1]) * nu + 3 * X[1]; 380649ef022SMatthew Knepley } 381649ef022SMatthew Knepley 382d71ae5a4SJacob Faibussowitsch static void f0_cubic_trig_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 383d71ae5a4SJacob Faibussowitsch { 384444129b9SMatthew G. Knepley const PetscReal alpha = PetscRealPart(constants[ALPHA]); 385649ef022SMatthew Knepley 386444129b9SMatthew G. Knepley f0[0] -= 100. * PetscCosReal(t) * X[0] + 100. * PetscSinReal(t) * (X[1] - 1.) + X[0] * X[0] * X[0] * X[0] + 2.0 * X[0] * X[0] * X[0] * X[1] - 3.0 * X[0] * X[0] * X[1] * X[1] + X[0] * X[1] * X[1] * X[1] - 2.0 * alpha; 387649ef022SMatthew Knepley } 388649ef022SMatthew Knepley 389606d57d4SMatthew G. Knepley /* 390444129b9SMatthew G. Knepley CASE: Taylor-Green vortex 391606d57d4SMatthew G. Knepley In 2D we use exact solution: 392606d57d4SMatthew G. Knepley 393606d57d4SMatthew G. Knepley u = 1 - cos(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t) 394606d57d4SMatthew G. Knepley v = 1 + sin(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t) 395606d57d4SMatthew G. Knepley p = -1/4 [cos(2 \pi(x - t)) + cos(2 \pi(y - t))] exp(-4 \pi^2 \nu t) 396606d57d4SMatthew G. Knepley T = t + x + y 397606d57d4SMatthew G. Knepley f = <\nu \pi^2 exp(-2\nu \pi^2 t) cos(\pi(x-t)) sin(\pi(y-t)), -\nu \pi^2 exp(-2\nu \pi^2 t) sin(\pi(x-t)) cos(\pi(y-t)) > 398606d57d4SMatthew G. Knepley Q = 3 + sin(\pi(x-y)) exp(-2\nu \pi^2 t) 399606d57d4SMatthew G. Knepley 400606d57d4SMatthew G. Knepley so that 401606d57d4SMatthew G. Knepley 402606d57d4SMatthew G. Knepley \nabla \cdot u = \pi sin(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t) - \pi sin(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t) = 0 403606d57d4SMatthew G. Knepley 404606d57d4SMatthew G. Knepley f = du/dt + u \cdot \nabla u - \nu \Delta u + \nabla p 405606d57d4SMatthew G. Knepley = <-\pi (sin(\pi(x - t)) sin(\pi(y - t)) - cos(\pi(x - t)) cos(\pi(y - t)) - 2\pi cos(\pi(x - t)) sin(\pi(y - t))) exp(-2 \pi^2 \nu t), 406606d57d4SMatthew G. Knepley \pi (sin(\pi(x - t)) sin(\pi(y - t)) - cos(\pi(x - t)) cos(\pi(y - t)) - 2\pi sin(\pi(x - t)) cos(\pi(y - t))) exp(-2 \pi^2 \nu t)> 407606d57d4SMatthew G. Knepley + < \pi (1 - cos(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t)) sin(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t), 408606d57d4SMatthew G. Knepley \pi (1 - cos(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t)) cos(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t)> 409606d57d4SMatthew G. Knepley + <-\pi (1 + sin(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t)) cos(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t), 410606d57d4SMatthew G. Knepley -\pi (1 + sin(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t)) sin(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t)> 411606d57d4SMatthew G. Knepley + <-2\pi^2 cos(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t), 412606d57d4SMatthew G. Knepley 2\pi^2 sin(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t)> 413606d57d4SMatthew G. Knepley + < \pi/2 sin(2\pi(x - t)) exp(-4 \pi^2 \nu t), 414606d57d4SMatthew G. Knepley \pi/2 sin(2\pi(y - t)) exp(-4 \pi^2 \nu t)> 415606d57d4SMatthew G. Knepley = <-\pi (sin(\pi(x - t)) sin(\pi(y - t)) - cos(\pi(x - t)) cos(\pi(y - t)) - 2\pi cos(\pi(x - t)) sin(\pi(y - t))) exp(-2 \pi^2 \nu t), 416606d57d4SMatthew G. Knepley \pi (sin(\pi(x - t)) sin(\pi(y - t)) - cos(\pi(x - t)) cos(\pi(y - t)) - 2\pi sin(\pi(x - t)) cos(\pi(y - t))) exp(-2 \pi^2 \nu t)> 417606d57d4SMatthew G. Knepley + < \pi sin(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t), 418606d57d4SMatthew G. Knepley \pi cos(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t)> 419606d57d4SMatthew G. Knepley + <-\pi cos(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t), 420606d57d4SMatthew G. Knepley -\pi sin(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t)> 421606d57d4SMatthew G. Knepley + <-\pi/2 sin(2\pi(x - t)) exp(-4 \pi^2 \nu t), 422606d57d4SMatthew G. Knepley -\pi/2 sin(2\pi(y - t)) exp(-4 \pi^2 \nu t)> 423606d57d4SMatthew G. Knepley + <-2\pi^2 cos(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t), 424606d57d4SMatthew G. Knepley 2\pi^2 sin(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t)> 425606d57d4SMatthew G. Knepley + < \pi/2 sin(2\pi(x - t)) exp(-4 \pi^2 \nu t), 426606d57d4SMatthew G. Knepley \pi/2 sin(2\pi(y - t)) exp(-4 \pi^2 \nu t)> 427606d57d4SMatthew G. Knepley = <-\pi (sin(\pi(x - t)) sin(\pi(y - t)) - cos(\pi(x - t)) cos(\pi(y - t))) exp(-2 \pi^2 \nu t), 428606d57d4SMatthew G. Knepley \pi (sin(\pi(x - t)) sin(\pi(y - t)) - cos(\pi(x - t)) cos(\pi(y - t))) exp(-2 \pi^2 \nu t)> 429606d57d4SMatthew G. Knepley + < \pi sin(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t), 430606d57d4SMatthew G. Knepley \pi cos(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t)> 431606d57d4SMatthew G. Knepley + <-\pi cos(\pi(x - t)) cos(\pi(y - t)) exp(-2 \pi^2 \nu t), 432606d57d4SMatthew G. Knepley -\pi sin(\pi(x - t)) sin(\pi(y - t)) exp(-2 \pi^2 \nu t)> 433606d57d4SMatthew G. Knepley = < \pi cos(\pi(x - t)) cos(\pi(y - t)), 434606d57d4SMatthew G. Knepley \pi sin(\pi(x - t)) sin(\pi(y - t))> 435606d57d4SMatthew G. Knepley + <-\pi cos(\pi(x - t)) cos(\pi(y - t)), 436606d57d4SMatthew G. Knepley -\pi sin(\pi(x - t)) sin(\pi(y - t))> = 0 437606d57d4SMatthew G. Knepley Q = dT/dt + u \cdot \nabla T - \alpha \Delta T 438606d57d4SMatthew G. Knepley = 1 + u \cdot <1, 1> - 0 439606d57d4SMatthew G. Knepley = 1 + u + v 440606d57d4SMatthew G. Knepley */ 441606d57d4SMatthew G. Knepley 442d71ae5a4SJacob Faibussowitsch static PetscErrorCode taylor_green_u(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 443d71ae5a4SJacob Faibussowitsch { 444606d57d4SMatthew G. Knepley u[0] = 1 - PetscCosReal(PETSC_PI * (X[0] - time)) * PetscSinReal(PETSC_PI * (X[1] - time)) * PetscExpReal(-2 * PETSC_PI * PETSC_PI * time); 445606d57d4SMatthew G. Knepley u[1] = 1 + PetscSinReal(PETSC_PI * (X[0] - time)) * PetscCosReal(PETSC_PI * (X[1] - time)) * PetscExpReal(-2 * PETSC_PI * PETSC_PI * time); 4463ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 447606d57d4SMatthew G. Knepley } 448d71ae5a4SJacob Faibussowitsch static PetscErrorCode taylor_green_u_t(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 449d71ae5a4SJacob Faibussowitsch { 4509371c9d4SSatish Balay u[0] = -PETSC_PI * (PetscSinReal(PETSC_PI * (X[0] - time)) * PetscSinReal(PETSC_PI * (X[1] - time)) - PetscCosReal(PETSC_PI * (X[0] - time)) * PetscCosReal(PETSC_PI * (X[1] - time)) - 2 * PETSC_PI * PetscCosReal(PETSC_PI * (X[0] - time)) * PetscSinReal(PETSC_PI * (X[1] - time))) * PetscExpReal(-2 * PETSC_PI * PETSC_PI * time); 4519371c9d4SSatish Balay u[1] = PETSC_PI * (PetscSinReal(PETSC_PI * (X[0] - time)) * PetscSinReal(PETSC_PI * (X[1] - time)) - PetscCosReal(PETSC_PI * (X[0] - time)) * PetscCosReal(PETSC_PI * (X[1] - time)) - 2 * PETSC_PI * PetscSinReal(PETSC_PI * (X[0] - time)) * PetscCosReal(PETSC_PI * (X[1] - time))) * PetscExpReal(-2 * PETSC_PI * PETSC_PI * time); 4523ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 453606d57d4SMatthew G. Knepley } 454606d57d4SMatthew G. Knepley 455d71ae5a4SJacob Faibussowitsch static PetscErrorCode taylor_green_p(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *p, void *ctx) 456d71ae5a4SJacob Faibussowitsch { 457606d57d4SMatthew G. Knepley p[0] = -0.25 * (PetscCosReal(2 * PETSC_PI * (X[0] - time)) + PetscCosReal(2 * PETSC_PI * (X[1] - time))) * PetscExpReal(-4 * PETSC_PI * PETSC_PI * time); 4583ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 459606d57d4SMatthew G. Knepley } 460606d57d4SMatthew G. Knepley 461d71ae5a4SJacob Faibussowitsch static PetscErrorCode taylor_green_p_t(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *p, void *ctx) 462d71ae5a4SJacob Faibussowitsch { 4639371c9d4SSatish Balay p[0] = PETSC_PI * (0.5 * (PetscSinReal(2 * PETSC_PI * (X[0] - time)) + PetscSinReal(2 * PETSC_PI * (X[1] - time))) + PETSC_PI * (PetscCosReal(2 * PETSC_PI * (X[0] - time)) + PetscCosReal(2 * PETSC_PI * (X[1] - time)))) * PetscExpReal(-4 * PETSC_PI * PETSC_PI * time); 4643ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 465606d57d4SMatthew G. Knepley } 466606d57d4SMatthew G. Knepley 467d71ae5a4SJacob Faibussowitsch static PetscErrorCode taylor_green_T(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 468d71ae5a4SJacob Faibussowitsch { 469606d57d4SMatthew G. Knepley T[0] = time + X[0] + X[1]; 4703ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 471606d57d4SMatthew G. Knepley } 472d71ae5a4SJacob Faibussowitsch static PetscErrorCode taylor_green_T_t(PetscInt Dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 473d71ae5a4SJacob Faibussowitsch { 474606d57d4SMatthew G. Knepley T[0] = 1.0; 4753ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 476606d57d4SMatthew G. Knepley } 477606d57d4SMatthew G. Knepley 478d71ae5a4SJacob Faibussowitsch static void f0_taylor_green_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 479d71ae5a4SJacob Faibussowitsch { 480606d57d4SMatthew G. Knepley PetscScalar vel[2]; 481606d57d4SMatthew G. Knepley 4823ba16761SJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF, taylor_green_u(dim, t, X, Nf, vel, NULL)); 483444129b9SMatthew G. Knepley f0[0] -= 1.0 + vel[0] + vel[1]; 484606d57d4SMatthew G. Knepley } 485606d57d4SMatthew G. Knepley 486444129b9SMatthew G. Knepley /* 487444129b9SMatthew G. Knepley CASE: Pipe flow 488444129b9SMatthew G. Knepley Poiseuille flow, with the incoming fluid having a parabolic temperature profile and the side walls being held at T_in 489444129b9SMatthew G. Knepley 490444129b9SMatthew G. Knepley u = \Delta Re/(2 mu) y (1 - y) 491444129b9SMatthew G. Knepley v = 0 492444129b9SMatthew G. Knepley p = -\Delta x 493444129b9SMatthew G. Knepley T = y (1 - y) + T_in 494444129b9SMatthew G. Knepley rho = p^{th} / T 495444129b9SMatthew G. Knepley 496444129b9SMatthew G. Knepley so that 497444129b9SMatthew G. Knepley 498444129b9SMatthew G. Knepley \nabla \cdot u = 0 - 0 = 0 499444129b9SMatthew G. Knepley grad u = \Delta Re/(2 mu) <<0, 0>, <1 - 2y, 0>> 500444129b9SMatthew G. Knepley epsilon(u) = 1/2 (grad u + grad u^T) = \Delta Re/(4 mu) <<0, 1 - 2y>, <<1 - 2y, 0>> 501444129b9SMatthew G. Knepley epsilon'(u) = epsilon(u) - 1/3 (div u) I = epsilon(u) 502444129b9SMatthew G. Knepley div epsilon'(u) = -\Delta Re/(2 mu) <1, 0> 503444129b9SMatthew G. Knepley 504444129b9SMatthew G. Knepley f = rho S du/dt + rho u \cdot \nabla u - 2\mu/Re div \epsilon'(u) + \nabla p + rho / F^2 \hat y 505444129b9SMatthew G. Knepley = 0 + 0 - div (2\mu/Re \epsilon'(u) - pI) + rho / F^2 \hat y 506444129b9SMatthew G. Knepley = -\Delta div <<x, (1 - 2y)/2>, <<(1 - 2y)/2, x>> + rho / F^2 \hat y 507444129b9SMatthew G. Knepley = \Delta <1, 0> - \Delta <1, 0> + rho/F^2 <0, 1> 508444129b9SMatthew G. Knepley = rho/F^2 <0, 1> 509444129b9SMatthew G. Knepley 510444129b9SMatthew G. Knepley g = S rho_t + div (rho u) 511444129b9SMatthew G. Knepley = 0 + rho div (u) + u . grad rho 512444129b9SMatthew G. Knepley = 0 + 0 - pth u . grad T / T^2 513444129b9SMatthew G. Knepley = 0 514444129b9SMatthew G. Knepley 515444129b9SMatthew G. Knepley Q = rho c_p S dT/dt + rho c_p u . grad T - 1/Pe div k grad T 516444129b9SMatthew G. Knepley = 0 + c_p pth / T 0 + 2 k/Pe 517444129b9SMatthew G. Knepley = 2 k/Pe 518444129b9SMatthew G. Knepley 519444129b9SMatthew G. Knepley The boundary conditions on the top and bottom are zero velocity and T_in temperature. The boundary term is 520444129b9SMatthew G. Knepley 521444129b9SMatthew G. Knepley (2\mu/Re \epsilon'(u) - p I) . n = \Delta <<x, (1 - 2y)/2>, <<(1 - 2y)/2, x>> . n 522444129b9SMatthew G. Knepley 523444129b9SMatthew G. Knepley so that 524444129b9SMatthew G. Knepley 525444129b9SMatthew G. Knepley x = 0: \Delta <<0, (1 - 2y)/2>, <<(1 - 2y)/2, 0>> . <-1, 0> = <0, (2y - 1)/2> 526444129b9SMatthew G. Knepley x = 1: \Delta <<1, (1 - 2y)/2>, <<(1 - 2y)/2, 1>> . <1, 0> = <1, (1 - 2y)/2> 527444129b9SMatthew G. Knepley */ 528d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_u(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 529d71ae5a4SJacob Faibussowitsch { 530444129b9SMatthew G. Knepley Parameter *param = (Parameter *)ctx; 531444129b9SMatthew G. Knepley 532444129b9SMatthew G. Knepley u[0] = (0.5 * param->Reynolds / param->mu) * X[1] * (1.0 - X[1]); 533444129b9SMatthew G. Knepley u[1] = 0.0; 5343ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 535444129b9SMatthew G. Knepley } 536d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_u_t(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 537d71ae5a4SJacob Faibussowitsch { 538444129b9SMatthew G. Knepley u[0] = 0.0; 539444129b9SMatthew G. Knepley u[1] = 0.0; 5403ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 541444129b9SMatthew G. Knepley } 542444129b9SMatthew G. Knepley 543d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_p(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *p, void *ctx) 544d71ae5a4SJacob Faibussowitsch { 545444129b9SMatthew G. Knepley p[0] = -X[0]; 5463ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 547444129b9SMatthew G. Knepley } 548d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_p_t(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *p, void *ctx) 549d71ae5a4SJacob Faibussowitsch { 550444129b9SMatthew G. Knepley p[0] = 0.0; 5513ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 552444129b9SMatthew G. Knepley } 553444129b9SMatthew G. Knepley 554d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_T(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 555d71ae5a4SJacob Faibussowitsch { 556444129b9SMatthew G. Knepley Parameter *param = (Parameter *)ctx; 557444129b9SMatthew G. Knepley 558444129b9SMatthew G. Knepley T[0] = X[1] * (1.0 - X[1]) + param->T_in; 5593ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 560444129b9SMatthew G. Knepley } 561d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_T_t(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 562d71ae5a4SJacob Faibussowitsch { 563444129b9SMatthew G. Knepley T[0] = 0.0; 5643ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 565444129b9SMatthew G. Knepley } 566444129b9SMatthew G. Knepley 567d71ae5a4SJacob Faibussowitsch static void f0_conduct_pipe_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 568d71ae5a4SJacob Faibussowitsch { 569444129b9SMatthew G. Knepley const PetscReal F = PetscRealPart(constants[FROUDE]); 570444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 571444129b9SMatthew G. Knepley const PetscReal T_in = PetscRealPart(constants[T_IN]); 572444129b9SMatthew G. Knepley const PetscReal rho = p_th / (X[1] * (1. - X[1]) + T_in); 573444129b9SMatthew G. Knepley const PetscInt gd = (PetscInt)PetscRealPart(constants[G_DIR]); 574444129b9SMatthew G. Knepley 575444129b9SMatthew G. Knepley f0[gd] -= rho / PetscSqr(F); 576444129b9SMatthew G. Knepley } 577444129b9SMatthew G. Knepley 578d71ae5a4SJacob Faibussowitsch static void f0_conduct_bd_pipe_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 579d71ae5a4SJacob Faibussowitsch { 580*9fa27a79SStefano Zampini PetscReal sigma[4] = {X[0], (PetscReal)(0.5 * (1. - 2. * X[1])), (PetscReal)(0.5 * (1. - 2. * X[1])), X[0]}; 581444129b9SMatthew G. Knepley PetscInt d, e; 582444129b9SMatthew G. Knepley 583444129b9SMatthew G. Knepley for (d = 0; d < dim; ++d) { 584ad540459SPierre Jolivet for (e = 0; e < dim; ++e) f0[d] -= sigma[d * dim + e] * n[e]; 585444129b9SMatthew G. Knepley } 586444129b9SMatthew G. Knepley } 587444129b9SMatthew G. Knepley 588d71ae5a4SJacob Faibussowitsch static void f0_conduct_pipe_q(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 589d71ae5a4SJacob Faibussowitsch { 590444129b9SMatthew G. Knepley f0[0] += 0.0; 591444129b9SMatthew G. Knepley } 592444129b9SMatthew G. Knepley 593d71ae5a4SJacob Faibussowitsch static void f0_conduct_pipe_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 594d71ae5a4SJacob Faibussowitsch { 595444129b9SMatthew G. Knepley const PetscReal k = PetscRealPart(constants[K]); 596444129b9SMatthew G. Knepley const PetscReal Pe = PetscRealPart(constants[PECLET]); 597444129b9SMatthew G. Knepley 598444129b9SMatthew G. Knepley f0[0] -= 2 * k / Pe; 599444129b9SMatthew G. Knepley } 600444129b9SMatthew G. Knepley 601367970cfSMatthew G. Knepley /* 602367970cfSMatthew G. Knepley CASE: Wiggly pipe flow 603367970cfSMatthew G. Knepley Perturbed Poiseuille flow, with the incoming fluid having a perturbed parabolic temperature profile and the side walls being held at T_in 604367970cfSMatthew G. Knepley 605367970cfSMatthew G. Knepley u = \Delta Re/(2 mu) [y (1 - y) + a sin(pi y)] 606367970cfSMatthew G. Knepley v = 0 607367970cfSMatthew G. Knepley p = -\Delta x 608367970cfSMatthew G. Knepley T = y (1 - y) + a sin(pi y) + T_in 609367970cfSMatthew G. Knepley rho = p^{th} / T 610367970cfSMatthew G. Knepley 611367970cfSMatthew G. Knepley so that 612367970cfSMatthew G. Knepley 613367970cfSMatthew G. Knepley \nabla \cdot u = 0 - 0 = 0 614367970cfSMatthew G. Knepley grad u = \Delta Re/(2 mu) <<0, 0>, <1 - 2y + a pi cos(pi y), 0>> 615367970cfSMatthew G. Knepley epsilon(u) = 1/2 (grad u + grad u^T) = \Delta Re/(4 mu) <<0, 1 - 2y + a pi cos(pi y)>, <<1 - 2y + a pi cos(pi y), 0>> 616367970cfSMatthew G. Knepley epsilon'(u) = epsilon(u) - 1/3 (div u) I = epsilon(u) 617367970cfSMatthew G. Knepley div epsilon'(u) = -\Delta Re/(2 mu) <1 + a pi^2/2 sin(pi y), 0> 618367970cfSMatthew G. Knepley 619367970cfSMatthew G. Knepley f = rho S du/dt + rho u \cdot \nabla u - 2\mu/Re div \epsilon'(u) + \nabla p + rho / F^2 \hat y 620367970cfSMatthew G. Knepley = 0 + 0 - div (2\mu/Re \epsilon'(u) - pI) + rho / F^2 \hat y 621367970cfSMatthew G. Knepley = -\Delta div <<x, (1 - 2y)/2 + a pi/2 cos(pi y)>, <<(1 - 2y)/2 + a pi/2 cos(pi y), x>> + rho / F^2 \hat y 622367970cfSMatthew G. Knepley = -\Delta <1 - 1 - a pi^2/2 sin(pi y), 0> + rho/F^2 <0, 1> 623367970cfSMatthew G. Knepley = a \Delta pi^2/2 sin(pi y) <1, 0> + rho/F^2 <0, 1> 624367970cfSMatthew G. Knepley 625367970cfSMatthew G. Knepley g = S rho_t + div (rho u) 626367970cfSMatthew G. Knepley = 0 + rho div (u) + u . grad rho 627367970cfSMatthew G. Knepley = 0 + 0 - pth u . grad T / T^2 628367970cfSMatthew G. Knepley = 0 629367970cfSMatthew G. Knepley 630367970cfSMatthew G. Knepley Q = rho c_p S dT/dt + rho c_p u . grad T - 1/Pe div k grad T 631367970cfSMatthew G. Knepley = 0 + c_p pth / T 0 - k/Pe div <0, 1 - 2y + a pi cos(pi y)> 632367970cfSMatthew G. Knepley = - k/Pe (-2 - a pi^2 sin(pi y)) 633367970cfSMatthew G. Knepley = 2 k/Pe (1 + a pi^2/2 sin(pi y)) 634367970cfSMatthew G. Knepley 635367970cfSMatthew G. Knepley The boundary conditions on the top and bottom are zero velocity and T_in temperature. The boundary term is 636367970cfSMatthew G. Knepley 637367970cfSMatthew G. Knepley (2\mu/Re \epsilon'(u) - p I) . n = \Delta <<x, (1 - 2y)/2 + a pi/2 cos(pi y)>, <<(1 - 2y)/2 + a pi/2 cos(pi y), x>> . n 638367970cfSMatthew G. Knepley 639367970cfSMatthew G. Knepley so that 640367970cfSMatthew G. Knepley 641367970cfSMatthew G. Knepley x = 0: \Delta <<0, (1 - 2y)/2>, <<(1 - 2y)/2, 0>> . <-1, 0> = <0, (2y - 1)/2 - a pi/2 cos(pi y)> 642367970cfSMatthew G. Knepley x = 1: \Delta <<1, (1 - 2y)/2>, <<(1 - 2y)/2, 1>> . < 1, 0> = <1, (1 - 2y)/2 + a pi/2 cos(pi y)> 643367970cfSMatthew G. Knepley */ 644d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_wiggly_u(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 645d71ae5a4SJacob Faibussowitsch { 646367970cfSMatthew G. Knepley Parameter *param = (Parameter *)ctx; 647367970cfSMatthew G. Knepley 648367970cfSMatthew G. Knepley u[0] = (0.5 * param->Reynolds / param->mu) * (X[1] * (1.0 - X[1]) + param->epsilon * PetscSinReal(PETSC_PI * X[1])); 649367970cfSMatthew G. Knepley u[1] = 0.0; 6503ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 651367970cfSMatthew G. Knepley } 652d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_wiggly_u_t(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *u, void *ctx) 653d71ae5a4SJacob Faibussowitsch { 654367970cfSMatthew G. Knepley u[0] = 0.0; 655367970cfSMatthew G. Knepley u[1] = 0.0; 6563ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 657367970cfSMatthew G. Knepley } 658367970cfSMatthew G. Knepley 659d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_wiggly_p(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *p, void *ctx) 660d71ae5a4SJacob Faibussowitsch { 661367970cfSMatthew G. Knepley p[0] = -X[0]; 6623ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 663367970cfSMatthew G. Knepley } 664d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_wiggly_p_t(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *p, void *ctx) 665d71ae5a4SJacob Faibussowitsch { 666367970cfSMatthew G. Knepley p[0] = 0.0; 6673ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 668367970cfSMatthew G. Knepley } 669367970cfSMatthew G. Knepley 670d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_wiggly_T(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 671d71ae5a4SJacob Faibussowitsch { 672367970cfSMatthew G. Knepley Parameter *param = (Parameter *)ctx; 673367970cfSMatthew G. Knepley 674367970cfSMatthew G. Knepley T[0] = X[1] * (1.0 - X[1]) + param->epsilon * PetscSinReal(PETSC_PI * X[1]) + param->T_in; 6753ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 676367970cfSMatthew G. Knepley } 677d71ae5a4SJacob Faibussowitsch static PetscErrorCode pipe_wiggly_T_t(PetscInt dim, PetscReal time, const PetscReal X[], PetscInt Nf, PetscScalar *T, void *ctx) 678d71ae5a4SJacob Faibussowitsch { 679367970cfSMatthew G. Knepley T[0] = 0.0; 6803ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 681367970cfSMatthew G. Knepley } 682367970cfSMatthew G. Knepley 683d71ae5a4SJacob Faibussowitsch static void f0_conduct_pipe_wiggly_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 684d71ae5a4SJacob Faibussowitsch { 685367970cfSMatthew G. Knepley const PetscReal F = PetscRealPart(constants[FROUDE]); 686367970cfSMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 687367970cfSMatthew G. Knepley const PetscReal T_in = PetscRealPart(constants[T_IN]); 688367970cfSMatthew G. Knepley const PetscReal eps = PetscRealPart(constants[EPSILON]); 689367970cfSMatthew G. Knepley const PetscReal rho = p_th / (X[1] * (1. - X[1]) + T_in); 690367970cfSMatthew G. Knepley const PetscInt gd = (PetscInt)PetscRealPart(constants[G_DIR]); 691367970cfSMatthew G. Knepley 692367970cfSMatthew G. Knepley f0[0] -= eps * 0.5 * PetscSqr(PETSC_PI) * PetscSinReal(PETSC_PI * X[1]); 693367970cfSMatthew G. Knepley f0[gd] -= rho / PetscSqr(F); 694367970cfSMatthew G. Knepley } 695367970cfSMatthew G. Knepley 696d71ae5a4SJacob Faibussowitsch static void f0_conduct_bd_pipe_wiggly_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 697d71ae5a4SJacob Faibussowitsch { 698367970cfSMatthew G. Knepley const PetscReal eps = PetscRealPart(constants[EPSILON]); 699*9fa27a79SStefano Zampini PetscReal sigma[4] = {X[0], (PetscReal)(0.5 * (1. - 2. * X[1]) + eps * 0.5 * PETSC_PI * PetscCosReal(PETSC_PI * X[1])), (PetscReal)(0.5 * (1. - 2. * X[1]) + eps * 0.5 * PETSC_PI * PetscCosReal(PETSC_PI * X[1])), X[0]}; 700367970cfSMatthew G. Knepley PetscInt d, e; 701367970cfSMatthew G. Knepley 702367970cfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 703ad540459SPierre Jolivet for (e = 0; e < dim; ++e) f0[d] -= sigma[d * dim + e] * n[e]; 704367970cfSMatthew G. Knepley } 705367970cfSMatthew G. Knepley } 706367970cfSMatthew G. Knepley 707d71ae5a4SJacob Faibussowitsch static void f0_conduct_pipe_wiggly_q(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 708d71ae5a4SJacob Faibussowitsch { 709367970cfSMatthew G. Knepley f0[0] += 0.0; 710367970cfSMatthew G. Knepley } 711367970cfSMatthew G. Knepley 712d71ae5a4SJacob Faibussowitsch static void f0_conduct_pipe_wiggly_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 713d71ae5a4SJacob Faibussowitsch { 714367970cfSMatthew G. Knepley const PetscReal k = PetscRealPart(constants[K]); 715367970cfSMatthew G. Knepley const PetscReal Pe = PetscRealPart(constants[PECLET]); 716367970cfSMatthew G. Knepley const PetscReal eps = PetscRealPart(constants[EPSILON]); 717367970cfSMatthew G. Knepley 718367970cfSMatthew G. Knepley f0[0] -= 2 * k / Pe * (1.0 + eps * 0.5 * PetscSqr(PETSC_PI) * PetscSinReal(PETSC_PI * X[1])); 719367970cfSMatthew G. Knepley } 720367970cfSMatthew G. Knepley 721444129b9SMatthew G. Knepley /* Physics Kernels */ 722444129b9SMatthew G. Knepley 723d71ae5a4SJacob Faibussowitsch static void f0_q(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 724d71ae5a4SJacob Faibussowitsch { 725649ef022SMatthew Knepley PetscInt d; 726649ef022SMatthew Knepley for (d = 0, f0[0] = 0.0; d < dim; ++d) f0[0] += u_x[d * dim + d]; 727649ef022SMatthew Knepley } 728649ef022SMatthew Knepley 729444129b9SMatthew G. Knepley /* -\frac{Sp^{th}}{T^2} \frac{\partial T}{\partial t} + \frac{p^{th}}{T} \nabla \cdot \vb{u} - \frac{p^{th}}{T^2} \vb{u} \cdot \nabla T */ 730d71ae5a4SJacob Faibussowitsch static void f0_conduct_q(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 731d71ae5a4SJacob Faibussowitsch { 732444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 733444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 734444129b9SMatthew G. Knepley PetscInt d; 735444129b9SMatthew G. Knepley 736444129b9SMatthew G. Knepley // -\frac{S p^{th}}{T^2} \frac{\partial T}{\partial t} 737444129b9SMatthew G. Knepley f0[0] += -u_t[uOff[TEMP]] * S * p_th / PetscSqr(u[uOff[TEMP]]); 738444129b9SMatthew G. Knepley 739444129b9SMatthew G. Knepley // \frac{p^{th}}{T} \nabla \cdot \vb{u} 740ad540459SPierre Jolivet for (d = 0; d < dim; ++d) f0[0] += p_th / u[uOff[TEMP]] * u_x[uOff_x[VEL] + d * dim + d]; 741444129b9SMatthew G. Knepley 742444129b9SMatthew G. Knepley // - \frac{p^{th}}{T^2} \vb{u} \cdot \nabla T 743ad540459SPierre Jolivet for (d = 0; d < dim; ++d) f0[0] -= p_th / (u[uOff[TEMP]] * u[uOff[TEMP]]) * u[uOff[VEL] + d] * u_x[uOff_x[TEMP] + d]; 744444129b9SMatthew G. Knepley 745444129b9SMatthew G. Knepley // Add in any fixed source term 746ad540459SPierre Jolivet if (NfAux > 0) f0[0] += a[aOff[MASS]]; 747444129b9SMatthew G. Knepley } 748444129b9SMatthew G. Knepley 749444129b9SMatthew G. Knepley /* \vb{u}_t + \vb{u} \cdot \nabla\vb{u} */ 750d71ae5a4SJacob Faibussowitsch static void f0_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 751d71ae5a4SJacob Faibussowitsch { 752444129b9SMatthew G. Knepley const PetscInt Nc = dim; 753444129b9SMatthew G. Knepley PetscInt c, d; 754444129b9SMatthew G. Knepley 755444129b9SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 756444129b9SMatthew G. Knepley /* \vb{u}_t */ 757444129b9SMatthew G. Knepley f0[c] += u_t[uOff[VEL] + c]; 758444129b9SMatthew G. Knepley /* \vb{u} \cdot \nabla\vb{u} */ 759444129b9SMatthew G. Knepley for (d = 0; d < dim; ++d) f0[c] += u[uOff[VEL] + d] * u_x[uOff_x[VEL] + c * dim + d]; 760444129b9SMatthew G. Knepley } 761444129b9SMatthew G. Knepley } 762444129b9SMatthew G. Knepley 763444129b9SMatthew G. Knepley /* \rho S \frac{\partial \vb{u}}{\partial t} + \rho \vb{u} \cdot \nabla \vb{u} + \rho \frac{\hat{\vb{z}}}{F^2} */ 764d71ae5a4SJacob Faibussowitsch static void f0_conduct_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 765d71ae5a4SJacob Faibussowitsch { 766444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 767444129b9SMatthew G. Knepley const PetscReal F = PetscRealPart(constants[FROUDE]); 768444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 769444129b9SMatthew G. Knepley const PetscReal rho = p_th / PetscRealPart(u[uOff[TEMP]]); 770444129b9SMatthew G. Knepley const PetscInt gdir = (PetscInt)PetscRealPart(constants[G_DIR]); 771444129b9SMatthew G. Knepley PetscInt Nc = dim; 772444129b9SMatthew G. Knepley PetscInt c, d; 773444129b9SMatthew G. Knepley 774444129b9SMatthew G. Knepley // \rho S \frac{\partial \vb{u}}{\partial t} 775ad540459SPierre Jolivet for (d = 0; d < dim; ++d) f0[d] = rho * S * u_t[uOff[VEL] + d]; 776444129b9SMatthew G. Knepley 777444129b9SMatthew G. Knepley // \rho \vb{u} \cdot \nabla \vb{u} 778444129b9SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 779ad540459SPierre Jolivet for (d = 0; d < dim; ++d) f0[c] += rho * u[uOff[VEL] + d] * u_x[uOff_x[VEL] + c * dim + d]; 780444129b9SMatthew G. Knepley } 781444129b9SMatthew G. Knepley 782444129b9SMatthew G. Knepley // rho \hat{z}/F^2 783444129b9SMatthew G. Knepley f0[gdir] += rho / (F * F); 784444129b9SMatthew G. Knepley 785444129b9SMatthew G. Knepley // Add in any fixed source term 786444129b9SMatthew G. Knepley if (NfAux > 0) { 787ad540459SPierre Jolivet for (d = 0; d < dim; ++d) f0[d] += a[aOff[MOMENTUM] + d]; 788444129b9SMatthew G. Knepley } 789444129b9SMatthew G. Knepley } 790444129b9SMatthew G. Knepley 791649ef022SMatthew Knepley /*f1_v = \nu[grad(u) + grad(u)^T] - pI */ 792d71ae5a4SJacob Faibussowitsch static void f1_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]) 793d71ae5a4SJacob Faibussowitsch { 794444129b9SMatthew G. Knepley const PetscReal nu = PetscRealPart(constants[NU]); 795649ef022SMatthew Knepley const PetscInt Nc = dim; 796649ef022SMatthew Knepley PetscInt c, d; 797649ef022SMatthew Knepley 798649ef022SMatthew Knepley for (c = 0; c < Nc; ++c) { 799ad540459SPierre Jolivet for (d = 0; d < dim; ++d) f1[c * dim + d] = nu * (u_x[c * dim + d] + u_x[d * dim + c]); 800649ef022SMatthew Knepley f1[c * dim + c] -= u[uOff[1]]; 801649ef022SMatthew Knepley } 802649ef022SMatthew Knepley } 803649ef022SMatthew Knepley 804444129b9SMatthew G. Knepley /* 2 \mu/Re (1/2 (\nabla \vb{u} + \nabla \vb{u}^T) - 1/3 (\nabla \cdot \vb{u}) I) - p I */ 805d71ae5a4SJacob Faibussowitsch static void f1_conduct_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]) 806d71ae5a4SJacob Faibussowitsch { 807444129b9SMatthew G. Knepley const PetscReal Re = PetscRealPart(constants[REYNOLDS]); 808444129b9SMatthew G. Knepley const PetscReal mu = PetscRealPart(constants[MU]); 809444129b9SMatthew G. Knepley const PetscReal coef = mu / Re; 810444129b9SMatthew G. Knepley PetscReal u_div = 0.0; 811444129b9SMatthew G. Knepley const PetscInt Nc = dim; 812444129b9SMatthew G. Knepley PetscInt c, d; 813444129b9SMatthew G. Knepley 814ad540459SPierre Jolivet for (c = 0; c < Nc; ++c) u_div += PetscRealPart(u_x[uOff_x[VEL] + c * dim + c]); 815444129b9SMatthew G. Knepley 816444129b9SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 817444129b9SMatthew G. Knepley // 2 \mu/Re 1/2 (\nabla \vb{u} + \nabla \vb{u}^T 818ad540459SPierre Jolivet for (d = 0; d < dim; ++d) f1[c * dim + d] += coef * (u_x[uOff_x[VEL] + c * dim + d] + u_x[uOff_x[VEL] + d * dim + c]); 819444129b9SMatthew G. Knepley // -2/3 \mu/Re (\nabla \cdot \vb{u}) I 820444129b9SMatthew G. Knepley f1[c * dim + c] -= 2.0 * coef / 3.0 * u_div; 821444129b9SMatthew G. Knepley } 822444129b9SMatthew G. Knepley 823444129b9SMatthew G. Knepley // -p I 824ad540459SPierre Jolivet for (c = 0; c < Nc; ++c) f1[c * dim + c] -= u[uOff[PRES]]; 825444129b9SMatthew G. Knepley } 826444129b9SMatthew G. Knepley 827444129b9SMatthew G. Knepley /* T_t + \vb{u} \cdot \nabla T */ 828d71ae5a4SJacob Faibussowitsch static void f0_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 829d71ae5a4SJacob Faibussowitsch { 830444129b9SMatthew G. Knepley PetscInt d; 831444129b9SMatthew G. Knepley 832444129b9SMatthew G. Knepley /* T_t */ 833444129b9SMatthew G. Knepley f0[0] += u_t[uOff[TEMP]]; 834444129b9SMatthew G. Knepley /* \vb{u} \cdot \nabla T */ 835444129b9SMatthew G. Knepley for (d = 0; d < dim; ++d) f0[0] += u[uOff[VEL] + d] * u_x[uOff_x[TEMP] + d]; 836444129b9SMatthew G. Knepley } 837444129b9SMatthew G. Knepley 838444129b9SMatthew G. Knepley /* \frac{C_p S p^{th}}{T} \frac{\partial T}{\partial t} + \frac{C_p p^{th}}{T} \vb{u} \cdot \nabla T */ 839d71ae5a4SJacob Faibussowitsch static void f0_conduct_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 840d71ae5a4SJacob Faibussowitsch { 841444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 842444129b9SMatthew G. Knepley const PetscReal c_p = PetscRealPart(constants[C_P]); 843444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 844444129b9SMatthew G. Knepley PetscInt d; 845444129b9SMatthew G. Knepley 846444129b9SMatthew G. Knepley // \frac{C_p S p^{th}}{T} \frac{\partial T}{\partial t} 847444129b9SMatthew G. Knepley f0[0] = c_p * S * p_th / u[uOff[TEMP]] * u_t[uOff[TEMP]]; 848444129b9SMatthew G. Knepley 849444129b9SMatthew G. Knepley // \frac{C_p p^{th}}{T} \vb{u} \cdot \nabla T 850ad540459SPierre Jolivet for (d = 0; d < dim; ++d) f0[0] += c_p * p_th / u[uOff[TEMP]] * u[uOff[VEL] + d] * u_x[uOff_x[TEMP] + d]; 851444129b9SMatthew G. Knepley 852444129b9SMatthew G. Knepley // Add in any fixed source term 853ad540459SPierre Jolivet if (NfAux > 0) f0[0] += a[aOff[ENERGY]]; 854444129b9SMatthew G. Knepley } 855444129b9SMatthew G. Knepley 856d71ae5a4SJacob Faibussowitsch static void f1_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]) 857d71ae5a4SJacob Faibussowitsch { 858444129b9SMatthew G. Knepley const PetscReal alpha = PetscRealPart(constants[ALPHA]); 859649ef022SMatthew Knepley PetscInt d; 860444129b9SMatthew G. Knepley 861649ef022SMatthew Knepley for (d = 0; d < dim; ++d) f1[d] = alpha * u_x[uOff_x[2] + d]; 862649ef022SMatthew Knepley } 863649ef022SMatthew Knepley 864444129b9SMatthew G. Knepley /* \frac{k}{Pe} \nabla T */ 865d71ae5a4SJacob Faibussowitsch static void f1_conduct_w(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]) 866d71ae5a4SJacob Faibussowitsch { 867444129b9SMatthew G. Knepley const PetscReal Pe = PetscRealPart(constants[PECLET]); 868444129b9SMatthew G. Knepley const PetscReal k = PetscRealPart(constants[K]); 869444129b9SMatthew G. Knepley PetscInt d; 870444129b9SMatthew G. Knepley 871444129b9SMatthew G. Knepley // \frac{k}{Pe} \nabla T 872ad540459SPierre Jolivet for (d = 0; d < dim; ++d) f1[d] = k / Pe * u_x[uOff_x[TEMP] + d]; 873444129b9SMatthew G. Knepley } 874444129b9SMatthew G. Knepley 875d71ae5a4SJacob Faibussowitsch static void g1_qu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]) 876d71ae5a4SJacob Faibussowitsch { 877649ef022SMatthew Knepley PetscInt d; 878649ef022SMatthew Knepley for (d = 0; d < dim; ++d) g1[d * dim + d] = 1.0; 879649ef022SMatthew Knepley } 880649ef022SMatthew Knepley 881d71ae5a4SJacob Faibussowitsch static void g0_vu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 882d71ae5a4SJacob Faibussowitsch { 883649ef022SMatthew Knepley PetscInt c, d; 884649ef022SMatthew Knepley const PetscInt Nc = dim; 885649ef022SMatthew Knepley 886649ef022SMatthew Knepley for (d = 0; d < dim; ++d) g0[d * dim + d] = u_tShift; 887649ef022SMatthew Knepley 888649ef022SMatthew Knepley for (c = 0; c < Nc; ++c) { 889ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g0[c * Nc + d] += u_x[c * Nc + d]; 890649ef022SMatthew Knepley } 891649ef022SMatthew Knepley } 892649ef022SMatthew Knepley 893d71ae5a4SJacob Faibussowitsch static void g1_vu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]) 894d71ae5a4SJacob Faibussowitsch { 895649ef022SMatthew Knepley PetscInt NcI = dim; 896649ef022SMatthew Knepley PetscInt NcJ = dim; 897649ef022SMatthew Knepley PetscInt c, d, e; 898649ef022SMatthew Knepley 899649ef022SMatthew Knepley for (c = 0; c < NcI; ++c) { 900649ef022SMatthew Knepley for (d = 0; d < NcJ; ++d) { 901649ef022SMatthew Knepley for (e = 0; e < dim; ++e) { 902ad540459SPierre Jolivet if (c == d) g1[(c * NcJ + d) * dim + e] += u[e]; 903649ef022SMatthew Knepley } 904649ef022SMatthew Knepley } 905649ef022SMatthew Knepley } 906649ef022SMatthew Knepley } 907649ef022SMatthew Knepley 908d71ae5a4SJacob Faibussowitsch static void g0_conduct_qu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 909d71ae5a4SJacob Faibussowitsch { 910444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 911444129b9SMatthew G. Knepley PetscInt d; 912444129b9SMatthew G. Knepley 913444129b9SMatthew G. Knepley // - \phi_i \frac{p^{th}}{T^2} \frac{\partial T}{\partial x_c} \psi_{j, u_c} 914ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g0[d] = -p_th / PetscSqr(u[uOff[TEMP]]) * u_x[uOff_x[TEMP] + d]; 915444129b9SMatthew G. Knepley } 916444129b9SMatthew G. Knepley 917d71ae5a4SJacob Faibussowitsch static void g1_conduct_qu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]) 918d71ae5a4SJacob Faibussowitsch { 919444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 920444129b9SMatthew G. Knepley PetscInt d; 921444129b9SMatthew G. Knepley 922444129b9SMatthew G. Knepley // \phi_i \frac{p^{th}}{T} \frac{\partial \psi_{u_c,j}}{\partial x_c} 923ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g1[d * dim + d] = p_th / u[uOff[TEMP]]; 924444129b9SMatthew G. Knepley } 925444129b9SMatthew G. Knepley 926d71ae5a4SJacob Faibussowitsch static void g0_conduct_qT(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 927d71ae5a4SJacob Faibussowitsch { 928444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 929444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 930444129b9SMatthew G. Knepley PetscInt d; 931444129b9SMatthew G. Knepley 932444129b9SMatthew G. Knepley // - \phi_i \frac{S p^{th}}{T^2} \psi_j 933444129b9SMatthew G. Knepley g0[0] -= S * p_th / PetscSqr(u[uOff[TEMP]]) * u_tShift; 934444129b9SMatthew G. Knepley // \phi_i 2 \frac{S p^{th}}{T^3} T_t \psi_j 935444129b9SMatthew G. Knepley g0[0] += 2.0 * S * p_th / PetscPowScalarInt(u[uOff[TEMP]], 3) * u_t[uOff[TEMP]]; 936444129b9SMatthew G. Knepley // \phi_i \frac{p^{th}}{T^2} \left( - \nabla \cdot \vb{u} \psi_j + \frac{2}{T} \vb{u} \cdot \nabla T \psi_j \right) 937ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g0[0] += p_th / PetscSqr(u[uOff[TEMP]]) * (-u_x[uOff_x[VEL] + d * dim + d] + 2.0 / u[uOff[TEMP]] * u[uOff[VEL] + d] * u_x[uOff_x[TEMP] + d]); 938444129b9SMatthew G. Knepley } 939444129b9SMatthew G. Knepley 940d71ae5a4SJacob Faibussowitsch static void g1_conduct_qT(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]) 941d71ae5a4SJacob Faibussowitsch { 942444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 943444129b9SMatthew G. Knepley PetscInt d; 944444129b9SMatthew G. Knepley 945444129b9SMatthew G. Knepley // - \phi_i \frac{p^{th}}{T^2} \vb{u} \cdot \nabla \psi_j 946ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g1[d] = -p_th / PetscSqr(u[uOff[TEMP]]) * u[uOff[VEL] + d]; 947444129b9SMatthew G. Knepley } 948444129b9SMatthew G. Knepley 949d71ae5a4SJacob Faibussowitsch static void g2_vp(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]) 950d71ae5a4SJacob Faibussowitsch { 951649ef022SMatthew Knepley PetscInt d; 952649ef022SMatthew Knepley for (d = 0; d < dim; ++d) g2[d * dim + d] = -1.0; 953649ef022SMatthew Knepley } 954649ef022SMatthew Knepley 955d71ae5a4SJacob Faibussowitsch static void g3_vu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]) 956d71ae5a4SJacob Faibussowitsch { 957444129b9SMatthew G. Knepley const PetscReal nu = PetscRealPart(constants[NU]); 958649ef022SMatthew Knepley const PetscInt Nc = dim; 959649ef022SMatthew Knepley PetscInt c, d; 960649ef022SMatthew Knepley 961649ef022SMatthew Knepley for (c = 0; c < Nc; ++c) { 962649ef022SMatthew Knepley for (d = 0; d < dim; ++d) { 963606d57d4SMatthew G. Knepley g3[((c * Nc + c) * dim + d) * dim + d] += nu; 964606d57d4SMatthew G. Knepley g3[((c * Nc + d) * dim + d) * dim + c] += nu; 965649ef022SMatthew Knepley } 966649ef022SMatthew Knepley } 967649ef022SMatthew Knepley } 968649ef022SMatthew Knepley 969d71ae5a4SJacob Faibussowitsch static void g0_conduct_vT(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 970d71ae5a4SJacob Faibussowitsch { 971444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 972444129b9SMatthew G. Knepley const PetscReal F = PetscRealPart(constants[FROUDE]); 973444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 974444129b9SMatthew G. Knepley const PetscInt gdir = (PetscInt)PetscRealPart(constants[G_DIR]); 975444129b9SMatthew G. Knepley const PetscInt Nc = dim; 976444129b9SMatthew G. Knepley PetscInt c, d; 977444129b9SMatthew G. Knepley 978444129b9SMatthew G. Knepley // - \vb{\phi}_i \cdot \vb{u}_t \frac{p^{th} S}{T^2} \psi_j 979ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g0[d] -= p_th * S / PetscSqr(u[uOff[TEMP]]) * u_t[uOff[VEL] + d]; 980444129b9SMatthew G. Knepley 981444129b9SMatthew G. Knepley // - \vb{\phi}_i \cdot \vb{u} \cdot \nabla \vb{u} \frac{p^{th}}{T^2} \psi_j 982444129b9SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 983ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g0[c] -= p_th / PetscSqr(u[uOff[TEMP]]) * u[uOff[VEL] + d] * u_x[uOff_x[VEL] + c * dim + d]; 984444129b9SMatthew G. Knepley } 985444129b9SMatthew G. Knepley 986444129b9SMatthew G. Knepley // - \vb{\phi}_i \cdot \vu{z} \frac{p^{th}}{T^2 F^2} \psi_j 987444129b9SMatthew G. Knepley g0[gdir] -= p_th / PetscSqr(u[uOff[TEMP]] * F); 988444129b9SMatthew G. Knepley } 989444129b9SMatthew G. Knepley 990d71ae5a4SJacob Faibussowitsch static void g0_conduct_vu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 991d71ae5a4SJacob Faibussowitsch { 992444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 993444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 994444129b9SMatthew G. Knepley const PetscInt Nc = dim; 995444129b9SMatthew G. Knepley PetscInt c, d; 996444129b9SMatthew G. Knepley 997444129b9SMatthew G. Knepley // \vb{\phi}_i \cdot S \rho \psi_j 998ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g0[d * dim + d] = S * p_th / u[uOff[TEMP]] * u_tShift; 999444129b9SMatthew G. Knepley 1000444129b9SMatthew G. Knepley // \phi^c_i \cdot \rho \frac{\partial u^c}{\partial x^d} \psi^d_j 1001444129b9SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 1002ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g0[c * Nc + d] += p_th / u[uOff[TEMP]] * u_x[uOff_x[VEL] + c * Nc + d]; 1003444129b9SMatthew G. Knepley } 1004444129b9SMatthew G. Knepley } 1005444129b9SMatthew G. Knepley 1006d71ae5a4SJacob Faibussowitsch static void g1_conduct_vu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]) 1007d71ae5a4SJacob Faibussowitsch { 1008444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 1009444129b9SMatthew G. Knepley const PetscInt NcI = dim; 1010444129b9SMatthew G. Knepley const PetscInt NcJ = dim; 1011444129b9SMatthew G. Knepley PetscInt c, d, e; 1012444129b9SMatthew G. Knepley 1013444129b9SMatthew G. Knepley // \phi^c_i \rho u^e \frac{\partial \psi^d_j}{\partial x^e} 1014444129b9SMatthew G. Knepley for (c = 0; c < NcI; ++c) { 1015444129b9SMatthew G. Knepley for (d = 0; d < NcJ; ++d) { 1016444129b9SMatthew G. Knepley for (e = 0; e < dim; ++e) { 1017ad540459SPierre Jolivet if (c == d) g1[(c * NcJ + d) * dim + e] += p_th / u[uOff[TEMP]] * u[uOff[VEL] + e]; 1018444129b9SMatthew G. Knepley } 1019444129b9SMatthew G. Knepley } 1020444129b9SMatthew G. Knepley } 1021444129b9SMatthew G. Knepley } 1022444129b9SMatthew G. Knepley 1023d71ae5a4SJacob Faibussowitsch static void g3_conduct_vu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]) 1024d71ae5a4SJacob Faibussowitsch { 1025444129b9SMatthew G. Knepley const PetscReal Re = PetscRealPart(constants[REYNOLDS]); 1026444129b9SMatthew G. Knepley const PetscReal mu = PetscRealPart(constants[MU]); 1027444129b9SMatthew G. Knepley const PetscInt Nc = dim; 1028444129b9SMatthew G. Knepley PetscInt c, d; 1029444129b9SMatthew G. Knepley 1030444129b9SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 1031444129b9SMatthew G. Knepley for (d = 0; d < dim; ++d) { 1032444129b9SMatthew G. Knepley // \frac{\partial \phi^c_i}{\partial x^d} \mu/Re \frac{\partial \psi^c_i}{\partial x^d} 1033444129b9SMatthew G. Knepley g3[((c * Nc + c) * dim + d) * dim + d] += mu / Re; // gradU 1034444129b9SMatthew G. Knepley // \frac{\partial \phi^c_i}{\partial x^d} \mu/Re \frac{\partial \psi^d_i}{\partial x^c} 1035444129b9SMatthew G. Knepley g3[((c * Nc + d) * dim + d) * dim + c] += mu / Re; // gradU transpose 1036444129b9SMatthew G. Knepley // \frac{\partial \phi^c_i}{\partial x^d} -2/3 \mu/Re \frac{\partial \psi^d_i}{\partial x^c} 1037444129b9SMatthew G. Knepley g3[((c * Nc + d) * dim + c) * dim + d] -= 2.0 / 3.0 * mu / Re; 1038444129b9SMatthew G. Knepley } 1039444129b9SMatthew G. Knepley } 1040444129b9SMatthew G. Knepley } 1041444129b9SMatthew G. Knepley 1042d71ae5a4SJacob Faibussowitsch static void g2_conduct_vp(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]) 1043d71ae5a4SJacob Faibussowitsch { 1044444129b9SMatthew G. Knepley PetscInt d; 1045ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g2[d * dim + d] = -1.0; 1046444129b9SMatthew G. Knepley } 1047444129b9SMatthew G. Knepley 1048d71ae5a4SJacob Faibussowitsch static void g0_wT(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 1049d71ae5a4SJacob Faibussowitsch { 1050a712f3bbSMatthew G. Knepley g0[0] = u_tShift; 1051649ef022SMatthew Knepley } 1052649ef022SMatthew Knepley 1053d71ae5a4SJacob Faibussowitsch static void g0_wu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 1054d71ae5a4SJacob Faibussowitsch { 1055649ef022SMatthew Knepley PetscInt d; 1056649ef022SMatthew Knepley for (d = 0; d < dim; ++d) g0[d] = u_x[uOff_x[2] + d]; 1057649ef022SMatthew Knepley } 1058649ef022SMatthew Knepley 1059d71ae5a4SJacob Faibussowitsch static void g1_wT(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]) 1060d71ae5a4SJacob Faibussowitsch { 1061649ef022SMatthew Knepley PetscInt d; 1062649ef022SMatthew Knepley for (d = 0; d < dim; ++d) g1[d] = u[uOff[0] + d]; 1063649ef022SMatthew Knepley } 1064649ef022SMatthew Knepley 1065d71ae5a4SJacob Faibussowitsch static void g3_wT(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]) 1066d71ae5a4SJacob Faibussowitsch { 1067444129b9SMatthew G. Knepley const PetscReal alpha = PetscRealPart(constants[ALPHA]); 1068649ef022SMatthew Knepley PetscInt d; 1069649ef022SMatthew Knepley 1070649ef022SMatthew Knepley for (d = 0; d < dim; ++d) g3[d * dim + d] = alpha; 1071649ef022SMatthew Knepley } 1072649ef022SMatthew Knepley 1073d71ae5a4SJacob Faibussowitsch static void g0_conduct_wu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 1074d71ae5a4SJacob Faibussowitsch { 1075444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 1076444129b9SMatthew G. Knepley const PetscReal c_p = PetscRealPart(constants[C_P]); 1077444129b9SMatthew G. Knepley PetscInt d; 1078444129b9SMatthew G. Knepley 1079444129b9SMatthew G. Knepley // \phi_i \frac{C_p p^{th}}{T} \nabla T \cdot \psi_j 1080ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g0[d] = c_p * p_th / u[uOff[TEMP]] * u_x[uOff_x[TEMP] + d]; 1081444129b9SMatthew G. Knepley } 1082444129b9SMatthew G. Knepley 1083d71ae5a4SJacob Faibussowitsch static void g0_conduct_wT(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 1084d71ae5a4SJacob Faibussowitsch { 1085444129b9SMatthew G. Knepley const PetscReal S = PetscRealPart(constants[STROUHAL]); 1086444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 1087444129b9SMatthew G. Knepley const PetscReal c_p = PetscRealPart(constants[C_P]); 1088444129b9SMatthew G. Knepley PetscInt d; 1089444129b9SMatthew G. Knepley 1090444129b9SMatthew G. Knepley // \psi_i C_p S p^{th}\T \psi_{j} 1091444129b9SMatthew G. Knepley g0[0] += c_p * S * p_th / u[uOff[TEMP]] * u_tShift; 1092444129b9SMatthew G. Knepley // - \phi_i C_p S p^{th}/T^2 T_t \psi_j 1093444129b9SMatthew G. Knepley g0[0] -= c_p * S * p_th / PetscSqr(u[uOff[TEMP]]) * u_t[uOff[TEMP]]; 1094444129b9SMatthew G. Knepley // - \phi_i C_p p^{th}/T^2 \vb{u} \cdot \nabla T \psi_j 1095ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g0[0] -= c_p * p_th / PetscSqr(u[uOff[TEMP]]) * u[uOff[VEL] + d] * u_x[uOff_x[TEMP] + d]; 1096444129b9SMatthew G. Knepley } 1097444129b9SMatthew G. Knepley 1098d71ae5a4SJacob Faibussowitsch static void g1_conduct_wT(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]) 1099d71ae5a4SJacob Faibussowitsch { 1100444129b9SMatthew G. Knepley const PetscReal p_th = PetscRealPart(constants[P_TH]); 1101444129b9SMatthew G. Knepley const PetscReal c_p = PetscRealPart(constants[C_P]); 1102444129b9SMatthew G. Knepley PetscInt d; 1103444129b9SMatthew G. Knepley 1104444129b9SMatthew G. Knepley // \phi_i C_p p^{th}/T \vb{u} \cdot \nabla \psi_j 1105ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g1[d] += c_p * p_th / u[uOff[TEMP]] * u[uOff[VEL] + d]; 1106444129b9SMatthew G. Knepley } 1107444129b9SMatthew G. Knepley 1108d71ae5a4SJacob Faibussowitsch static void g3_conduct_wT(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]) 1109d71ae5a4SJacob Faibussowitsch { 1110444129b9SMatthew G. Knepley const PetscReal Pe = PetscRealPart(constants[PECLET]); 1111444129b9SMatthew G. Knepley const PetscReal k = PetscRealPart(constants[K]); 1112444129b9SMatthew G. Knepley PetscInt d; 1113444129b9SMatthew G. Knepley 1114444129b9SMatthew G. Knepley // \nabla \phi_i \frac{k}{Pe} \nabla \phi_j 1115ad540459SPierre Jolivet for (d = 0; d < dim; ++d) g3[d * dim + d] = k / Pe; 1116444129b9SMatthew G. Knepley } 1117444129b9SMatthew G. Knepley 1118d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 1119d71ae5a4SJacob Faibussowitsch { 1120444129b9SMatthew G. Knepley PetscInt mod, sol; 1121649ef022SMatthew Knepley 1122649ef022SMatthew Knepley PetscFunctionBeginUser; 1123444129b9SMatthew G. Knepley options->modType = MOD_INCOMPRESSIBLE; 1124649ef022SMatthew Knepley options->solType = SOL_QUADRATIC; 1125444129b9SMatthew G. Knepley options->hasNullSpace = PETSC_TRUE; 1126367970cfSMatthew G. Knepley options->dmCell = NULL; 1127649ef022SMatthew Knepley 1128d0609cedSBarry Smith PetscOptionsBegin(comm, "", "Low Mach flow Problem Options", "DMPLEX"); 1129444129b9SMatthew G. Knepley mod = options->modType; 11309566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-mod_type", "The model type", "ex76.c", modTypes, NUM_MOD_TYPES, modTypes[options->modType], &mod, NULL)); 1131444129b9SMatthew G. Knepley options->modType = (ModType)mod; 1132649ef022SMatthew Knepley sol = options->solType; 11339566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-sol_type", "The solution type", "ex76.c", solTypes, NUM_SOL_TYPES, solTypes[options->solType], &sol, NULL)); 1134649ef022SMatthew Knepley options->solType = (SolType)sol; 1135d0609cedSBarry Smith PetscOptionsEnd(); 11363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1137649ef022SMatthew Knepley } 1138649ef022SMatthew Knepley 1139d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupParameters(DM dm, AppCtx *user) 1140d71ae5a4SJacob Faibussowitsch { 1141649ef022SMatthew Knepley PetscBag bag; 1142649ef022SMatthew Knepley Parameter *p; 1143444129b9SMatthew G. Knepley PetscReal dir; 1144444129b9SMatthew G. Knepley PetscInt dim; 1145649ef022SMatthew Knepley 1146649ef022SMatthew Knepley PetscFunctionBeginUser; 11479566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1148444129b9SMatthew G. Knepley dir = (PetscReal)(dim - 1); 1149649ef022SMatthew Knepley /* setup PETSc parameter bag */ 11509566063dSJacob Faibussowitsch PetscCall(PetscBagGetData(user->bag, (void **)&p)); 11519566063dSJacob Faibussowitsch PetscCall(PetscBagSetName(user->bag, "par", "Low Mach flow parameters")); 1152649ef022SMatthew Knepley bag = user->bag; 11539566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->Strouhal, 1.0, "S", "Strouhal number")); 11549566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->Froude, 1.0, "Fr", "Froude number")); 11559566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->Reynolds, 1.0, "Re", "Reynolds number")); 11569566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->Peclet, 1.0, "Pe", "Peclet number")); 11579566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->p_th, 1.0, "p_th", "Thermodynamic pressure")); 11589566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->mu, 1.0, "mu", "Dynamic viscosity")); 11599566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->nu, 1.0, "nu", "Kinematic viscosity")); 11609566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->c_p, 1.0, "c_p", "Specific heat at constant pressure")); 11619566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->k, 1.0, "k", "Thermal conductivity")); 11629566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->alpha, 1.0, "alpha", "Thermal diffusivity")); 11639566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->T_in, 1.0, "T_in", "Inlet temperature")); 11649566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->g_dir, dir, "g_dir", "Gravity direction")); 11659566063dSJacob Faibussowitsch PetscCall(PetscBagRegisterReal(bag, &p->epsilon, 1.0, "epsilon", "Perturbation strength")); 11663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1167649ef022SMatthew Knepley } 1168649ef022SMatthew Knepley 1169d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 1170d71ae5a4SJacob Faibussowitsch { 1171649ef022SMatthew Knepley PetscFunctionBeginUser; 11729566063dSJacob Faibussowitsch PetscCall(DMCreate(comm, dm)); 11739566063dSJacob Faibussowitsch PetscCall(DMSetType(*dm, DMPLEX)); 11749566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(*dm)); 11759566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 11763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1177649ef022SMatthew Knepley } 1178649ef022SMatthew Knepley 1179d71ae5a4SJacob Faibussowitsch static PetscErrorCode UniformBoundaryConditions(DM dm, DMLabel label, PetscSimplePointFunc exactFuncs[], PetscSimplePointFunc exactFuncs_t[], AppCtx *user) 1180d71ae5a4SJacob Faibussowitsch { 1181444129b9SMatthew G. Knepley PetscDS ds; 1182444129b9SMatthew G. Knepley PetscInt id; 1183444129b9SMatthew G. Knepley void *ctx; 1184444129b9SMatthew G. Knepley 1185444129b9SMatthew G. Knepley PetscFunctionBeginUser; 11869566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 11879566063dSJacob Faibussowitsch PetscCall(PetscBagGetData(user->bag, &ctx)); 1188444129b9SMatthew G. Knepley id = 3; 11899566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "top wall velocity", label, 1, &id, VEL, 0, NULL, (void (*)(void))exactFuncs[VEL], (void (*)(void))exactFuncs_t[VEL], ctx, NULL)); 1190444129b9SMatthew G. Knepley id = 1; 11919566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "bottom wall velocity", label, 1, &id, VEL, 0, NULL, (void (*)(void))exactFuncs[VEL], (void (*)(void))exactFuncs_t[VEL], ctx, NULL)); 1192444129b9SMatthew G. Knepley id = 2; 11939566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "right wall velocity", label, 1, &id, VEL, 0, NULL, (void (*)(void))exactFuncs[VEL], (void (*)(void))exactFuncs_t[VEL], ctx, NULL)); 1194444129b9SMatthew G. Knepley id = 4; 11959566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "left wall velocity", label, 1, &id, VEL, 0, NULL, (void (*)(void))exactFuncs[VEL], (void (*)(void))exactFuncs_t[VEL], ctx, NULL)); 1196444129b9SMatthew G. Knepley id = 3; 11979566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "top wall temp", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 1198444129b9SMatthew G. Knepley id = 1; 11999566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "bottom wall temp", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 1200444129b9SMatthew G. Knepley id = 2; 12019566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "right wall temp", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 1202444129b9SMatthew G. Knepley id = 4; 12039566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "left wall temp", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 12043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1205444129b9SMatthew G. Knepley } 1206444129b9SMatthew G. Knepley 1207d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupProblem(DM dm, AppCtx *user) 1208d71ae5a4SJacob Faibussowitsch { 120945480ffeSMatthew G. Knepley PetscSimplePointFunc exactFuncs[3]; 121045480ffeSMatthew G. Knepley PetscSimplePointFunc exactFuncs_t[3]; 1211444129b9SMatthew G. Knepley PetscDS ds; 1212444129b9SMatthew G. Knepley PetscWeakForm wf; 121345480ffeSMatthew G. Knepley DMLabel label; 1214649ef022SMatthew Knepley Parameter *ctx; 1215444129b9SMatthew G. Knepley PetscInt id, bd; 1216649ef022SMatthew Knepley 1217649ef022SMatthew Knepley PetscFunctionBeginUser; 12189566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "marker", &label)); 12199566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 12209566063dSJacob Faibussowitsch PetscCall(PetscDSGetWeakForm(ds, &wf)); 1221444129b9SMatthew G. Knepley 1222444129b9SMatthew G. Knepley switch (user->modType) { 1223444129b9SMatthew G. Knepley case MOD_INCOMPRESSIBLE: 12249566063dSJacob Faibussowitsch PetscCall(PetscDSSetResidual(ds, VEL, f0_v, f1_v)); 12259566063dSJacob Faibussowitsch PetscCall(PetscDSSetResidual(ds, PRES, f0_q, NULL)); 12269566063dSJacob Faibussowitsch PetscCall(PetscDSSetResidual(ds, TEMP, f0_w, f1_w)); 1227444129b9SMatthew G. Knepley 12289566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, VEL, VEL, g0_vu, g1_vu, NULL, g3_vu)); 12299566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, VEL, PRES, NULL, NULL, g2_vp, NULL)); 12309566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, PRES, VEL, NULL, g1_qu, NULL, NULL)); 12319566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, TEMP, VEL, g0_wu, NULL, NULL, NULL)); 12329566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, TEMP, TEMP, g0_wT, g1_wT, NULL, g3_wT)); 1233444129b9SMatthew G. Knepley 1234649ef022SMatthew Knepley switch (user->solType) { 1235649ef022SMatthew Knepley case SOL_QUADRATIC: 12369566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, VEL, 0, 1, f0_quadratic_v, 0, NULL)); 12379566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, TEMP, 0, 1, f0_quadratic_w, 0, NULL)); 1238649ef022SMatthew Knepley 1239444129b9SMatthew G. Knepley exactFuncs[VEL] = quadratic_u; 1240444129b9SMatthew G. Knepley exactFuncs[PRES] = quadratic_p; 1241444129b9SMatthew G. Knepley exactFuncs[TEMP] = quadratic_T; 1242444129b9SMatthew G. Knepley exactFuncs_t[VEL] = quadratic_u_t; 1243444129b9SMatthew G. Knepley exactFuncs_t[PRES] = NULL; 1244444129b9SMatthew G. Knepley exactFuncs_t[TEMP] = quadratic_T_t; 1245444129b9SMatthew G. Knepley 12469566063dSJacob Faibussowitsch PetscCall(UniformBoundaryConditions(dm, label, exactFuncs, exactFuncs_t, user)); 1247649ef022SMatthew Knepley break; 1248649ef022SMatthew Knepley case SOL_CUBIC: 12499566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, VEL, 0, 1, f0_cubic_v, 0, NULL)); 12509566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, TEMP, 0, 1, f0_cubic_w, 0, NULL)); 1251649ef022SMatthew Knepley 1252444129b9SMatthew G. Knepley exactFuncs[VEL] = cubic_u; 1253444129b9SMatthew G. Knepley exactFuncs[PRES] = cubic_p; 1254444129b9SMatthew G. Knepley exactFuncs[TEMP] = cubic_T; 1255444129b9SMatthew G. Knepley exactFuncs_t[VEL] = cubic_u_t; 1256444129b9SMatthew G. Knepley exactFuncs_t[PRES] = NULL; 1257444129b9SMatthew G. Knepley exactFuncs_t[TEMP] = cubic_T_t; 1258444129b9SMatthew G. Knepley 12599566063dSJacob Faibussowitsch PetscCall(UniformBoundaryConditions(dm, label, exactFuncs, exactFuncs_t, user)); 1260649ef022SMatthew Knepley break; 1261649ef022SMatthew Knepley case SOL_CUBIC_TRIG: 12629566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, VEL, 0, 1, f0_cubic_trig_v, 0, NULL)); 12639566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, TEMP, 0, 1, f0_cubic_trig_w, 0, NULL)); 1264649ef022SMatthew Knepley 1265444129b9SMatthew G. Knepley exactFuncs[VEL] = cubic_trig_u; 1266444129b9SMatthew G. Knepley exactFuncs[PRES] = cubic_trig_p; 1267444129b9SMatthew G. Knepley exactFuncs[TEMP] = cubic_trig_T; 1268444129b9SMatthew G. Knepley exactFuncs_t[VEL] = cubic_trig_u_t; 1269444129b9SMatthew G. Knepley exactFuncs_t[PRES] = NULL; 1270444129b9SMatthew G. Knepley exactFuncs_t[TEMP] = cubic_trig_T_t; 1271444129b9SMatthew G. Knepley 12729566063dSJacob Faibussowitsch PetscCall(UniformBoundaryConditions(dm, label, exactFuncs, exactFuncs_t, user)); 1273649ef022SMatthew Knepley break; 1274606d57d4SMatthew G. Knepley case SOL_TAYLOR_GREEN: 12759566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, TEMP, 0, 1, f0_taylor_green_w, 0, NULL)); 1276606d57d4SMatthew G. Knepley 1277444129b9SMatthew G. Knepley exactFuncs[VEL] = taylor_green_u; 1278444129b9SMatthew G. Knepley exactFuncs[PRES] = taylor_green_p; 1279444129b9SMatthew G. Knepley exactFuncs[TEMP] = taylor_green_T; 1280444129b9SMatthew G. Knepley exactFuncs_t[VEL] = taylor_green_u_t; 1281444129b9SMatthew G. Knepley exactFuncs_t[PRES] = taylor_green_p_t; 1282444129b9SMatthew G. Knepley exactFuncs_t[TEMP] = taylor_green_T_t; 1283444129b9SMatthew G. Knepley 12849566063dSJacob Faibussowitsch PetscCall(UniformBoundaryConditions(dm, label, exactFuncs, exactFuncs_t, user)); 1285606d57d4SMatthew G. Knepley break; 1286d71ae5a4SJacob Faibussowitsch default: 1287d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Unsupported solution type: %s (%d)", solTypes[PetscMin(user->solType, NUM_SOL_TYPES)], user->solType); 1288649ef022SMatthew Knepley } 1289444129b9SMatthew G. Knepley break; 1290444129b9SMatthew G. Knepley case MOD_CONDUCTING: 12919566063dSJacob Faibussowitsch PetscCall(PetscDSSetResidual(ds, VEL, f0_conduct_v, f1_conduct_v)); 12929566063dSJacob Faibussowitsch PetscCall(PetscDSSetResidual(ds, PRES, f0_conduct_q, NULL)); 12939566063dSJacob Faibussowitsch PetscCall(PetscDSSetResidual(ds, TEMP, f0_conduct_w, f1_conduct_w)); 1294649ef022SMatthew Knepley 12959566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, VEL, VEL, g0_conduct_vu, g1_conduct_vu, NULL, g3_conduct_vu)); 12969566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, VEL, PRES, NULL, NULL, g2_conduct_vp, NULL)); 12979566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, VEL, TEMP, g0_conduct_vT, NULL, NULL, NULL)); 12989566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, PRES, VEL, g0_conduct_qu, g1_conduct_qu, NULL, NULL)); 12999566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, PRES, TEMP, g0_conduct_qT, g1_conduct_qT, NULL, NULL)); 13009566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, TEMP, VEL, g0_conduct_wu, NULL, NULL, NULL)); 13019566063dSJacob Faibussowitsch PetscCall(PetscDSSetJacobian(ds, TEMP, TEMP, g0_conduct_wT, g1_conduct_wT, NULL, g3_conduct_wT)); 1302649ef022SMatthew Knepley 1303444129b9SMatthew G. Knepley switch (user->solType) { 1304444129b9SMatthew G. Knepley case SOL_QUADRATIC: 13059566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, VEL, 0, 1, f0_conduct_quadratic_v, 0, NULL)); 13069566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, PRES, 0, 1, f0_conduct_quadratic_q, 0, NULL)); 13079566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, TEMP, 0, 1, f0_conduct_quadratic_w, 0, NULL)); 1308444129b9SMatthew G. Knepley 1309444129b9SMatthew G. Knepley exactFuncs[VEL] = quadratic_u; 1310444129b9SMatthew G. Knepley exactFuncs[PRES] = quadratic_p; 1311444129b9SMatthew G. Knepley exactFuncs[TEMP] = quadratic_T; 1312444129b9SMatthew G. Knepley exactFuncs_t[VEL] = quadratic_u_t; 1313444129b9SMatthew G. Knepley exactFuncs_t[PRES] = NULL; 1314444129b9SMatthew G. Knepley exactFuncs_t[TEMP] = quadratic_T_t; 1315444129b9SMatthew G. Knepley 13169566063dSJacob Faibussowitsch PetscCall(UniformBoundaryConditions(dm, label, exactFuncs, exactFuncs_t, user)); 1317444129b9SMatthew G. Knepley break; 1318444129b9SMatthew G. Knepley case SOL_PIPE: 1319444129b9SMatthew G. Knepley user->hasNullSpace = PETSC_FALSE; 13209566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, VEL, 0, 1, f0_conduct_pipe_v, 0, NULL)); 13219566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, PRES, 0, 1, f0_conduct_pipe_q, 0, NULL)); 13229566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, TEMP, 0, 1, f0_conduct_pipe_w, 0, NULL)); 1323444129b9SMatthew G. Knepley 1324444129b9SMatthew G. Knepley exactFuncs[VEL] = pipe_u; 1325444129b9SMatthew G. Knepley exactFuncs[PRES] = pipe_p; 1326444129b9SMatthew G. Knepley exactFuncs[TEMP] = pipe_T; 1327444129b9SMatthew G. Knepley exactFuncs_t[VEL] = pipe_u_t; 1328444129b9SMatthew G. Knepley exactFuncs_t[PRES] = pipe_p_t; 1329444129b9SMatthew G. Knepley exactFuncs_t[TEMP] = pipe_T_t; 1330444129b9SMatthew G. Knepley 13319566063dSJacob Faibussowitsch PetscCall(PetscBagGetData(user->bag, (void **)&ctx)); 1332444129b9SMatthew G. Knepley id = 2; 13339566063dSJacob Faibussowitsch PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "right wall", label, 1, &id, 0, 0, NULL, NULL, NULL, ctx, &bd)); 13349566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); 13359566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, VEL, 0, 0, f0_conduct_bd_pipe_v, 0, NULL)); 1336444129b9SMatthew G. Knepley id = 4; 13379566063dSJacob Faibussowitsch PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "left wall", label, 1, &id, 0, 0, NULL, NULL, NULL, ctx, &bd)); 13389566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); 13399566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, VEL, 0, 0, f0_conduct_bd_pipe_v, 0, NULL)); 1340444129b9SMatthew G. Knepley id = 4; 13419566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "left wall temperature", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 1342444129b9SMatthew G. Knepley id = 3; 13439566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "top wall velocity", label, 1, &id, VEL, 0, NULL, (void (*)(void))exactFuncs[VEL], (void (*)(void))exactFuncs_t[VEL], ctx, NULL)); 13449566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "top wall temperature", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 1345444129b9SMatthew G. Knepley id = 1; 13469566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "bottom wall velocity", label, 1, &id, VEL, 0, NULL, (void (*)(void))exactFuncs[VEL], (void (*)(void))exactFuncs_t[VEL], ctx, NULL)); 13479566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "bottom wall temperature", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 1348444129b9SMatthew G. Knepley break; 1349367970cfSMatthew G. Knepley case SOL_PIPE_WIGGLY: 1350367970cfSMatthew G. Knepley user->hasNullSpace = PETSC_FALSE; 13519566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, VEL, 0, 1, f0_conduct_pipe_wiggly_v, 0, NULL)); 13529566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, PRES, 0, 1, f0_conduct_pipe_wiggly_q, 0, NULL)); 13539566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, TEMP, 0, 1, f0_conduct_pipe_wiggly_w, 0, NULL)); 1354367970cfSMatthew G. Knepley 1355367970cfSMatthew G. Knepley exactFuncs[VEL] = pipe_wiggly_u; 1356367970cfSMatthew G. Knepley exactFuncs[PRES] = pipe_wiggly_p; 1357367970cfSMatthew G. Knepley exactFuncs[TEMP] = pipe_wiggly_T; 1358367970cfSMatthew G. Knepley exactFuncs_t[VEL] = pipe_wiggly_u_t; 1359367970cfSMatthew G. Knepley exactFuncs_t[PRES] = pipe_wiggly_p_t; 1360367970cfSMatthew G. Knepley exactFuncs_t[TEMP] = pipe_wiggly_T_t; 1361367970cfSMatthew G. Knepley 13629566063dSJacob Faibussowitsch PetscCall(PetscBagGetData(user->bag, (void **)&ctx)); 1363367970cfSMatthew G. Knepley id = 2; 13649566063dSJacob Faibussowitsch PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "right wall", label, 1, &id, 0, 0, NULL, NULL, NULL, ctx, &bd)); 13659566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); 13669566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, VEL, 0, 0, f0_conduct_bd_pipe_wiggly_v, 0, NULL)); 1367367970cfSMatthew G. Knepley id = 4; 13689566063dSJacob Faibussowitsch PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "left wall", label, 1, &id, 0, 0, NULL, NULL, NULL, ctx, &bd)); 13699566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); 13709566063dSJacob Faibussowitsch PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, VEL, 0, 0, f0_conduct_bd_pipe_wiggly_v, 0, NULL)); 1371367970cfSMatthew G. Knepley id = 4; 13729566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "left wall temperature", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 1373367970cfSMatthew G. Knepley id = 3; 13749566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "top wall velocity", label, 1, &id, VEL, 0, NULL, (void (*)(void))exactFuncs[VEL], (void (*)(void))exactFuncs_t[VEL], ctx, NULL)); 13759566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "top wall temperature", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 1376367970cfSMatthew G. Knepley id = 1; 13779566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "bottom wall velocity", label, 1, &id, VEL, 0, NULL, (void (*)(void))exactFuncs[VEL], (void (*)(void))exactFuncs_t[VEL], ctx, NULL)); 13789566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "bottom wall temperature", label, 1, &id, TEMP, 0, NULL, (void (*)(void))exactFuncs[TEMP], (void (*)(void))exactFuncs_t[TEMP], ctx, NULL)); 1379367970cfSMatthew G. Knepley break; 1380d71ae5a4SJacob Faibussowitsch default: 1381d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Unsupported solution type: %s (%d)", solTypes[PetscMin(user->solType, NUM_SOL_TYPES)], user->solType); 1382444129b9SMatthew G. Knepley } 1383444129b9SMatthew G. Knepley break; 1384d71ae5a4SJacob Faibussowitsch default: 1385d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Unsupported model type: %s (%d)", modTypes[PetscMin(user->modType, NUM_MOD_TYPES)], user->modType); 1386444129b9SMatthew G. Knepley } 1387649ef022SMatthew Knepley /* Setup constants */ 1388649ef022SMatthew Knepley { 1389649ef022SMatthew Knepley Parameter *param; 1390367970cfSMatthew G. Knepley PetscScalar constants[13]; 1391649ef022SMatthew Knepley 13929566063dSJacob Faibussowitsch PetscCall(PetscBagGetData(user->bag, (void **)¶m)); 1393649ef022SMatthew Knepley 1394444129b9SMatthew G. Knepley constants[STROUHAL] = param->Strouhal; 1395444129b9SMatthew G. Knepley constants[FROUDE] = param->Froude; 1396444129b9SMatthew G. Knepley constants[REYNOLDS] = param->Reynolds; 1397444129b9SMatthew G. Knepley constants[PECLET] = param->Peclet; 1398444129b9SMatthew G. Knepley constants[P_TH] = param->p_th; 1399444129b9SMatthew G. Knepley constants[MU] = param->mu; 1400444129b9SMatthew G. Knepley constants[NU] = param->nu; 1401444129b9SMatthew G. Knepley constants[C_P] = param->c_p; 1402444129b9SMatthew G. Knepley constants[K] = param->k; 1403444129b9SMatthew G. Knepley constants[ALPHA] = param->alpha; 1404444129b9SMatthew G. Knepley constants[T_IN] = param->T_in; 1405444129b9SMatthew G. Knepley constants[G_DIR] = param->g_dir; 1406367970cfSMatthew G. Knepley constants[EPSILON] = param->epsilon; 14079566063dSJacob Faibussowitsch PetscCall(PetscDSSetConstants(ds, 13, constants)); 1408649ef022SMatthew Knepley } 1409649ef022SMatthew Knepley 14109566063dSJacob Faibussowitsch PetscCall(PetscBagGetData(user->bag, (void **)&ctx)); 14119566063dSJacob Faibussowitsch PetscCall(PetscDSSetExactSolution(ds, VEL, exactFuncs[VEL], ctx)); 14129566063dSJacob Faibussowitsch PetscCall(PetscDSSetExactSolution(ds, PRES, exactFuncs[PRES], ctx)); 14139566063dSJacob Faibussowitsch PetscCall(PetscDSSetExactSolution(ds, TEMP, exactFuncs[TEMP], ctx)); 14149566063dSJacob Faibussowitsch PetscCall(PetscDSSetExactSolutionTimeDerivative(ds, VEL, exactFuncs_t[VEL], ctx)); 14159566063dSJacob Faibussowitsch PetscCall(PetscDSSetExactSolutionTimeDerivative(ds, PRES, exactFuncs_t[PRES], ctx)); 14169566063dSJacob Faibussowitsch PetscCall(PetscDSSetExactSolutionTimeDerivative(ds, TEMP, exactFuncs_t[TEMP], ctx)); 14173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1418649ef022SMatthew Knepley } 1419649ef022SMatthew Knepley 1420d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateCellDM(DM dm, AppCtx *user) 1421d71ae5a4SJacob Faibussowitsch { 1422367970cfSMatthew G. Knepley PetscFE fe, fediv; 1423367970cfSMatthew G. Knepley DMPolytopeType ct; 1424367970cfSMatthew G. Knepley PetscInt dim, cStart; 1425367970cfSMatthew G. Knepley PetscBool simplex; 1426367970cfSMatthew G. Knepley 1427367970cfSMatthew G. Knepley PetscFunctionBeginUser; 14289566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 14299566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 14309566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 1431367970cfSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE; 1432367970cfSMatthew G. Knepley 14339566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, VEL, NULL, (PetscObject *)&fe)); 14349566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, 1, simplex, "div_", PETSC_DEFAULT, &fediv)); 14359566063dSJacob Faibussowitsch PetscCall(PetscFECopyQuadrature(fe, fediv)); 14369566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fediv, "divergence")); 1437367970cfSMatthew G. Knepley 14389566063dSJacob Faibussowitsch PetscCall(DMDestroy(&user->dmCell)); 14399566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &user->dmCell)); 14409566063dSJacob Faibussowitsch PetscCall(DMSetField(user->dmCell, 0, NULL, (PetscObject)fediv)); 14419566063dSJacob Faibussowitsch PetscCall(DMCreateDS(user->dmCell)); 14429566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fediv)); 14433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1444367970cfSMatthew G. Knepley } 1445367970cfSMatthew G. Knepley 1446d71ae5a4SJacob Faibussowitsch static PetscErrorCode GetCellDM(DM dm, AppCtx *user, DM *dmCell) 1447d71ae5a4SJacob Faibussowitsch { 1448367970cfSMatthew G. Knepley PetscInt cStart, cEnd, cellStart = -1, cellEnd = -1; 1449367970cfSMatthew G. Knepley 1450367970cfSMatthew G. Knepley PetscFunctionBeginUser; 14519566063dSJacob Faibussowitsch PetscCall(DMPlexGetSimplexOrBoxCells(dm, 0, &cStart, &cEnd)); 14529566063dSJacob Faibussowitsch if (user->dmCell) PetscCall(DMPlexGetSimplexOrBoxCells(user->dmCell, 0, &cellStart, &cellEnd)); 14539566063dSJacob Faibussowitsch if (cStart != cellStart || cEnd != cellEnd) PetscCall(CreateCellDM(dm, user)); 1454367970cfSMatthew G. Knepley *dmCell = user->dmCell; 14553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1456367970cfSMatthew G. Knepley } 1457367970cfSMatthew G. Knepley 1458d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupDiscretization(DM dm, AppCtx *user) 1459d71ae5a4SJacob Faibussowitsch { 1460649ef022SMatthew Knepley DM cdm = dm; 1461367970cfSMatthew G. Knepley PetscFE fe[3]; 1462649ef022SMatthew Knepley Parameter *param; 1463649ef022SMatthew Knepley DMPolytopeType ct; 1464649ef022SMatthew Knepley PetscInt dim, cStart; 1465649ef022SMatthew Knepley PetscBool simplex; 1466649ef022SMatthew Knepley 1467649ef022SMatthew Knepley PetscFunctionBeginUser; 14689566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 14699566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 14709566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 1471649ef022SMatthew Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE; 1472649ef022SMatthew Knepley /* Create finite element */ 14739566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, dim, simplex, "vel_", PETSC_DEFAULT, &fe[0])); 14749566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe[0], "velocity")); 1475649ef022SMatthew Knepley 14769566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, 1, simplex, "pres_", PETSC_DEFAULT, &fe[1])); 14779566063dSJacob Faibussowitsch PetscCall(PetscFECopyQuadrature(fe[0], fe[1])); 14789566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe[1], "pressure")); 1479649ef022SMatthew Knepley 14809566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, 1, simplex, "temp_", PETSC_DEFAULT, &fe[2])); 14819566063dSJacob Faibussowitsch PetscCall(PetscFECopyQuadrature(fe[0], fe[2])); 14829566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe[2], "temperature")); 1483649ef022SMatthew Knepley 1484649ef022SMatthew Knepley /* Set discretization and boundary conditions for each mesh */ 14859566063dSJacob Faibussowitsch PetscCall(DMSetField(dm, VEL, NULL, (PetscObject)fe[VEL])); 14869566063dSJacob Faibussowitsch PetscCall(DMSetField(dm, PRES, NULL, (PetscObject)fe[PRES])); 14879566063dSJacob Faibussowitsch PetscCall(DMSetField(dm, TEMP, NULL, (PetscObject)fe[TEMP])); 14889566063dSJacob Faibussowitsch PetscCall(DMCreateDS(dm)); 14899566063dSJacob Faibussowitsch PetscCall(SetupProblem(dm, user)); 14909566063dSJacob Faibussowitsch PetscCall(PetscBagGetData(user->bag, (void **)¶m)); 1491649ef022SMatthew Knepley while (cdm) { 14929566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, cdm)); 14939566063dSJacob Faibussowitsch PetscCall(DMGetCoarseDM(cdm, &cdm)); 1494649ef022SMatthew Knepley } 14959566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe[VEL])); 14969566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe[PRES])); 14979566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe[TEMP])); 1498649ef022SMatthew Knepley 1499444129b9SMatthew G. Knepley if (user->hasNullSpace) { 1500649ef022SMatthew Knepley PetscObject pressure; 1501649ef022SMatthew Knepley MatNullSpace nullspacePres; 1502649ef022SMatthew Knepley 15039566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, PRES, NULL, &pressure)); 15049566063dSJacob Faibussowitsch PetscCall(MatNullSpaceCreate(PetscObjectComm(pressure), PETSC_TRUE, 0, NULL, &nullspacePres)); 15059566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose(pressure, "nullspace", (PetscObject)nullspacePres)); 15069566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullspacePres)); 1507649ef022SMatthew Knepley } 15083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1509649ef022SMatthew Knepley } 1510649ef022SMatthew Knepley 1511d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreatePressureNullSpace(DM dm, PetscInt ofield, PetscInt nfield, MatNullSpace *nullSpace) 1512d71ae5a4SJacob Faibussowitsch { 1513649ef022SMatthew Knepley Vec vec; 1514649ef022SMatthew Knepley PetscErrorCode (*funcs[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *) = {zero, zero, zero}; 1515649ef022SMatthew Knepley 1516649ef022SMatthew Knepley PetscFunctionBeginUser; 151763a3b9bcSJacob Faibussowitsch PetscCheck(ofield == PRES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Nullspace must be for pressure field at index %" PetscInt_FMT ", not %" PetscInt_FMT, PRES, ofield); 1518649ef022SMatthew Knepley funcs[nfield] = constant; 15199566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &vec)); 15209566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, 0.0, funcs, NULL, INSERT_ALL_VALUES, vec)); 15219566063dSJacob Faibussowitsch PetscCall(VecNormalize(vec, NULL)); 15229566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)vec, "Pressure Null Space")); 15239566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(vec, NULL, "-pressure_nullspace_view")); 15249566063dSJacob Faibussowitsch PetscCall(MatNullSpaceCreate(PetscObjectComm((PetscObject)dm), PETSC_FALSE, 1, &vec, nullSpace)); 15259566063dSJacob Faibussowitsch PetscCall(VecDestroy(&vec)); 15263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1527649ef022SMatthew Knepley } 1528649ef022SMatthew Knepley 1529d71ae5a4SJacob Faibussowitsch static PetscErrorCode RemoveDiscretePressureNullspace_Private(TS ts, Vec u) 1530d71ae5a4SJacob Faibussowitsch { 1531649ef022SMatthew Knepley DM dm; 1532444129b9SMatthew G. Knepley AppCtx *user; 1533649ef022SMatthew Knepley MatNullSpace nullsp; 1534649ef022SMatthew Knepley 15357510d9b0SBarry Smith PetscFunctionBeginUser; 15369566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 15379566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dm, &user)); 15383ba16761SJacob Faibussowitsch if (!user->hasNullSpace) PetscFunctionReturn(PETSC_SUCCESS); 15399566063dSJacob Faibussowitsch PetscCall(CreatePressureNullSpace(dm, 1, 1, &nullsp)); 15409566063dSJacob Faibussowitsch PetscCall(MatNullSpaceRemove(nullsp, u)); 15419566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullsp)); 15423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1543649ef022SMatthew Knepley } 1544649ef022SMatthew Knepley 1545649ef022SMatthew Knepley /* Make the discrete pressure discretely divergence free */ 1546d71ae5a4SJacob Faibussowitsch static PetscErrorCode RemoveDiscretePressureNullspace(TS ts) 1547d71ae5a4SJacob Faibussowitsch { 1548649ef022SMatthew Knepley Vec u; 1549649ef022SMatthew Knepley 15507510d9b0SBarry Smith PetscFunctionBeginUser; 15519566063dSJacob Faibussowitsch PetscCall(TSGetSolution(ts, &u)); 15529566063dSJacob Faibussowitsch PetscCall(RemoveDiscretePressureNullspace_Private(ts, u)); 15533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1554649ef022SMatthew Knepley } 1555649ef022SMatthew Knepley 1556d71ae5a4SJacob Faibussowitsch static void divergence(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar divu[]) 1557d71ae5a4SJacob Faibussowitsch { 1558367970cfSMatthew G. Knepley PetscInt d; 1559367970cfSMatthew G. Knepley 1560367970cfSMatthew G. Knepley divu[0] = 0.; 1561367970cfSMatthew G. Knepley for (d = 0; d < dim; ++d) divu[0] += u_x[d * dim + d]; 1562367970cfSMatthew G. Knepley } 1563367970cfSMatthew G. Knepley 1564d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetInitialConditions(TS ts, Vec u) 1565d71ae5a4SJacob Faibussowitsch { 1566444129b9SMatthew G. Knepley AppCtx *user; 1567649ef022SMatthew Knepley DM dm; 1568649ef022SMatthew Knepley PetscReal t; 1569649ef022SMatthew Knepley 15707510d9b0SBarry Smith PetscFunctionBeginUser; 15719566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 15729566063dSJacob Faibussowitsch PetscCall(TSGetTime(ts, &t)); 15739566063dSJacob Faibussowitsch PetscCall(DMComputeExactSolution(dm, t, u, NULL)); 15749566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dm, &user)); 15759566063dSJacob Faibussowitsch PetscCall(RemoveDiscretePressureNullspace_Private(ts, u)); 15763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1577649ef022SMatthew Knepley } 1578649ef022SMatthew Knepley 1579d71ae5a4SJacob Faibussowitsch static PetscErrorCode MonitorError(TS ts, PetscInt step, PetscReal crtime, Vec u, void *ctx) 1580d71ae5a4SJacob Faibussowitsch { 1581649ef022SMatthew Knepley PetscErrorCode (*exactFuncs[3])(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 1582649ef022SMatthew Knepley void *ctxs[3]; 1583a712f3bbSMatthew G. Knepley PetscPointFunc diagnostics[1] = {divergence}; 1584367970cfSMatthew G. Knepley DM dm, dmCell = NULL; 1585649ef022SMatthew Knepley PetscDS ds; 1586a712f3bbSMatthew G. Knepley Vec v, divu; 1587a712f3bbSMatthew G. Knepley PetscReal ferrors[3], massFlux; 1588649ef022SMatthew Knepley PetscInt f; 1589649ef022SMatthew Knepley 1590649ef022SMatthew Knepley PetscFunctionBeginUser; 15919566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 15929566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 1593649ef022SMatthew Knepley 15949566063dSJacob Faibussowitsch for (f = 0; f < 3; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f])); 15959566063dSJacob Faibussowitsch PetscCall(DMComputeL2FieldDiff(dm, crtime, exactFuncs, ctxs, u, ferrors)); 15969566063dSJacob Faibussowitsch PetscCall(GetCellDM(dm, (AppCtx *)ctx, &dmCell)); 15979566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dmCell, &divu)); 15989566063dSJacob Faibussowitsch PetscCall(DMProjectField(dmCell, crtime, u, diagnostics, INSERT_VALUES, divu)); 15999566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(divu, NULL, "-divu_vec_view")); 16009566063dSJacob Faibussowitsch PetscCall(VecNorm(divu, NORM_2, &massFlux)); 16019566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [%2.3g, %2.3g, %2.3g] ||div u||: %2.3g\n", (int)step, (double)crtime, (double)ferrors[0], (double)ferrors[1], (double)ferrors[2], (double)massFlux)); 1602649ef022SMatthew Knepley 16039566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view")); 1604649ef022SMatthew Knepley 16059566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &v)); 16069566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, crtime, exactFuncs, ctxs, INSERT_ALL_VALUES, v)); 16079566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)v, "Exact Solution")); 16089566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view")); 16099566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &v)); 1610649ef022SMatthew Knepley 16119566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(divu, NULL, "-div_vec_view")); 16129566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dmCell, &divu)); 1613a712f3bbSMatthew G. Knepley 16143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1615649ef022SMatthew Knepley } 1616649ef022SMatthew Knepley 1617d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 1618d71ae5a4SJacob Faibussowitsch { 1619649ef022SMatthew Knepley DM dm; /* problem definition */ 1620649ef022SMatthew Knepley TS ts; /* timestepper */ 1621649ef022SMatthew Knepley Vec u; /* solution */ 1622649ef022SMatthew Knepley AppCtx user; /* user-defined work context */ 1623649ef022SMatthew Knepley PetscReal t; 1624649ef022SMatthew Knepley 1625327415f7SBarry Smith PetscFunctionBeginUser; 16269566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 16279566063dSJacob Faibussowitsch PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 16289566063dSJacob Faibussowitsch PetscCall(PetscBagCreate(PETSC_COMM_WORLD, sizeof(Parameter), &user.bag)); 16299566063dSJacob Faibussowitsch PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 16309566063dSJacob Faibussowitsch PetscCall(SetupParameters(dm, &user)); 16319566063dSJacob Faibussowitsch PetscCall(TSCreate(PETSC_COMM_WORLD, &ts)); 16329566063dSJacob Faibussowitsch PetscCall(TSSetDM(ts, dm)); 16339566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(dm, &user)); 1634649ef022SMatthew Knepley /* Setup problem */ 16359566063dSJacob Faibussowitsch PetscCall(SetupDiscretization(dm, &user)); 16369566063dSJacob Faibussowitsch PetscCall(DMPlexCreateClosureIndex(dm, NULL)); 1637649ef022SMatthew Knepley 16389566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &u)); 16399566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Numerical Solution")); 16409566063dSJacob Faibussowitsch if (user.hasNullSpace) PetscCall(DMSetNullSpaceConstructor(dm, 1, CreatePressureNullSpace)); 1641649ef022SMatthew Knepley 16429566063dSJacob Faibussowitsch PetscCall(DMTSSetBoundaryLocal(dm, DMPlexTSComputeBoundary, &user)); 16439566063dSJacob Faibussowitsch PetscCall(DMTSSetIFunctionLocal(dm, DMPlexTSComputeIFunctionFEM, &user)); 16449566063dSJacob Faibussowitsch PetscCall(DMTSSetIJacobianLocal(dm, DMPlexTSComputeIJacobianFEM, &user)); 16459566063dSJacob Faibussowitsch PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP)); 16469566063dSJacob Faibussowitsch PetscCall(TSSetPreStep(ts, RemoveDiscretePressureNullspace)); 16479566063dSJacob Faibussowitsch PetscCall(TSSetFromOptions(ts)); 1648649ef022SMatthew Knepley 16499566063dSJacob Faibussowitsch PetscCall(TSSetComputeInitialCondition(ts, SetInitialConditions)); /* Must come after SetFromOptions() */ 16509566063dSJacob Faibussowitsch PetscCall(SetInitialConditions(ts, u)); 16519566063dSJacob Faibussowitsch PetscCall(TSGetTime(ts, &t)); 16529566063dSJacob Faibussowitsch PetscCall(DMSetOutputSequenceNumber(dm, 0, t)); 16539566063dSJacob Faibussowitsch PetscCall(DMTSCheckFromOptions(ts, u)); 16549566063dSJacob Faibussowitsch PetscCall(TSMonitorSet(ts, MonitorError, &user, NULL)); 1655649ef022SMatthew Knepley 16569566063dSJacob Faibussowitsch PetscCall(TSSolve(ts, u)); 16579566063dSJacob Faibussowitsch PetscCall(DMTSCheckFromOptions(ts, u)); 1658649ef022SMatthew Knepley 16599566063dSJacob Faibussowitsch PetscCall(VecDestroy(&u)); 16609566063dSJacob Faibussowitsch PetscCall(DMDestroy(&user.dmCell)); 16619566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 16629566063dSJacob Faibussowitsch PetscCall(TSDestroy(&ts)); 16639566063dSJacob Faibussowitsch PetscCall(PetscBagDestroy(&user.bag)); 16649566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 1665b122ec5aSJacob Faibussowitsch return 0; 1666649ef022SMatthew Knepley } 1667649ef022SMatthew Knepley 1668649ef022SMatthew Knepley /*TEST 1669649ef022SMatthew Knepley 1670444129b9SMatthew G. Knepley testset: 1671649ef022SMatthew Knepley requires: triangle !single 1672444129b9SMatthew G. Knepley args: -dm_plex_separate_marker \ 1673a712f3bbSMatthew G. Knepley -div_petscdualspace_lagrange_use_moments -div_petscdualspace_lagrange_moment_order 3 \ 1674444129b9SMatthew G. Knepley -snes_error_if_not_converged -snes_convergence_test correct_pressure \ 1675649ef022SMatthew Knepley -ksp_type fgmres -ksp_gmres_restart 10 -ksp_rtol 1.0e-9 -ksp_error_if_not_converged \ 1676444129b9SMatthew G. Knepley -pc_type fieldsplit -pc_fieldsplit_0_fields 0,2 -pc_fieldsplit_1_fields 1 \ 1677444129b9SMatthew G. Knepley -pc_fieldsplit_type schur -pc_fieldsplit_schur_factorization_type full \ 1678649ef022SMatthew Knepley -fieldsplit_0_pc_type lu \ 1679649ef022SMatthew Knepley -fieldsplit_pressure_ksp_rtol 1e-10 -fieldsplit_pressure_pc_type jacobi 1680649ef022SMatthew Knepley 1681444129b9SMatthew G. Knepley test: 1682444129b9SMatthew G. Knepley suffix: 2d_tri_p2_p1_p1 1683444129b9SMatthew G. Knepley args: -sol_type quadratic \ 1684444129b9SMatthew G. Knepley -vel_petscspace_degree 2 -pres_petscspace_degree 1 -temp_petscspace_degree 1 \ 1685444129b9SMatthew G. Knepley -dmts_check .001 -ts_max_steps 4 -ts_dt 0.1 1686444129b9SMatthew G. Knepley 1687649ef022SMatthew Knepley test: 1688649ef022SMatthew Knepley # Using -dm_refine 5 -convest_num_refine 2 gives L_2 convergence rate: [0.89, 0.011, 1.0] 1689649ef022SMatthew Knepley suffix: 2d_tri_p2_p1_p1_tconv 1690444129b9SMatthew G. Knepley args: -sol_type cubic_trig \ 1691649ef022SMatthew Knepley -vel_petscspace_degree 2 -pres_petscspace_degree 1 -temp_petscspace_degree 1 \ 1692444129b9SMatthew G. Knepley -ts_max_steps 4 -ts_dt 0.1 -ts_convergence_estimate -convest_num_refine 1 1693649ef022SMatthew Knepley 1694649ef022SMatthew Knepley test: 1695649ef022SMatthew Knepley # Using -dm_refine 3 -convest_num_refine 3 gives L_2 convergence rate: [3.0, 2.5, 1.9] 1696649ef022SMatthew Knepley suffix: 2d_tri_p2_p1_p1_sconv 1697444129b9SMatthew G. Knepley args: -sol_type cubic \ 1698649ef022SMatthew Knepley -vel_petscspace_degree 2 -pres_petscspace_degree 1 -temp_petscspace_degree 1 \ 1699444129b9SMatthew G. Knepley -ts_max_steps 1 -ts_dt 1e-4 -ts_convergence_estimate -ts_convergence_temporal 0 -convest_num_refine 1 1700649ef022SMatthew Knepley 1701649ef022SMatthew Knepley test: 1702649ef022SMatthew Knepley suffix: 2d_tri_p3_p2_p2 1703444129b9SMatthew G. Knepley args: -sol_type cubic \ 1704649ef022SMatthew Knepley -vel_petscspace_degree 3 -pres_petscspace_degree 2 -temp_petscspace_degree 2 \ 1705444129b9SMatthew G. Knepley -dmts_check .001 -ts_max_steps 4 -ts_dt 0.1 1706649ef022SMatthew Knepley 1707606d57d4SMatthew G. Knepley test: 1708606d57d4SMatthew G. Knepley # Using -dm_refine 3 -convest_num_refine 3 gives L_2 convergence rate: [3.0, 2.1, 3.1] 1709606d57d4SMatthew G. Knepley suffix: 2d_tri_p2_p1_p1_tg_sconv 1710444129b9SMatthew G. Knepley args: -sol_type taylor_green \ 1711606d57d4SMatthew G. Knepley -vel_petscspace_degree 2 -pres_petscspace_degree 1 -temp_petscspace_degree 1 \ 1712444129b9SMatthew G. Knepley -ts_max_steps 1 -ts_dt 1e-8 -ts_convergence_estimate -ts_convergence_temporal 0 -convest_num_refine 1 1713606d57d4SMatthew G. Knepley 1714606d57d4SMatthew G. Knepley test: 1715606d57d4SMatthew G. Knepley # Using -dm_refine 3 -convest_num_refine 2 gives L_2 convergence rate: [1.2, 1.5, 1.2] 1716606d57d4SMatthew G. Knepley suffix: 2d_tri_p2_p1_p1_tg_tconv 1717444129b9SMatthew G. Knepley args: -sol_type taylor_green \ 1718606d57d4SMatthew G. Knepley -vel_petscspace_degree 2 -pres_petscspace_degree 1 -temp_petscspace_degree 1 \ 1719444129b9SMatthew G. Knepley -ts_max_steps 4 -ts_dt 0.1 -ts_convergence_estimate -convest_num_refine 1 1720444129b9SMatthew G. Knepley 1721444129b9SMatthew G. Knepley testset: 1722444129b9SMatthew G. Knepley requires: triangle !single 1723444129b9SMatthew G. Knepley args: -dm_plex_separate_marker -mod_type conducting \ 1724a712f3bbSMatthew G. Knepley -div_petscdualspace_lagrange_use_moments -div_petscdualspace_lagrange_moment_order 3 \ 1725444129b9SMatthew G. Knepley -snes_error_if_not_converged -snes_max_linear_solve_fail 5 \ 172682894d03SBarry Smith -ksp_type fgmres -ksp_max_it 2 -ksp_gmres_restart 10 -ksp_rtol 1.0e-9 \ 1727444129b9SMatthew G. Knepley -pc_type fieldsplit -pc_fieldsplit_0_fields 0,2 -pc_fieldsplit_1_fields 1 \ 1728444129b9SMatthew G. Knepley -pc_fieldsplit_type schur -pc_fieldsplit_schur_factorization_type full \ 1729606d57d4SMatthew G. Knepley -fieldsplit_0_pc_type lu \ 1730606d57d4SMatthew G. Knepley -fieldsplit_pressure_ksp_rtol 1e-10 -fieldsplit_pressure_pc_type jacobi 1731606d57d4SMatthew G. Knepley 1732444129b9SMatthew G. Knepley test: 1733444129b9SMatthew G. Knepley # At this resolution, the rhs is inconsistent on some Newton steps 1734444129b9SMatthew G. Knepley suffix: 2d_tri_p2_p1_p1_conduct 1735444129b9SMatthew G. Knepley args: -sol_type quadratic \ 1736444129b9SMatthew G. Knepley -vel_petscspace_degree 2 -pres_petscspace_degree 1 -temp_petscspace_degree 1 \ 1737444129b9SMatthew G. Knepley -dmts_check .001 -ts_max_steps 4 -ts_dt 0.1 \ 1738444129b9SMatthew G. Knepley -pc_fieldsplit_schur_precondition full \ 1739444129b9SMatthew G. Knepley -fieldsplit_pressure_ksp_max_it 2 -fieldsplit_pressure_pc_type svd 1740444129b9SMatthew G. Knepley 1741444129b9SMatthew G. Knepley test: 1742444129b9SMatthew G. Knepley suffix: 2d_tri_p2_p1_p2_conduct_pipe 1743444129b9SMatthew G. Knepley args: -sol_type pipe \ 1744444129b9SMatthew G. Knepley -vel_petscspace_degree 2 -pres_petscspace_degree 1 -temp_petscspace_degree 2 \ 1745444129b9SMatthew G. Knepley -dmts_check .001 -ts_max_steps 4 -ts_dt 0.1 1746444129b9SMatthew G. Knepley 1747367970cfSMatthew G. Knepley test: 1748367970cfSMatthew G. Knepley suffix: 2d_tri_p2_p1_p2_conduct_pipe_wiggly_sconv 1749367970cfSMatthew G. Knepley args: -sol_type pipe_wiggly -Fr 1e10 \ 1750367970cfSMatthew G. Knepley -vel_petscspace_degree 2 -pres_petscspace_degree 1 -temp_petscspace_degree 2 \ 1751367970cfSMatthew G. Knepley -ts_convergence_estimate -ts_convergence_temporal 0 -convest_num_refine 1 \ 1752367970cfSMatthew G. Knepley -ts_max_steps 1 -ts_dt 1e10 \ 1753367970cfSMatthew G. Knepley -ksp_atol 1e-12 -ksp_max_it 300 \ 1754367970cfSMatthew G. Knepley -fieldsplit_pressure_ksp_atol 1e-14 1755367970cfSMatthew G. Knepley 1756649ef022SMatthew Knepley TEST*/ 1757