Sierra Toolkit Version of the Day
DofMapper.cpp
00001 /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010 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 
00010 #include <sstream>
00011 #include <stdexcept>
00012 
00013 #include <stk_linsys/DofMapper.hpp>
00014 
00015 #include <stk_mesh/base/FieldData.hpp>
00016 #include <stk_mesh/base/Selector.hpp>
00017 #include <stk_mesh/base/GetBuckets.hpp>
00018 
00019 #include <stk_linsys/ImplDetails.hpp>
00020 
00021 namespace stk {
00022 namespace linsys {
00023 
00024 DofMapper::DofMapper(MPI_Comm comm, bool create_reverse_mappings)
00025  : m_field_id_map(),
00026    m_fei_vecspace(new fei::VectorSpace(comm)),
00027    m_reverse_mappings_enabled(create_reverse_mappings),
00028    m_fei_reversemap(NULL)
00029 {
00030 }
00031 
00032 DofMapper::~DofMapper()
00033 {
00034   delete m_fei_reversemap;
00035 }
00036 
00037 namespace {
00038 
00039 void throw_fei_err(const std::string& mesg, int err)
00040 {
00041   std::ostringstream osstr;
00042   osstr << mesg << err;
00043   std::string str = osstr.str();
00044   throw std::runtime_error(str);
00045 }
00046 
00047 }//namespace <anonymous>
00048 
00049 void
00050 DofMapper::add_dof_mappings(const stk::mesh::BulkData& mesh_bulk,
00051                             const stk::mesh::Selector& selector,
00052                             stk::mesh::EntityRank ent_type,
00053                             const stk::mesh::FieldBase& field)
00054 {
00055   int idType = static_cast<int>(ent_type);
00056 
00057   m_fei_vecspace->defineIDTypes( 1, &idType );
00058 
00059   int field_id = impl::map_field_to_int(m_field_id_map, field);
00060 
00061   const std::vector<stk::mesh::Bucket*>& all_buckets = mesh_bulk.buckets(ent_type);
00062   std::vector<stk::mesh::Bucket*> buckets;
00063   stk::mesh::get_buckets(selector, all_buckets, buckets);
00064 
00065   bool already_declared_fei_field = false;
00066 
00067   for(size_t i=0; i<buckets.size(); ++i) {
00068     int field_data_size = stk::mesh::field_data_size( field, *buckets[i] );
00069 
00070     if (field_data_size == 0) continue;
00071 
00072     if (!already_declared_fei_field) {
00073       int field_size = field.max_size(ent_type);
00074       m_fei_vecspace->defineFields(1, &field_id, &field_size);
00075       already_declared_fei_field = true;
00076     }
00077 
00078     std::vector<int> ids(buckets[i]->size());
00079 
00080     stk::mesh::Bucket::iterator
00081       iter = buckets[i]->begin(), iter_end = buckets[i]->end();
00082 
00083     int num_ids = 0;
00084 
00085     for(; iter != iter_end; ++iter) {
00086       stk::mesh::Entity& entity = *iter;
00087       ids[num_ids++] = impl::entityid_to_int(entity.identifier());
00088     }
00089 
00090     int err = m_fei_vecspace->addDOFs(field_id, idType, num_ids, &ids[0]);
00091     if (err != 0) throw_fei_err("stk::linsys::DofMapper::add_dof_mappings ERROR: fei::VectorSpace::addDOFs returned error-code=",err);
00092   }
00093 
00094   std::vector<int> shared_ids;
00095   std::vector<int> sharing_procs;
00096 
00097   const std::vector<stk::mesh::Entity*>& entity_comm = mesh_bulk.entity_comm();
00098   for(size_t i=0; i<entity_comm.size(); ++i) {
00099     stk::mesh::Entity* ent = entity_comm[i] ;
00100 
00101     //we only care about entities of the right type, and which have data for 'field'.
00102     if (ent->entity_rank() != ent_type) continue;
00103     if (!stk::mesh::field_data_valid(field, *ent)) continue;
00104 
00105     const stk::mesh::PairIterEntityComm ec = ent->sharing();
00106 
00107     for ( size_t j = 0 ; j < ec.size() ; ++j ) {
00108       shared_ids.push_back(impl::entityid_to_int(ent->identifier()));
00109       sharing_procs.push_back(ec[j].proc);
00110     }
00111   }
00112 
00113   if (shared_ids.size() > 0) {
00114     std::vector<int> num_sharing_procs_per_id(shared_ids.size(), 1);
00115 
00116     int err = m_fei_vecspace->initSharedIDs(shared_ids.size(), idType,
00117                                            &shared_ids[0], &num_sharing_procs_per_id[0],
00118                                            &sharing_procs[0]);
00119     if (err != 0) throw_fei_err("stk::linsys::DofMapper::add_dof_mappings ERROR: fei::VectorSpace::initSharedIDs returned error-code=",err);
00120   }
00121 }
00122 
00123 void
00124 DofMapper::finalize()
00125 {
00126   int err = m_fei_vecspace->initComplete();
00127   if (err != 0) throw_fei_err("stk::linsys::DofMapper::finalize ERROR: fei::VectorSpace::initComplete returned error-code=",err);
00128 
00129   if (m_reverse_mappings_enabled) {
00130     delete m_fei_reversemap;
00131     m_fei_reversemap = new fei::ReverseMapper(*m_fei_vecspace);
00132   }
00133 }
00134 
00135 int
00136 DofMapper::get_field_id(const stk::mesh::FieldBase& field) const
00137 {
00138   return impl::query_field_to_int_mapping(m_field_id_map, field);
00139 }
00140 
00141 int
00142 DofMapper::get_global_index(stk::mesh::EntityRank ent_type,
00143                             stk::mesh::EntityId ent_id,
00144                             stk::mesh::FieldBase& field,
00145                             int offset_into_field)
00146 {
00147   int err = 0, index = 0;
00148   int field_id = get_field_id(field);
00149   int int_id = impl::entityid_to_int(ent_id);
00150 
00151   try {
00152     err = m_fei_vecspace->getGlobalIndex(ent_type, int_id, field_id, index);
00153     if (err != 0) throw_fei_err("fei::VectorSpace::getGlobalIndex error=",err);
00154   }
00155   catch (...) {
00156     std::ostringstream msg;
00157     msg << "stk::linsys::DofMapper::get_global_index ERROR: "
00158      << "fei::VectorSpace::getGlobalIndex returned error-code ("<<err
00159      << ") or threw exception, probably meaning that the entity with type="<<ent_type<<" and id="
00160      << ent_id<<" was not found.";
00161     std::string str = msg.str();
00162     throw std::runtime_error(str);
00163   }
00164 
00165   return index + offset_into_field;
00166 }
00167 
00168 void
00169 DofMapper::get_dof(int global_index,
00170                    stk::mesh::EntityRank& ent_type,
00171                    stk::mesh::EntityId& ent_id,
00172                    const stk::mesh::FieldBase*& field,
00173                    int& offset_into_field) const
00174 {
00175   if (!m_reverse_mappings_enabled || m_fei_reversemap == NULL) {
00176     std::ostringstream msg;
00177     msg << "stk::linsys::DofMapper::get_dof ERROR: "
00178      << "either reverse-mappings are disabled or DofMapper::finalize hasn't "
00179      << "been called yet.";
00180     std::string str = msg.str();
00181     throw std::runtime_error(str);
00182   }
00183 
00184   fei::EqnRecord eqrec = m_fei_reversemap->getEqnRecord(global_index);
00185 
00186   ent_type = eqrec.IDType;
00187   ent_id   = eqrec.ID;
00188   offset_into_field = eqrec.offset;
00189   field = impl::get_field(m_field_id_map, eqrec.fieldID);
00190 }
00191 
00192 }//namespace linsys
00193 }//namespace stk
00194 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines