PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
ElementIterator.hh
Go to the documentation of this file.
1 /* Copyright (C) 2020 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 PISM_ELEMENTITERATOR_H
20 #define PISM_ELEMENTITERATOR_H
21 
22 namespace pism {
23 
24 class Grid;
25 
26 namespace fem {
27 
28 //! Manages iterating over element indices.
29 /*! When computing residuals and Jacobians, there is a loop over all the elements in the
30  Grid, and computations are done on each element. The Grid has an underlying PETSc
31  DM, and a process typically does not own all of the nodes in the grid. Therefore we
32  should perform a computation on a subset of the elements. In general, an element will
33  have ghost (o) and real (*) vertices:
34 
35  \verbatim
36  o---*---*---*---o
37  | | | | |
38  o---*---*---*---o
39  | | | | |
40  o---o---o---o---o
41  \endverbatim
42 
43  The strategy is to perform computations on this process on every element that has
44  a vertex that is owned by this processor. But we only update entries in the
45  global residual and Jacobian matrices if the corresponding row corresponds to a
46  vertex that we own. In the worst case, where each vertex of an element is owned by
47  a different processor, the computations for that element will be repeated four times,
48  once for each processor.
49 
50  This same strategy also correctly deals with periodic boundary conditions. The way PETSc
51  deals with periodic boundaries can be thought of as using a kind of ghost. So the rule
52  still works: compute on all elements containg a real vertex, but only update rows
53  corresponding to that real vertex.
54 
55  The calculation of what elements to index over needs to account for ghosts and the
56  presence or absense of periodic boundary conditions in the Grid. The ElementIterator
57  performs that computation for you (see ElementIterator::xs and friends).
58 */
60 public:
61  ElementIterator(const Grid &g);
62 
63  /*!\brief The total number of elements to be iterated over. Useful for creating per-element storage.*/
64  int element_count() {
65  return xm*ym;
66  }
67 
68  /*!\brief Convert an element index (`i`,`j`) into a flattened (1-d) array index, with the first
69  element (`i`, `j`) to be iterated over corresponding to flattened index 0. */
70  int flatten(int i, int j) {
71  return (i-xs) + (j-ys)*xm;
72  }
73 
74  //! x-coordinate of the first element to loop over.
75  int xs;
76  //! total number of elements to loop over in the x-direction.
77  int xm;
78 
79  //! y-coordinate of the first element to loop over.
80  int ys;
81  //! total number of elements to loop over in the y-direction.
82  int ym;
83 
84  //! x-index of the first local element.
85  int lxs;
86  //! total number local elements in x direction.
87  int lxm;
88 
89  //! y-index of the first local element.
90  int lys;
91  //! total number local elements in y direction.
92  int lym;
93 };
94 
95 } // end of namespace fem
96 } // end of namespace pism
97 
98 #endif /* PISM_ELEMENTITERATOR_H */
Describes the PISM grid and the distribution of data across processors.
Definition: Grid.hh:282
int xm
total number of elements to loop over in the x-direction.
int lym
total number local elements in y direction.
int lxm
total number local elements in x direction.
int lxs
x-index of the first local element.
int ym
total number of elements to loop over in the y-direction.
int ys
y-coordinate of the first element to loop over.
int element_count()
The total number of elements to be iterated over. Useful for creating per-element storage.
int flatten(int i, int j)
Convert an element index (i,j) into a flattened (1-d) array index, with the first element (i,...
int lys
y-index of the first local element.
int xs
x-coordinate of the first element to loop over.
Manages iterating over element indices.
static const double g
Definition: exactTestP.cc:36