PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
Staggered.cc
Go to the documentation of this file.
1 /* Copyright (C) 2022, 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/util/array/Staggered.hh"
21 
22 #include "pism/util/Mask.hh"
23 
24 #include "pism/util/pism_utilities.hh"
25 #include "pism/util/array/CellType.hh"
26 #include "pism/util/array/Vector.hh"
27 
28 namespace pism {
29 namespace array {
30 
31 Staggered::Staggered(std::shared_ptr<const Grid> grid, const std::string &name)
32  : Array(grid, name, WITHOUT_GHOSTS, 2, 1, {0.0}) {
33  set_begin_access_use_dof(true);
34 }
35 
36 Staggered::Staggered(std::shared_ptr<const Grid> grid, const std::string &name,
37  unsigned int stencil_width)
38  : Array(grid, name, WITH_GHOSTS, 2, stencil_width, {0.0}){
39  set_begin_access_use_dof(true);
40 }
41 
42 void Staggered::copy_from(const Staggered &input) {
43  array::AccessScope list {this, &input};
44  // FIXME: this should be simplified
45 
46  ParallelSection loop(grid()->com);
47  try {
48  for (auto p = grid()->points(); p; p.next()) {
49  const int i = p.i(), j = p.j();
50 
51  (*this)(i, j, 0) = input(i, j, 0);
52  (*this)(i, j, 1) = input(i, j, 1);
53  }
54  } catch (...) {
55  loop.failed();
56  }
57  loop.check();
58 
59  update_ghosts();
60 
62 }
63 
64 Staggered1::Staggered1(std::shared_ptr<const Grid> grid, const std::string &name)
65  : Staggered(grid, name, 1) {
66  // empty
67 }
68 
69 std::array<double,2> absmax(const array::Staggered &input) {
70 
71  double z[2] = {0.0, 0.0};
72 
73  array::AccessScope list(input);
74  for (auto p = input.grid()->points(); p; p.next()) {
75  const int i = p.i(), j = p.j();
76 
77  z[0] = std::max(z[0], std::abs(input(i, j, 0)));
78  z[1] = std::max(z[1], std::abs(input(i, j, 1)));
79  }
80 
81  double result[2];
82  GlobalMax(input.grid()->com, z, result, 2);
83 
84  return {result[0], result[1]};
85 }
86 
87 void staggered_to_regular(const array::CellType1 &cell_type,
88  const array::Staggered1 &input,
89  bool include_floating_ice,
90  array::Scalar &result) {
91 
92  using mask::grounded_ice;
93  using mask::icy;
94 
95  auto grid = result.grid();
96 
97  array::AccessScope list{&cell_type, &input, &result};
98 
99  for (auto p = grid->points(); p; p.next()) {
100  const int i = p.i(), j = p.j();
101 
102  if (cell_type.grounded_ice(i, j) or
103  (include_floating_ice and cell_type.icy(i, j))) {
104  auto M = cell_type.star(i, j);
105  auto F = input.star(i, j);
106 
107  int n = 0, e = 0, s = 0, w = 0;
108  if (include_floating_ice) {
109  n = static_cast<int>(icy(M.n));
110  e = static_cast<int>(icy(M.e));
111  s = static_cast<int>(icy(M.s));
112  w = static_cast<int>(icy(M.w));
113  } else {
114  n = static_cast<int>(grounded_ice(M.n));
115  e = static_cast<int>(grounded_ice(M.e));
116  s = static_cast<int>(grounded_ice(M.s));
117  w = static_cast<int>(grounded_ice(M.w));
118  }
119 
120  if (n + e + s + w > 0) {
121  result(i, j) = (n * F.n + e * F.e + s * F.s + w * F.w) / (n + e + s + w);
122  } else {
123  result(i, j) = 0.0;
124  }
125  } else {
126  result(i, j) = 0.0;
127  }
128  }
129 }
130 
132  const array::Staggered1 &input,
133  bool include_floating_ice,
134  array::Vector &result) {
135 
136  using mask::grounded_ice;
137  using mask::icy;
138 
139  assert(cell_type.stencil_width() > 0);
140  assert(input.stencil_width() > 0);
141 
142  auto grid = result.grid();
143 
144  array::AccessScope list{&cell_type, &input, &result};
145 
146  for (auto p = grid->points(); p; p.next()) {
147  const int i = p.i(), j = p.j();
148 
149  auto M = cell_type.star(i, j);
150  auto F = input.star(i, j);
151 
152  int n = 0, e = 0, s = 0, w = 0;
153  if (include_floating_ice) {
154  n = static_cast<int>(icy(M.n));
155  e = static_cast<int>(icy(M.e));
156  s = static_cast<int>(icy(M.s));
157  w = static_cast<int>(icy(M.w));
158  } else {
159  n = static_cast<int>(grounded_ice(M.n));
160  e = static_cast<int>(grounded_ice(M.e));
161  s = static_cast<int>(grounded_ice(M.s));
162  w = static_cast<int>(grounded_ice(M.w));
163  }
164 
165  if (e + w > 0) {
166  result(i, j).u = (e * F.e + w * F.w) / (e + w);
167  } else {
168  result(i, j).u = 0.0;
169  }
170 
171  if (n + s > 0) {
172  result(i, j).v = (n * F.n + s * F.s) / (n + s);
173  } else {
174  result(i, j).v = 0.0;
175  }
176  }
177 }
178 
179 } // end of namespace array
180 
181 } // end of namespace pism
void failed()
Indicates a failure of a parallel section.
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition: Array.hh:65
stencils::Star< T > star(int i, int j) const
Definition: Array2D.hh:79
std::shared_ptr< const Grid > grid() const
Definition: Array.cc:132
void inc_state_counter()
Increment the object state counter.
Definition: Array.cc:151
void update_ghosts()
Updates ghost points.
Definition: Array.cc:693
unsigned int stencil_width() const
Get the stencil width of the current Array. Returns 0 if ghosts are not available.
Definition: Array.cc:331
Abstract class for reading, writing, allocating, and accessing a DA-based PETSc Vec (2D and 3D fields...
Definition: Array.hh:208
bool grounded_ice(int i, int j) const
Definition: CellType.hh:46
bool icy(int i, int j) const
Definition: CellType.hh:42
Staggered1(std::shared_ptr< const Grid > grid, const std::string &name)
Definition: Staggered.cc:64
stencils::Star< double > star(int i, int j) const
Returns the values at interfaces of the cell i,j using the staggered grid.
Definition: Staggered.hh:73
void copy_from(const array::Staggered &input)
Definition: Staggered.cc:42
Staggered(std::shared_ptr< const Grid > grid, const std::string &name)
Definition: Staggered.cc:31
A class for storing and accessing internal staggered-grid 2D fields. Uses dof=2 storage....
Definition: Staggered.hh:35
#define n
Definition: exactTestM.c:37
void staggered_to_regular(const array::CellType1 &cell_type, const array::Staggered1 &input, bool include_floating_ice, array::Scalar &result)
Definition: Staggered.cc:87
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:165
@ WITH_GHOSTS
Definition: Array.hh:62
@ WITHOUT_GHOSTS
Definition: Array.hh:62
double absmax(const array::Scalar &input)
Finds maximum over all the absolute values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:179
bool icy(int M)
Ice-filled cell (grounded or floating).
Definition: Mask.hh:48
bool grounded_ice(int M)
Definition: Mask.hh:51
static double F(double SL, double B, double H, double alpha)
void GlobalMax(MPI_Comm comm, double *local, double *result, int count)