Canoe
Comprehensive Atmosphere N' Ocean Engine
stream_transport.cpp
Go to the documentation of this file.
1 // dealii headers
2 #include <deal.II/lac/precondition.h>
3 
4 // athena headers
5 #include <athena/athena.hpp>
6 
7 // IceChem headers
8 #include "stream_transport.hpp"
9 
10 StreamTransport::StreamTransport(int rows, int cols, bool fourth_order)
11  : fourth_order_(fourth_order),
12  rows_(rows),
13  cols_(cols),
14  rank_(rows * cols),
15  rowsh_(rows + 2 * GhostZoneSize),
16  colsh_(cols + 2 * GhostZoneSize),
17  rankh_(rowsh_ * colsh_),
18  skh_(rank_, rankh_, 9),
19  skk_(rank_, rank_, 9),
20  shk_(rankh_, rank_, 1),
21  qvec_(rankh_),
22  dqvec_(rank_),
23  rhs_(rank_),
24  control_(1000, 1e-12),
25  solver_(control_) {
26  // 9 elements maximum
27  for (int j = 0; j < rows_; ++j)
28  for (int i = 0; i < cols_; ++i) {
29  int k = global(j, i);
30  skh_.add(k, globalh(j, i));
31  skh_.add(k, globalh(j - 1, i));
32  skh_.add(k, globalh(j, i - 1));
33  skh_.add(k, globalh(j + 1, i));
34  skh_.add(k, globalh(j, i + 1));
35  skh_.add(k, globalh(j - 1, i - 1));
36  skh_.add(k, globalh(j - 1, i + 1));
37  skh_.add(k, globalh(j + 1, i - 1));
38  skh_.add(k, globalh(j + 1, i + 1));
39  }
40  skh_.compress();
41 
42  diffusion_.reinit(skh_);
43  advection_.reinit(skh_);
44  KmJ_.reinit(skh_);
45 
46  // 9 elements maximum
47  for (int j = 0; j < rows_; ++j)
48  for (int i = 0; i < cols_; ++i) {
49  int64_t k = global(j, i);
50  skk_.add(k, global(j, i));
51  if (j > 0) skk_.add(k, global(j - 1, i));
52  if (i > 0) skk_.add(k, global(j, i - 1));
53  if (j < rows_ - 1) skk_.add(k, global(j + 1, i));
54  if (i < cols_ - 1) skk_.add(k, global(j, i + 1));
55  if (j > 0 && i > 0) skk_.add(k, global(j - 1, i - 1));
56  if (j > 0 && i < cols_ - 1) skk_.add(k, global(j - 1, i + 1));
57  if (j < rows_ - 1 && i > 0) skk_.add(k, global(j + 1, i - 1));
58  if (j < rows_ - 1 && i < cols_ - 1) skk_.add(k, global(j + 1, i + 1));
59  }
60  skk_.compress();
61 
62  mass_.reinit(skk_);
63  KmJmN_.reinit(skk_);
64 
65  // 2 element
66  for (int j = 0; j < rows_; ++j)
67  for (int i = 0; i < cols_; ++i) {
68  shk_.add(globalh(j, i), global(j, i));
69  }
70  shk_.compress();
71 
72  // neumann boundary condition
73  bneumann_.reinit(shk_);
74  for (int i = 0; i < cols_; ++i) {
75  bneumann_.set(globalh(-1, i), global(0, i), 1.);
76  for (int j = 0; j < rows_; ++j)
77  bneumann_.set(globalh(j, i), global(j, i), 1.);
78  bneumann_.set(globalh(rows_, i), global(rows_ - 1, i), 1.);
79  }
80 }
81 
83 
84 void StreamTransport::setDiffusionMatrix(Real kdiff, Real dx) {
85  if (fourth_order_) {
86  for (int j = 0; j < rows_; ++j)
87  for (int i = 0; i < cols_; ++i) {
88  int64_t k = global(j, i);
89  diffusion_.set(k, globalh(j, i), -10. / 3.);
90  diffusion_.set(k, globalh(j - 1, i), 2. / 3.);
91  diffusion_.set(k, globalh(j, i - 1), 2. / 3.);
92  diffusion_.set(k, globalh(j + 1, i), 2. / 3.);
93  diffusion_.set(k, globalh(j, i + 1), 2. / 3.);
94  diffusion_.set(k, globalh(j - 1, i - 1), 1. / 6.);
95  diffusion_.set(k, globalh(j - 1, i + 1), 1. / 6.);
96  diffusion_.set(k, globalh(j + 1, i - 1), 1. / 6.);
97  diffusion_.set(k, globalh(j + 1, i + 1), 1. / 6.);
98  }
99  } else {
100  for (int j = 0; j < rows_; ++j)
101  for (int i = 0; i < cols_; ++i) {
102  int64_t k = global(j, i);
103  diffusion_.set(k, globalh(j, i), -4.);
104  diffusion_.set(k, globalh(j - 1, i), 1.);
105  diffusion_.set(k, globalh(j + 1, i), 1.);
106  diffusion_.set(k, globalh(j, i - 1), 1.);
107  diffusion_.set(k, globalh(j, i + 1), 1.);
108  }
109  }
110  diffusion_ *= kdiff / (dx * dx);
111 }
112 
114  Real dx) {
115  for (int j = 0; j < rows_; ++j)
116  for (int i = 0; i < cols_; ++i) {
117  int64_t k = global(j, i);
118  int j1 = j + GhostZoneSize;
119  int i1 = i + GhostZoneSize;
120  advection_.set(k, globalh(j - 1, i - 1),
121  -streamf(j1, i1 - 1) + streamf(j1 - 1, i1));
122 
123  advection_.set(k, globalh(j - 1, i),
124  -streamf(j1 - 1, i1 - 1) - streamf(j1, i1 - 1) +
125  streamf(j1 - 1, i1 + 1) + streamf(j1, i1 + 1));
126 
127  advection_.set(k, globalh(j - 1, i + 1),
128  +streamf(j1, i1 + 1) - streamf(j1 - 1, i1));
129 
130  advection_.set(k, globalh(j, i - 1),
131  -streamf(j1 + 1, i1 - 1) - streamf(j1 + 1, i1) +
132  streamf(j1 - 1, i1 - 1) + streamf(j1 - 1, i1));
133 
134  advection_.set(k, globalh(j, i + 1),
135  +streamf(j1 + 1, i1) + streamf(j1 + 1, i1 + 1) -
136  streamf(j1 - 1, i1) - streamf(j1 - 1, i1 + 1));
137 
138  advection_.set(k, globalh(j + 1, i - 1),
139  -streamf(j1 + 1, i1) + streamf(j1, i1 - 1));
140 
141  advection_.set(k, globalh(j + 1, i),
142  +streamf(j1, i1 - 1) + streamf(j1 + 1, i1 - 1) -
143  streamf(j1, i1 + 1) - streamf(j1 + 1, i1 + 1));
144 
145  advection_.set(k, globalh(j + 1, i + 1),
146  +streamf(j1 + 1, i1) - streamf(j1, i1 + 1));
147  }
148  advection_ *= 1. / (12. * dx * dx);
149 }
150 
152  KmJ_ = 0.;
153  KmJ_.add(1., diffusion_);
154  KmJ_.add(-1., advection_);
155  KmJ_.mmult(KmJmN_, bneumann_);
156 
157  mass_ = dealii::IdentityMatrix(rank_);
158  mass_ /= dt;
159  mass_.add(-theta, KmJmN_);
160 }
161 
163  assembleSystem(dt, theta);
164 
165  for (int j = 0; j < rowsh_; ++j)
166  for (int i = 0; i < colsh_; ++i) {
167  int j1 = j - GhostZoneSize;
168  int i1 = i - GhostZoneSize;
169  int64_t k = globalh(j1, i1);
170  qvec_(k) = (*q)(j, i);
171  }
172 
173  KmJ_.vmult(rhs_, qvec_);
174  solver_.solve(mass_, dqvec_, rhs_, dealii::PreconditionIdentity());
175 
176  for (int j = 0; j < rows_; ++j)
177  for (int i = 0; i < cols_; ++i) {
178  int64_t k = global(j, i);
179  int j1 = j + GhostZoneSize;
180  int i1 = i + GhostZoneSize;
181  (*q)(j1, i1) += dqvec_(k);
182  }
183 }
dealii::Vector< Real > dqvec_
void evolve(AthenaArray< Real > *q, Real dt, Real theta=1.)
void setAdvectionMatrix(AthenaArray< Real > const &streamf, Real dx)
dealii::SparseMatrix< Real > bneumann_
dealii::SparsityPattern skk_
dealii::Vector< Real > rhs_
void setDiffusionMatrix(Real kdiff, Real dx)
dealii::Vector< Real > qvec_
dealii::SparseMatrix< Real > KmJ_
dealii::SparseMatrix< Real > mass_
dealii::SparseMatrix< Real > KmJmN_
dealii::SolverGMRES solver_
dealii::SparseMatrix< Real > diffusion_
int64_t globalh(int i, int j) const
dealii::SparsityPattern skh_
int64_t global(int i, int j) const
void assembleSystem(Real dt, Real theta)
StreamTransport(int rows, int cols, bool fourth_order=true)
dealii::SparsityPattern shk_
dealii::SparseMatrix< Real > advection_