PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
BlatterISMIPHOM.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/ismip-hom/BlatterISMIPHOM.hh"
21 
22 #include "pism/util/node_types.hh"
23 
24 namespace pism {
25 namespace stressbalance {
26 
27 static double A_surface(double x, double y, double L) {
28  (void) y;
29  (void) L;
30  double alpha = 0.5 * (M_PI / 180.0); // 0.5 degrees
31  return -x * tan(alpha);
32 }
33 
34 static double A_bed(double x, double y, double L) {
35  double omega = 2 * M_PI / L;
36  return A_surface(x, y, L) - 1000.0 + 500.0 * sin(omega * x) * sin(omega * y);
37 }
38 
39 static double B_bed(double x, double y, double L) {
40  (void) y;
41  double omega = 2 * M_PI / L;
42  return A_surface(x, y, L) - 1000.0 + 500.0 * sin(omega * x);
43 }
44 
45 static double C_surface(double x, double y, double L) {
46  (void) y;
47  (void) L;
48  double alpha = 0.1 * (M_PI / 180.0); // 0.1 degrees
49  return -x * tan(alpha);
50 }
51 
52 static double C_bed(double x, double y, double L) {
53  return C_surface(x, y, L) - 1000.0;
54 }
55 
56 BlatterISMIPHOM::BlatterISMIPHOM(std::shared_ptr<const Grid> grid,
57  int Mz,
58  int coarsening_factor,
59  ISMIPHOMTest test)
60  : Blatter(grid, Mz, coarsening_factor),
61  m_test(test),
62  m_L(2.0 * grid->Lx()) {
63 
64  char testname[] = "ABCD";
65  m_log->message(2, "Running ISMIP-HOM Experiment %c (L = %d km)...\n",
66  testname[m_test],
67  (int)(m_L * 1e-3));
68 
69  switch (m_test) {
70  case HOM_A:
71  m_b = A_bed;
72  m_s = A_surface;
73  break;
74  case HOM_B:
75  m_b = B_bed;
76  // test B surface is the same as for test A
77  m_s = A_surface;
78  break;
79  case HOM_C:
80  m_b = C_bed;
81  m_s = C_surface;
82  break;
83  case HOM_D:
84  // test D geometry is the same as for test C
85  m_b = C_bed;
86  m_s = C_surface;
87  break;
88  default:
89  m_b = nullptr;
90  m_s = nullptr;
91  break;
92  }
93 }
94 
96  Parameters **P,
97  int i,
98  int j,
99  int *node_type,
100  double *bottom_elevation,
101  double *ice_thickness,
102  double *surface_elevation,
103  double *sea_level) const {
104  (void) P;
105 
106  // This method is called before we get a chance to "reset" the current element, so the
107  // element argument does not yet know about its physical coordinates. This is why we
108  // have to compute x and y "by hand".
109  double
110  x_min = m_grid->x0() - m_grid->Lx(),
111  y_min = m_grid->y0() - m_grid->Ly(),
112  dx = m_grid->dx(),
113  dy = m_grid->dy();
114 
115  for (int n = 0; n < fem::q13d::n_chi; ++n) {
116  auto I = element.local_to_global(i, j, 0, n);
117 
118  double
119  x = x_min + I.i * dx,
120  y = y_min + I.j * dy;
121 
122  node_type[n] = NODE_INTERIOR;
123  bottom_elevation[n] = m_b(x, y, m_L);
124  ice_thickness[n] = m_s(x, y, m_L) - m_b(x, y, m_L);
125 
126  if (surface_elevation) {
127  surface_elevation[n] = m_s(x, y, m_L);
128  }
129 
130  if (sea_level) {
131  // set sea level low enough to ensure that all ice is grounded
132  sea_level[n] = bottom_elevation[n] - 1.0;
133  }
134  }
135 }
136 
137 
138 } // end of namespace stressbalance
139 } // end of namespace pism
const Logger::ConstPtr m_log
logger (for easy access)
Definition: Component.hh:162
const std::shared_ptr< const Grid > m_grid
grid used by this component
Definition: Component.hh:156
GlobalIndex local_to_global(int i, int j, int k, unsigned int n) const
Definition: Element.hh:298
3D Q1 element
Definition: Element.hh:351
void nodal_parameter_values(const fem::Q1Element3 &element, Parameters **P, int i, int j, int *node_type, double *bottom, double *thickness, double *surface, double *sea_level) const
BlatterISMIPHOM(std::shared_ptr< const Grid > grid, int Mz, int coarsening_factor, ISMIPHOMTest test)
static const double L
Definition: exactTestL.cc:40
#define n
Definition: exactTestM.c:37
const int n_chi
Number of shape functions on a Q1 element.
Definition: FEM.hh:213
static double A_surface(double x, double y, double L)
static double C_surface(double x, double y, double L)
static double A_bed(double x, double y, double L)
static double C_bed(double x, double y, double L)
static double B_bed(double x, double y, double L)
@ NODE_INTERIOR
Definition: node_types.hh:34
const int I[]
Definition: ssafd_code.cc:24