|
| 1 | +// Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at |
| 2 | +// the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights |
| 3 | +// reserved. See files LICENSE and NOTICE for details. |
| 4 | +// |
| 5 | +// This file is part of CEED, a collection of benchmarks, miniapps, software |
| 6 | +// libraries and APIs for efficient high-order finite element and spectral |
| 7 | +// element discretizations for exascale applications. For more information and |
| 8 | +// source code availability see http://github.com/ceed. |
| 9 | +// |
| 10 | +// The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, |
| 11 | +// a collaborative effort of two U.S. Department of Energy organizations (Office |
| 12 | +// of Science and the National Nuclear Security Administration) responsible for |
| 13 | +// the planning and preparation of a capable exascale ecosystem, including |
| 14 | +// software, applications, hardware, advanced system engineering and early |
| 15 | +// testbed platforms, in support of the nation's exascale computing imperative. |
| 16 | + |
| 17 | +/// @file |
| 18 | +/// Force of Richard problem 2D (quad element) using PETSc |
| 19 | + |
| 20 | +#ifndef RICHARD_FORCE2D_H |
| 21 | +#define RICHARD_FORCE2D_H |
| 22 | + |
| 23 | +#include <math.h> |
| 24 | +#include "utils.h" |
| 25 | + |
| 26 | +// See Matthew Farthing, Christopher Kees, Cass Miller (2003) |
| 27 | +// https://www.sciencedirect.com/science/article/pii/S0309170802001872 |
| 28 | +// ----------------------------------------------------------------------------- |
| 29 | +// Strong form: |
| 30 | +// k*K^{-1} * u = -\grad(p) + rho*g in \Omega x [0,T] |
| 31 | +// -\div(u) = -f + d (rho/rho_0*theta)/dt in \Omega x [0,T] |
| 32 | +// p = p_b on \Gamma_D x [0,T] |
| 33 | +// u.n = u_b on \Gamma_N x [0,T] |
| 34 | +// p = p_0 in \Omega, t = 0 |
| 35 | +// |
| 36 | +// Where g is gravity vector, rho = rho_0*exp(beta * (p - p0)), p0 = 101325 Pa is atmospheric pressure |
| 37 | +// f = fs/rho_0, where g is gravity, rho_0 is the density at p_0, K = kappa*I, and |
| 38 | +// k_r = b_a + alpha_a * (\psi - x2), where \psi = p / (rho_0 * norm(g)) and x2 is vertical axis |
| 39 | +// |
| 40 | +// Weak form: Find (u, p) \in VxQ (V=H(div), Q=L^2) on \Omega |
| 41 | +// (v, k*K^{-1} * u) -(v, rho*g) - (\div(v), p) = - <v, p_b*n>_{\Gamma_D} |
| 42 | +// -(q, \div(u)) = -(q, f) + (v, d (rho/rho_0*theta)/dt ) |
| 43 | +// |
| 44 | +// where k*K^{-1} = (rho_0^2*norm(g)/rho*k_r)*K^{-1} |
| 45 | +// This QFunction sets up the force |
| 46 | +// Inputs: |
| 47 | +// x : interpolation of the physical coordinate |
| 48 | +// w : weight of quadrature |
| 49 | +// J : dx/dX. x physical coordinate, X reference coordinate [-1,1]^dim |
| 50 | +// |
| 51 | +// Output: |
| 52 | +// force_u : which is 0.0 for this problem (-<v, p0 n> is in pressure-boundary qfunction) |
| 53 | +// force_p : -(q, f) = -\int( q * f * w*detJ)dx |
| 54 | +// ----------------------------------------------------------------------------- |
| 55 | +// We have 3 experiment parameters as described in Table 1:P1, P2, P3 |
| 56 | +// Matthew Farthing, Christopher Kees, Cass Miller (2003) |
| 57 | +// https://www.sciencedirect.com/science/article/pii/S0309170802001872 |
| 58 | +#ifndef RICHARD_CTX |
| 59 | +#define RICHARD_CTX |
| 60 | +typedef struct RICHARDContext_ *RICHARDContext; |
| 61 | +struct RICHARDContext_ { |
| 62 | + CeedScalar kappa; |
| 63 | + CeedScalar alpha_a; |
| 64 | + CeedScalar b_a; |
| 65 | + CeedScalar rho_0; |
| 66 | + CeedScalar beta; |
| 67 | + CeedScalar g; |
| 68 | + CeedScalar p0; |
| 69 | +}; |
| 70 | +#endif |
| 71 | +// ----------------------------------------------------------------------------- |
| 72 | +// Force evaluation for Richard problem |
| 73 | +// ----------------------------------------------------------------------------- |
| 74 | +CEED_QFUNCTION(RichardForce2D)(void *ctx, const CeedInt Q, |
| 75 | + const CeedScalar *const *in, |
| 76 | + CeedScalar *const *out) { |
| 77 | + // *INDENT-OFF* |
| 78 | + // Inputs |
| 79 | + const CeedScalar (*coords) = in[0], |
| 80 | + (*w) = in[1], |
| 81 | + (*dxdX)[2][CEED_Q_VLA] = (const CeedScalar(*)[2][CEED_Q_VLA])in[2]; |
| 82 | + // Outputs |
| 83 | + CeedScalar (*rhs_u) = out[0], (*rhs_p) = out[1], |
| 84 | + (*true_soln) = out[2]; |
| 85 | + // Context |
| 86 | + RICHARDContext context = (RICHARDContext)ctx; |
| 87 | + const CeedScalar kappa = context->kappa;//10.; |
| 88 | + // Quadrature Point Loop |
| 89 | + CeedPragmaSIMD |
| 90 | + for (CeedInt i=0; i<Q; i++) { |
| 91 | + // Setup, (x,y) and J = dx/dX |
| 92 | + CeedScalar x = coords[i+0*Q], y = coords[i+1*Q]; |
| 93 | + const CeedScalar J[2][2] = {{dxdX[0][0][i], dxdX[1][0][i]}, |
| 94 | + {dxdX[0][1][i], dxdX[1][1][i]}}; |
| 95 | + const CeedScalar det_J = MatDet2x2(J); |
| 96 | + // *INDENT-ON* |
| 97 | + CeedScalar pe = sin(PI_DOUBLE*x) * sin(PI_DOUBLE*y); |
| 98 | + CeedScalar grad_pe[2] = {PI_DOUBLE*cos(PI_DOUBLE*x) *sin(PI_DOUBLE*y), PI_DOUBLE*sin(PI_DOUBLE*x) *cos(PI_DOUBLE*y)}; |
| 99 | + CeedScalar K[2][2] = {{kappa, 0.},{0., kappa}}; |
| 100 | + CeedScalar ue[2]; |
| 101 | + AlphaMatVecMult2x2(-1., K, grad_pe, ue); |
| 102 | + CeedScalar f = 2*PI_DOUBLE*PI_DOUBLE*sin(PI_DOUBLE*x)*sin(PI_DOUBLE*y); |
| 103 | + |
| 104 | + // 1st eq: component 1 |
| 105 | + rhs_u[i+0*Q] = 0.; |
| 106 | + // 1st eq: component 2 |
| 107 | + rhs_u[i+1*Q] = 0.; |
| 108 | + // 2nd eq |
| 109 | + rhs_p[i] = -f*w[i]*det_J; |
| 110 | + // True solution Ue=[p,u] |
| 111 | + true_soln[i+0*Q] = pe; |
| 112 | + true_soln[i+1*Q] = ue[0]; |
| 113 | + true_soln[i+2*Q] = ue[1]; |
| 114 | + } // End of Quadrature Point Loop |
| 115 | + return 0; |
| 116 | +} |
| 117 | +// ----------------------------------------------------------------------------- |
| 118 | + |
| 119 | +#endif //End of RICHARD_FORCE2D_H |
0 commit comments