Sierra Toolkit Version of the Day
FEMMetaData.hpp
00001 #ifndef stk_mesh_FEMMetaData_hpp
00002 #define stk_mesh_FEMMetaData_hpp
00003 
00004 #include <stk_util/environment/ReportHandler.hpp>
00005 #include <stk_util/util/string_case_compare.hpp>
00006 #include <stk_mesh/base/Types.hpp>
00007 #include <stk_mesh/base/MetaData.hpp>
00008 #include <stk_mesh/base/BulkData.hpp> // TODO:  Remove!
00009 #include <stk_mesh/fem/CellTopology.hpp>
00010 
00011 #include <vector>
00012 #include <string>
00013 
00014 namespace stk {
00015 namespace mesh {
00016 namespace fem {
00017 
00018 
00044 // 02/10/11 FEMMetaData Todo:
00045 // * Implement get_cell_topology for Part.
00046 // * Implement declare_part with cell topology
00047 // Non-critical:
00048 // * Implement stk::mesh::fem::get namespace to include getters for MetaData,
00049 //   BulkData, FEMMetaData, FEMBulkData, CellTopology from things like Part,
00050 //   Bucket, Entity, etc.
00051 // * Create impl class inside the handle classes to hold their parent pointer
00052 //   and a friend to the getter above.
00053 
00054 class FEMMetaData {
00055   public:
00056 
00058   typedef std::map<fem::CellTopology, std::pair<Part *, EntityRank> > CellTopologyPartEntityRankMap;
00060   typedef std::vector<fem::CellTopology> PartCellTopologyVector;
00061 
00062   
00063 #ifdef SWIG   //SRK from NLM, this is to avoid pulling in a bunch more headers just to define EntityRank
00064   enum 
00065   {
00066     INVALID_RANK = stk::mesh::InvalidEntityRank,
00067     NODE_RANK = 0u,
00068     EDGE_RANK = 1u,
00069     FACE_RANK = 2u,
00070     VOLUME_RANK = 3u
00071   };
00072 #else
00073   static const EntityRank INVALID_RANK = stk::mesh::InvalidEntityRank;
00074   static const EntityRank NODE_RANK = 0u;
00075   static const EntityRank EDGE_RANK = 1u;
00076   static const EntityRank FACE_RANK = 2u;
00077   static const EntityRank VOLUME_RANK = 3u;
00078 #endif
00079 
00080   FEMMetaData();
00081   ~FEMMetaData() {}
00082 
00086   FEMMetaData(size_t spatial_dimension,
00087               const std::vector<std::string>& in_entity_rank_names = std::vector<std::string>());
00088 
00089 
00093 
00098   void FEM_initialize(
00099       size_t spatial_dimension,
00100       const std::vector<std::string>& in_entity_rank_names = std::vector<std::string>()
00101       );
00102 
00105   bool is_FEM_initialized() const
00106   {
00107     return m_fem_initialized;
00108   }
00109 
00110   // NOTE: This is a temporary function that will be removed once a FEMBulkData exists.
00113   inline static MetaData & get_meta_data( FEMMetaData & fem_meta )
00114     { return fem_meta.m_meta_data; }
00115 
00118   size_t spatial_dimension() const
00119   {
00120     return m_spatial_dimension;
00121   }
00122 
00125   EntityRank node_rank() const
00126   {
00127     return NODE_RANK;
00128   }
00129 
00132   EntityRank edge_rank() const
00133   {
00134     return EDGE_RANK;
00135   }
00136 
00139   EntityRank face_rank() const
00140   {
00141     return FACE_RANK;
00142   }
00143 
00146   EntityRank volume_rank() const
00147   {
00148     return VOLUME_RANK;
00149   }
00150 
00153   EntityRank side_rank() const
00154   {
00155     return m_side_rank;
00156   }
00157 
00160   EntityRank element_rank() const
00161   {
00162     return m_element_rank;
00163   }
00164   //  void check_topo_db();
00165 
00166 
00173   void register_cell_topology(const fem::CellTopology cell_topology, EntityRank in_entity_rank);
00174 
00178   Part &get_cell_topology_root_part(const fem::CellTopology cell_topology) const;
00179 
00184   fem::CellTopology get_cell_topology( const Part & part) const;
00185 
00186   fem::CellTopology get_cell_topology( const std::string & topology_name) const;
00187 
00192   EntityRank get_entity_rank(const fem::CellTopology cell_topology) const;
00193 
00196   inline static FEMMetaData & get ( const MetaData & meta )
00197     { return *const_cast<FEMMetaData * >(meta.get_attribute<FEMMetaData>()); }
00198 
00201   inline static FEMMetaData & get( const Part & part )
00202     { return FEMMetaData::get(MetaData::get(part)); }
00203 
00206   inline static FEMMetaData & get( const FieldBase & field )
00207     { return FEMMetaData::get(MetaData::get(field)); }
00208 
00211   inline static FEMMetaData & get( const PropertyBase & property )
00212     { return FEMMetaData::get(MetaData::get(property)); }
00213 
00216   inline static FEMMetaData & get( const BulkData & bulk_data )
00217     { return FEMMetaData::get(MetaData::get(bulk_data)); }
00218 
00221   inline static FEMMetaData & get( const Bucket & bucket )
00222     { return FEMMetaData::get(MetaData::get(bucket)); }
00223 
00226   inline static FEMMetaData & get( const Entity & entity )
00227     { return FEMMetaData::get(MetaData::get(entity)); }
00228 
00231   inline static FEMMetaData & get( const Ghosting & ghost )
00232     { return FEMMetaData::get(MetaData::get(ghost)); }
00233 
00236   Part &declare_part( const std::string &name, fem::CellTopology cell_topology)
00237   {
00238     ThrowRequireMsg(is_FEM_initialized(),"FEMMetaData::declare_part: FEM_initialize() must be called before this function");
00239     Part &root_part = get_cell_topology_root_part(cell_topology);
00240     EntityRank primary_entity_rank = root_part.primary_entity_rank();
00241     Part & part = m_meta_data.declare_part(name, primary_entity_rank);
00242     declare_part_subset(root_part, part);
00243     return part;
00244   }
00245 
00248   template< class Top >
00249   Part &declare_part(const std::string &name) {
00250     return declare_part(name, shards::getCellTopologyData<Top>());
00251   }
00252 
00256 
00260 
00261   //------------------------------------
00268   Part & universal_part() const { return m_meta_data.universal_part(); }
00269 
00273   Part & locally_owned_part()  const { return m_meta_data.locally_owned_part(); }
00274 
00278   Part & globally_shared_part() const { return m_meta_data.globally_shared_part(); }
00279 
00280   //------------------------------------
00290 
00291   Part * get_part( const std::string & p_name,
00292                    const char * required_by = NULL ) const
00293     { return m_meta_data.get_part(p_name,required_by); }
00294 
00296   Part & get_part( unsigned ord ) const
00297     { return m_meta_data.get_part(ord); }
00298 
00300   const PartVector & get_parts() const
00301     { return m_meta_data.get_parts(); }
00302 
00310   Part & declare_part( const std::string & p_name, EntityRank rank )
00311     { return m_meta_data.declare_part(p_name,rank); }
00312 
00318   Part & declare_part( const std::string & p_name)
00319     { return m_meta_data.declare_part(p_name); }
00320 
00325   void declare_part_subset( Part & superset , Part & subset );
00326 
00336   void declare_part_relation( Part & root_part ,
00337                               relation_stencil_ptr stencil ,
00338                               Part & target_part )
00339     { m_meta_data.declare_part_relation(root_part, stencil, target_part); }
00340 
00344   void set_entity_rank_names(const std::vector<std::string> &in_entity_rank_names)
00345   {
00346     m_entity_rank_names = in_entity_rank_names;
00347     m_meta_data.set_entity_rank_names(in_entity_rank_names);
00348   }
00349 
00352   EntityRank entity_rank( const std::string &name ) const
00353   {
00354     EntityRank my_entity_rank = InvalidEntityRank;
00355 
00356     for (size_t i = 0; i < m_entity_rank_names.size(); ++i)
00357       if (equal_case(name, m_entity_rank_names[i])) {
00358         my_entity_rank = i;
00359       break;
00360       }
00361     return my_entity_rank;
00362   }
00363 
00366   const std::vector<std::string> & entity_rank_names() const
00367   {
00368     return m_entity_rank_names;
00369   }
00370 
00373   std::vector<std::string>::size_type entity_rank_count() const
00374   {
00375     return m_entity_rank_names.size();
00376   }
00377 
00380   const std::string & entity_rank_name( EntityRank in_entity_rank ) const
00381   {
00382     ThrowErrorMsgIf( in_entity_rank >= m_entity_rank_names.size(),
00383         "entity-rank " << in_entity_rank <<
00384         " out of range. Must be in range 0.." << m_entity_rank_names.size());
00385     return m_entity_rank_names[in_entity_rank];
00386   }
00387 
00390   bool is_valid_entity_rank(EntityRank rank) const
00391   {
00392     return rank < m_entity_rank_names.size();
00393   }
00394 
00395   //------------------------------------
00406   template< class field_type >
00407   field_type * get_field( const std::string & name ) const
00408     { return m_meta_data.get_field<field_type>(name); }
00409 
00411   const FieldVector & get_fields() const {
00412     return m_meta_data.get_fields();
00413   }
00414 
00422   template< class field_type >
00423   field_type & declare_field( const std::string & name ,
00424                               unsigned number_of_states = 1 )
00425     { return m_meta_data.declare_field<field_type>( name, number_of_states ); }
00426 
00444   template< class PointerFieldType , class ReferencedFieldType >
00445   void declare_field_relation( PointerFieldType & pointer_field ,
00446                                relation_stencil_ptr stencil ,
00447                                ReferencedFieldType & referenced_field )
00448     { return m_meta_data.declare_field_relation( pointer_field, stencil, referenced_field ); }
00449 
00451   const std::vector<FieldRelation> & get_field_relations() const
00452     { return m_meta_data.get_field_relations(); }
00453 
00462   void commit()
00463     { m_meta_data.commit(); }
00464 
00466   bool is_commit() const
00467     { return m_meta_data.is_commit(); }
00468 
00469   //------------------------------------
00470 
00476   FieldBase * declare_field_base(
00477     const std::string & arg_name,
00478     const DataTraits  & arg_traits ,
00479     unsigned            arg_rank ,
00480     const shards::ArrayDimTag * const * arg_dim_tags ,
00481     unsigned arg_num_states )
00482     { return m_meta_data.declare_field_base( arg_name, arg_traits, arg_rank, arg_dim_tags, arg_num_states); }
00483 
00486   void declare_field_restriction( FieldBase      & arg_field ,
00487                                   EntityRank       arg_entity_rank ,
00488                                   const Part     & arg_part ,
00489                                   const unsigned * arg_stride ,
00490                                   const void     * arg_init_value = NULL)
00491     { m_meta_data.declare_field_restriction(arg_field, arg_entity_rank, arg_part, arg_stride, arg_init_value); }
00492 
00493   private: // functions
00494 
00495     void internal_set_spatial_dimension_and_ranks(size_t spatial_dimension);
00496 
00497     void internal_declare_known_cell_topology_parts();
00498 
00499   private: // data
00500     MetaData                      m_meta_data;
00501     bool                          m_fem_initialized;
00502     size_t                        m_spatial_dimension;
00503     EntityRank                    m_side_rank;
00504     EntityRank                    m_element_rank;
00505     std::vector< std::string >    m_entity_rank_names;
00507     CellTopologyPartEntityRankMap m_cellTopologyPartEntityRankMap;
00509     PartCellTopologyVector        m_partCellTopologyVector;
00510 };
00511 
00514 bool is_cell_topology_root_part(const Part & part);
00515 
00517 void set_cell_topology( Part &part, const fem::CellTopology cell_topology);
00518 
00520 template<class Topology>
00521 inline void set_cell_topology(Part & part)
00522 {
00523   stk::mesh::fem::set_cell_topology(part, fem::CellTopology(shards::getCellTopologyData<Topology>()));
00524 }
00525 
00526 
00528 CellTopology get_cell_topology(const Bucket &bucket);
00529 
00530 
00532 inline CellTopology get_cell_topology(const Entity &entity) {
00533   return get_cell_topology(entity.bucket());
00534 }
00535 
00536 
00537 
00538 std::vector<std::string> entity_rank_names(size_t spatial_dimension);
00539 
00540 } // namespace fem
00541 } // namespace mesh
00542 } // namespace stk
00543 
00544 #endif //  stk_mesh_FEMMetaData_hpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends