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 //
4 // Panzer: A partial differential equation assembly
5 // engine for strongly coupled complex multiphysics systems
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39 // Eric C. Cyr (eccyr@sandia.gov)
40 // ***********************************************************************
41 // @HEADER
42 
43 #ifndef __Panzer_DOF_Functors_hpp__
44 #define __Panzer_DOF_Functors_hpp__
45 
46 #include "Phalanx_MDField.hpp"
47 #include "Phalanx_KokkosDeviceTypes.hpp"
48 
49 namespace panzer {
50 
51 //**********************************************************************
52 
53 // This hides the EvaluateDOF functors outside of this file
54 namespace dof_functors {
55 
56 template <typename ScalarT,typename Array,int spaceDim>
58  PHX::View<const ScalarT**> dof_basis; // <C,P>
59  PHX::View<ScalarT***> dof_ip; // <C,P,D>
61  const int numFields;
62  const int numPoints;
63  const int fadSize;
64  const bool use_shared_memory;
65 
66 public:
67  using scratch_view = Kokkos::View<ScalarT* ,typename PHX::DevLayout<ScalarT>::type,typename PHX::exec_space::scratch_memory_space,Kokkos::MemoryUnmanaged>;
68 
69  EvaluateDOFWithSens_Vector(PHX::View<const ScalarT**> in_dof_basis,
70  PHX::View<ScalarT***> in_dof_ip,
71  Array in_basis,
72  bool in_use_shared_memory = false)
73  : dof_basis(in_dof_basis), dof_ip(in_dof_ip), basis(in_basis),
74  numFields(static_cast<int>(basis.extent(1))),
75  numPoints(static_cast<int>(basis.extent(2))),
76  fadSize(static_cast<int>(Kokkos::dimension_scalar(dof_basis))),
77  use_shared_memory(in_use_shared_memory)
78  {}
79 
80  KOKKOS_INLINE_FUNCTION
81  void operator()(const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
82  {
83  const int cell = team.league_rank();
84 
85  if (not use_shared_memory) {
86  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numPoints), [&] (const int& pt) {
87  for (int d=0; d<spaceDim; ++d) {
88  // first initialize to the right thing (prevents over writing with 0)
89  // then loop over one less basis function
90  dof_ip(cell,pt,d) = dof_basis(cell, 0) * basis(cell, 0, pt, d);
91  // The start index is one, not zero since we used the zero index for initialization above.
92  for (int bf=1; bf<numFields; ++bf) {
93  dof_ip(cell,pt,d) += dof_basis(cell, bf) * basis(cell, bf, pt, d);
94  }
95  }
96  });
97  }
98  else {
99 
100  // Copy reused data into fast scratch space
101  scratch_view dof_values;
102  scratch_view point_values;
103  if (Sacado::IsADType<ScalarT>::value) {
104  dof_values = scratch_view(team.team_shmem(),numFields,fadSize);
105  point_values = scratch_view(team.team_shmem(),numPoints,fadSize);
106  }
107  else {
108  dof_values = scratch_view(team.team_shmem(),numFields);
109  point_values = scratch_view(team.team_shmem(),numPoints);
110  }
111 
112  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numFields), [&] (const int& dof) {
113  dof_values(dof) = dof_basis(cell,dof);
114  });
115 
116  team.team_barrier();
117 
118  for (int dim=0; dim < spaceDim; ++dim) {
119 
120  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numPoints), [&] (const int& pt) {
121  point_values(pt) = 0.0;
122  });
123 
124  // Perform contraction
125  for (int dof=0; dof<numFields; ++dof) {
126  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numPoints), [&] (const int& pt) {
127  point_values(pt) += dof_values(dof) * basis(cell,dof,pt,dim);
128  });
129  }
130 
131  // Copy to main memory
132  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numPoints), [&] (const int& pt) {
133  dof_ip(cell,pt,dim) = point_values(pt);
134  });
135 
136  } // loop over dim
137  } // if (use_shared_memory) {
138  }
139 
140  size_t team_shmem_size(int /* team_size */ ) const
141  {
142  if (not use_shared_memory)
143  return 0;
144 
145  size_t bytes;
146  if (Sacado::IsADType<ScalarT>::value)
147  bytes = scratch_view::shmem_size(numFields,fadSize) + scratch_view::shmem_size(numPoints,fadSize);
148  else
149  bytes = scratch_view::shmem_size(numFields) + scratch_view::shmem_size(numPoints);
150  return bytes;
151  }
152 
153 };
154 
155 template <typename ScalarT, typename Array>
160 
163 
164 public:
165  typedef typename PHX::Device execution_space;
166 
169  Array in_basis)
170  : dof_basis(in_dof_basis), dof_ip(in_dof_ip), basis(in_basis)
171  {
172  numFields = basis.extent(1);
173  numPoints = basis.extent(2);
174  }
175  KOKKOS_INLINE_FUNCTION
176  void operator()(const unsigned int cell) const
177  {
178  for (int pt=0; pt<numPoints; pt++) {
179  // first initialize to the right thing (prevents over writing with 0)
180  // then loop over one less basis function
181  dof_ip(cell,pt) = dof_basis(cell, 0) * basis(cell, 0, pt);
182  for (int bf=1; bf<numFields; bf++) {
183  dof_ip(cell,pt) += dof_basis(cell, bf) * basis(cell, bf, pt);
184  }
185  }
186  }
187 };
188 
189 template <typename ScalarT,typename Array,int spaceDim>
193  PHX::View<const int*> offsets;
195 
196  const int numFields;
197  const int numPoints;
198 
199 public:
200  typedef typename PHX::Device execution_space;
201 
204  PHX::View<const int*> in_offsets,
205  Array in_basis)
206  : dof_basis(in_dof_basis), dof_ip(in_dof_ip), offsets(in_offsets), basis(in_basis),
207  numFields(in_basis.extent(1)),
208  numPoints(in_basis.extent(2))
209  {}
210 
211  KOKKOS_INLINE_FUNCTION
212  void operator()(const unsigned int cell) const
213  {
214  for (int pt=0; pt<numPoints; pt++) {
215  for (int d=0; d<spaceDim; d++) {
216  // first initialize to the right thing (prevents over writing with 0)
217  // then loop over one less basis function
218 
219  // This is a possible issue if you need sensitivity to coordinates (you will need to
220  // change basis and then use the product rule!)
221  dof_ip(cell,pt,d) = dof_basis(cell, 0).val() * basis(cell, 0, pt, d);
222  dof_ip(cell,pt,d).fastAccessDx(offsets(0)) = dof_basis(cell, 0).fastAccessDx(offsets(0)) * Sacado::scalarValue(basis(cell, 0, pt, d));
223 
224  for (int bf=1; bf<numFields; bf++) {
225  dof_ip(cell,pt,d).val() += dof_basis(cell, bf).val() * Sacado::scalarValue(basis(cell, bf, pt, d));
226  dof_ip(cell,pt,d).fastAccessDx(offsets(bf)) += dof_basis(cell, bf).fastAccessDx(offsets(bf)) * Sacado::scalarValue(basis(cell, bf, pt, d));
227  }
228  }
229  }
230  }
231 };
232 
233 template <typename ScalarT, typename Array>
237  PHX::View<const int*> offsets;
239 
242 
243 public:
244  typedef typename PHX::Device execution_space;
245 
248  PHX::View<const int*> in_offsets,
249  Array in_basis)
250  : dof_basis(in_dof_basis), dof_ip(in_dof_ip), offsets(in_offsets), basis(in_basis)
251  {
252  numFields = basis.extent(1);
253  numPoints = basis.extent(2);
254  }
255  KOKKOS_INLINE_FUNCTION
256  void operator()(const unsigned int cell) const
257  {
258  for (int pt=0; pt<numPoints; pt++) {
259  // first initialize to the right thing (prevents over writing with 0)
260  // then loop over one less basis function
261 
262  // This is a possible issue if you need sensitivity to coordinates (you will need to
263  // change basis and then use the product rule!)
264  dof_ip(cell,pt) = dof_basis(cell, 0).val() * Sacado::scalarValue(basis(cell, 0, pt));
265  dof_ip(cell,pt).fastAccessDx(offsets(0)) = dof_basis(cell, 0).fastAccessDx(offsets(0)) * Sacado::scalarValue(basis(cell, 0, pt));
266 
267  for (int bf=1; bf<numFields; bf++) {
268  dof_ip(cell,pt).val() += dof_basis(cell, bf).val() * Sacado::scalarValue(basis(cell, bf, pt));
269  dof_ip(cell,pt).fastAccessDx(offsets(bf)) += dof_basis(cell, bf).fastAccessDx(offsets(bf)) * Sacado::scalarValue(basis(cell, bf, pt));
270  }
271  }
272  }
273 };
274 
275 }
276 
277 }
278 
279 #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)