Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_IntrepidFieldPattern.cpp
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
12
13#include "Teuchos_Assert.hpp"
14#include "Intrepid2_CellTools.hpp"
15#include "Shards_CellTopology.hpp"
16
17namespace panzer {
18
20 Intrepid2FieldPattern(const Teuchos::RCP< Intrepid2::Basis<PHX::Device,double,double> > &intrepidBasis)
21 : intrepidBasis_(intrepidBasis) {
22 const auto dofOrd = intrepidBasis_->getAllDofOrdinal(); // rank 3 view
23 const auto dofTag = intrepidBasis_->getAllDofTags(); // rank 2 view
24
25 const int
26 iend = dofOrd.extent(0),
27 jend = dofOrd.extent(1);
28
29 subcellIndicies_.resize(iend);
30 for (int i=0;i<iend;++i) {
31 subcellIndicies_[i].resize(jend);
32 for (int j=0;j<jend;++j) {
33 const int ord = dofOrd(i, j, 0);
34 if (ord >= 0) {
35 const int ndofs = dofTag(ord, 3);
36 subcellIndicies_[i][j].resize(ndofs);
37 for (int k=0;k<ndofs;++k)
38 subcellIndicies_[i][j][k] = dofOrd(i, j, k);
39 } else {
40 // if ordinal does not exist empty container.
41 subcellIndicies_[i][j].clear();
42 }
43 }
44 }
45 }
46
47 int
49 getSubcellCount(int dim) const
50 {
51 const shards::CellTopology ct = intrepidBasis_->getBaseCellTopology();
52 return ct.getSubcellCount(dim);
53 }
54
55 const std::vector<int> &
56 Intrepid2FieldPattern::getSubcellIndices(int dim, int cellIndex) const
57 {
58 if ((dim < static_cast<int>(subcellIndicies_.size() )) and
59 (cellIndex < static_cast<int>(subcellIndicies_[dim].size())))
60 return subcellIndicies_[dim][cellIndex];
61
62 return empty_;
63 }
64
65 void
67 getSubcellClosureIndices(int dim,int cellIndex,std::vector<int> & indices) const
68 {
69 // wipe out previous values
70 indices.clear();
71
72 if (dim == 0) {
73 indices = getSubcellIndices(dim,cellIndex);
74 } else {
75 // construct full topology
76 const shards::CellTopology ct = intrepidBasis_->getBaseCellTopology();
77
78 std::set<std::pair<unsigned,unsigned> > closure;
79 Intrepid2FieldPattern::buildSubcellClosure(ct,dim,cellIndex,closure);
80
81 // grab basis indices on the closure of the sub cell
82 std::set<std::pair<unsigned,unsigned> >::const_iterator itr;
83 for (itr=closure.begin();itr!=closure.end();++itr) {
84 // grab indices for this sub cell
85 const std::vector<int> & subcellIndices = getSubcellIndices(itr->first,itr->second);
86
87 // concatenate the two vectors
88 indices.insert(indices.end(),subcellIndices.begin(),subcellIndices.end());
89 }
90 }
91 }
92
93 int
95 getDimension() const
96 {
97 return intrepidBasis_->getBaseCellTopology().getDimension();
98 }
99
100 shards::CellTopology
102 getCellTopology() const
103 {
104 // TODO BWR Probably should change the name of this call...
105 // TODO BWR However this is a virtual function
106 return intrepidBasis_->getBaseCellTopology();
107 }
108
109 void
111 getSubcellNodes(const shards::CellTopology & cellTopo,unsigned dim,unsigned subCell,
112 std::vector<unsigned> & nodes)
113 {
114 if(dim==0) {
115 nodes.push_back(subCell);
116 return;
117 }
118
119 // get all nodes on requested sub cell
120 unsigned subCellNodeCount = cellTopo.getNodeCount(dim,subCell);
121 for(unsigned node=0;node<subCellNodeCount;++node)
122 nodes.push_back(cellTopo.getNodeMap(dim,subCell,node));
123
124 // sort them so they are ordered correctly for "includes" call
125 std::sort(nodes.begin(),nodes.end());
126 }
127
128 void
130 findContainedSubcells(const shards::CellTopology & cellTopo,unsigned dim,
131 const std::vector<unsigned> & nodes,
132 std::set<std::pair<unsigned,unsigned> > & subCells)
133 {
134 unsigned subCellCount = cellTopo.getSubcellCount(dim);
135 for(unsigned subCellOrd=0;subCellOrd<subCellCount;++subCellOrd) {
136 // get all nodes in sub cell
137 std::vector<unsigned> subCellNodes;
138 getSubcellNodes(cellTopo,dim,subCellOrd,subCellNodes);
139
140 // if subCellNodes \subset nodes => add (dim,subCellOrd) to subCells
141 bool isSubset = std::includes( nodes.begin(), nodes.end(),
142 subCellNodes.begin(), subCellNodes.end());
143 if(isSubset)
144 subCells.insert(std::make_pair(dim,subCellOrd));
145
146 }
147
148 // stop recursion base case
149 if (dim==0) return;
150
151 // find subcells in next sub dimension
152 findContainedSubcells(cellTopo,dim-1,nodes,subCells);
153 }
154
155 void
157 buildSubcellClosure(const shards::CellTopology & cellTopo,unsigned dim,unsigned subCell,
158 std::set<std::pair<unsigned,unsigned> > & closure)
159 {
160 switch(dim) {
161 case 0:
162 closure.insert(std::make_pair(0,subCell));
163 break;
164 case 1:
165 closure.insert(std::make_pair(0,cellTopo.getNodeMap(dim,subCell,0)));
166 closure.insert(std::make_pair(0,cellTopo.getNodeMap(dim,subCell,1)));
167 closure.insert(std::make_pair(1,subCell));
168 break;
169 case 2:
170 {
171 unsigned cnt = (shards::CellTopology(cellTopo.getCellTopologyData(dim,subCell))).getSubcellCount(dim-1);
172 for(unsigned i=0;i<cnt;i++) {
173 int edge = mapCellFaceEdge(cellTopo.getCellTopologyData(),subCell,i);
174 buildSubcellClosure(cellTopo,dim-1,edge,closure);
175 }
176 closure.insert(std::make_pair(2,subCell));
177 }
178 break;
179 default:
180 // beyond a two dimension surface this thing crashes!
181 TEUCHOS_ASSERT(false);
182 };
183 }
184
185 bool
188 {
189 // we no longer use CoordsInterface
190 return true;
191 }
192
198 void
200 getInterpolatoryCoordinates(Kokkos::DynRankView<double,PHX::Device> & coords) const
201 {
202 // this may not be efficient if coords is allocated every time this function is called
203 coords = Kokkos::DynRankView<double,PHX::Device>("coords",intrepidBasis_->getCardinality(),getDimension());
204 intrepidBasis_->getDofCoords(coords);
205 }
206
212 void
214 getInterpolatoryCoordinates(const Kokkos::DynRankView<double,PHX::Device> & cellNodes,
215 Kokkos::DynRankView<double,PHX::Device> & coords,
216 Teuchos::RCP<const shards::CellTopology> meshCellTopology) const
217 {
218 TEUCHOS_ASSERT(cellNodes.rank()==3);
219
220 int numCells = cellNodes.extent(0);
221
222 // grab the local coordinates
223 Kokkos::DynRankView<double,PHX::Device> localCoords;
224 getInterpolatoryCoordinates(localCoords);
225
226 // resize the coordinates field container
227 coords = Kokkos::DynRankView<double,PHX::Device>("coords",numCells,localCoords.extent(0),getDimension());
228
229 if(numCells>0) {
230 Intrepid2::CellTools<PHX::Device> cellTools;
231 // For backwards compatability, allow the FE basis to supply the mesh cell topology (via the FEM base cell topo)
232 // This will occur if no meshCellTopology is provided (defaults to Teuchos::null)
233 // If provided, use the mesh topology directly
234 if (meshCellTopology==Teuchos::null) {
235 cellTools.mapToPhysicalFrame(coords,localCoords,cellNodes,intrepidBasis_->getBaseCellTopology());
236 } else {
237 cellTools.mapToPhysicalFrame(coords,localCoords,cellNodes,*meshCellTopology);
238 }
239 }
240 }
241
242 Teuchos::RCP< Intrepid2::Basis<PHX::Device,double,double> >
245
246}
Teuchos::RCP< Intrepid2::Basis< PHX::Device, double, double > > intrepidBasis_
virtual void getSubcellClosureIndices(int dim, int cellIndex, std::vector< int > &indices) const
static void getSubcellNodes(const shards::CellTopology &cellTopo, unsigned dim, unsigned subCell, std::vector< unsigned > &nodes)
void getInterpolatoryCoordinates(Kokkos::DynRankView< double, PHX::Device > &coords) const
virtual shards::CellTopology getCellTopology() const
Teuchos::RCP< Intrepid2::Basis< PHX::Device, double, double > > getIntrepidBasis() const
Returns the underlying Intrepid2::Basis object.
bool supportsInterpolatoryCoordinates() const
Does this field pattern support interpolatory coordinates?
Intrepid2FieldPattern(const Teuchos::RCP< Intrepid2::Basis< PHX::Device, double, double > > &intrepidBasis)
std::vector< std::vector< std::vector< int > > > subcellIndicies_
static void findContainedSubcells(const shards::CellTopology &cellTopo, unsigned dim, const std::vector< unsigned > &nodes, std::set< std::pair< unsigned, unsigned > > &subCells)
virtual const std::vector< int > & getSubcellIndices(int dim, int cellIndex) const
static void buildSubcellClosure(const shards::CellTopology &cellTopo, unsigned dim, unsigned subCell, std::set< std::pair< unsigned, unsigned > > &closure)