Panzer Version of the Day
Loading...
Searching...
No Matches
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
49namespace panzer {
50
51//**********************************************************************
52
53// This hides the EvaluateDOF functors outside of this file
54namespace dof_functors {
55
56template <typename ScalarT,typename Array,int spaceDim>
58 PHX::View<const ScalarT**> dof_basis; // <C,P>
59 PHX::View<ScalarT***> dof_ip; // <C,P,D>
60 Array basis;
61 const int numFields;
62 const int numPoints;
63 const int fadSize;
65
66public:
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
155template <typename ScalarT, typename Array>
157 PHX::MDField<const ScalarT,Cell,Point> dof_basis;
158 PHX::MDField<ScalarT,Cell,Point> dof_ip;
159 Array basis;
160
163
164public:
165 typedef typename PHX::Device execution_space;
166
167 EvaluateDOFWithSens_Scalar(PHX::MDField<const ScalarT,Cell,Point> in_dof_basis,
168 PHX::MDField<ScalarT,Cell,Point> in_dof_ip,
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
189template <typename ScalarT,typename Array,int spaceDim>
191 PHX::MDField<const ScalarT,Cell,Point> dof_basis;
192 PHX::MDField<ScalarT,Cell,Point,Dim> dof_ip;
193 PHX::View<const int*> offsets;
194 Array basis;
195
196 const int numFields;
197 const int numPoints;
198
199public:
200 typedef typename PHX::Device execution_space;
201
202 EvaluateDOFFastSens_Vector(PHX::MDField<const ScalarT,Cell,Point> in_dof_basis,
203 PHX::MDField<ScalarT,Cell,Point,Dim> in_dof_ip,
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
233template <typename ScalarT, typename Array>
235 PHX::MDField<const ScalarT,Cell,Point> dof_basis;
236 PHX::MDField<ScalarT,Cell,Point> dof_ip;
237 PHX::View<const int*> offsets;
238 Array basis;
239
242
243public:
244 typedef typename PHX::Device execution_space;
245
246 EvaluateDOFFastSens_Scalar(PHX::MDField<const ScalarT,Cell,Point> in_dof_basis,
247 PHX::MDField<ScalarT,Cell,Point> in_dof_ip,
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
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< const ScalarT, Cell, Point > dof_basis
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)
PHX::MDField< ScalarT, Cell, Point, Dim > dof_ip
PHX::MDField< const ScalarT, Cell, Point > dof_basis
KOKKOS_INLINE_FUNCTION void operator()(const unsigned int cell) const
EvaluateDOFWithSens_Scalar(PHX::MDField< const ScalarT, Cell, Point > in_dof_basis, PHX::MDField< ScalarT, Cell, Point > in_dof_ip, Array in_basis)
PHX::MDField< const ScalarT, Cell, Point > dof_basis
KOKKOS_INLINE_FUNCTION void operator()(const unsigned int cell) const
KOKKOS_INLINE_FUNCTION void operator()(const Kokkos::TeamPolicy< PHX::exec_space >::member_type &team) const
Kokkos::View< ScalarT *,typename PHX::DevLayout< ScalarT >::type, typename PHX::exec_space::scratch_memory_space, Kokkos::MemoryUnmanaged > scratch_view
EvaluateDOFWithSens_Vector(PHX::View< const ScalarT ** > in_dof_basis, PHX::View< ScalarT *** > in_dof_ip, Array in_basis, bool in_use_shared_memory=false)