49 #ifndef __INTREPID2_CELLTOOLS_DEF_CONTROL_VOLUME_HPP__
50 #define __INTREPID2_CELLTOOLS_DEF_CONTROL_VOLUME_HPP__
53 #if defined (__clang__) && !defined (__INTEL_COMPILER)
54 #pragma clang system_header
65 namespace FunctorCellTools {
71 template<
typename centerViewType,
typename vertViewType>
72 KOKKOS_INLINE_FUNCTION
73 void getBaryCenter( centerViewType center,
74 const vertViewType verts) {
76 const ordinal_type nvert = verts.extent(0);
77 const ordinal_type dim = verts.extent(1);
83 typename centerViewType::value_type area = 0;
84 for (ordinal_type i=0;i<nvert;++i) {
85 const ordinal_type j = (i + 1)%nvert;
86 const auto scale = verts(i,0)*verts(j,1) - verts(j,0)*verts(i,1);
87 center(0) += (verts(i,0) + verts(j,0))*scale;
88 center(1) += (verts(i,1) + verts(j,1))*scale;
91 center(0) /= (6.0*area);
92 center(1) /= (6.0*area);
99 for (ordinal_type j=0;j<dim;++j) {
101 for (ordinal_type i=0;i<nvert;++i)
102 center(j) += verts(i,j);
110 template<
typename m
idPo
intViewType,
typename nodeMapViewType,
typename vertViewType>
111 KOKKOS_INLINE_FUNCTION
112 void getMidPoints( midPointViewType midpts,
113 const nodeMapViewType map,
114 const vertViewType verts) {
115 const ordinal_type npts = map.extent(0);
116 const ordinal_type dim = verts.extent(1);
118 for (ordinal_type i=0;i<npts;++i) {
120 const ordinal_type nvert_per_subcell = map(i, 0);
121 for (ordinal_type j=0;j<dim;++j) {
123 for (ordinal_type k=1;k<=nvert_per_subcell;++k)
124 midpts(i,j) += verts(map(i,k),j);
125 midpts(i,j) /= nvert_per_subcell;
130 template<
typename subcvCoordViewType,
131 typename cellCoordViewType,
132 typename mapViewType>
137 subcvCoordViewType _subcvCoords;
138 const cellCoordViewType _cellCoords;
139 const mapViewType _edgeMap;
141 KOKKOS_INLINE_FUNCTION
143 cellCoordViewType cellCoords_,
144 mapViewType edgeMap_ )
145 : _subcvCoords(subcvCoords_), _cellCoords(cellCoords_), _edgeMap(edgeMap_) {}
147 KOKKOS_INLINE_FUNCTION
148 void operator()(
const ordinal_type cell)
const {
150 const auto verts = Kokkos::subdynrankview( _cellCoords, cell,
151 Kokkos::ALL(), Kokkos::ALL() );
152 const ordinal_type nvert = verts.extent(0);
153 const ordinal_type dim = verts.extent(1);
156 auto cvCoords = Kokkos::subdynrankview( _subcvCoords, cell,
157 Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
160 typedef typename subcvCoordViewType::value_type value_type;
161 value_type buf_center[2], buf_midpts[4*2];
162 Kokkos::View<value_type*,Kokkos::Impl::ActiveExecutionMemorySpace> center(buf_center, 2);
163 Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> midpts(buf_midpts, 4, 2);
165 getBaryCenter(center, verts);
166 getMidPoints(midpts, _edgeMap, verts);
168 for (ordinal_type i=0;i<nvert;++i) {
169 for (ordinal_type j=0;j<dim;++j) {
171 cvCoords(i, 0, j) = verts(i, j);
172 cvCoords(i, 1, j) = midpts(i, j);
173 cvCoords(i, 2, j) = center(j);
174 cvCoords(i, 3, j) = midpts((i+nvert-1)%nvert, j);
180 template<
typename subcvCoordViewType,
181 typename cellCoordViewType,
182 typename mapViewType>
187 subcvCoordViewType _subcvCoords;
188 const cellCoordViewType _cellCoords;
189 const mapViewType _edgeMap, _faceMap;
191 KOKKOS_INLINE_FUNCTION
193 cellCoordViewType cellCoords_,
194 mapViewType edgeMap_,
195 mapViewType faceMap_ )
196 : _subcvCoords(subcvCoords_), _cellCoords(cellCoords_), _edgeMap(edgeMap_), _faceMap(faceMap_) {}
198 KOKKOS_INLINE_FUNCTION
199 void operator()(
const ordinal_type cell)
const {
201 const auto verts = Kokkos::subdynrankview( _cellCoords, cell,
202 Kokkos::ALL(), Kokkos::ALL() );
204 const ordinal_type dim = verts.extent(1);
207 auto cvCoords = Kokkos::subdynrankview( _subcvCoords, cell,
208 Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
211 typedef typename subcvCoordViewType::value_type value_type;
212 value_type buf_center[3], buf_edge_midpts[12*3], buf_face_midpts[6*3];
213 Kokkos::View<value_type*,Kokkos::Impl::ActiveExecutionMemorySpace> center(buf_center, 3);
214 Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> edge_midpts(buf_edge_midpts, 12, 3);
215 Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> face_midpts(buf_face_midpts, 6, 3);
217 getBaryCenter(center, verts);
218 getMidPoints(edge_midpts, _edgeMap, verts);
219 getMidPoints(face_midpts, _faceMap, verts);
221 for (ordinal_type i=0;i<4;++i) {
222 const ordinal_type ii = (i+4-1)%4;
223 for (ordinal_type j=0;j<dim;++j) {
227 cvCoords(i, 0,j) = verts(i, j);
228 cvCoords(i+4,4,j) = verts(i+4,j);
232 cvCoords(i, 1,j) = edge_midpts(i, j);
233 cvCoords(i+4,5,j) = edge_midpts(i+4,j);
237 cvCoords(i, 2,j) = face_midpts(4,j);
238 cvCoords(i+4,6,j) = face_midpts(5,j);
242 cvCoords(i, 3,j) = edge_midpts(ii, j);
243 cvCoords(i+4,7,j) = edge_midpts(ii+4,j);
247 cvCoords(i, 4,j) = edge_midpts(i+8,j);
248 cvCoords(i+4,0,j) = edge_midpts(i+8,j);
252 cvCoords(i, 5,j) = face_midpts(i,j);
253 cvCoords(i+4,1,j) = face_midpts(i,j);
257 cvCoords(i, 6,j) = center(j);
258 cvCoords(i+4,2,j) = center(j);
262 cvCoords(i, 7,j) = face_midpts(ii,j);
263 cvCoords(i+4,3,j) = face_midpts(ii,j);
270 template<
typename subcvCoordViewType,
271 typename cellCoordViewType,
272 typename mapViewType>
277 subcvCoordViewType _subcvCoords;
278 const cellCoordViewType _cellCoords;
279 const mapViewType _edgeMap, _faceMap;
281 KOKKOS_INLINE_FUNCTION
283 cellCoordViewType cellCoords_,
284 mapViewType edgeMap_,
285 mapViewType faceMap_ )
286 : _subcvCoords(subcvCoords_), _cellCoords(cellCoords_), _edgeMap(edgeMap_), _faceMap(faceMap_) {}
288 KOKKOS_INLINE_FUNCTION
289 void operator()(
const ordinal_type cell)
const {
291 const auto verts = Kokkos::subdynrankview( _cellCoords, cell,
292 Kokkos::ALL(), Kokkos::ALL() );
294 const ordinal_type dim = verts.extent(1);
297 auto cvCoords = Kokkos::subdynrankview( _subcvCoords, cell,
298 Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
301 typedef typename subcvCoordViewType::value_type value_type;
302 value_type buf_center[3], buf_edge_midpts[6*3], buf_face_midpts[4*3];
303 Kokkos::View<value_type*,Kokkos::Impl::ActiveExecutionMemorySpace> center(buf_center, 3);
304 Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> edge_midpts(buf_edge_midpts, 6, 3);
305 Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> face_midpts(buf_face_midpts, 4, 3);
307 getBaryCenter(center, verts);
308 getMidPoints(edge_midpts, _edgeMap, verts);
309 getMidPoints(face_midpts, _faceMap, verts);
311 for (ordinal_type i=0;i<3;++i) {
312 const ordinal_type ii = (i+3-1)%3;
313 for (ordinal_type j=0;j<dim;++j) {
315 cvCoords(i,0,j) = verts(i,j);
318 cvCoords(i,1,j) = edge_midpts(i,j);
321 cvCoords(i,2,j) = face_midpts(3,j);
324 cvCoords(i,3,j) = edge_midpts(ii,j);
327 cvCoords(i,4,j) = edge_midpts(i+3,j);
330 cvCoords(i,5,j) = face_midpts(i,j);
333 cvCoords(i,6,j) = center(j);
336 cvCoords(i,7,j) = face_midpts(ii,j);
340 for (ordinal_type j=0;j<dim;++j) {
343 cvCoords(3,0,j) = verts(3,j);
346 cvCoords(3,1,j) = edge_midpts(3,j);
349 cvCoords(3,2,j) = face_midpts(2,j);
352 cvCoords(3,3,j) = edge_midpts(5,j);
355 cvCoords(3,4,j) = edge_midpts(4,j);
358 cvCoords(3,5,j) = face_midpts(0,j);
361 cvCoords(3,6,j) = center(j);
364 cvCoords(3,7,j) = face_midpts(1,j);
371 template<
typename SpT>
372 template<
typename subcvCoordValueType,
class ...subcvCoordProperties,
373 typename cellCoordValueType,
class ...cellCoordProperties>
376 getSubcvCoords( Kokkos::DynRankView<subcvCoordValueType,subcvCoordProperties...> subcvCoords,
377 const Kokkos::DynRankView<cellCoordValueType,cellCoordProperties...> cellCoords,
378 const shards::CellTopology primaryCell ) {
379 #ifdef HAVE_INTREPID2_DEBUG
380 INTREPID2_TEST_FOR_EXCEPTION( !hasReferenceCell(primaryCell), std::invalid_argument,
381 ">>> ERROR (Intrepid2::CellTools::getSubcvCoords): the primary cell must have a reference cell." );
383 INTREPID2_TEST_FOR_EXCEPTION( cellCoords.extent(1) != primaryCell.getVertexCount(), std::invalid_argument,
384 ">>> ERROR (Intrepid2::CellTools::getSubcvCoords): cell coords dimension(1) does not match to # of vertices of the cell." );
386 INTREPID2_TEST_FOR_EXCEPTION( cellCoords.extent(2) != primaryCell.getDimension(), std::invalid_argument,
387 ">>> ERROR (Intrepid2::CellTools::getSubcvCoords): cell coords dimension(2) does not match to the dimension of the cell." );
391 const ordinal_type numCells = cellCoords.extent(0);
393 const ordinal_type spaceDim = cellCoords.extent(2);
396 const ordinal_type numEdge = primaryCell.getSubcellCount(1);
397 Kokkos::View<ordinal_type**,Kokkos::LayoutRight,Kokkos::HostSpace> edgeMapHost(
"CellTools::getSubcvCoords::edgeMapHost", numEdge, 3);
398 for (ordinal_type i=0;i<numEdge;++i) {
399 edgeMapHost(i,0) = primaryCell.getNodeCount(1, i);
400 for (ordinal_type j=0;j<edgeMapHost(i,0);++j)
401 edgeMapHost(i,j+1) = primaryCell.getNodeMap(1, i, j);
404 const ordinal_type numFace = (spaceDim > 2 ? primaryCell.getSubcellCount(2) : 0);
405 Kokkos::View<ordinal_type**,Kokkos::LayoutRight,Kokkos::HostSpace> faceMapHost(
"CellTools::getSubcvCoords::faceMapHost", numFace, 5);
406 for (ordinal_type i=0;i<numFace;++i) {
407 faceMapHost(i,0) = primaryCell.getNodeCount(2, i);
408 for (ordinal_type j=0;j<faceMapHost(i,0);++j)
409 faceMapHost(i,j+1) = primaryCell.getNodeMap(2, i, j);
413 auto edgeMap = Kokkos::create_mirror_view(
typename SpT::memory_space(), edgeMapHost);
414 auto faceMap = Kokkos::create_mirror_view(
typename SpT::memory_space(), faceMapHost);
416 Kokkos::deep_copy(edgeMap, edgeMapHost);
417 Kokkos::deep_copy(faceMap, faceMapHost);
420 typedef Kokkos::DynRankView<subcvCoordValueType,subcvCoordProperties...> subcvCoordViewType;
421 typedef Kokkos::DynRankView<cellCoordValueType,cellCoordProperties...> cellCoordViewType;
422 typedef Kokkos::View<ordinal_type**,Kokkos::LayoutRight,SpT> mapViewType;
424 typedef typename ExecSpace<typename subcvCoordViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
426 const auto loopSize = numCells;
427 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
429 switch (primaryCell.getKey()) {
430 case shards::Triangle<3>::key:
431 case shards::Quadrilateral<4>::key: {
434 Kokkos::parallel_for( policy, FunctorType(subcvCoords, cellCoords, edgeMap) );
437 case shards::Hexahedron<8>::key: {
439 Kokkos::parallel_for( policy, FunctorType(subcvCoords, cellCoords, edgeMap, faceMap) );
442 case shards::Tetrahedron<4>::key: {
444 Kokkos::parallel_for( policy, FunctorType(subcvCoords, cellCoords, edgeMap, faceMap) );
448 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
449 ">>> ERROR (Intrepid2::CellTools::getSubcvCoords: the give cell topology is not supported.");