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
ColumnSystem.hh
Go to the documentation of this file.
1// Copyright (C) 2009-2011, 2013, 2014, 2015, 2016, 2019, 2021, 2025 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_COLUMNSYSTEM_HH
20#define PISM_COLUMNSYSTEM_HH
21
22#include <string>
23#include <ostream>
24#include <vector>
25
26namespace pism {
27
28namespace array {
29class Array3D;
30} // end of namespace array
31
32//! Virtual base class. Abstracts a tridiagonal system to solve in a column of ice and/or bedrock.
33/*!
34 Because both the age evolution and conservation of energy equations require us to set up
35 and solve a tridiagonal system of equations, this is structure is worth abstracting.
36
37 This base class just holds the tridiagonal system and the ability to
38 solve it, but does not insert entries into the relevant matrix locations.
39 Derived classes will actually set up instances of the system.
40
41 The sequence requires setting the column-independent (public) data members,
42 calling the initAllColumns() routine, and then setting up and solving
43 the system in each column.
44
45 The tridiagonal algorithm here comes from Numerical Recipes in C
46 Section 2.4, page 50. It solves the system:
47
48@verbatim
49 [b_1 c_1 0 ... ] [ u_1 ] [ r_1 ]
50 [a_2 b_2 c_2 ... ] [ u_2 ] [ r_2 ]
51 [ ... ].[ ... ] = [ ... ]
52 [ ... a_{N-1} b_{N-1} c_{N-1}] [u_{N-1}] [ r_{N-1} ]
53 [ ... 0 a_N b_N ] [ u_N ] [ r_N ]
54@endverbatim
55
56 HOWEVER... the version in this code is different from Numerical
57 Recipes in two ways:
58
59 - Indexing is zero-based
60 - Variables have been renamed.
61
62@verbatim
63 NR PISM
64 ==================
65 a L "Lower Diagonal" (L doesn't use index 0)
66 b D "Diagonal"
67 c U "Upper Diagonal"
68 u x
69 r rhs
70 bet b
71 j k
72 n n
73 gam work
74@endverbatim
75
76 Therefore... this version of the code solves the following problem:
77
78@verbatim
79 [D_0 U_0 0 ... ] [ x_0 ] [ r_0 ]
80 [L_1 D_1 U_1 ... ] [ x_1 ] [ r_1 ]
81 [ ... ].[ ... ] = [ ... ]
82 [ ... L_{N-2} D_{N-2} U_{N-2}] [x_{N-2}] [ r_{N-2} ]
83 [ ... 0 L_{N-1} D_{N-1}] [x_{N-1}] [ r_{N-1} ]
84@endverbatim
85*/
87public:
88 TridiagonalSystem(unsigned int max_size, const std::string &prefix);
89
90 double norm1(unsigned int system_size) const;
91 double ddratio(unsigned int system_size) const;
92 void reset();
93
94 // uses an output argument to allow re-using storage and avoid
95 // copying
96 void solve(unsigned int system_size, std::vector<double> &result);
97 void solve(unsigned int system_size, double *result);
98
99 void save_system_with_solution(const std::string &filename,
100 unsigned int system_size,
101 const std::vector<double> &solution);
102
103 //! Save the system to a stream using the ASCII MATLAB (Octave)
104 //! format. Virtual to allow saving more info in derived classes.
105 void save_system(std::ostream &output,
106 unsigned int system_size) const;
107
108 void save_matrix(std::ostream &output,
109 unsigned int system_size,
110 const std::string &variable) const;
111
112 static void save_vector(std::ostream &output,
113 const std::vector<double> &v,
114 unsigned int system_size,
115 const std::string &variable);
116
117 std::string prefix() const;
118
119 double& L(size_t i) {
120 return m_L[i];
121 }
122 double& D(size_t i) {
123 return m_D[i];
124 }
125 double& U(size_t i) {
126 return m_U[i];
127 }
128 double& RHS(size_t i) {
129 return m_rhs[i];
130 }
131private:
132 unsigned int m_max_system_size; // maximum system size
133 std::vector<double> m_L, m_D, m_U, m_rhs, m_work; // vectors for tridiagonal system
134
135 std::string m_prefix;
136};
137
139
140//! Base class for tridiagonal systems in the ice.
141/*! Adds data members used in time-dependent systems with advection
142 (dx, dy, dz, dt, velocity components).
143 */
145public:
146 columnSystemCtx(const std::vector<double>& storage_grid, const std::string &prefix,
147 double dx, double dy, double dt,
148 const array::Array3D &u3, const array::Array3D &v3, const array::Array3D &w3);
150
151 void save_to_file(const std::vector<double> &x);
152 void save_to_file(const std::string &filename, const std::vector<double> &x);
153
154 unsigned int ks() const;
155 double dz() const;
156 const std::vector<double>& z() const;
157 void fine_to_coarse(const std::vector<double> &input, int i, int j,
158 array::Array3D& output) const;
159protected:
161
163
164 //! current system size; corresponds to the highest vertical level within the ice
165 unsigned int m_ks;
166 //! current column indexes
167 int m_i, m_j;
168
169 double m_dx, m_dy, m_dz, m_dt;
170
171 //! u-component of the ice velocity
172 std::vector<double> m_u;
173 //! v-component of the ice velocity
174 std::vector<double> m_v;
175 //! w-component of the ice velocity
176 std::vector<double> m_w;
177 //! levels of the fine vertical grid
178 std::vector<double> m_z;
179
180 //! pointers to 3D velocity components
182
183 void init_column(int i, int j, double ice_thickness);
184
185 void reportColumnZeroPivotErrorMFile(unsigned int M);
186
187 void init_fine_grid(const std::vector<double>& storage_grid);
188
189 void coarse_to_fine(const array::Array3D &input, int i, int j, double* output) const;
190};
191
192} // end of namespace pism
193
194#endif /* PISM_COLUMNSYSTEM_HH */
double & D(size_t i)
double & L(size_t i)
void save_matrix(std::ostream &output, unsigned int system_size, const std::string &variable) const
View the tridiagonal matrix.
void save_system(std::ostream &output, unsigned int system_size) const
View the tridiagonal system A x = b to an output stream, both A as a full matrix and b as a vector.
std::vector< double > m_work
std::string prefix() const
unsigned int m_max_system_size
double & RHS(size_t i)
void solve(unsigned int system_size, std::vector< double > &result)
double ddratio(unsigned int system_size) const
Compute diagonal-dominance ratio. If this is less than one then the matrix is strictly diagonally-dom...
double norm1(unsigned int system_size) const
Compute 1-norm, which is max sum of absolute values of columns.
double & U(size_t i)
static void save_vector(std::ostream &output, const std::vector< double > &v, unsigned int system_size, const std::string &variable)
Utility for simple ascii view of a vector (one-dimensional column) quantity.
std::vector< double > m_D
std::vector< double > m_U
void reset()
Zero all entries.
std::vector< double > m_L
void save_system_with_solution(const std::string &filename, unsigned int system_size, const std::vector< double > &solution)
std::vector< double > m_rhs
Virtual base class. Abstracts a tridiagonal system to solve in a column of ice and/or bedrock.
A virtual class collecting methods common to ice and bedrock 3D fields.
Definition Array3D.hh:33
const array::Array3D & m_w3
void coarse_to_fine(const array::Array3D &input, int i, int j, double *output) const
const std::vector< double > & z() const
void reportColumnZeroPivotErrorMFile(unsigned int M)
Write system matrix and right-hand-side into an Python script. The file name contains ZERO_PIVOT_ERRO...
void save_to_file(const std::vector< double > &x)
Write system matrix, right-hand-side, and (provided) solution into Python script. Constructs file nam...
std::vector< double > m_z
levels of the fine vertical grid
void fine_to_coarse(const std::vector< double > &input, int i, int j, array::Array3D &output) const
unsigned int m_ks
current system size; corresponds to the highest vertical level within the ice
std::vector< double > m_u
u-component of the ice velocity
const array::Array3D & m_u3
pointers to 3D velocity components
void init_column(int i, int j, double ice_thickness)
const array::Array3D & m_v3
unsigned int ks() const
void init_fine_grid(const std::vector< double > &storage_grid)
int m_i
current column indexes
TridiagonalSystem * m_solver
ColumnInterpolation * m_interp
std::vector< double > m_w
w-component of the ice velocity
std::vector< double > m_v
v-component of the ice velocity
Base class for tridiagonal systems in the ice.