Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
advection_const_basis/common.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 // *****************************************************************************
8 // @HEADER
9 
10 #pragma once
11 
12 const int fad_dim = 50;
16 
17 template <typename ExecSpace>
18 struct is_cuda_space {
19  static const bool value = false;
20 };
21 
22 #ifdef KOKKOS_ENABLE_CUDA
23 template <>
24 struct is_cuda_space<Kokkos::Cuda> {
25  static const bool value = true;
26 };
27 #endif
28 
29 template <typename scalar>
30 scalar
31 generate_fad(const size_t n0, const size_t n1,
32  const size_t n2, const size_t n3, const int fad_size,
33  const size_t i0, const size_t i1,
34  const size_t i2, const size_t i3,
35  const int i_fad)
36 {
37  const scalar x0 = 10.0 + scalar(n0) / scalar(i0+1);
38  const scalar x1 = 100.0 + scalar(n1) / scalar(i1+1);
39  const scalar x2 = 1000.0 + scalar(n2) / scalar(i2+1);
40  const scalar x3 = 10000.0 + scalar(n3) / scalar(i3+1);
41  const scalar x = x0 + x1 + x2 + x3;
42  if (i_fad == fad_size)
43  return x;
44  const scalar x_fad = 1.0 + scalar(fad_size) / scalar(i_fad+1);
45  return x + x_fad;
46 }
47 
48 template <typename WgbView, typename WbsView, typename FluxView,
49  typename SrcView, typename ResidualView>
50 void init_fad(const WgbView& wgb, const WbsView& wbs, const FluxView& flux,
51  const SrcView& src, const ResidualView& residual)
52 {
53  typedef typename ResidualView::non_const_value_type::value_type scalar;
54 
55  const int ncells = wgb.extent(0);
56  const int num_basis = wgb.extent(1);
57  const int num_points = wgb.extent(2);
58  const int ndim = wgb.extent(3);
59  const int N = Kokkos::dimension_scalar(residual)-1;
60 
61  auto wgb_h = Kokkos::create_mirror_view(wgb);
62  auto wbs_h = Kokkos::create_mirror_view(wbs);
63  auto flux_h = Kokkos::create_mirror_view(flux);
64  auto src_h = Kokkos::create_mirror_view(src);
65  for (int cell=0; cell<ncells; ++cell) {
66  for (int basis=0; basis<num_basis; ++basis) {
67  for (int qp=0; qp<num_points; ++qp) {
68  for (int dim=0; dim<ndim; ++dim) {
69  wgb_h(cell,basis,qp,dim) =
70  generate_fad<scalar>(ncells,num_basis,num_points,ndim,N,cell,basis,qp,dim,N);
71  }
72  wbs_h(cell,basis,qp) =
73  generate_fad<scalar>(ncells,num_basis,num_points,1,N,cell,basis,qp,0,N);
74  }
75  }
76  for (int qp=0; qp<num_points; ++qp) {
77  for (int dim=0; dim<ndim; ++dim) {
78  for (int i=0; i<N; ++i)
79  flux_h(cell,qp,dim).fastAccessDx(i) =
80  generate_fad<scalar>(ncells,1,num_points,ndim,N,cell,0,qp,dim,i);
81  flux_h(cell,qp,dim).val() =
82  generate_fad<scalar>(ncells,1,num_points,ndim,N,cell,0,qp,dim,N);
83  }
84  for (int i=0; i<N; ++i)
85  src_h(cell,qp).fastAccessDx(i) =
86  generate_fad<scalar>(ncells,1,num_points,1,N,cell,0,qp,0,i);
87  src_h(cell,qp).val() =
88  generate_fad<scalar>(ncells,1,num_points,1,N,cell,0,qp,0,N);
89  }
90  }
91 
92  Kokkos::deep_copy( wgb, wgb_h );
93  Kokkos::deep_copy( wbs, wbs_h );
94  Kokkos::deep_copy( flux, flux_h );
95  Kokkos::deep_copy( src, src_h );
96 
97 #if KOKKOS_VERSION >= 40799
98  Kokkos::deep_copy(typename ResidualView::type(residual), 0.0);
99 #else
100  Kokkos::deep_copy(typename ResidualView::array_type(residual), 0.0);
101 #endif
102 }
103 
104 template <typename WgbView, typename WbsView, typename FluxView,
105  typename SrcView, typename ResidualView>
106 void init_array(const WgbView& wgb, const WbsView& wbs, const FluxView& flux,
107  const SrcView& src, const ResidualView& residual)
108 {
109  typedef typename ResidualView::non_const_value_type scalar;
110 
111  const int ncells = wgb.extent(0);
112  const int num_basis = wgb.extent(1);
113  const int num_points = wgb.extent(2);
114  const int ndim = wgb.extent(3);
115  const int N = residual.extent(2)-1;
116 
117  auto wgb_h = Kokkos::create_mirror_view(wgb);
118  auto wbs_h = Kokkos::create_mirror_view(wbs);
119  auto flux_h = Kokkos::create_mirror_view(flux);
120  auto src_h = Kokkos::create_mirror_view(src);
121  for (int cell=0; cell<ncells; ++cell) {
122  for (int basis=0; basis<num_basis; ++basis) {
123  for (int qp=0; qp<num_points; ++qp) {
124  for (int dim=0; dim<ndim; ++dim) {
125  wgb_h(cell,basis,qp,dim) =
126  generate_fad<scalar>(ncells,num_basis,num_points,ndim,N,cell,basis,qp,dim,N);
127  }
128  wbs_h(cell,basis,qp) =
129  generate_fad<scalar>(ncells,num_basis,num_points,1,N,cell,basis,qp,0,N);
130  }
131  }
132  for (int qp=0; qp<num_points; ++qp) {
133  for (int dim=0; dim<ndim; ++dim) {
134  for (int i=0; i<N; ++i)
135  flux_h(cell,qp,dim,i) =
136  generate_fad<scalar>(ncells,1,num_points,ndim,N,cell,0,qp,dim,i);
137  flux_h(cell,qp,dim,N) =
138  generate_fad<scalar>(ncells,1,num_points,ndim,N,cell,0,qp,dim,N);
139  }
140  for (int i=0; i<N; ++i)
141  src_h(cell,qp,i) =
142  generate_fad<scalar>(ncells,1,num_points,1,N,cell,0,qp,0,i);
143  src_h(cell,qp,N) =
144  generate_fad<scalar>(ncells,1,num_points,1,N,cell,0,qp,0,N);
145  }
146  }
147 
148  Kokkos::deep_copy( wgb, wgb_h );
149  Kokkos::deep_copy( wbs, wbs_h );
150  Kokkos::deep_copy( flux, flux_h );
151  Kokkos::deep_copy( src, src_h );
152 
153  Kokkos::deep_copy(residual, 0.0);
154 }
155 
156 template <typename View1, typename View2>
158 check(const View1& v_gold, const View2& v, const double tol)
159 {
160  // Copy to host
161  typename View1::host_mirror_type v_gold_h = Kokkos::create_mirror_view(v_gold);
162  typename View2::host_mirror_type v_h = Kokkos::create_mirror_view(v);
163  Kokkos::deep_copy(v_gold_h, v_gold);
164  Kokkos::deep_copy(v_h, v);
165 
166  typedef typename View1::value_type value_type;
167 
168  const size_t n0 = v_gold_h.extent(0);
169  const size_t n1 = v_gold_h.extent(1);
170  const size_t n2 = v_gold_h.extent(2);
171 
172  bool success = true;
173  for ( size_t i0 = 0 ; i0 < n0 ; ++i0 ) {
174  for ( size_t i1 = 0 ; i1 < n1 ; ++i1 ) {
175  for ( size_t i2 = 0 ; i2 < n2 ; ++i2 ) {
176  value_type x_gold = v_gold_h(i0,i1,i2);
177  value_type x = v_h(i0,i1,i2);
178  if (std::abs(x_gold-x) > tol*std::abs(x_gold)) {
179  std::cout << "Comparison failed! x_gold("
180  << i0 << "," << i1 << "," << i2 << ") = "
181  << x_gold << " , x = " << x
182  << std::endl;
183  success = false;
184  }
185  }
186  }
187  }
188 
189  return success;
190 }
191 
192 template <typename View1, typename View2>
194 check(const View1& v_gold, const View2& v, const double tol)
195 {
196  // Copy to host
197  typename View1::host_mirror_type v_gold_h = Kokkos::create_mirror_view(v_gold);
198  typename View2::host_mirror_type v_h = Kokkos::create_mirror_view(v);
199  Kokkos::deep_copy(v_gold_h, v_gold);
200  Kokkos::deep_copy(v_h, v);
201 
202  typedef typename View1::value_type value_type;
203 
204  const size_t n0 = v_gold_h.extent(0);
205  const size_t n1 = v_gold_h.extent(1);
206  const size_t n2 = v_gold_h.extent(2);
207 
208  bool success = true;
209  for ( size_t i0 = 0 ; i0 < n0 ; ++i0 ) {
210  for ( size_t i1 = 0 ; i1 < n1 ; ++i1 ) {
211  for ( size_t i2 = 0 ; i2 < n2 ; ++i2 ) {
212  value_type x_gold = v_gold_h(i0,i1,i2);
213  value_type x = (i2 == n2-1) ? v_h(i0,i1).val() : v_h(i0,i1).dx(i2);
214  if (std::abs(x_gold-x) > tol*std::abs(x_gold)) {
215  std::cout << "Comparison failed! x_gold("
216  << i0 << "," << i1 << "," << i2 << ") = "
217  << x_gold << " , x = " << x
218  << std::endl;
219  success = false;
220  }
221  }
222  }
223  }
224 
225  return success;
226 }
227 
228 template<typename FluxView, typename WgbView, typename SrcView,
229  typename WbsView>
230 Kokkos::View<double***,typename FluxView::execution_space>
232  const FluxView& flux, const WgbView& wgb, const SrcView& src,
233  const WbsView& wbs,
234  typename std::enable_if< Kokkos::is_view_fad<FluxView>::value>::type* = 0)
235 {
236  typedef typename FluxView::execution_space execution_space;
237 
238  const size_t num_cells = wgb.extent(0);
239  const int num_basis = wgb.extent(1);
240  const int num_points = wgb.extent(2);
241  const int num_dim = wgb.extent(3);
242  const int N = Kokkos::dimension_scalar(flux)-1;
243 
244  Kokkos::View<double***,typename FluxView::execution_space> residual(
245  "",num_cells,num_basis,N+1);
246 
247  Kokkos::parallel_for(Kokkos::RangePolicy<execution_space>( 0,num_cells ),
248  KOKKOS_LAMBDA (const size_t cell)
249  {
250  double value, value2;
251 
252  // Value
253  for (int basis=0; basis<num_basis; ++basis) {
254  value = value2 = 0.0;
255  for (int qp=0; qp<num_points; ++qp) {
256  for (int dim=0; dim<num_dim; ++dim)
257  value += flux(cell,qp,dim).val()*wgb(cell,basis,qp,dim);
258  value2 += src(cell,qp).val()*wbs(cell,basis,qp);
259  }
260  residual(cell,basis,N) = value+value2;
261  }
262 
263  // Derivatives
264  for (int k=0; k<N; ++k) {
265  for (int basis=0; basis<num_basis; ++basis) {
266  value = value2 = 0.0;
267  for (int qp=0; qp<num_points; ++qp) {
268  for (int dim=0; dim<num_dim; ++dim)
269  value +=
270  flux(cell,qp,dim).dx(k)*wgb(cell,basis,qp,dim);
271  value2 +=
272  src(cell,qp).dx(k)*wbs(cell,basis,qp);
273  }
274  residual(cell,basis,k) = value+value2;
275  }
276  }
277  });
278 
279  return residual;
280 }
281 
282 template<typename FluxView, typename WgbView, typename SrcView,
283  typename WbsView>
284 Kokkos::View<double***,typename FluxView::execution_space>
286  const FluxView& flux, const WgbView& wgb, const SrcView& src,
287  const WbsView& wbs,
288  typename std::enable_if< !Kokkos::is_view_fad<FluxView>::value>::type* = 0)
289 {
290  typedef typename FluxView::execution_space execution_space;
291 
292  const size_t num_cells = wgb.extent(0);
293  const int num_basis = wgb.extent(1);
294  const int num_points = wgb.extent(2);
295  const int num_dim = wgb.extent(3);
296  const int N = flux.extent(3)-1;
297 
298  Kokkos::View<double***,typename FluxView::execution_space> residual(
299  "",num_cells,num_basis,N+1);
300 
301  Kokkos::parallel_for(Kokkos::RangePolicy<execution_space>( 0,num_cells ),
302  KOKKOS_LAMBDA (const size_t cell)
303  {
304  double value, value2;
305  for (int k=0; k<=N; ++k) {
306  for (int basis=0; basis<num_basis; ++basis) {
307  value = value2 = 0.0;
308  for (int qp=0; qp<num_points; ++qp) {
309  for (int dim=0; dim<num_dim; ++dim)
310  value += flux(cell,qp,dim,k)*wgb(cell,basis,qp,dim);
311  value2 += src(cell,qp,k)*wbs(cell,basis,qp);
312  }
313  residual(cell,basis,k) = value+value2;
314  }
315  }
316  });
317 
318  return residual;
319 }
320 
321 template<typename FluxView, typename WgbView, typename SrcView,
322  typename WbsView, typename ResidualView>
323 void check_residual(const FluxView& flux, const WgbView& wgb,
324  const SrcView& src, const WbsView& wbs,
325  const ResidualView& residual)
326 {
327  // Generate gold residual
328  auto residual_gold = compute_gold_residual(flux, wgb, src, wbs);
329 
330  // Compare residual and residual_gold
331  const double tol = 1.0e-14;
332  check(residual_gold, residual, tol);
333 }
abs(expr.val())
std::enable_if< !Kokkos::is_view_fad< View2 >::value, bool >::type check(const View1 &v_gold, const View2 &v, const double tol)
scalar generate_fad(const size_t n0, const size_t n1, const size_t n2, const size_t n3, const int fad_size, const size_t i0, const size_t i1, const size_t i2, const size_t i3, const int i_fad)
Sacado::Fad::SFad< double, fad_dim > SFadType
expr val()
Kokkos::View< double ***, typename FluxView::execution_space > compute_gold_residual(const FluxView &flux, const WgbView &wgb, const SrcView &src, const WbsView &wbs, typename std::enable_if< Kokkos::is_view_fad< FluxView >::value >::type *=0)
void init_array(const V1 &v1, const V2 &v2, const V3 &v3, const V4 &v4, const V5 &v5)
void init_fad(const V1 &v1, const V2 &v2, const V3 &v3, const V4 &v4, const V5 &v5)
int value
Sacado::Fad::SLFad< double, fad_dim > SLFadType
const int N
Sacado::Fad::DFad< double > DFadType
void check_residual(const FluxView &flux, const WgbView &wgb, const SrcView &src, const WbsView &wbs, const ResidualView &residual)
static const bool value
const int fad_dim
const double tol