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