Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_DOF_Functors.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Panzer: A partial differential equation assembly
4 // engine for strongly coupled complex multiphysics systems
5 //
6 // Copyright 2011 NTESS and the Panzer contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
11 #ifndef __Panzer_DOF_Functors_hpp__
12 #define __Panzer_DOF_Functors_hpp__
13 
14 #include "Phalanx_MDField.hpp"
15 #include "Phalanx_KokkosDeviceTypes.hpp"
16 
17 namespace panzer {
18 
19 //**********************************************************************
20 
21 // This hides the EvaluateDOF functors outside of this file
22 namespace dof_functors {
23 
24 template <typename ScalarT,typename Array,int spaceDim>
26  PHX::View<const ScalarT**> dof_basis; // <C,P>
27  PHX::View<ScalarT***> dof_ip; // <C,P,D>
29  const int numFields;
30  const int numPoints;
31  const int fadSize;
32  const bool use_shared_memory;
33 
34 public:
35  using scratch_view = Kokkos::View<ScalarT* ,typename PHX::DevLayout<ScalarT>::type,typename PHX::exec_space::scratch_memory_space,Kokkos::MemoryUnmanaged>;
36 
37  EvaluateDOFWithSens_Vector(PHX::View<const ScalarT**> in_dof_basis,
38  PHX::View<ScalarT***> in_dof_ip,
39  Array in_basis,
40  bool in_use_shared_memory = false)
41  : dof_basis(in_dof_basis), dof_ip(in_dof_ip), basis(in_basis),
42  numFields(static_cast<int>(basis.extent(1))),
43  numPoints(static_cast<int>(basis.extent(2))),
44  fadSize(static_cast<int>(Kokkos::dimension_scalar(dof_basis))),
45  use_shared_memory(in_use_shared_memory)
46  {}
47 
48  KOKKOS_INLINE_FUNCTION
49  void operator()(const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
50  {
51  const int cell = team.league_rank();
52 
53  if (not use_shared_memory) {
54  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numPoints), [&] (const int& pt) {
55  for (int d=0; d<spaceDim; ++d) {
56  // first initialize to the right thing (prevents over writing with 0)
57  // then loop over one less basis function
58  dof_ip(cell,pt,d) = dof_basis(cell, 0) * basis(cell, 0, pt, d);
59  // The start index is one, not zero since we used the zero index for initialization above.
60  for (int bf=1; bf<numFields; ++bf) {
61  dof_ip(cell,pt,d) += dof_basis(cell, bf) * basis(cell, bf, pt, d);
62  }
63  }
64  });
65  }
66  else {
67 
68  // Copy reused data into fast scratch space
69  scratch_view dof_values;
70  scratch_view point_values;
71  if (Sacado::IsADType<ScalarT>::value) {
72  dof_values = scratch_view(team.team_shmem(),numFields,fadSize);
73  point_values = scratch_view(team.team_shmem(),numPoints,fadSize);
74  }
75  else {
76  dof_values = scratch_view(team.team_shmem(),numFields);
77  point_values = scratch_view(team.team_shmem(),numPoints);
78  }
79 
80  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numFields), [&] (const int& dof) {
81  dof_values(dof) = dof_basis(cell,dof);
82  });
83 
84  team.team_barrier();
85 
86  for (int dim=0; dim < spaceDim; ++dim) {
87 
88  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numPoints), [&] (const int& pt) {
89  point_values(pt) = 0.0;
90  });
91 
92  // Perform contraction
93  for (int dof=0; dof<numFields; ++dof) {
94  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numPoints), [&] (const int& pt) {
95  point_values(pt) += dof_values(dof) * basis(cell,dof,pt,dim);
96  });
97  }
98 
99  // Copy to main memory
100  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numPoints), [&] (const int& pt) {
101  dof_ip(cell,pt,dim) = point_values(pt);
102  });
103 
104  } // loop over dim
105  } // if (use_shared_memory) {
106  }
107 
108  size_t team_shmem_size(int /* team_size */ ) const
109  {
110  if (not use_shared_memory)
111  return 0;
112 
113  size_t bytes;
114  if (Sacado::IsADType<ScalarT>::value)
115  bytes = scratch_view::shmem_size(numFields,fadSize) + scratch_view::shmem_size(numPoints,fadSize);
116  else
117  bytes = scratch_view::shmem_size(numFields) + scratch_view::shmem_size(numPoints);
118  return bytes;
119  }
120 
121 };
122 
123 template <typename ScalarT, typename Array>
128 
131 
132 public:
133  typedef typename PHX::Device execution_space;
134 
137  Array in_basis)
138  : dof_basis(in_dof_basis), dof_ip(in_dof_ip), basis(in_basis)
139  {
140  numFields = basis.extent(1);
141  numPoints = basis.extent(2);
142  }
143  KOKKOS_INLINE_FUNCTION
144  void operator()(const unsigned int cell) const
145  {
146  for (int pt=0; pt<numPoints; pt++) {
147  // first initialize to the right thing (prevents over writing with 0)
148  // then loop over one less basis function
149  dof_ip(cell,pt) = dof_basis(cell, 0) * basis(cell, 0, pt);
150  for (int bf=1; bf<numFields; bf++) {
151  dof_ip(cell,pt) += dof_basis(cell, bf) * basis(cell, bf, pt);
152  }
153  }
154  }
155 };
156 
157 template <typename ScalarT,typename Array,int spaceDim>
161  PHX::View<const int*> offsets;
163 
164  const int numFields;
165  const int numPoints;
166 
167 public:
168  typedef typename PHX::Device execution_space;
169 
172  PHX::View<const int*> in_offsets,
173  Array in_basis)
174  : dof_basis(in_dof_basis), dof_ip(in_dof_ip), offsets(in_offsets), basis(in_basis),
175  numFields(in_basis.extent(1)),
176  numPoints(in_basis.extent(2))
177  {}
178 
179  KOKKOS_INLINE_FUNCTION
180  void operator()(const unsigned int cell) const
181  {
182  for (int pt=0; pt<numPoints; pt++) {
183  for (int d=0; d<spaceDim; d++) {
184  // first initialize to the right thing (prevents over writing with 0)
185  // then loop over one less basis function
186 
187  // This is a possible issue if you need sensitivity to coordinates (you will need to
188  // change basis and then use the product rule!)
189  dof_ip(cell,pt,d) = dof_basis(cell, 0).val() * basis(cell, 0, pt, d);
190  dof_ip(cell,pt,d).fastAccessDx(offsets(0)) = dof_basis(cell, 0).fastAccessDx(offsets(0)) * Sacado::scalarValue(basis(cell, 0, pt, d));
191 
192  for (int bf=1; bf<numFields; bf++) {
193  dof_ip(cell,pt,d).val() += dof_basis(cell, bf).val() * Sacado::scalarValue(basis(cell, bf, pt, d));
194  dof_ip(cell,pt,d).fastAccessDx(offsets(bf)) += dof_basis(cell, bf).fastAccessDx(offsets(bf)) * Sacado::scalarValue(basis(cell, bf, pt, d));
195  }
196  }
197  }
198  }
199 };
200 
201 template <typename ScalarT, typename Array>
205  PHX::View<const int*> offsets;
207 
210 
211 public:
212  typedef typename PHX::Device execution_space;
213 
216  PHX::View<const int*> in_offsets,
217  Array in_basis)
218  : dof_basis(in_dof_basis), dof_ip(in_dof_ip), offsets(in_offsets), basis(in_basis)
219  {
220  numFields = basis.extent(1);
221  numPoints = basis.extent(2);
222  }
223  KOKKOS_INLINE_FUNCTION
224  void operator()(const unsigned int cell) const
225  {
226  for (int pt=0; pt<numPoints; pt++) {
227  // first initialize to the right thing (prevents over writing with 0)
228  // then loop over one less basis function
229 
230  // This is a possible issue if you need sensitivity to coordinates (you will need to
231  // change basis and then use the product rule!)
232  dof_ip(cell,pt) = dof_basis(cell, 0).val() * Sacado::scalarValue(basis(cell, 0, pt));
233  dof_ip(cell,pt).fastAccessDx(offsets(0)) = dof_basis(cell, 0).fastAccessDx(offsets(0)) * Sacado::scalarValue(basis(cell, 0, pt));
234 
235  for (int bf=1; bf<numFields; bf++) {
236  dof_ip(cell,pt).val() += dof_basis(cell, bf).val() * Sacado::scalarValue(basis(cell, bf, pt));
237  dof_ip(cell,pt).fastAccessDx(offsets(bf)) += dof_basis(cell, bf).fastAccessDx(offsets(bf)) * Sacado::scalarValue(basis(cell, bf, pt));
238  }
239  }
240  }
241 };
242 
243 }
244 
245 }
246 
247 #endif
KOKKOS_INLINE_FUNCTION void operator()(const unsigned int cell) const
KOKKOS_INLINE_FUNCTION void operator()(const unsigned int cell) const
Kokkos::View< ScalarT *,typename PHX::DevLayout< ScalarT >::type, typename PHX::exec_space::scratch_memory_space, Kokkos::MemoryUnmanaged > scratch_view
PHX::MDField< const ScalarT, Cell, Point > dof_basis
PHX::MDField< const ScalarT, Cell, Point > dof_basis
KOKKOS_INLINE_FUNCTION void operator()(const unsigned int cell) const
EvaluateDOFFastSens_Scalar(PHX::MDField< const ScalarT, Cell, Point > in_dof_basis, PHX::MDField< ScalarT, Cell, Point > in_dof_ip, PHX::View< const int * > in_offsets, Array in_basis)
PHX::MDField< ScalarT, Cell, Point, Dim > dof_ip
EvaluateDOFWithSens_Scalar(PHX::MDField< const ScalarT, Cell, Point > in_dof_basis, PHX::MDField< ScalarT, Cell, Point > in_dof_ip, Array in_basis)
KOKKOS_INLINE_FUNCTION void operator()(const Kokkos::TeamPolicy< PHX::exec_space >::member_type &team) const
PHX::MDField< const ScalarT, Cell, Point > dof_basis
EvaluateDOFWithSens_Vector(PHX::View< const ScalarT ** > in_dof_basis, PHX::View< ScalarT *** > in_dof_ip, Array in_basis, bool in_use_shared_memory=false)
EvaluateDOFFastSens_Vector(PHX::MDField< const ScalarT, Cell, Point > in_dof_basis, PHX::MDField< ScalarT, Cell, Point, Dim > in_dof_ip, PHX::View< const int * > in_offsets, Array in_basis)