17 #include "Panzer_Workset_Builder.hpp"
23 #include <stk_mesh/base/Selector.hpp>
24 #include <stk_mesh/base/GetEntities.hpp>
25 #include <stk_mesh/base/GetBuckets.hpp>
26 #include <stk_mesh/base/CreateAdjacentEntities.hpp>
28 #include "Shards_CellTopology.hpp"
30 #include "Intrepid2_CellTools_Serial.hpp"
31 #include "Teuchos_Assert.hpp"
33 namespace panzer_stk {
37 const std::string& sidesetName,
38 const std::string& elementBlockName,
54 stk::mesh::Part * sidePart = mesh->
getSideset(sidesetName);
56 stk::mesh::Selector sideSelector = *sidePart;
57 stk::mesh::Selector blockSelector = *elmtPart;
58 stk::mesh::Selector mySelector = metaData->universal_part() & blockSelector & sideSelector;
59 std::vector<stk::mesh::Entity> sides;
60 stk::mesh::get_selected_entities(mySelector,bulkData->buckets(metaData->side_rank()),sides);
62 std::vector<std::size_t> missingElementIndices;
63 std::vector<std::size_t> localSideTopoIDs;
64 std::vector<stk::mesh::Entity> parentElements;
68 std::vector<std::size_t>::reverse_iterator index;
69 for(index=missingElementIndices.rbegin(); index != missingElementIndices.rend(); ++index) {
70 sides.erase(sides.begin()+*index);
74 for (std::size_t i=0; i < localSideTopoIDs.size(); ++i) {
75 *pout <<
"parent element: "
76 <<
" gid(" << bulkData->identifier(parentElements[i]) <<
")"
77 <<
", local_face(" << localSideTopoIDs[i] <<
")"
86 std::unordered_map<unsigned,std::vector<double> > nodeNormals;
95 std::vector<stk::mesh::Entity>::const_iterator side = sides.begin();
96 std::vector<std::size_t>::const_iterator sideID = localSideTopoIDs.begin();
97 std::vector<stk::mesh::Entity>::const_iterator parentElement = parentElements.begin();
101 auto side_parametrization = Intrepid2::RefSubcellParametrization<Kokkos::HostSpace>::get(2,parentTopology->getKey());
102 Kokkos::DynRankView<double,Kokkos::HostSpace> normal_at_point(
"normal",3);
103 for ( ; sideID != localSideTopoIDs.end(); ++side,++sideID,++parentElement) {
105 std::vector<stk::mesh::Entity> elementEntities;
106 elementEntities.push_back(*parentElement);
109 auto node_view = nodes.get_view();
121 auto jac_at_point = Kokkos::subview(iv.
jac.get_view(), 0, 0, Kokkos::ALL(), Kokkos::ALL());
122 auto jac_at_point_h = Kokkos::create_mirror_view(jac_at_point);
123 Kokkos::deep_copy(jac_at_point_h, jac_at_point);
125 CellTools::Serial::getPhysicalSideNormal(normal_at_point, side_parametrization, jac_at_point_h, *sideID);
129 *pout <<
"element normals: "
130 <<
"gid(" << bulkData->identifier(*parentElement) <<
")"
131 <<
", normal(" << normal_at_point(0) <<
"," << normal_at_point(1) <<
"," << normal_at_point(2) <<
")"
136 const size_t numNodes = bulkData->num_nodes(*side);
137 stk::mesh::Entity
const* nodeRelations = bulkData->begin_nodes(*side);
138 for (
size_t n=0; n<numNodes; ++n) {
139 stk::mesh::Entity node = nodeRelations[n];
140 for (
unsigned dim = 0; dim < parentTopology->getDimension(); ++dim) {
141 nodeNormals[bulkData->identifier(node)].push_back(normal_at_point(dim));
149 for (std::unordered_map<
unsigned,std::vector<double> >::const_iterator node = nodeNormals.begin(); node != nodeNormals.end(); ++node) {
151 TEUCHOS_ASSERT( (node->second.size() % parentTopology->getDimension()) == 0);
153 int numSurfaceContributions = node->second.size() / parentTopology->getDimension();
154 std::vector<double> contribArea(numSurfaceContributions);
155 double totalArea = 0.0;
156 for (
int surface = 0; surface < numSurfaceContributions; ++surface) {
159 for (
unsigned dim = 0; dim < parentTopology->getDimension(); ++dim)
160 sum += (node->second[surface*parentTopology->getDimension() + dim]) *
161 (node->second[surface*parentTopology->getDimension() + dim]);
163 contribArea[surface] = std::sqrt(sum);
165 totalArea += contribArea[surface];
169 for (std::size_t i = 0; i < contribArea.size(); ++i)
170 contribArea[i] /= totalArea;
173 normals[node->first].resize(parentTopology->getDimension());
174 for (
unsigned dim = 0; dim < parentTopology->getDimension(); ++dim) {
175 normals[node->first][dim] = 0.0;
176 for (
int surface = 0; surface < numSurfaceContributions; ++surface) {
177 normals[node->first][dim] += node->second[surface*parentTopology->getDimension() + dim] * contribArea[surface] / totalArea;
182 *pout <<
"surface normal before normalization: "
183 <<
"gid(" << node->first <<
")"
184 <<
", normal(" << normals[node->first][0] <<
"," << normals[node->first][1] <<
"," << normals[node->first][2] <<
")"
189 for (
unsigned dim = 0; dim < parentTopology->getDimension(); ++dim)
190 sum += normals[node->first][dim] * normals[node->first][dim];
192 for (
unsigned dim = 0; dim < parentTopology->getDimension(); ++dim)
193 normals[node->first][dim] /= std::sqrt(sum);
196 *pout <<
"surface normal after normalization: "
197 <<
"gid(" << node->first <<
")"
199 << normals[node->first][0] <<
","
200 << normals[node->first][1] <<
","
201 << normals[node->first][2] <<
")"
211 const std::string& sidesetName,
212 const std::string& elementBlockName,
218 std::unordered_map<unsigned,std::vector<double> > nodeEntityIdToNormals;
226 stk::mesh::Part * sidePart = mesh->
getSideset(sidesetName);
228 stk::mesh::Selector sideSelector = *sidePart;
229 stk::mesh::Selector blockSelector = *elmtPart;
230 stk::mesh::Selector mySelector = metaData->universal_part() & blockSelector & sideSelector;
231 std::vector<stk::mesh::Entity> sides;
232 stk::mesh::get_selected_entities(mySelector,bulkData->buckets(metaData->side_rank()),sides);
236 std::vector<std::size_t> missingElementIndices;
237 std::vector<std::size_t> localSideTopoIDs;
238 std::vector<stk::mesh::Entity> parentElements;
242 std::vector<std::size_t>::reverse_iterator index;
243 for(index=missingElementIndices.rbegin(); index != missingElementIndices.rend(); ++index) {
244 sides.erase(sides.begin()+*index);
247 std::vector<stk::mesh::Entity>::const_iterator side = sides.begin();
248 std::vector<std::size_t>::const_iterator sideID = localSideTopoIDs.begin();
249 std::vector<stk::mesh::Entity>::const_iterator parentElement = parentElements.begin();
250 for ( ; sideID != localSideTopoIDs.end(); ++side,++sideID,++parentElement) {
253 const size_t numNodes = bulkData->num_nodes(*parentElement);
254 stk::mesh::Entity
const* nodeRelations = bulkData->begin_nodes(*parentElement);
256 normals[mesh->
elementLocalId(*parentElement)] = Kokkos::DynRankView<double,PHX::Device>(
"normals",numNodes,parentTopology->getDimension());
257 auto normals_h = Kokkos::create_mirror_view(normals[mesh->
elementLocalId(*parentElement)]);
258 for (
size_t nodeIndex=0; nodeIndex<numNodes; ++nodeIndex) {
259 stk::mesh::Entity node = nodeRelations[nodeIndex];
262 if (nodeEntityIdToNormals.find(bulkData->identifier(node)) != nodeEntityIdToNormals.end()) {
263 for (
unsigned dim = 0; dim < parentTopology->getDimension(); ++dim) {
264 normals_h(nodeIndex,dim) = (nodeEntityIdToNormals[bulkData->identifier(node)])[dim];
268 for (
unsigned dim = 0; dim < parentTopology->getDimension(); ++dim) {
269 normals_h(nodeIndex,dim) = 0.0;
273 Kokkos::deep_copy(normals[mesh->
elementLocalId(*parentElement)], normals_h);
void computeSidesetNodeNormals(std::unordered_map< unsigned, std::vector< double > > &normals, const Teuchos::RCP< const panzer_stk::STK_Interface > &mesh, const std::string &sidesetName, const std::string &elementBlockName, std::ostream *, std::ostream *pout)
Computes the normals for all nodes associated with a sideset surface.
void getElementNodesNoResize(const std::vector< std::size_t > &localIds, ArrayT &nodes) const
stk::mesh::Part * getElementBlockPart(const std::string &name) const
get the block part
PHX::MDField< Scalar, T0 > buildStaticArray(const std::string &str, int d0) const
stk::mesh::Part * getSideset(const std::string &name) const
std::size_t elementLocalId(stk::mesh::Entity elmt) const
unsigned getDimension() const
get the dimension
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Data for determining cell topology and dimensionality.
void getUniversalSubcellElements(const panzer_stk::STK_Interface &mesh, const std::string &blockId, const std::vector< stk::mesh::Entity > &entities, std::vector< std::size_t > &localEntityIds, std::vector< stk::mesh::Entity > &elements, std::vector< std::size_t > &missingElementIndices)
Teuchos::RCP< stk::mesh::BulkData > getBulkData() const
void setupArrays(const Teuchos::RCP< const panzer::IntegrationRule > &ir)
Sizes/allocates memory for arrays.
Teuchos::RCP< stk::mesh::MetaData > getMetaData() const
#define TEUCHOS_ASSERT(assertion_test)
void evaluateValues(const PHX::MDField< Scalar, Cell, NODE, Dim > &cell_node_coordinates, const int num_cells=-1, const Teuchos::RCP< const SubcellConnectivity > &face_connectivity=Teuchos::null, const int num_virtual_cells=-1)
Evaluate basis values.
Teuchos::RCP< const shards::CellTopology > getCellTopology(const std::string &eBlock) const