PISM, A Parallel Ice Sheet Model  stable v2.1.1 committed by Constantine Khrulev on 2024-12-04 13:36:58 -0900
BlatterTestCFBC.cc
Go to the documentation of this file.
1 /* Copyright (C) 2020, 2021, 2023 PISM Authors
2  *
3  * This file is part of PISM.
4  *
5  * PISM is free software; you can redistribute it and/or modify it under the
6  * terms of the GNU General Public License as published by the Free Software
7  * Foundation; either version 3 of the License, or (at your option) any later
8  * version.
9  *
10  * PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with PISM; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #include "pism/stressbalance/blatter/verification/BlatterTestCFBC.hh"
21 
22 #include "pism/rheology/FlowLaw.hh"
23 #include "pism/stressbalance/StressBalance.hh"
24 #include "pism/geometry/Geometry.hh"
25 #include "pism/stressbalance/blatter/verification/manufactured_solutions.hh"
26 
27 namespace pism {
28 namespace stressbalance {
29 
30 BlatterTestCFBC::BlatterTestCFBC(std::shared_ptr<const Grid> grid, int Mz, int coarsening_factor)
31  : Blatter(grid, Mz, coarsening_factor) {
32 
33  assert(m_flow_law->exponent() == 1.0);
34 
35  m_B = m_flow_law->hardness(1e5, 0.0);
36 
37  m_g = m_config->get_number("constants.standard_gravity");
38 
39  m_rho_i = m_config->get_number("constants.ice.density");
40 
41  m_rho_w = m_config->get_number("constants.sea_water.density");
42 
43  m_L = 2.0 * m_grid->Lx();
44 }
45 
46 bool BlatterTestCFBC::dirichlet_node(const DMDALocalInfo &info,
48  (void) info;
49  return I.i == 0;
50 }
51 
52 Vector2d BlatterTestCFBC::u_bc(double x, double y, double z) const {
53  (void) y;
54 
55  return blatter_xz_cfbc_exact(x, z, m_B, m_L, m_rho_i, m_rho_w, m_g);
56 }
57 
59  const double *surface,
60  const double *bed,
61  Vector2d *residual) {
62  (void) surface;
63  (void) bed;
64 
65  // compute x and z coordinates of quadrature points
66  double
67  *x = m_work[0],
68  *z = m_work[1];
69  {
70  double
71  *x_nodal = m_work[2],
72  *z_nodal = m_work[3];
73 
74  for (int n = 0; n < fem::q13d::n_chi; ++n) {
75  x_nodal[n] = element.x(n);
76  z_nodal[n] = element.z(n);
77  }
78 
79  element.evaluate(x_nodal, x);
80  element.evaluate(z_nodal, z);
81  }
82 
83  // loop over all quadrature points
84  for (int q = 0; q < element.n_pts(); ++q) {
85  auto W = element.weight(q) / m_scaling;
86 
87  auto F = blatter_xz_cfbc_source(x[q], z[q], m_L, m_rho_i, m_rho_w, m_g);
88 
89  // loop over all test functions
90  for (int t = 0; t < element.n_chi(); ++t) {
91  const auto &psi = element.chi(q, t);
92 
93  residual[t] += W * psi.val * F;
94  }
95  }
96 }
97 
99  const fem::Q1Element3Face &face,
100  Vector2d *residual) {
101  // compute x and z coordinates of quadrature points
102  double *x = m_work[0];
103  {
104  double *x_nodal = m_work[1];
105 
106  for (int n = 0; n < fem::q13d::n_chi; ++n) {
107  x_nodal[n] = element.x(n);
108  }
109 
110  face.evaluate(x_nodal, x);
111  }
112 
113  for (int q = 0; q < face.n_pts(); ++q) {
114  auto W = face.weight(q) / m_scaling;
115 
116  auto F = blatter_xz_cfbc_surface(x[q], m_L, m_rho_i, m_rho_w, m_g);
117 
118  // loop over all test functions
119  for (int t = 0; t < element.n_chi(); ++t) {
120  auto psi = face.chi(q, t);
121 
122  residual[t] += - W * psi * F;
123  }
124  }
125 }
126 
127 
129  const fem::Q1Element3Face &face,
130  const double *tauc_nodal,
131  const double *f_nodal,
132  const Vector2d *u_nodal,
133  Vector2d *residual) {
134  (void) tauc_nodal;
135  (void) f_nodal;
136  (void) u_nodal;
137 
138  // compute x and z coordinates of quadrature points
139  double *x = m_work[0];
140  {
141  double *x_nodal = m_work[1];
142 
143  for (int n = 0; n < fem::q13d::n_chi; ++n) {
144  x_nodal[n] = element.x(n);
145  }
146 
147  face.evaluate(x_nodal, x);
148  }
149 
150  for (int q = 0; q < face.n_pts(); ++q) {
151  auto W = face.weight(q) / m_scaling;
152 
153  auto F = blatter_xz_cfbc_base(x[q], m_L, m_rho_i, m_rho_w, m_g);
154 
155  // loop over all test functions
156  for (int t = 0; t < element.n_chi(); ++t) {
157  auto psi = face.chi(q, t);
158 
159  residual[t] += - W * psi * F;
160  }
161  }
162 }
163 
165  const double *tauc_nodal,
166  const double *f_nodal,
167  const Vector2d *u_nodal,
168  double K[2 * fem::q13d::n_chi][2 * fem::q13d::n_chi]) {
169  (void) face;
170  (void) tauc_nodal;
171  (void) f_nodal;
172  (void) u_nodal;
173  (void) K;
174  // empty: residual contribution from the basal boundary does not depend on ice velocity
175 }
176 
177 /*!
178  * Do not use the floatation criterion, i.e. assume that the ice is always grounded.
179  */
181 
183 
184  const array::Scalar &b = inputs.geometry->bed_elevation;
185 
186  {
187  array::AccessScope list{&b, &m_parameters};
188 
189  for (auto p = m_grid->points(); p; p.next()) {
190  const int i = p.i(), j = p.j();
191 
192  m_parameters(i, j).bed = b(i, j);
193  m_parameters(i, j).floatation = 0.0;
194  }
195  }
196 
197  m_parameters.update_ghosts();
198 }
199 
200 } // end of namespace stressbalance
201 } // end of namespace pism
const Config::ConstPtr m_config
configuration database used by this component
Definition: Component.hh:158
const std::shared_ptr< const Grid > m_grid
grid used by this component
Definition: Component.hh:156
array::Scalar2 bed_elevation
Definition: Geometry.hh:47
This class represents a 2D vector field (such as ice velocity) at a certain grid point.
Definition: Vector2d.hh:29
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition: Array.hh:65
void evaluate(const T *x, T *vals, T *dx, T *dy, T *dz) const
Given nodal values, compute the values and partial derivatives at the quadrature points.
Definition: Element.hh:278
const Germ & chi(unsigned int q, unsigned int k) const
Definition: Element.hh:73
int n_pts() const
Number of quadrature points.
Definition: Element.hh:80
int n_chi() const
Definition: Element.hh:65
double weight(unsigned int q) const
Weight of the quadrature point q
Definition: Element.hh:85
double weight(unsigned int q) const
Definition: Element.hh:407
const double & chi(unsigned int q, unsigned int k) const
Definition: Element.hh:412
void evaluate(const T *x, T *result) const
Definition: Element.hh:427
int n_pts() const
Number of quadrature points.
Definition: Element.hh:404
double z(int n) const
Definition: Element.hh:374
double x(int n) const
Definition: Element.hh:364
3D Q1 element
Definition: Element.hh:351
void residual_source_term(const fem::Q1Element3 &element, const double *surface, const double *bed, Vector2d *residual)
BlatterTestCFBC(std::shared_ptr< const Grid > grid, int Mz, int coarsening_factor)
void jacobian_basal(const fem::Q1Element3Face &face, const double *tauc_nodal, const double *f_nodal, const Vector2d *u_nodal, double K[2 *fem::q13d::n_chi][2 *fem::q13d::n_chi])
void init_2d_parameters(const Inputs &inputs)
Vector2d u_bc(double x, double y, double z) const
bool dirichlet_node(const DMDALocalInfo &info, const fem::Element3::GlobalIndex &I)
void residual_surface(const fem::Q1Element3 &element, const fem::Q1Element3Face &face, Vector2d *residual)
void residual_basal(const fem::Q1Element3 &element, const fem::Q1Element3Face &face, const double *tauc_nodal, const double *f_nodal, const Vector2d *u_nodal, Vector2d *residual)
virtual void init_2d_parameters(const Inputs &inputs)
Definition: Blatter.cc:532
double m_work[m_n_work][m_Nq]
Definition: Blatter.hh:108
array::Array2D< Parameters > m_parameters
Definition: Blatter.hh:79
std::shared_ptr< rheology::FlowLaw > m_flow_law
#define n
Definition: exactTestM.c:37
const int n_chi
Number of shape functions on a Q1 element.
Definition: FEM.hh:213
static double K(double psi_x, double psi_y, double speed, double epsilon)
Vector2d blatter_xz_cfbc_source(double x, double z, double L, double rho_i, double rho_w, double g)
static double F(double SL, double B, double H, double alpha)
Vector2d blatter_xz_cfbc_base(double x, double L, double rho_i, double rho_w, double g)
Vector2d blatter_xz_cfbc_exact(double x, double z, double B, double L, double rho_i, double rho_w, double g)
Vector2d blatter_xz_cfbc_surface(double x, double L, double rho_i, double rho_w, double g)
const int I[]
Definition: ssafd_code.cc:24