|
Sierra Toolkit
Version of the Day
|
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_classic { 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_classic::mesh::BulkData& mesh_bulk, 00051 const stk_classic::mesh::Selector& selector, 00052 stk_classic::mesh::EntityRank ent_type, 00053 const stk_classic::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_classic::mesh::Bucket*>& all_buckets = mesh_bulk.buckets(ent_type); 00062 std::vector<stk_classic::mesh::Bucket*> buckets; 00063 stk_classic::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_classic::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_classic::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_classic::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_classic::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_classic::mesh::Entity*>& entity_comm = mesh_bulk.entity_comm(); 00098 for(size_t i=0; i<entity_comm.size(); ++i) { 00099 stk_classic::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_classic::mesh::field_data_valid(field, *ent)) continue; 00104 00105 const stk_classic::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_classic::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_classic::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_classic::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_classic::mesh::EntityRank ent_type, 00143 stk_classic::mesh::EntityId ent_id, 00144 stk_classic::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_classic::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_classic::mesh::EntityRank& ent_type, 00171 stk_classic::mesh::EntityId& ent_id, 00172 const stk_classic::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_classic::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_classic 00194