ticeModelVec_helpers.hh - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
HTML git clone git://src.adamsgaard.dk/pism
DIR Log
DIR Files
DIR Refs
DIR LICENSE
---
ticeModelVec_helpers.hh (3083B)
---
1 // Copyright (C) 2011, 2013, 2014, 2016, 2017 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 #ifndef _ICEMODELVEC_HELPERS_H_
20 #define _ICEMODELVEC_HELPERS_H_
21
22 namespace pism {
23
24 void compute_params(const IceModelVec* const x, const IceModelVec* const y,
25 const IceModelVec* const z, int &ghosts, bool &scatter);
26
27 //! \brief Computes result = x + alpha * y, where x, y, and z are 2D
28 //! IceModelVecs (scalar or vector).
29 /*!
30 * This implementation tries to be smart about handling IceModelVecs with and
31 * without ghosts and with different stencil widths.
32 *
33 * This template function was written to re-use this code for both
34 * IceModelVec2S and IceModel2V.
35 *
36 * This cannot go into a protected member IceModelVec because
37 * IceModelVec2S::operator() and IceModelVec2V::operator() return different
38 * types.
39 *
40 * Note: this code uses overloaded operators (Vector2::operator*, etc).
41 */
42 template<class V>
43 void add_2d(const IceModelVec* const x_in, double alpha,
44 const IceModelVec* const y_in,
45 IceModelVec* const result) {
46 const V *x = dynamic_cast<const V*>(x_in),
47 *y = dynamic_cast<const V*>(y_in);
48
49 V *z = dynamic_cast<V*>(result);
50
51 if (x == NULL || y == NULL || z == NULL) {
52 throw RuntimeError(PISM_ERROR_LOCATION, "incompatible arguments");
53 }
54
55 int stencil = 0;
56 bool scatter = false;
57 compute_params(x, y, z, stencil, scatter);
58
59 IceModelVec::AccessList list{x, y, z};
60 for (PointsWithGhosts p(*z->grid(), stencil); p; p.next()) {
61 const int i = p.i(), j = p.j();
62
63 (*z)(i, j) = (*x)(i, j) + (*y)(i, j) * alpha;
64 }
65
66 if (scatter) {
67 z->update_ghosts();
68 }
69
70 result->inc_state_counter();
71 }
72
73 template<class V>
74 void copy_2d(const IceModelVec* const source,
75 IceModelVec* const destination) {
76 const V *x = dynamic_cast<const V*>(source);
77
78 V *z = dynamic_cast<V*>(destination);
79
80 if (x == NULL || z == NULL) {
81 throw RuntimeError(PISM_ERROR_LOCATION, "incompatible arguments");
82 }
83
84 int stencil = 0;
85 bool scatter = false;
86 compute_params(x, x, z, stencil, scatter);
87
88 IceModelVec::AccessList list{x, z};
89
90 for (PointsWithGhosts p(*z->grid(), stencil); p; p.next()) {
91 const int i = p.i(), j = p.j();
92
93 (*z)(i, j) = (*x)(i, j);
94 }
95
96 if (scatter) {
97 z->update_ghosts();
98 }
99
100 destination->inc_state_counter();
101 }
102
103 } // end of namespace pism
104
105 #endif /* _ICEMODELVEC_HELPERS_H_ */