Flow123d  last_with_con_2.0.0-4-g42e6930
region_set.cc
Go to the documentation of this file.
1 /*
2  * region_set.cc
3  *
4  * Created on: Nov 27, 2012
5  * Author: jb
6  */
7 
8 #include "mesh/region_set.hh"
9 #include "mesh/mesh.h"
10 #include <string>
11 #include <sstream>
12 
13 
14 namespace IT = Input::Type;
15 
16 
17 /*******************************************************************
18  * implementation of RegionSetBase
19  */
20 
22 : region_db_(mesh->region_db_),
23  el_to_reg_map_(mesh->region_db_.el_to_reg_map_) {}
24 
26  return IT::Abstract("Region", "Abstract record for Region.")
27  .close();
28 }
29 
30 
31 
32 /*******************************************************************
33  * implementation of RegionSetFromId
34  */
35 
37 : RegionSetBase(mesh)
38 {
39  Region reg;
40  string region_label = rec.val<string>("name");
41  unsigned int region_id = rec.val<unsigned int>("id");
42 
43  try {
44  reg = mesh->region_db().find_id(region_id);
45  } catch(RegionDB::ExcUniqueRegionId &e) {
46  e << rec.ei_address();
47  }
48  if ( reg.is_valid() ) {
49  try {
50  region_db_.rename_region(reg, region_label);
51  } catch (RegionDB::ExcNonuniqueLabel &e) {
52  e << rec.ei_address();
53  throw;
54  }
55  } else {
56  unsigned int dim = rec.val<unsigned int>("dim", RegionDB::undefined_dim);
57  try {
58  region_db_.add_region(region_id, region_label, dim, rec.address_string() );
59  } catch (RegionDB::ExcNonuniqueLabel &e) {
60  e << rec.ei_address();
61  throw;
62  } catch (RegionDB::ExcAddingIntoClosed &e) {
63  e << rec.ei_address();
64  throw;
65  } catch (RegionDB::ExcCantAdd &e) {
66  e << rec.ei_address();
67  throw;
68  }
69  }
70 }
71 
72 
73 
75 {
76  return IT::Record("From_Id", "Region declared by id and name.\n"
77  "Allows to create new region with given id and label\n"
78  "or specify existing region by id which will be renamed.")
81  "Label (name) of the region. Has to be unique in one mesh.\n")
83  "The ID of the region to which you assign label.")
85  "The dim of the region to which you assign label. "
86  "Value is taken into account only if new region is created.")
87  .close();
88 }
89 
90 
91 
93  Input::register_class< RegionSetFromId, const Input::Record &, Mesh * >("From_Id") +
95 
96 
97 
98 /*******************************************************************
99  * implementation of RegionSetFromLabel
100  */
101 
103 : RegionSetBase(mesh)
104 {
105  string new_name = rec.val<string>("name");
106  string mesh_label = rec.val<string>("mesh_label");
107 
108  Region reg = mesh->region_db().find_label(mesh_label);
109  if ( reg.is_valid() ) {
110  try {
111  region_db_.rename_region(reg, new_name);
112  } catch (RegionDB::ExcNonuniqueLabel &e) {
113  e << rec.ei_address();
114  throw;
115  }
116  } else {
117  WarningOut().fmt("Unknown region in mesh with label '%s'\n", mesh_label);
118  }
119 }
120 
121 
122 
124 {
125  return IT::Record("From_Label", "Allows to rename existing region specified by mesh_label.")
128  "New label (name) of the region. Has to be unique in one mesh.")
129  .declare_key("mesh_label", IT::String(), IT::Default::obligatory(),
130  "The mesh_label is e.g. physical volume name in GMSH format.")
131  .close();
132 }
133 
134 
135 
137  Input::register_class< RegionSetFromLabel, const Input::Record &, Mesh * >("From_Label") +
139 
140 
141 
142 /*******************************************************************
143  * implementation of RegionSetFromElements
144  */
145 
147 : RegionSetBase(mesh)
148 {
149  unsigned int region_id;
150  string region_label = rec.val<string>("name");
151  Input::Iterator<unsigned int> it = rec.find<unsigned int>("id");
152 
153  if (it) {
154  region_id = (*it);
155  } else {
156  region_id = this->get_max_region_id();
157  }
158 
159  try {
160  region_db_.add_region(region_id, region_label, RegionDB::undefined_dim, rec.address_string() );
161  } catch (RegionDB::ExcNonuniqueLabel &e) {
162  e << rec.ei_address();
163  throw;
164  } catch (RegionDB::ExcAddingIntoClosed &e) {
165  e << rec.ei_address();
166  throw;
167  } catch (RegionDB::ExcCantAdd &e) {
168  e << rec.ei_address();
169  throw;
170  }
171 
172  Input::Array element_list = rec.val<Input::Array>("element_list");
173  std::vector<unsigned int> element_ids;
174  for (Input::Iterator<unsigned int> it_element = element_list.begin<unsigned int>();
175  it_element != element_list.end();
176  ++it_element) {
178  if (it_map != el_to_reg_map_.end()) {
179  WarningOut().fmt("Region assigned to element with id {} will be rewritten.\n", (*it_element));
180  }
181  el_to_reg_map_.insert( std::make_pair((*it_element), region_id) );
182 
183  }
184 }
185 
186 
187 
189 {
190  return IT::Record("From_Elements", "Region declared by name, ID and enum of elements.\n"
191  "Allows to create new region and assign elements to its.\n"
192  "Elements are specified by ids.")
195  "Label (name) of the region. Has to be unique in one mesh.\n")
197  "The ID of the region to which you assign label.\n"
198  "If new region is created and ID is not set, unique ID will be generated automatically.")
199  .declare_key("element_list", IT::Array( IT::Integer(0), 1 ), IT::Default::obligatory(),
200  "Specification of the region by the list of elements.")
201  .close();
202 }
203 
204 
205 
207  Input::register_class< RegionSetFromElements, const Input::Record &, Mesh * >("From_Elements") +
209 
210 
211 
212 /*******************************************************************
213  * implementation of RegionSetBoundary
214  * Need new implementation, will be solved later.
215  */
216 
217 // RegionSetBoundary::RegionSetBoundary(const Input::Record &rec, Mesh *mesh) : RegionSetBase(mesh) {}
218 
219 // const IT::Record & RegionSetBoundary::get_region_input_type() {}
220 
221 //const int RegionSetBoundary::registrar =
222 // Input::register_class< RegionSetBoundary, const Input::Record &, Mesh * >("Region_Boundary") +
223 // RegionSetBoundary::get_region_input_type().size();
224 
225 
226 
227 /*******************************************************************
228  * implementation of RegionSetUnion
229  */
230 
232 : RegionSetBase(mesh)
233 {
234  string name_of_set = rec.val<string>("name");
235  Input::Iterator<Input::Array> region_ids = rec.find<Input::Array>("region_ids");
236  Input::Iterator<Input::Array> regions = rec.find<Input::Array>("regions");
237  std::vector<string> set_names;
238 
239  if (regions) {
240  set_names = region_db_.get_and_check_operands(*regions);
241  }
242  if (region_ids) {
243  for (Input::Iterator<unsigned int> it_ids = region_ids->begin<unsigned int>();
244  it_ids != region_ids->end();
245  ++it_ids) {
246  Region reg;
247  try {
248  reg = region_db_.find_id(*it_ids);
249  } catch(RegionDB::ExcUniqueRegionId &e) {
250  e << region_ids->ei_address();
251  throw;
252  }
253  if (!reg.is_valid()) {
254  std::string label = region_db_.create_label_from_id(*it_ids);
255  reg = region_db_.add_region(*it_ids, label, RegionDB::undefined_dim, rec.address_string() );
256  }
257  set_names.push_back( reg.label() );
258  }
259 
260  }
261 
262  RegionSet region_set = region_db_.union_set(set_names);
263  if (region_set.size() == 0) {
264  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Union") << rec.ei_address() );
265  }
266  region_db_.add_set(name_of_set, region_set);
267 }
268 
269 
270 
272 {
273  return IT::Record("Union", "Defines region as a union of given two or more regions.\n"
274  "Regions can be given by names or IDs or both ways together.")
277  "Label (name) of the region. Has to be unique in one mesh.\n")
278  .declare_key("region_ids", IT::Array( IT::Integer(0)),
279  "List of region ID numbers that has to be added to the region set.")
280  .declare_key("regions", IT::Array( IT::String() ),
281  "Defines region as a union of given pair of regions.")
282  .close();
283 }
284 
285 
286 
287 const int RegionSetUnion::registrar =
288  Input::register_class< RegionSetUnion, const Input::Record &, Mesh * >("Union") +
290 
291 
292 
293 /*******************************************************************
294  * implementation of RegionSetDifference
295  */
296 
298 : RegionSetBase(mesh)
299 {
300  string name_of_set = rec.val<string>("name");
301  Input::Iterator<Input::Array> labels = rec.find<Input::Array>("regions");
302 
303  std::vector<string> set_names = mesh->region_db().get_and_check_operands(*labels);
304  OLD_ASSERT( set_names.size() == 2, "Wrong number of operands. Expect 2.\n" );
305 
306  RegionSet set_1 = region_db_.get_region_set( set_names[0] );
307  RegionSet set_2 = region_db_.get_region_set( set_names[1] );
308  RegionSet set_diff;
309 
310  std::stable_sort(set_1.begin(), set_1.end(), Region::comp);
311  std::stable_sort(set_2.begin(), set_2.end(), Region::comp);
312  set_diff.resize(set_1.size() + set_2.size());
313 
314  RegionSet::iterator it = std::set_difference(set_1.begin(), set_1.end(), set_2.begin(), set_2.end(), set_diff.begin(), Region::comp);
315  set_diff.resize(it - set_diff.begin());
316 
317  if (set_diff.size() == 0) {
318  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Difference") << rec.ei_address() );
319  }
320  region_db_.add_set(name_of_set, set_diff);
321 }
322 
323 
324 
326 {
327  return IT::Record("Difference", "Defines region as a difference of given pair of regions.")
330  "Label (name) of the region. Has to be unique in one mesh.\n")
331  .declare_key("regions", IT::Array( IT::String(), 2, 2 ), IT::Default::obligatory(),
332  "Defines region as a difference of given pair of regions.")
333  .close();
334 }
335 
336 
337 
339  Input::register_class< RegionSetDifference, const Input::Record &, Mesh * >("Difference") +
341 
342 
343 
344 /*******************************************************************
345  * implementation of RegionSetIntersection
346  */
347 
349 : RegionSetBase(mesh)
350 {
351  string name_of_set = rec.val<string>("name");
352  Input::Iterator<Input::Array> regions = rec.find<Input::Array>("regions");
353  std::vector<string> set_names = mesh->region_db().get_and_check_operands(*regions);
354 
355  RegionSet region_set = region_db_.get_region_set(set_names[0]);
356  for (unsigned int i=1; i<set_names.size(); i++) {
357  region_set = this->intersection( region_set, set_names[i] );
358  }
359 
360  if (region_set.size() == 0) {
361  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Intersection") << rec.ei_address() );
362  }
363  region_db_.add_set(name_of_set, region_set);
364 }
365 
366 
367 
369 {
370  return IT::Record("Intersection", "Defines region as an intersection of given two or more regions.")
373  "Label (name) of the region. Has to be unique in one mesh.\n")
375  "Defines region as an intersection of given pair of regions.")
376  .close();
377 }
378 
379 
381  Input::register_class< RegionSetIntersection, const Input::Record &, Mesh * >("Intersection") +
383 
384 
385 RegionSet RegionSetIntersection::intersection( RegionSet target_set, const string & source_set_name) const {
386  RegionSet set_insec;
387  RegionSet source_set = region_db_.get_region_set( source_set_name );
388  RegionSet::iterator it;
389 
390  std::stable_sort(target_set.begin(), target_set.end(), Region::comp);
391  std::stable_sort(source_set.begin(), source_set.end(), Region::comp);
392 
393  set_insec.resize(target_set.size() + source_set.size());
394  it = std::set_intersection(target_set.begin(), target_set.end(), source_set.begin(), source_set.end(), set_insec.begin(), Region::comp);
395  set_insec.resize(it - set_insec.begin());
396 
397  return set_insec;
398 }
Iterator< ValueType > begin() const
RegionDB & region_db_
Reference to region_db_ of Mesh.
Definition: region_set.hh:40
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:94
Accessor to input data conforming to declared Array.
Definition: accessors.hh:552
Region rename_region(Region reg, const std::string &new_label)
Definition: region.cc:109
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:582
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:368
RegionSetIntersection(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:348
RegionSet union_set(std::vector< string > set_names) const
Definition: region.cc:472
RegionSetFromLabel(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:102
RegionSet intersection(RegionSet target_set, const string &source_set_name) const
Definition: region_set.cc:385
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:99
RegionSetFromId(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:36
RegionSet get_region_set(const string &set_name) const
Definition: region.cc:328
Definition: mesh.h:95
Iterator< Ret > find(const string &key) const
static bool comp(const Region &a, const Region &b)
Comparative method of two regions.
Definition: region.hh:172
void add_set(const string &set_name, const RegionSet &set)
Definition: region.cc:293
string create_label_from_id(unsigned int id) const
Definition: region.cc:337
const RegionDB & region_db() const
Definition: mesh.h:152
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:190
Class for declaration of the integral input data.
Definition: type_base.hh:465
Abstract & close()
Can be used to close the Abstract for further declarations of keys.
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:119
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:188
RegionSetBase(Mesh *mesh)
Constructor.
Definition: region_set.cc:21
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:286
Class for declaration of inputs sequences.
Definition: type_base.hh:321
RegionDB::MapElementIDToRegionID & el_to_reg_map_
Reference to map stored relevance of elements to regions.
Definition: region_set.hh:42
IteratorBase end() const
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:166
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
EI_Address ei_address() const
Definition: accessors.cc:170
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:113
#define OLD_ASSERT(...)
Definition: global_defs.h:131
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:123
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:271
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:325
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:74
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:71
Region find_id(unsigned int id, unsigned int dim) const
Definition: region.cc:180
std::vector< string > get_and_check_operands(const Input::Array &operands) const
Definition: region.cc:312
Accessor to the data with type Type::Record.
Definition: accessors.hh:277
const Ret val(const string &key) const
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:468
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:214
Class for declaration of polymorphic Record.
Region add_region(unsigned int id, const std::string &label, unsigned int dim, const std::string &address="implicit")
Definition: region.cc:85
RegionSetUnion(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:231
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:234
static Input::Type::Abstract & get_input_type()
Definition: region_set.cc:25
RegionSetDifference(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:297
Record type proxy class.
Definition: type_record.hh:171
static const unsigned int undefined_dim
Definition: region.hh:331
Region find_label(const std::string &label) const
Definition: region.cc:169
RegionSetFromElements(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:146
bool is_valid() const
Returns false if the region has undefined/invalid value.
Definition: region.hh:77
std::string label() const
Returns label of the region (using RegionDB)
Definition: region.cc:33
unsigned int get_max_region_id()
Definition: region_set.hh:44
Class for declaration of the input data that are in string format.
Definition: type_base.hh:568
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45
string address_string() const
Definition: accessors.cc:176