Sierra Toolkit  Version of the Day
DofMapper.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 
10 #include <sstream>
11 #include <stdexcept>
12 
13 #include <stk_linsys/DofMapper.hpp>
14 
15 #include <stk_mesh/base/FieldData.hpp>
16 #include <stk_mesh/base/Selector.hpp>
17 #include <stk_mesh/base/GetBuckets.hpp>
18 
19 #include <stk_linsys/ImplDetails.hpp>
20 
21 namespace stk_classic {
22 namespace linsys {
23 
24 DofMapper::DofMapper(MPI_Comm comm, bool create_reverse_mappings)
25  : m_field_id_map(),
26  m_fei_vecspace(new fei::VectorSpace(comm)),
27  m_reverse_mappings_enabled(create_reverse_mappings),
28  m_fei_reversemap(NULL)
29 {
30 }
31 
33 {
34  delete m_fei_reversemap;
35 }
36 
37 namespace {
38 
39 void throw_fei_err(const std::string& mesg, int err)
40 {
41  std::ostringstream osstr;
42  osstr << mesg << err;
43  std::string str = osstr.str();
44  throw std::runtime_error(str);
45 }
46 
47 }//namespace <anonymous>
48 
49 void
51  const stk_classic::mesh::Selector& selector,
52  stk_classic::mesh::EntityRank ent_type,
53  const stk_classic::mesh::FieldBase& field)
54 {
55  int idType = static_cast<int>(ent_type);
56 
57  m_fei_vecspace->defineIDTypes( 1, &idType );
58 
59  int field_id = impl::map_field_to_int(m_field_id_map, field);
60 
61  const std::vector<stk_classic::mesh::Bucket*>& all_buckets = mesh_bulk.buckets(ent_type);
62  std::vector<stk_classic::mesh::Bucket*> buckets;
63  stk_classic::mesh::get_buckets(selector, all_buckets, buckets);
64 
65  bool already_declared_fei_field = false;
66 
67  for(size_t i=0; i<buckets.size(); ++i) {
68  int field_data_size = stk_classic::mesh::field_data_size( field, *buckets[i] );
69 
70  if (field_data_size == 0) continue;
71 
72  if (!already_declared_fei_field) {
73  int field_size = field.max_size(ent_type);
74  m_fei_vecspace->defineFields(1, &field_id, &field_size);
75  already_declared_fei_field = true;
76  }
77 
78  std::vector<int> ids(buckets[i]->size());
79 
80  stk_classic::mesh::Bucket::iterator
81  iter = buckets[i]->begin(), iter_end = buckets[i]->end();
82 
83  int num_ids = 0;
84 
85  for(; iter != iter_end; ++iter) {
86  stk_classic::mesh::Entity& entity = *iter;
87  ids[num_ids++] = impl::entityid_to_int(entity.identifier());
88  }
89 
90  int err = m_fei_vecspace->addDOFs(field_id, idType, num_ids, &ids[0]);
91  if (err != 0) throw_fei_err("stk_classic::linsys::DofMapper::add_dof_mappings ERROR: fei::VectorSpace::addDOFs returned error-code=",err);
92  }
93 
94  std::vector<int> shared_ids;
95  std::vector<int> sharing_procs;
96 
97  const std::vector<stk_classic::mesh::Entity*>& entity_comm = mesh_bulk.entity_comm();
98  for(size_t i=0; i<entity_comm.size(); ++i) {
99  stk_classic::mesh::Entity* ent = entity_comm[i] ;
100 
101  //we only care about entities of the right type, and which have data for 'field'.
102  if (ent->entity_rank() != ent_type) continue;
103  if (!stk_classic::mesh::field_data_valid(field, *ent)) continue;
104 
106 
107  for ( size_t j = 0 ; j < ec.size() ; ++j ) {
108  shared_ids.push_back(impl::entityid_to_int(ent->identifier()));
109  sharing_procs.push_back(ec[j].proc);
110  }
111  }
112 
113  if (shared_ids.size() > 0) {
114  std::vector<int> num_sharing_procs_per_id(shared_ids.size(), 1);
115 
116  int err = m_fei_vecspace->initSharedIDs(shared_ids.size(), idType,
117  &shared_ids[0], &num_sharing_procs_per_id[0],
118  &sharing_procs[0]);
119  if (err != 0) throw_fei_err("stk_classic::linsys::DofMapper::add_dof_mappings ERROR: fei::VectorSpace::initSharedIDs returned error-code=",err);
120  }
121 }
122 
123 void
125 {
126  int err = m_fei_vecspace->initComplete();
127  if (err != 0) throw_fei_err("stk_classic::linsys::DofMapper::finalize ERROR: fei::VectorSpace::initComplete returned error-code=",err);
128 
129  if (m_reverse_mappings_enabled) {
130  delete m_fei_reversemap;
131  m_fei_reversemap = new fei::ReverseMapper(*m_fei_vecspace);
132  }
133 }
134 
135 int
137 {
138  return impl::query_field_to_int_mapping(m_field_id_map, field);
139 }
140 
141 int
142 DofMapper::get_global_index(stk_classic::mesh::EntityRank ent_type,
143  stk_classic::mesh::EntityId ent_id,
145  int offset_into_field)
146 {
147  int err = 0, index = 0;
148  int field_id = get_field_id(field);
149  int int_id = impl::entityid_to_int(ent_id);
150 
151  try {
152  err = m_fei_vecspace->getGlobalIndex(ent_type, int_id, field_id, index);
153  if (err != 0) throw_fei_err("fei::VectorSpace::getGlobalIndex error=",err);
154  }
155  catch (...) {
156  std::ostringstream msg;
157  msg << "stk_classic::linsys::DofMapper::get_global_index ERROR: "
158  << "fei::VectorSpace::getGlobalIndex returned error-code ("<<err
159  << ") or threw exception, probably meaning that the entity with type="<<ent_type<<" and id="
160  << ent_id<<" was not found.";
161  std::string str = msg.str();
162  throw std::runtime_error(str);
163  }
164 
165  return index + offset_into_field;
166 }
167 
168 void
169 DofMapper::get_dof(int global_index,
170  stk_classic::mesh::EntityRank& ent_type,
171  stk_classic::mesh::EntityId& ent_id,
172  const stk_classic::mesh::FieldBase*& field,
173  int& offset_into_field) const
174 {
175  if (!m_reverse_mappings_enabled || m_fei_reversemap == NULL) {
176  std::ostringstream msg;
177  msg << "stk_classic::linsys::DofMapper::get_dof ERROR: "
178  << "either reverse-mappings are disabled or DofMapper::finalize hasn't "
179  << "been called yet.";
180  std::string str = msg.str();
181  throw std::runtime_error(str);
182  }
183 
184  fei::EqnRecord eqrec = m_fei_reversemap->getEqnRecord(global_index);
185 
186  ent_type = eqrec.IDType;
187  ent_id = eqrec.ID;
188  offset_into_field = eqrec.offset;
189  field = impl::get_field(m_field_id_map, eqrec.fieldID);
190 }
191 
192 }//namespace linsys
193 }//namespace stk_classic
194 
unsigned field_data_size(const FieldBase &f, const Bucket &k)
Size, in bytes, of the field data for each entity.
Definition: FieldData.hpp:99
const stk_classic::mesh::FieldBase * get_field(const FieldIdMap &field_id_map, int field_id)
Definition: ImplDetails.cpp:51
Field base class with an anonymous data type and anonymous multi-dimension.
Definition: FieldBase.hpp:53
PairIterEntityComm sharing() const
Parallel processes which share this entity.
Definition: Entity.hpp:178
const std::vector< Entity * > & entity_comm() const
All entities with communication information.
Definition: BulkData.hpp:367
void get_dof(int global_index, stk_classic::mesh::EntityRank &ent_type, stk_classic::mesh::EntityId &ent_id, const stk_classic::mesh::FieldBase *&field, int &offset_into_field) const
Definition: DofMapper.cpp:169
This is a class for selecting buckets based on a set of meshparts and set logic.
Definition: Selector.hpp:112
const std::vector< Bucket * > & buckets(EntityRank rank) const
Query all buckets of a given entity rank.
Definition: BulkData.hpp:195
int entityid_to_int(stk_classic::mesh::EntityId id)
Definition: ImplDetails.cpp:79
int get_field_id(const stk_classic::mesh::FieldBase &field) const
Definition: DofMapper.cpp:136
bool field_data_valid(const FieldBase &f, const Bucket &k, unsigned ord, const char *required_by)
Check for existence of field data.
Definition: Bucket.cpp:194
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
void add_dof_mappings(const stk_classic::mesh::BulkData &mesh_bulk, const stk_classic::mesh::Selector &selector, stk_classic::mesh::EntityRank ent_type, const stk_classic::mesh::FieldBase &field)
Definition: DofMapper.cpp:50
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120
Sierra Toolkit.
int map_field_to_int(FieldIdMap &field_id_map, const stk_classic::mesh::FieldBase &field)
Definition: ImplDetails.cpp:21
int query_field_to_int_mapping(const FieldIdMap &field_id_map, const stk_classic::mesh::FieldBase &field)
Definition: ImplDetails.cpp:34
AllSelectedBucketsRange get_buckets(const Selector &selector, const BulkData &mesh)
Definition: GetBuckets.cpp:26
EntityRank entity_rank() const
The rank of this entity.
Definition: Entity.hpp:128
EntityId identifier() const
Identifier for this entity which is globally unique for a given entity type.
Definition: Entity.hpp:133
int get_global_index(stk_classic::mesh::EntityRank ent_type, stk_classic::mesh::EntityId ent_id, stk_classic::mesh::FieldBase &field, int offset_into_field=0)
Definition: DofMapper.cpp:142
DofMapper(MPI_Comm comm, bool create_reverse_mappings=true)
Definition: DofMapper.cpp:24