Sierra Toolkit Version of the Day
FEMHelpers.hpp
00001 /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010, 2011 Sandia Corporation.                     */
00003 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00004 /*  license for use of this work by or on behalf of the U.S. Government.  */
00005 /*  Export of this program may require a license from the                 */
00006 /*  United States Government.                                             */
00007 /*------------------------------------------------------------------------*/
00008 
00009 #ifndef stk_mesh_FEMHelpers_hpp
00010 #define stk_mesh_FEMHelpers_hpp
00011 
00012 #include <stk_mesh/base/Types.hpp>
00013 
00014 #include <stk_mesh/fem/FEMMetaData.hpp>
00015 #include <stk_mesh/fem/CellTopology.hpp>
00016 // This is needed for ElementNode class
00017 #include <stk_mesh/fem/TopologyDimensions.hpp>
00018 
00019 namespace stk {
00020 namespace mesh {
00021 
00022 class Bucket;
00023 class Entity;
00024 
00025 namespace fem {
00026 
00031 //----------------------------------------------------------------------
00035 Entity & declare_element( BulkData & mesh ,
00036                           Part & part ,
00037                           const EntityId elem_id ,
00038                           const EntityId node_id[] );
00039 
00040 
00045 Entity & declare_element_side( BulkData & mesh ,
00046                                const stk::mesh::EntityId global_side_id ,
00047                                Entity & elem ,
00048                                const unsigned local_side_id ,
00049                                Part * part = NULL );
00050 
00055 Entity & declare_element_edge( BulkData & mesh ,
00056                                const stk::mesh::EntityId global_side_id ,
00057                                Entity & elem ,
00058                                const unsigned local_side_id ,
00059                                Part * part = NULL );
00060 
00064 bool element_side_polarity( const Entity & elem ,
00065                             const Entity & side , int local_side_id = -1 );
00066 
00071 Entity & declare_element_side( Entity & elem ,
00072                                Entity & side ,
00073                                const unsigned local_side_id ,
00074                                Part * part = NULL );
00075 
00076 
00077 
00082 Entity & declare_element_edge( Entity & elem ,
00083                                Entity & edge ,
00084                                const unsigned local_edge_id ,
00085                                Part * part = NULL );
00086 
00087 
00088 
00092 template< class Top >
00093 Part &declare_part(FEMMetaData& meta_data, const std::string &name) {
00094   return meta_data.declare_part(name, shards::getCellTopologyData<Top>());
00095 }
00096 
00108 const CellTopologyData * get_subcell_nodes(
00109     const Entity     & entity ,
00110     EntityRank         subcell_rank ,
00111     unsigned           subcell_identifier ,
00112     EntityVector     & subcell_nodes
00113     );
00114 
00119 int get_entity_subcell_id( const Entity            & entity ,
00120                            const EntityRank          subcell_rank,
00121                            const CellTopologyData  * side_topology,
00122                            const EntityVector      & side_nodes );
00123 
00125 bool comm_mesh_counts( BulkData & ,
00126                        std::vector<size_t> & counts ,
00127                        bool = false );
00128 
00129 typedef Field<double*,stk::mesh::ElementNode> ElementNodePointerField ;
00130 
00133 template< class NodeField >
00134 inline
00135 ElementNodePointerField &
00136 declare_element_node_pointer_field(
00137   FEMMetaData & fmd , const std::string & s ,
00138   NodeField & node_field )
00139 {
00140   const unsigned num_states = node_field.number_of_states();
00141 
00142   ElementNodePointerField & f =
00143     fmd.template declare_field< ElementNodePointerField >( s, num_states );
00144 
00145   for ( unsigned i = 0 ; i < num_states ; ++i ) {
00146     FieldState state = (FieldState) i;
00147     fmd.declare_field_relation(
00148       f.field_of_state( state ) ,
00149       fem::get_element_node_stencil(fmd.spatial_dimension()) ,
00150       node_field.field_of_state( state ) );
00151   }
00152 
00153   return f ;
00154 }
00155 
00156 template< class Traits >
00157 void get_parts_with_topology(stk::mesh::BulkData& mesh,
00158                              stk::mesh::PartVector& parts,
00159                              bool skip_topology_root_parts=false)
00160 {
00161   parts.clear();
00162 
00163   stk::mesh::fem::FEMMetaData & fem_meta = stk::mesh::fem::FEMMetaData::get(mesh);
00164 
00165   const stk::mesh::PartVector& all_parts = fem_meta.get_parts();
00166 
00167   stk::mesh::PartVector::const_iterator
00168     iter = all_parts.begin(),
00169     iter_end = all_parts.end();
00170 
00171   const CellTopologyData* topology = shards::getCellTopologyData<Traits>();
00172 
00173   for(; iter!=iter_end; ++iter) {
00174     stk::mesh::Part* part =  *iter;
00175     if (fem_meta.get_cell_topology(*part).getCellTopologyData() == topology) {
00176       if (skip_topology_root_parts && stk::mesh::fem::is_cell_topology_root_part(*part)) {
00177         continue;
00178       }
00179       parts.push_back(part);
00180     }
00181   }
00182 }
00183 
00184 inline
00185 unsigned get_spatial_dimension(const Entity& entity)
00186 {
00187   // expose some dot-chain to ensure everything inlined
00188   return entity.bucket().mesh().mesh_meta_data().get_spatial_dimension();
00189 }
00190 
00191 /* The Fmwk uses an enum to identify nodes, edges, faces and elements. The
00192    toolkit is similar, but the the toolkit rank depends on the spatial
00193    dimension. For 3D parts they are identical. With 2D, the element rank is
00194    2 (not 3). etc.
00195 */
00196 
00197 #ifdef SIERRA_MIGRATION
00198 
00199 inline
00200 unsigned convert_fmwk_rank_to_stk(unsigned fmwk_rank, unsigned spatial_dim)
00201 {
00202   ThrowAssert(spatial_dim > 0);
00203   ThrowAssert(spatial_dim < 4);
00204   ThrowAssert(fmwk_rank <= 4); // up to four basic entities types and constraints
00205   static int map2Stk[4][5] = { {-1,-1,-1,-1, 4},
00206                                { 0,-1,-1, 1, 4},
00207                                { 0, 1,-1, 2, 4},
00208                                { 0, 1, 2, 3, 4}};
00209   int stk_rank = map2Stk[spatial_dim][fmwk_rank];
00210 
00211   return static_cast<unsigned>(stk_rank);
00212 }
00213 
00214 inline
00215 unsigned convert_stk_rank_to_fmwk(unsigned stk_rank,  unsigned spatial_dim)
00216 {
00217   ThrowAssert(spatial_dim > 0);
00218   ThrowAssert(spatial_dim < 4);
00219   ThrowAssert(stk_rank <= 4); // up to four basic entities types and constraints
00220   static int map2Fmwk[4][5]={ {-1,-1,-1,-1, 4},
00221                               { 0, 3,-1,-1, 4},
00222                               { 0, 1, 3,-1, 4},
00223                               { 0, 1, 2, 3, 4}};
00224   int fmwk_rank=map2Fmwk[spatial_dim][stk_rank];
00225 
00226   return static_cast<unsigned>(fmwk_rank);
00227 }
00228 
00229 inline
00230 unsigned get_derived_type(const Entity& entity)
00231 {
00232   return convert_stk_rank_to_fmwk(entity.entity_rank(), get_spatial_dimension(entity));
00233 }
00234 
00235 #endif
00236 
00239 } //namespace fem
00240 } //namespace mesh
00241 } //namespace stk
00242 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines