PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
Scalar.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/Scalar.hh"
21 
22 #include "pism/util/array/Vector.hh"
23 #include "pism/util/VariableMetadata.hh"
24 #include "pism/util/pism_utilities.hh"
25 
26 namespace pism {
27 namespace array {
28 
29 // protected constructor
30 Scalar::Scalar(std::shared_ptr<const Grid> grid, const std::string &name,
31  int width)
32  : Array2D<double>(grid, name,
33  width > 0 ? WITH_GHOSTS : WITHOUT_GHOSTS,
34  width) {
35  // empty
36 }
37 
38 // public constructor
39 Scalar::Scalar(std::shared_ptr<const Grid> grid, const std::string &name)
40  : Array2D<double>(grid, name, WITHOUT_GHOSTS, 1) {
41  // empty
42 }
43 
44 std::shared_ptr<Scalar> Scalar::duplicate() const {
45  auto result = std::make_shared<Scalar>(this->grid(), this->get_name());
46  result->metadata() = this->metadata();
47 
48  return result;
49 }
50 
51 Scalar1::Scalar1(std::shared_ptr<const Grid> grid, const std::string &name)
52  : Scalar(grid, name, 1) {
53  // empty
54 }
55 
56 Scalar1::Scalar1(std::shared_ptr<const Grid> grid, const std::string &name, int width)
57  : Scalar(grid, name, width) {
58  // empty
59 }
60 
61 Scalar2::Scalar2(std::shared_ptr<const Grid> grid, const std::string &name)
62  : Scalar1(grid, name, 2) {
63  // empty
64 }
65 
66 void compute_magnitude(const array::Vector &input, array::Scalar &result) {
67  array::AccessScope list{&result, &input};
68 
69  for (auto p = result.grid()->points(); p; p.next()) {
70  const int i = p.i(), j = p.j();
71 
72  result(i, j) = input(i, j).magnitude();
73  }
74 
75  result.inc_state_counter(); // mark as modified
76 }
77 
78 //! Masks out all the areas where \f$ M \le 0 \f$ by setting them to `fill`.
79 void apply_mask(const array::Scalar &M, double fill, array::Scalar &result) {
80  array::AccessScope list{&result, &M};
81 
82  for (auto p = result.grid()->points(); p; p.next()) {
83  const int i = p.i(), j = p.j();
84 
85  if (M(i, j) <= 0.0) {
86  result(i,j) = fill;
87  }
88  }
89 
90  result.inc_state_counter(); // mark as modified
91 }
92 
93 //! \brief Returns the x-derivative at i,j approximated using centered finite
94 //! differences.
95 double diff_x(const array::Scalar &array, int i, int j) {
96  return (array(i + 1,j) - array(i - 1,j)) / (2 * array.grid()->dx());
97 }
98 
99 //! \brief Returns the y-derivative at i,j approximated using centered finite
100 //! differences.
101 double diff_y(const array::Scalar &array, int i, int j) {
102  return (array(i,j + 1) - array(i,j - 1)) / (2 * array.grid()->dy());
103 }
104 
105 //! \brief Returns the x-derivative at i,j approximated using centered finite
106 //! differences. Respects grid periodicity and uses one-sided FD at grid edges
107 //! if necessary.
108 double diff_x_p(const array::Scalar &array, int i, int j) {
109  const auto &grid = *array.grid();
110 
111  if ((grid.periodicity() & grid::X_PERIODIC) != 0) {
112  return diff_x(array, i,j);
113  }
114 
115  if (i == 0) {
116  return (array(i + 1,j) - array(i,j)) / (grid.dx());
117  }
118 
119  if (i == (int)grid.Mx() - 1) {
120  return (array(i,j) - array(i - 1,j)) / (grid.dx());
121  }
122 
123  return diff_x(array, i,j);
124 }
125 
126 //! \brief Returns the y-derivative at i,j approximated using centered finite
127 //! differences. Respects grid periodicity and uses one-sided FD at grid edges
128 //! if necessary.
129 double diff_y_p(const array::Scalar &array, int i, int j) {
130  const auto &grid = *array.grid();
131 
132  if ((grid.periodicity() & grid::Y_PERIODIC) != 0) {
133  return diff_y(array, i,j);
134  }
135 
136  if (j == 0) {
137  return (array(i,j + 1) - array(i,j)) / (grid.dy());
138  }
139 
140  if (j == (int)grid.My() - 1) {
141  return (array(i,j) - array(i,j - 1)) / (grid.dy());
142  }
143 
144  return diff_y(array, i,j);
145 }
146 
147 //! Sums up all the values in an array::Scalar object. Ignores ghosts.
148 /*! Avoids copying to a "global" vector.
149  */
150 double sum(const array::Scalar &input) {
151  double result = 0;
152 
153  array::AccessScope list(input);
154 
155  // sum up the local part:
156  for (auto p = input.grid()->points(); p; p.next()) {
157  result += input(p.i(), p.j());
158  }
159 
160  // find the global sum:
161  return GlobalSum(input.grid()->com, result);
162 }
163 
164 //! Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
165 double max(const array::Scalar &input) {
166  array::AccessScope list(input);
167 
168  auto grid = input.grid();
169 
170  double result = input(grid->xs(), grid->ys());
171  for (auto p = grid->points(); p; p.next()) {
172  result = std::max(result, input(p.i(), p.j()));
173  }
174 
175  return GlobalMax(grid->com, result);
176 }
177 
178 //! Finds maximum over all the absolute values in an array::Scalar object. Ignores ghosts.
179 double absmax(const array::Scalar &input) {
180 
181  double result = 0.0;
182 
183  array::AccessScope list(input);
184  for (auto p = input.grid()->points(); p; p.next()) {
185  result = std::max(result, std::abs(input(p.i(), p.j())));
186  }
187 
188  return GlobalMax(input.grid()->com, result);
189 }
190 
191 
192 //! Finds minimum over all the values in an array::Scalar object. Ignores ghosts.
193 double min(const array::Scalar &input) {
194  array::AccessScope list(input);
195 
196  auto grid = input.grid();
197 
198  double result = input(grid->xs(), grid->ys());
199  for (auto p = grid->points(); p; p.next()) {
200  result = std::min(result, input(p.i(), p.j()));
201  }
202 
203  return GlobalMin(grid->com, result);
204 }
205 
206 } // end of namespace array
207 
208 } // end of namespace pism
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition: Array.hh:65
A storage vector combining related fields in a struct.
Definition: Array2D.hh:32
const std::string & get_name() const
Get the name of an Array object.
Definition: Array.cc:383
std::shared_ptr< const Grid > grid() const
Definition: Array.cc:132
void inc_state_counter()
Increment the object state counter.
Definition: Array.cc:151
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
Definition: Array.cc:553
Scalar1(std::shared_ptr< const Grid > grid, const std::string &name)
Definition: Scalar.cc:51
Scalar2(std::shared_ptr< const Grid > grid, const std::string &name)
Definition: Scalar.cc:61
Scalar(std::shared_ptr< const Grid > grid, const std::string &name)
Definition: Scalar.cc:39
std::shared_ptr< Scalar > duplicate() const
Definition: Scalar.cc:44
void apply_mask(const array::Scalar &M, double fill, array::Scalar &result)
Masks out all the areas where by setting them to fill.
Definition: Scalar.cc:79
double diff_y(const array::Scalar &array, int i, int j)
Returns the y-derivative at i,j approximated using centered finite differences.
Definition: Scalar.cc:101
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:165
double diff_x(const array::Scalar &array, int i, int j)
Returns the x-derivative at i,j approximated using centered finite differences.
Definition: Scalar.cc:95
double sum(const array::Scalar &input)
Sums up all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:150
double diff_x_p(const array::Scalar &array, int i, int j)
Returns the x-derivative at i,j approximated using centered finite differences. Respects grid periodi...
Definition: Scalar.cc:108
@ WITH_GHOSTS
Definition: Array.hh:62
@ WITHOUT_GHOSTS
Definition: Array.hh:62
double min(const array::Scalar &input)
Finds minimum over all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:193
double absmax(const array::Scalar &input)
Finds maximum over all the absolute values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:179
void compute_magnitude(const array::Vector &input, array::Scalar &result)
Definition: Scalar.cc:66
double diff_y_p(const array::Scalar &array, int i, int j)
Returns the y-derivative at i,j approximated using centered finite differences. Respects grid periodi...
Definition: Scalar.cc:129
@ Y_PERIODIC
Definition: Grid.hh:51
@ X_PERIODIC
Definition: Grid.hh:51
void GlobalMax(MPI_Comm comm, double *local, double *result, int count)
void GlobalMin(MPI_Comm comm, double *local, double *result, int count)
void GlobalSum(MPI_Comm comm, double *local, double *result, int count)