45 #include "Phalanx_DataLayout.hpp" 46 #include "Phalanx_DataLayout_MDALayout.hpp" 49 #include "Panzer_Workset_Builder.hpp" 60 #include "Shards_CellTopology.hpp" 67 applyBV2Orientations(
const int num_cells,
68 BasisValues2<double> & basis_values,
69 const Kokkos::View<const panzer::LocalOrdinal*,PHX::Device> & local_cell_ids,
70 const Teuchos::RCP<const OrientationsInterface> & orientations_interface)
76 if(orientations_interface.is_null())
80 if(basis_values.orientationsApplied())
83 const auto & local_orientations = *orientations_interface->getOrientations();
84 std::vector<Intrepid2::Orientation> workset_orientations(num_cells);
86 auto local_cell_ids_h = Kokkos::create_mirror_view(local_cell_ids);
87 Kokkos::deep_copy(local_cell_ids_h, local_cell_ids);
90 auto local_cell_ids_host = Kokkos::create_mirror_view(local_cell_ids);
91 Kokkos::deep_copy(local_cell_ids_host, local_cell_ids);
92 for(
int i=0; i<num_cells; ++i)
93 workset_orientations[i] = local_orientations[local_cell_ids_host[i]];
94 basis_values.applyOrientations(workset_orientations,num_cells);
99 const int num_real_cells,
100 const int num_virtual_cells,
101 const Teuchos::RCP<const shards::CellTopology> cell_topology,
102 const SubcellConnectivity & face_connectivity)
111 const int space_dim = cell_topology->getDimension();
112 const int faces_per_cell = cell_topology->getSubcellCount(space_dim-1);
113 const int points = iv->surface_normals.extent_int(1);
114 const int points_per_face = points / faces_per_cell;
116 auto surface_normals_view = PHX::as_view(iv->surface_normals);
117 auto surface_normals_h = Kokkos::create_mirror_view(surface_normals_view);
118 Kokkos::deep_copy(surface_normals_h, surface_normals_view);
120 auto surface_rotation_matrices_view = PHX::as_view(iv->surface_rotation_matrices);
121 auto surface_rotation_matrices_h = Kokkos::create_mirror_view(surface_rotation_matrices_view);
122 Kokkos::deep_copy(surface_rotation_matrices_h, surface_rotation_matrices_view);
125 for (
int virtual_cell_ordinal=0; virtual_cell_ordinal<num_virtual_cells; virtual_cell_ordinal++)
127 const panzer::LocalOrdinal virtual_cell = virtual_cell_ordinal+num_real_cells;
128 int virtual_local_face_id = -1;
129 int face_ordinal = -1;
130 for (
int local_face_id=0; local_face_id<faces_per_cell; local_face_id++)
132 face_ordinal = face_connectivity.subcellForCellHost(virtual_cell, local_face_id);
133 if (face_ordinal >= 0)
135 virtual_local_face_id = local_face_id;
139 if (face_ordinal >= 0)
141 const int first_cell_for_face = face_connectivity.cellForSubcellHost(face_ordinal, 0);
142 const panzer::LocalOrdinal other_side = (first_cell_for_face == virtual_cell) ? 1 : 0;
143 const panzer::LocalOrdinal real_cell = face_connectivity.cellForSubcellHost(face_ordinal,other_side);
144 const panzer::LocalOrdinal face_in_real_cell = face_connectivity.localSubcellForSubcellHost(face_ordinal,other_side);
145 TEUCHOS_ASSERT(real_cell < num_real_cells);
146 for (
int point_ordinal=0; point_ordinal<points_per_face; point_ordinal++)
148 int virtual_cell_point = points_per_face * virtual_local_face_id + point_ordinal;
149 int real_cell_point = points_per_face * face_in_real_cell + point_ordinal;
151 double normal[3], transverse[3], binormal[3];
159 for (
int d=0; d<space_dim; d++)
161 const auto n_d = surface_normals_h(real_cell,real_cell_point,d);
162 surface_normals_h(virtual_cell,virtual_cell_point,d) = -n_d;
168 for(
int dim=0; dim<3; ++dim){
169 surface_rotation_matrices_h(virtual_cell,virtual_cell_point,0,dim) = normal[dim];
170 surface_rotation_matrices_h(virtual_cell,virtual_cell_point,1,dim) = transverse[dim];
171 surface_rotation_matrices_h(virtual_cell,virtual_cell_point,2,dim) = binormal[dim];
175 for (
int local_face_id=0; local_face_id<faces_per_cell; local_face_id++)
177 if (local_face_id == virtual_local_face_id)
continue;
178 for (
int point_ordinal=0; point_ordinal<points_per_face; point_ordinal++)
180 int point = local_face_id * points_per_face + point_ordinal;
181 for (
int dim=0; dim<space_dim; dim++)
183 surface_normals_h(virtual_cell,point,dim) = 0.0;
186 for(
int dim1=0; dim1<3; ++dim1)
188 for(
int dim2=0; dim2<3; ++dim2)
190 surface_rotation_matrices_h(virtual_cell,point,dim1,dim2) = 0;
198 Kokkos::deep_copy(surface_normals_view, surface_normals_h);
199 Kokkos::deep_copy(surface_rotation_matrices_view, surface_rotation_matrices_h);
209 , ir_degrees(new
std::vector<int>())
210 , basis_names(new
std::vector<
std::string>())
212 , num_owned_cells_(0)
213 , num_ghost_cells_(0)
214 , num_virtual_cells_(0)
215 , num_dimensions_(-1)
244 Kokkos::View<LocalOrdinal*, PHX::Device> cell_ids = Kokkos::View<LocalOrdinal*, PHX::Device>(
"cell_ids",
num_cells);
245 Kokkos::deep_copy(cell_ids, partition.
local_cells);
249 auto local_cells_h = Kokkos::create_mirror_view(partition.
local_cells);
250 Kokkos::deep_copy(local_cells_h, partition.
local_cells);
253 const int local_cell = local_cells_h(cell);
264 const int num_partition_cells = partition.
cell_vertices.extent(0);
265 const int num_vertices_per_cell = partition.
cell_vertices.extent(1);
266 const int num_dims_per_vertex = partition.
cell_vertices.extent(2);
269 TEUCHOS_ASSERT(num_partition_cells ==
num_cells);
270 TEUCHOS_ASSERT(num_vertices_per_cell > 0);
271 TEUCHOS_ASSERT(num_dims_per_vertex > 0);
280 Kokkos::parallel_for(
num_cells, KOKKOS_LAMBDA (
int i) {
281 for(
int j=0;j<num_vertices_per_cell;++j)
282 for(
int k=0;k<num_dims_per_vertex;++k)
283 cvc(i,j,k) = partition_vertices(i,j,k);
291 face_connectivity->setup(partition);
314 "Workset::getSubcellConnectivity : Requested subcell dimension "<<subcell_dimension<<
" for a "<<
num_dimensions_<<
"D workset. This is not supported.");
335 return *(itr->second);
346 "Workset::getIntegrationValues : Attempted to build integration values for side '"<<description.
getSide()<<
"', but workset is constructed for side '"<<
getSubcellIndex()<<
"'");
363 ir_degrees->push_back(iv->int_rule->cubature_degree);
373 const bool lazy_version)
const 380 for(
const auto & pr : itr->second)
405 const bool lazy_version)
const 412 const auto & submap = itr->second;
413 const auto itr2 = submap.find(integration_description.
getKey());
414 if(itr2 != submap.end())
415 return *(itr2->second);
423 Teuchos::RCP<BasisValues2<double>> biv;
432 biv->setupUniform(bir, iv.cub_points, iv.jac, iv.jac_det, iv.jac_inv);
434 biv->setup(bir, iv.ref_ip_coordinates, iv.jac, iv.jac_det, iv.jac_inv);
437 biv->setWeightedMeasure(iv.weighted_measure);
445 biv->setupArrays(bir);
450 biv->evaluateValuesCV(iv.ref_ip_coordinates,
463 biv->evaluateValues(iv.cub_points,
474 biv->evaluateValues(iv.ref_ip_coordinates,
490 bases.push_back(biv);
507 return *(itr->second);
509 TEUCHOS_TEST_FOR_EXCEPT_MSG(not description.
hasGenerator(),
510 "Point Descriptor of type '"<<description.
getType()<<
"' does not have associated generator.");
533 const bool lazy_version)
const 540 const auto & submap = itr->second;
541 const auto itr2 = submap.find(point_description.
getKey());
542 if(itr2 != submap.end())
543 return *(itr2->second);
552 Teuchos::RCP<BasisValues2<double>> bpv;
560 bpv->setupUniform(bir, pv.coords_ref, pv.jac, pv.jac_det, pv.jac_inv);
570 bpv->setupArrays(bir);
571 bpv->evaluateValues(pv.coords_ref,
609 "Workset::getIntegrationValues : Attempted to build integration values for side '"<<description.
getSide()<<
"', but workset is constructed for side '"<<
getSubcellIndex()<<
"'");
618 return *(itr->second);
636 return *(itr->second);
658 os <<
"Workset" << endl;
660 os <<
" num_cells:" << w.
num_cells << endl;
664 os <<
" cell_local_ids (size=" << w.
getLocalCellIDs().size() <<
")" << endl;
668 os <<
" ir_degrees: " << endl;
669 for (std::vector<int>::const_iterator ir = w.
ir_degrees->begin();
671 os <<
" " << *ir << std::endl;
673 std::vector<int>::const_iterator ir = w.
ir_degrees->begin();
677 os <<
" IR Values (Degree=" << *ir <<
"):" << endl;
679 os <<
" cub_points:" << endl;
680 os << (*irv)->cub_points << endl;
682 os <<
" side_cub_points:" << endl;
683 os << (*irv)->side_cub_points << endl;
685 os <<
" cub_weights:" << endl;
686 os << (*irv)->cub_weights << endl;
688 os <<
" node_coordinates:" << endl;
689 os << (*irv)->node_coordinates << endl;
691 os <<
" jac:" << endl;
692 os << (*irv)->jac << endl;
694 os <<
" jac_inv:" << endl;
695 os << (*irv)->jac_inv << endl;
697 os <<
" jac_det:" << endl;
698 os << (*irv)->jac_det << endl;
700 os <<
" weighted_measure:" << endl;
701 os << (*irv)->weighted_measure << endl;
703 os <<
" covarient:" << endl;
704 os << (*irv)->covarient << endl;
706 os <<
" contravarient:" << endl;
707 os << (*irv)->contravarient << endl;
709 os <<
" norm_contravarient:" << endl;
710 os << (*irv)->norm_contravarient << endl;
712 os <<
" ip_coordinates:" << endl;
713 os << (*irv)->ip_coordinates << endl;
715 os <<
" int_rule->getName():" << (*irv)->int_rule->getName() << endl;
719 os <<
" basis_names: " << endl;
720 for (std::vector<std::string>::const_iterator b = w.
basis_names->begin();
722 os <<
" " << *b << std::endl;
724 std::vector<std::string>::const_iterator b = w.
basis_names->begin();
728 os <<
" Basis Values (basis_name=" << *b <<
"):" << endl;
756 os <<
" basis_layout->name():" << (*bv)->basis_layout->name() << endl;
std::size_t getKey() const
Get unique key associated with basis of this order and type The key is used to sort through a map of ...
Control volume side integral.
PHX::MDField< Scalar, T0 > buildStaticArray(const std::string &str, int d0) const
int num_cells
DEPRECATED - use: numCells()
Teuchos::RCP< const shards::CellTopology > cell_topology
const panzer::IntegrationRule & getIntegrationRule(const panzer::IntegrationDescriptor &description) const
Grab the integration rule for a given integration description (throws error if integration doesn't ex...
const SubcellConnectivity & getSubcellConnectivity(const unsigned int subcell_dimension) const
Get the subcell connectivity for the workset topology.
std::map< size_t, Teuchos::RCP< const panzer::IntegrationRule > > _integration_rule_map
const int & getSide() const
Get side associated with integration - this is for backward compatibility.
PHX::View< const int * > cell_local_ids_k
bool hasGenerator() const
Check if the point descriptor has a generator for generating point values.
virtual Kokkos::DynRankView< double > getPoints(const shards::CellTopology &topo) const =0
Get the points for a particular topology.
Teuchos::RCP< panzer::SubcellConnectivity > face_connectivity_
KOKKOS_INLINE_FUNCTION int numSubcells() const
Gives number of subcells (e.g. faces) in connectivity.
int numVirtualCells() const
Number of cells not owned by any workset - these are used for boundary conditions.
std::map< size_t, std::map< size_t, Teuchos::RCP< panzer::BasisValues2< double > > > > basis_point_values_map_
const int & getType() const
Get type of integrator.
std::vector< size_t > cell_local_ids
Integral over a specific side of cells (side must be set)
Used to define options for lazy evaluation of BasisValues and IntegrationValues objects.
PHX::View< panzer::LocalOrdinal * > local_cells
Teuchos::RCP< std::vector< int > > ir_degrees
If workset corresponds to a sub cell, what is the index?
std::vector< Teuchos::RCP< panzer::BasisValues2< double > > > bases
Static basis function data, key is basis name, value is index in the static_bases vector...
std::map< size_t, Teuchos::RCP< const panzer::IntegrationValues2< double > > > integration_values_map_
Teuchos::RCP< std::vector< std::string > > basis_names
Value corresponds to basis type. Use the offest for indexing.
PHX::View< double *** > cell_vertices
int subcell_dim
DEPRECATED - use: getSubcellDimension()
unsigned int numDimensions() const
Get the cell dimension for the mesh.
std::map< size_t, Teuchos::RCP< const panzer::PureBasis > > _pure_basis_map
const std::string & getElementBlock() const
Get the element block id.
int numCells() const
Number of total cells in workset (owned, ghost, and virtual)
No integral specified - default state.
Generates a SubcellConnectivity associated with faces and cells given a partition of the local mesh...
const std::string & getType() const
Get unique string associated with the type of point descriptor. This will be used generate a hash to ...
panzer::LocalOrdinal num_owned_cells
CellCoordArray cell_vertex_coordinates
DEPRECATED - use: getCellVertices()
panzer::PointValues2< double > & getPointValues(const panzer::PointDescriptor &point_description) const
Grab the basis values for a given basis description and integration description (throws error if it d...
void setNumberOfCells(const int owned_cells, const int ghost_cells, const int virtual_cells)
Provides access to set numbers of cells (required for backwards compatibility)
panzer::LocalOrdinal num_virtual_cells
Teuchos::RCP< const shards::CellTopology > cell_topology_
const panzer::IntegrationValues2< double > & getIntegrationValues(const panzer::IntegrationDescriptor &description) const
Get the integration values for a given integration description.
Teuchos::RCP< const OrientationsInterface > orientations_
Must be set to apply orientations - if it is set, then orientations will be applied to basis values...
int getSubcellIndex() const
Get the subcell index (returns -1 if not a subcell)
bool side_assembly_
Build integration values for sides.
std::vector< Teuchos::RCP< panzer::IntegrationValues2< double > > > int_rules
std::map< size_t, Teuchos::RCP< panzer::PointValues2< double > > > point_values_map_
const PointGenerator & getGenerator() const
const panzer::BasisValues2< double > & getBasisValues(const panzer::BasisDescriptor &basis_description, const bool lazy_version=false) const
bool hasSubcellConnectivity(const unsigned int subcell_dimension) const
Check if subcell connectivity exists for a given dimension.
KOKKOS_INLINE_FUNCTION void convertNormalToRotationMatrix(const Scalar normal[3], Scalar transverse[3], Scalar binormal[3])
int getSubcellDimension() const
Get the subcell dimension.
panzer::LocalOrdinal num_ghstd_cells
Integral over all sides of cells (closed surface integral)
std::map< size_t, std::map< size_t, Teuchos::RCP< panzer::BasisValues2< double > > > > basis_integration_values_map_
Kokkos::View< const int *, PHX::Device > getLocalCellIDs() const
Get the local cell IDs for the workset.
std::string block_id
DEPRECATED - use: getElementBlock()
WorksetDetails()
Default constructor.
int subcell_index
DEPRECATED - use: getSubcellIndex()
int numOwnedCells() const
Number of cells owned by this workset.
std::size_t getKey() const
Get unique key associated with integrator of this order and type The key is used to sort through a ma...
std::ostream & operator<<(std::ostream &os, const AssemblyEngineInArgs &in)
bool align_side_points_
If workset side integration values must align with another workset, there must be a unique order assi...
std::size_t getKey() const
Get unique key associated with integrator of this order and type The key is used to sort through a ma...
std::string element_block_name
const panzer::SubcellConnectivity & getFaceConnectivity() const
int numGhostCells() const
Number of cells owned by a different workset.
virtual bool hasPoints(const shards::CellTopology &topo) const =0
Check if the generator can generate points for the given topology.
Description and data layouts associated with a particular basis.
CellCoordArray getCellVertices() const
Get the vertices for the cells.
void setup(const LocalMeshPartition &partition, const WorksetOptions &options)
Constructs the workset details from a given chunk of the mesh.
int getOrder() const
Get order of basis.
const std::string & getType() const
Get type of basis.
const panzer::PureBasis & getBasis(const panzer::BasisDescriptor &description) const
Grab the pure basis (contains data layouts) for a given basis description (throws error if integratio...