Canoe
Comprehensive Atmosphere N' Ocean Engine
Variable.h
Go to the documentation of this file.
1 #ifndef SRC_TRANSPORT_VARIABLE_H_
2 #define SRC_TRANSPORT_VARIABLE_H_
3 #include <deal.II/lac/sparse_matrix.h>
4 
5 #include <Eigen/Core>
6 #include <array>
7 #include <fstream>
8 #include <iomanip>
9 #include <iostream>
10 #include <string>
11 
12 #include "Boundary.h"
13 #include "RectGrid.h"
14 
15 template <typename _Scalar, int _Dim>
16 class Variable {};
17 
18 template <typename _Scalar>
19 class Variable<_Scalar, 2>
20  : public Eigen::Array<_Scalar, Eigen::Dynamic, Eigen::Dynamic> {
21  template <typename STREAM>
22  friend STREAM& operator<<(STREAM& os, const Variable& var) {
23  os << std::setw(9) << var.m_name << "|";
24  for (int i = 0; i < var.rows(); i++)
25  os << std::setw(10) << i - var.m_grid.halo();
26  os << std::endl;
27  for (int i = -1; i < var.rows(); i++) os << "----------";
28  os << std::endl;
29  for (int j = 0; j < var.cols(); j++) {
30  os << std::setw(9) << j - var.m_grid.halo();
31  os << "|";
32  for (int i = 0; i < var.rows(); i++) os << std::setw(10) << var(i, j);
33  os << std::endl;
34  }
35  for (int i = -1; i < var.rows(); i++) os << "----------";
36  os << std::endl;
37 
38  return os;
39  }
40 
41  protected:
42  typedef _Scalar Scalar;
43  typedef Eigen::Array<Scalar, Eigen::Dynamic, Eigen::Dynamic> Base;
44  enum { Dimension = 2 };
45 
47 
48  Eigen::Block<Base> m_value;
49 
50  std::string m_name, m_longname, m_units;
51 
52  std::array<BoundaryInfo<Scalar>, 4> m_boundary;
53 
54  dealii::SparsityPattern m_pattern;
55 
56  dealii::SparseMatrix<Scalar> m_neumann;
57 
58  dealii::Vector<Scalar> m_dirichlet;
59 
60  public:
61  Variable() {}
62 
63  template <typename OtherDerived>
64  explicit Variable(const Eigen::DenseBase<OtherDerived>& other)
65  : Base(other) {}
66 
67  template <typename OtherDerived>
68  Variable& operator=(const Eigen::ArrayBase<OtherDerived>& other) {
69  Base::operator=(other);
70  return *this;
71  }
72 
73  Variable(const Variable& other)
74  : Base(other),
75  m_grid(other.m_grid),
76  m_value(*this, m_grid.halo(), m_grid.halo(), m_grid.rows(),
77  m_grid.cols()),
78  m_name(other.m_name),
79  m_longname(other.m_longname),
80  m_units(other.m_units),
81  m_pattern(m_grid.rankh(), m_grid.rank(), 1),
82  m_dirichlet(m_grid.rankh()) {
83  for (int i = 0; i < m_grid.rows(); i++)
84  for (int j = 0; j < m_grid.cols(); j++)
85  m_pattern.add(m_grid.globalh(i, j), m_grid.global(i, j));
86 
87  for (int i = 0; i < m_grid.rankh(); i++) m_dirichlet(i) = 0.;
88  }
89 
90  Variable& operator=(const Variable& other) {
91  m_value = other.m_value;
92  return *this;
93  }
94 
95  Variable(const RectGrid<Scalar, Dimension>& grid, std::string name = "",
96  std::string longname = "", std::string units = "")
97  : Base(grid.rowsh(), grid.colsh()),
98  m_grid(grid),
99  m_value(*this, grid.halo(), grid.halo(), grid.rows(), grid.cols()),
100  m_name(name),
101  m_longname(longname),
102  m_units(units),
103  m_pattern(grid.rankh(), grid.rank(), 1),
104  m_dirichlet(grid.rankh()) {
105  for (int i = 0; i < m_grid.rows(); i++)
106  for (int j = 0; j < m_grid.cols(); j++)
107  m_pattern.add(m_grid.globalh(i, j), m_grid.global(i, j));
108 
109  for (int i = 0; i < m_grid.rankh(); i++) m_dirichlet(i) = 0.;
110  }
111 
112  void set_boundary(int id, BoundaryType type, Scalar value) {
113  if (id < 0 || id > 3) {
114  std::cerr << "Boundary Id error" << std::endl;
115  exit(1);
116  }
117  m_boundary[id].m_type = type;
118  m_boundary[id].m_value = value;
119  }
120 
121  void write_binary(const char* filename) const {
122  std::ofstream out(filename,
123  std::ios::out | std::ios::binary | std::ios::trunc);
124  int nrows = m_grid.rows(), ncols = m_grid.cols(), ncolsh = m_grid.colsh(),
125  nhalo = m_grid.halo();
126  out.write(static_cast<char*>(&nrows), sizeof(int));
127  out.write(static_cast<char*>(&ncols), sizeof(int));
128  for (int i = nhalo; i < nhalo + nrows; i++)
129  out.write(static_cast<char*>(this->data() + nhalo + i * ncolsh),
130  ncols * sizeof(Scalar));
131  out.close();
132  }
133 
134  void write_file(const char* filename) const {
135  std::ofstream out(filename, std::ios::out | std::ios::trunc);
136  for (int j = 0; j < m_grid.cols(); j++) {
137  for (int i = 0; i < m_grid.rows(); i++)
138  out << std::setw(14) << std::setprecision(6) << m_value(i, j);
139  out << std::endl;
140  }
141  }
142 
143  void finish();
144 
145  const dealii::SparseMatrix<Scalar>& neumann() const { return m_neumann; }
146 
147  const dealii::Vector<Scalar>& dirichlet() const { return m_dirichlet; }
148 
149  inline Eigen::Block<Base>& val() { return m_value; }
150 
151  inline Scalar& val(int i, int j) { return m_value.coeffRef(i, j); }
152 
153  inline const Eigen::Block<Base>& val() const { return m_value; }
154 
155  inline const Scalar& val(int i, int j) const { return m_value.coeff(i, j); }
156 
157  inline std::string get_name() const { return m_name; }
158 
159  inline std::string get_longname() const { return m_longname; }
160 
161  inline std::string get_units() const { return m_units; }
162 };
163 
164 template <typename _Scalar>
166  switch (m_boundary[0].m_type) {
167  case Dirichlet:
168  for (int i = 0; i < m_grid.rows(); i++)
169  m_dirichlet(m_grid.globalh(i, -1)) = m_boundary[0].m_value;
170  break;
171  case Neumann:
172  break;
173  case Periodic:
174  break;
175  default:
176  std::cerr << "Boundary type not found" << std::endl;
177  exit(1);
178  }
179  switch (m_boundary[1].m_type) {
180  case Dirichlet:
181  for (int i = 0; i < m_grid.rows(); i++)
182  m_dirichlet(m_grid.globalh(i, m_grid.cols())) = m_boundary[1].m_value;
183  break;
184  case Neumann:
185  break;
186  case Periodic:
187  break;
188  default:
189  std::cerr << "Boundary type not found" << std::endl;
190  exit(1);
191  }
192  switch (m_boundary[2].m_type) {
193  case Dirichlet:
194  for (int j = 0; j < m_grid.cols(); j++)
195  m_dirichlet(m_grid.globalh(-1, j)) = m_boundary[2].m_value;
196  break;
197  case Neumann:
198  break;
199  case Periodic:
200  break;
201  default:
202  std::cerr << "Boundary type not found" << std::endl;
203  exit(1);
204  }
205  switch (m_boundary[3].m_type) {
206  case Dirichlet:
207  for (int j = 0; j < m_grid.cols(); j++)
208  m_dirichlet(m_grid.globalh(m_grid.rows(), j)) = m_boundary[3].m_value;
209  break;
210  case Neumann:
211  break;
212  case Periodic:
213  break;
214  default:
215  std::cerr << "Boundary type not found" << std::endl;
216  exit(1);
217  }
218  m_pattern.compress();
219 
220  m_neumann.reinit(m_pattern);
221  for (int i = 0; i < m_grid.rows(); i++)
222  for (int j = 0; j < m_grid.cols(); j++)
223  m_neumann.set(m_grid.globalh(i, j), m_grid.global(i, j), 1.);
224 }
225 
226 #endif // SRC_TRANSPORT_VARIABLE_H_
BoundaryType
Definition: Boundary.h:4
@ Neumann
Definition: Boundary.h:4
@ Periodic
Definition: Boundary.h:4
@ Dirichlet
Definition: Boundary.h:4
Eigen::Block< Base > m_value
Definition: Variable.h:48
Variable(const Variable &other)
Definition: Variable.h:73
std::string get_name() const
Definition: Variable.h:157
std::string get_longname() const
Definition: Variable.h:159
void write_file(const char *filename) const
Definition: Variable.h:134
const Eigen::Block< Base > & val() const
Definition: Variable.h:153
Variable & operator=(const Variable &other)
Definition: Variable.h:90
dealii::Vector< Scalar > m_dirichlet
Definition: Variable.h:58
std::array< BoundaryInfo< Scalar >, 4 > m_boundary
Definition: Variable.h:52
Variable(const RectGrid< Scalar, Dimension > &grid, std::string name="", std::string longname="", std::string units="")
Definition: Variable.h:95
Scalar & val(int i, int j)
Definition: Variable.h:151
const dealii::SparseMatrix< Scalar > & neumann() const
Definition: Variable.h:145
dealii::SparseMatrix< Scalar > m_neumann
Definition: Variable.h:56
friend STREAM & operator<<(STREAM &os, const Variable &var)
Definition: Variable.h:22
dealii::SparsityPattern m_pattern
Definition: Variable.h:54
void set_boundary(int id, BoundaryType type, Scalar value)
Definition: Variable.h:112
Eigen::Array< Scalar, Eigen::Dynamic, Eigen::Dynamic > Base
Definition: Variable.h:43
const Scalar & val(int i, int j) const
Definition: Variable.h:155
const RectGrid< Scalar, Dimension > & m_grid
Definition: Variable.h:46
std::string m_longname
Definition: Variable.h:50
const dealii::Vector< Scalar > & dirichlet() const
Definition: Variable.h:147
Variable & operator=(const Eigen::ArrayBase< OtherDerived > &other)
Definition: Variable.h:68
Variable(const Eigen::DenseBase< OtherDerived > &other)
Definition: Variable.h:64
std::string get_units() const
Definition: Variable.h:161
void write_binary(const char *filename) const
Definition: Variable.h:121
Eigen::Block< Base > & val()
Definition: Variable.h:149