Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
26namespace pism {
27namespace array {
28
29// protected constructor
30Scalar::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
39Scalar::Scalar(std::shared_ptr<const Grid> grid, const std::string &name)
40 : Array2D<double>(grid, name, WITHOUT_GHOSTS, 1) {
41 // empty
42}
43
44std::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
51Scalar1::Scalar1(std::shared_ptr<const Grid> grid, const std::string &name)
52 : Scalar(grid, name, 1) {
53 // empty
54}
55
56Scalar1::Scalar1(std::shared_ptr<const Grid> grid, const std::string &name, int width)
57 : Scalar(grid, name, width) {
58 // empty
59}
60
61Scalar2::Scalar2(std::shared_ptr<const Grid> grid, const std::string &name)
62 : Scalar1(grid, name, 2) {
63 // empty
64}
65
66void 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`.
79void 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.
95double 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.
101double 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.
108double 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.
129double 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 */
150double 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.
165double 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.
179double 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.
193double 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:64
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:354
std::shared_ptr< const Grid > grid() const
Definition Array.cc:131
void inc_state_counter()
Increment the object state counter.
Definition Array.cc:150
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
Definition Array.cc:476
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:61
@ WITHOUT_GHOSTS
Definition Array.hh:61
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:54
@ X_PERIODIC
Definition Grid.hh:54
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)