Flow123d  release_3.0.0-506-g34af125
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", "Elementary region declared by ID."
77  "Allows to create new region with given id and label"
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", "Gives a new name to an elementary region"
126  "with original name (in the mesh file) given by ```mesh_label.```")
129  "New label (name) of the region. Has to be unique in one mesh.")
130  .declare_key("mesh_label", IT::String(), IT::Default::obligatory(),
131  "The mesh_label is e.g. physical volume name in GMSH format.")
132  .close();
133 }
134 
135 
136 
138  Input::register_class< RegionSetFromLabel, const Input::Record &, Mesh * >("From_Label") +
140 
141 
142 
143 /*******************************************************************
144  * implementation of RegionSetFromElements
145  */
146 
148 : RegionSetBase(mesh)
149 {
150  unsigned int region_id;
151  string region_label = rec.val<string>("name");
152  Input::Iterator<unsigned int> it = rec.find<unsigned int>("id");
153 
154  if (it) {
155  region_id = (*it);
156  } else {
157  region_id = this->get_max_region_id();
158  }
159 
160  try {
161  region_db_.add_region(region_id, region_label, RegionDB::undefined_dim, rec.address_string() );
162  } catch (RegionDB::ExcNonuniqueLabel &e) {
163  e << rec.ei_address();
164  throw;
165  } catch (RegionDB::ExcAddingIntoClosed &e) {
166  e << rec.ei_address();
167  throw;
168  } catch (RegionDB::ExcCantAdd &e) {
169  e << rec.ei_address();
170  throw;
171  }
172 
173  Input::Array element_list = rec.val<Input::Array>("element_list");
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", "Elementary region declared by a list of elements. "
191  "The new region is assigned to the list of elements spefied by the key"
192  "```element_list```.")
195  "Label (name) of the region. Has to be unique in one mesh.\n")
197  "The ID of the region. "
198  "If unset a unique ID will be generated automatically.")
199  .declare_key("element_list", IT::Array( IT::Integer(0), 1 ), IT::Default::obligatory(),
200  "List of IDs 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 (set) as a union of given two or more regions. "
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 (set) as a difference of given pair of regions.")
330  "Label (name) of the region. Has to be unique in one mesh.")
331  .declare_key("regions", IT::Array( IT::String(), 2, 2 ), IT::Default::obligatory(),
332  "List of exactly two regions given by their names.")
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 (set) as an intersection of given two or more regions.")
373  "Label (name) of the region. Has to be unique in one mesh.\n")
375  "List of two or more regions given by their names.")
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:49
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:103
RegionSet get_region_set(const std::string &set_name) const
Definition: region.cc:329
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
Region rename_region(Region reg, const std::string &new_label)
Definition: region.cc:110
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:598
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
RegionSetFromLabel(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:102
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
RegionSetFromId(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:36
Definition: mesh.h:80
Iterator< Ret > find(const string &key) const
static bool comp(const Region &a, const Region &b)
Comparative method of two regions.
Definition: region.hh:173
std::string create_label_from_id(unsigned int id) const
Definition: region.cc:338
RegionSet union_set(std::vector< std::string > set_names) const
Definition: region.cc:473
const RegionDB & region_db() const
Definition: mesh.h:147
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:199
Class for declaration of the integral input data.
Definition: type_base.hh:490
Abstract & close()
Close the Abstract and add its to type repository (see TypeRepository::add_type). ...
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:128
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:303
Class for declaration of inputs sequences.
Definition: type_base.hh:346
RegionDB::MapElementIDToRegionID & el_to_reg_map_
Reference to map stored relevance of elements to regions.
Definition: region_set.hh:51
IteratorBase end() const
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:175
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:178
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
#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:80
Region find_id(unsigned int id, unsigned int dim) const
Definition: region.cc:181
std::vector< std::string > get_and_check_operands(const Input::Array &operands) const
Definition: region.cc:313
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
const Ret val(const string &key) const
void add_set(const std::string &set_name, const RegionSet &set)
Definition: region.cc:294
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:501
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:223
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:86
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:246
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:182
static const unsigned int undefined_dim
Definition: region.hh:332
Region find_label(const std::string &label) const
Definition: region.cc:170
RegionSetFromElements(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:147
bool is_valid() const
Returns false if the region has undefined/invalid value.
Definition: region.hh:78
std::string label() const
Returns label of the region (using RegionDB)
Definition: region.cc:34
RegionSet intersection(RegionSet target_set, const std::string &source_set_name) const
Definition: region_set.cc:385
unsigned int get_max_region_id()
Definition: region_set.hh:53
Class for declaration of the input data that are in string format.
Definition: type_base.hh:589
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
string address_string() const
Definition: accessors.cc:184