Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CDR_Model_Functors.hpp
Go to the documentation of this file.
1 #ifndef TEMPUS_CDR_MODEL_FUNCTORS_HPP
2 #define TEMPUS_CDR_MODEL_FUNCTORS_HPP
3 
4 #include "Kokkos_Core.hpp"
5 #include "Tpetra_Details_OrdinalTraits.hpp"
6 
7 namespace Tempus_Test {
8 
9 template <class TpetraVectorType>
10 struct CoordFiller {
11  using SC = typename TpetraVectorType::impl_scalar_type;
12  using LO = typename TpetraVectorType::local_ordinal_type;
13  using GO = typename TpetraVectorType::global_ordinal_type;
14  using Map = typename TpetraVectorType::map_type;
15  using LocalMap = typename Map::local_map_type;
16  using DV = typename TpetraVectorType::dual_view_type;
17  using View = typename DV::t_dev;
18 
20  const SC zMin_;
21  const SC dx_;
22  const SC minGI_;
23 
24  CoordFiller(TpetraVectorType &coords, const SC zMin, const SC dx,
25  const GO minGI)
26  : coordsView_(coords.getLocalViewDevice(Tpetra::Access::ReadWrite)),
27  zMin_(zMin),
28  dx_(dx),
29  minGI_(minGI)
30  {
31  }
32 
33  KOKKOS_INLINE_FUNCTION
34  void operator()(const LO i) const
35  {
36  coordsView_(i, 0) = zMin_ + dx_ * static_cast<SC>(minGI_ + i);
37  }
38 };
39 // Finite Element Basis Object
40 template <class Scalar, class LO>
41 class TBasis {
42  public:
43  // Calculates the values of z and u at the specified Gauss point
44  KOKKOS_INLINE_FUNCTION
45  void computeBasis(LO gp, Scalar *z, Scalar *u, Scalar *u_dot)
46  {
47  if (gp == 0) {
48  eta = -1.0 / sqrt(3.0);
49  wt = 1.0;
50  }
51  if (gp == 1) {
52  eta = 1.0 / sqrt(3.0);
53  wt = 1.0;
54  }
55 
56  // Calculate basis function and derivatives at Gauss point
57  phi[0] = (1.0 - eta) / 2.0;
58  phi[1] = (1.0 + eta) / 2.0;
59  dphide[0] = -0.5;
60  dphide[1] = 0.5;
61 
62  // Caculate function and derivative approximations at GP.
63  dz = 0.5 * (z[1] - z[0]);
64  zz = 0.0;
65  uu = 0.0;
66  duu = 0.0;
67  uu_dot = 0.0;
68  duu_dot = 0.0;
69 
70  for (LO i = 0; i < 2; i++) {
71  zz += z[i] * phi[i];
72  uu += u[i] * phi[i];
73  duu += u[i] * dphide[i];
74  uu_dot += u_dot[i] * phi[i];
75  duu_dot += u_dot[i] * dphide[i];
76  }
77  }
78 
79  public:
80  // Variables that are calculated at the Gauss point
81  Scalar phi[2];
82  Scalar dphide[2];
83  Scalar uu = 0.0;
84  Scalar zz = 0.0;
85  Scalar duu = 0.0;
86  Scalar eta = 0.0;
87  Scalar wt = 0.0;
88  Scalar dz = 0.0;
89 
90  // These are only needed for transient
91  Scalar uu_dot = 0.0;
92  Scalar duu_dot = 0.0;
93 };
94 
95 //==================================================================
96 
97 template <class TpetraVectorType, class TpetraMatrixType>
99  using SC = typename TpetraVectorType::impl_scalar_type;
100  using LO = typename TpetraVectorType::local_ordinal_type;
101  using Map = typename TpetraVectorType::map_type;
102  using LocalMap = typename Map::local_map_type;
103  using DV = typename TpetraVectorType::dual_view_type;
104  using ConstView = typename DV::t_dev::const_type;
105  using LocalMat = typename TpetraMatrixType::local_matrix_device_type;
106 
113  const int myRank_;
114  const SC a_;
115  const SC k_;
116  const SC alpha_;
117  const SC beta_;
118 
119  JacobianEvaluatorFunctor(const TpetraMatrixType &J, const TpetraVectorType &x,
120  const TpetraVectorType &u,
121  const TpetraVectorType &uDot, const int &myRank,
122  const SC a, const SC k, const SC alpha,
123  const SC beta)
124  : jLocal_(J.getLocalMatrixDevice()),
125  xView_(x.getLocalViewDevice(Tpetra::Access::ReadOnly)),
126  uView_(u.getLocalViewDevice(Tpetra::Access::ReadOnly)),
127  uDotView_(uDot.getLocalViewDevice(Tpetra::Access::ReadOnly)),
128  rowMap_(J.getRowMap()->getLocalMap()),
129  colMap_(J.getColMap()->getLocalMap()),
130  myRank_(myRank),
131  a_(a),
132  k_(k),
133  alpha_(alpha),
134  beta_(beta)
135  {
136  }
137 
138  // Adds the contribution from element ne to the Jacobian matrix
139  KOKKOS_INLINE_FUNCTION
140  void operator()(const LO ne) const
141  {
142  const auto invalid = Tpetra::Details::OrdinalTraits<LO>::invalid();
143  // Get the solution and coordinates at the nodes
144  SC xx[2];
145  xx[0] = xView_(ne, 0);
146  xx[1] = xView_(ne + 1, 0);
147 
148  SC uu[2];
149  uu[0] = uView_(ne, 0);
150  uu[1] = uView_(ne + 1, 0);
151 
152  SC uuDot[2];
153  uuDot[0] = uDotView_(ne, 0);
154  uuDot[1] = uDotView_(ne + 1, 0);
155 
156  TBasis<SC, LO> basis;
157  // Loop Over Gauss Points
158  for (LO gp = 0; gp < 2; ++gp) {
159  // Calculate the basis function at the gauss point
160  basis.computeBasis(gp, xx, uu, uuDot);
161 
162  // Loop over nodes in element
163  for (LO i = 0; i < 2; ++i) {
164  auto localRow =
165  rowMap_.getLocalElement(colMap_.getGlobalElement(ne + i));
166 
167  if (localRow != invalid) {
168  // Loop over trial functions
169  for (LO j = 0; j < 2; ++j) {
170  const auto localColumn = ne + j;
171  double jac =
172  basis.wt * basis.dz *
173  (alpha_ * basis.phi[i] * basis.phi[j] // transient
174  + beta_ * (+a_ / basis.dz * basis.dphide[j] *
175  basis.phi[i] // convection
176  + (1.0 / (basis.dz * basis.dz)) * basis.dphide[j] *
177  basis.dphide[i] // diffusion
178  + 2.0 * k_ * basis.uu * basis.phi[j] *
179  basis.phi[i] // source
180  ));
181 
182  jLocal_.sumIntoValues(localRow, &localColumn, 1, &jac, false, true);
183  }
184  }
185  }
186 
187  // Correct for Dirichlet BCs
188  if ((myRank_ == 0) && (ne == 0)) {
189  LO row = 0;
190  LO col = 0;
191  SC val = 1.0;
192  jLocal_.replaceValues(row, &col, 1, &val);
193 
194  col = 1;
195  val = 0.0;
196  jLocal_.replaceValues(row, &col, 1, &val);
197  }
198  }
199  }
200 };
201 
202 //==================================================================
203 
204 template <class TpetraVectorType, class TpetraMatrixType>
206  using SC = typename TpetraVectorType::impl_scalar_type;
207  using LO = typename TpetraVectorType::local_ordinal_type;
208  using Map = typename TpetraVectorType::map_type;
209  using LocalMap = typename Map::local_map_type;
210  using DV = typename TpetraVectorType::dual_view_type;
211  using ConstView = typename DV::t_dev::const_type;
212  using LocalMat = typename TpetraMatrixType::local_matrix_device_type;
213 
220  const int myRank_;
221  const SC a_;
222  const SC k_;
223  const SC alpha_;
224  const SC beta_;
225 
226  PreconditionerEvaluatorFunctor(const TpetraMatrixType &M,
227  const TpetraVectorType &x,
228  const TpetraVectorType &u,
229  const TpetraVectorType &uDot,
230  const int &myRank, const SC a, const SC k,
231  const SC alpha, const SC beta)
232  : mLocal_(M.getLocalMatrixDevice()),
233  xView_(x.getLocalViewDevice(Tpetra::Access::ReadOnly)),
234  uView_(u.getLocalViewDevice(Tpetra::Access::ReadOnly)),
235  uDotView_(uDot.getLocalViewDevice(Tpetra::Access::ReadOnly)),
236  rowMap_(M.getRowMap()->getLocalMap()),
237  colMap_(M.getColMap()->getLocalMap()),
238  myRank_(myRank),
239  a_(a),
240  k_(k),
241  alpha_(alpha),
242  beta_(beta)
243  {
244  }
245 
246  // Adds the contribution from element ne to the preconditioner matrix
247  KOKKOS_INLINE_FUNCTION
248  void operator()(const LO ne) const
249  {
250  const auto invalid = Tpetra::Details::OrdinalTraits<LO>::invalid();
251  // Get the solution and coordinates at the nodes
252  SC xx[2];
253  xx[0] = xView_(ne, 0);
254  xx[1] = xView_(ne + 1, 0);
255 
256  SC uu[2];
257  uu[0] = uView_(ne, 0);
258  uu[1] = uView_(ne + 1, 0);
259 
260  SC uuDot[2];
261  uuDot[0] = uDotView_(ne, 0);
262  uuDot[1] = uDotView_(ne + 1, 0);
263 
264  TBasis<SC, LO> basis;
265 
266  // Loop Over Gauss Points
267  for (LO gp = 0; gp < 2; ++gp) {
268  // Calculate the basis function at the gauss point
269  basis.computeBasis(gp, xx, uu, uuDot);
270 
271  // Loop over nodes in element
272  for (LO i = 0; i < 2; ++i) {
273  auto localRow =
274  rowMap_.getLocalElement(colMap_.getGlobalElement(ne + i));
275 
276  // Loop over trial functions
277  if (localRow != invalid) {
278  for (LO j = 0; j < 2; ++j) {
279  const auto localColumn = ne + j;
280  if (rowMap_.getGlobalElement(localRow) ==
281  colMap_.getGlobalElement(localColumn)) {
282  auto value = basis.wt * basis.dz *
283  (alpha_ * basis.phi[i] * basis.phi[j] // transient
284  + beta_ * (+a_ / basis.dz * basis.dphide[j] *
285  basis.phi[i] // convection
286  + (1.0 / (basis.dz * basis.dz)) *
287  basis.dphide[j] *
288  basis.dphide[i] // diffusion
289  + 2.0 * k_ * basis.uu * basis.phi[j] *
290  basis.phi[i] // source
291  ));
292  mLocal_.sumIntoValues(localRow, &localColumn, 1, &value);
293  }
294  }
295  }
296  }
297  }
298 
299  // Correct for Dirichlet BCs
300  if ((myRank_ == 0) && (ne == 0)) {
301  LO row = 0;
302  LO column = 0;
303  SC value = 1.0;
304  mLocal_.replaceValues(row, &column, 1, &value);
305  }
306  }
307 };
308 
309 //==================================================================
310 
311 template <class TpetraVectorType>
313  using SC = typename TpetraVectorType::impl_scalar_type;
314  using LO = typename TpetraVectorType::local_ordinal_type;
315  using Map = typename TpetraVectorType::map_type;
316  using LocalMap = typename Map::local_map_type;
317  using DV = typename TpetraVectorType::dual_view_type;
318  using View = typename DV::t_dev;
319  using ConstView = typename DV::t_dev::const_type;
320 
321  const View fView_;
327  const int myRank_;
328  const SC a_;
329  const SC k_;
330 
331  DfDp2EvaluatorFunctor(TpetraVectorType &f, const TpetraVectorType &x,
332  const TpetraVectorType &u, const TpetraVectorType &uDot,
333  const int myRank, SC a, SC k)
334  : fView_(f.getLocalViewDevice(Tpetra::Access::ReadWrite)),
335  xView_(x.getLocalViewDevice(Tpetra::Access::ReadOnly)),
336  uView_(u.getLocalViewDevice(Tpetra::Access::ReadOnly)),
337  uDotView_(uDot.getLocalViewDevice(Tpetra::Access::ReadOnly)),
338  rowMap_(f.getMap()->getLocalMap()),
339  colMap_(u.getMap()->getLocalMap()),
340  myRank_(myRank),
341  a_(a),
342  k_(k)
343  {
344  }
345 
346  // Adds the contribution from element ne to the residual vector
347  KOKKOS_INLINE_FUNCTION
348  void operator()(const LO ne) const
349  {
350  const auto invalid = Tpetra::Details::OrdinalTraits<LO>::invalid();
351  // Get the solution and coordinates at the nodes
352  SC xx[2];
353  xx[0] = xView_(ne, 0);
354  xx[1] = xView_(ne + 1, 0);
355 
356  SC uu[2];
357  uu[0] = uView_(ne, 0);
358  uu[1] = uView_(ne + 1, 0);
359 
360  SC uuDot[2];
361  uuDot[0] = uDotView_(ne, 0);
362  uuDot[1] = uDotView_(ne + 1, 0);
363 
364  TBasis<SC, LO> basis;
365  // Loop Over Gauss Points
366  for (LO gp = 0; gp < 2; ++gp) {
367  // Calculate the basis function at the gauss point
368  basis.computeBasis(gp, xx, uu, uuDot);
369 
370  // Loop over nodes in element
371  for (LO i = 0; i < 2; ++i) {
372  auto localRow =
373  rowMap_.getLocalElement(colMap_.getGlobalElement(ne + i));
374  if (localRow != invalid) {
375  auto value =
376  basis.wt * basis.dz *
377  (basis.uu_dot * basis.phi[i] // transient
378  + (a_ / basis.dz * basis.duu * basis.phi[i] // convection
379  + 1.0 / (basis.dz * basis.dz)) *
380  basis.duu * basis.dphide[i] // diffusion
381  + k_ * basis.uu * basis.uu * basis.phi[i]); // source
382  Kokkos::atomic_add(&fView_(localRow, 0), value);
383  }
384  }
385  }
386 
387  // Correct for Dirichlet BCs
388  if ((myRank_ == 0) && (ne == 0)) {
389  SC value = 0.0;
390  Kokkos::atomic_exchange(&fView_(0, 0), value);
391  }
392  }
393 };
394 
395 } // namespace Tempus_Test
396 
397 #endif // TEMPUS_CDR_MODEL_FUNCTORS_HPP
typename TpetraVectorType::map_type Map
KOKKOS_INLINE_FUNCTION void operator()(const LO ne) const
typename Map::local_map_type LocalMap
typename Map::local_map_type LocalMap
typename TpetraVectorType::global_ordinal_type GO
typename TpetraVectorType::dual_view_type DV
typename DV::t_dev::const_type ConstView
typename DV::t_dev::const_type ConstView
KOKKOS_INLINE_FUNCTION void operator()(const LO i) const
typename TpetraVectorType::dual_view_type DV
typename TpetraVectorType::local_ordinal_type LO
DfDp2EvaluatorFunctor(TpetraVectorType &f, const TpetraVectorType &x, const TpetraVectorType &u, const TpetraVectorType &uDot, const int myRank, SC a, SC k)
JacobianEvaluatorFunctor(const TpetraMatrixType &J, const TpetraVectorType &x, const TpetraVectorType &u, const TpetraVectorType &uDot, const int &myRank, const SC a, const SC k, const SC alpha, const SC beta)
typename TpetraVectorType::dual_view_type DV
typename TpetraMatrixType::local_matrix_device_type LocalMat
typename TpetraVectorType::impl_scalar_type SC
typename TpetraVectorType::impl_scalar_type SC
KOKKOS_INLINE_FUNCTION void operator()(const LO ne) const
typename TpetraVectorType::local_ordinal_type LO
typename TpetraVectorType::impl_scalar_type SC
typename Map::local_map_type LocalMap
typename TpetraVectorType::map_type Map
PreconditionerEvaluatorFunctor(const TpetraMatrixType &M, const TpetraVectorType &x, const TpetraVectorType &u, const TpetraVectorType &uDot, const int &myRank, const SC a, const SC k, const SC alpha, const SC beta)
typename TpetraVectorType::map_type Map
CoordFiller(TpetraVectorType &coords, const SC zMin, const SC dx, const GO minGI)
typename TpetraVectorType::local_ordinal_type LO
typename TpetraVectorType::local_ordinal_type LO
typename TpetraVectorType::dual_view_type DV
KOKKOS_INLINE_FUNCTION void operator()(const LO ne) const
typename TpetraMatrixType::local_matrix_device_type LocalMat
typename TpetraVectorType::map_type Map
typename TpetraVectorType::impl_scalar_type SC
KOKKOS_INLINE_FUNCTION void computeBasis(LO gp, Scalar *z, Scalar *u, Scalar *u_dot)