Flow123d  release_2.1.2-337-g6b7a56b
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  std::vector<unsigned int> element_ids;
175  for (Input::Iterator<unsigned int> it_element = element_list.begin<unsigned int>();
176  it_element != element_list.end();
177  ++it_element) {
179  if (it_map != el_to_reg_map_.end()) {
180  WarningOut().fmt("Region assigned to element with id {} will be rewritten.\n", (*it_element));
181  }
182  el_to_reg_map_.insert( std::make_pair((*it_element), region_id) );
183 
184  }
185 }
186 
187 
188 
190 {
191  return IT::Record("From_Elements", "Elementary region declared by a list of elements. "
192  "The new region is assigned to the list of elements spefied by the key"
193  "```element_list```.")
196  "Label (name) of the region. Has to be unique in one mesh.\n")
198  "The ID of the region. "
199  "If unset a unique ID will be generated automatically.")
200  .declare_key("element_list", IT::Array( IT::Integer(0), 1 ), IT::Default::obligatory(),
201  "List of IDs of elements.")
202  .close();
203 }
204 
205 
206 
208  Input::register_class< RegionSetFromElements, const Input::Record &, Mesh * >("From_Elements") +
210 
211 
212 
213 /*******************************************************************
214  * implementation of RegionSetBoundary
215  * Need new implementation, will be solved later.
216  */
217 
218 // RegionSetBoundary::RegionSetBoundary(const Input::Record &rec, Mesh *mesh) : RegionSetBase(mesh) {}
219 
220 // const IT::Record & RegionSetBoundary::get_region_input_type() {}
221 
222 //const int RegionSetBoundary::registrar =
223 // Input::register_class< RegionSetBoundary, const Input::Record &, Mesh * >("Region_Boundary") +
224 // RegionSetBoundary::get_region_input_type().size();
225 
226 
227 
228 /*******************************************************************
229  * implementation of RegionSetUnion
230  */
231 
233 : RegionSetBase(mesh)
234 {
235  string name_of_set = rec.val<string>("name");
236  Input::Iterator<Input::Array> region_ids = rec.find<Input::Array>("region_ids");
237  Input::Iterator<Input::Array> regions = rec.find<Input::Array>("regions");
238  std::vector<string> set_names;
239 
240  if (regions) {
241  set_names = region_db_.get_and_check_operands(*regions);
242  }
243  if (region_ids) {
244  for (Input::Iterator<unsigned int> it_ids = region_ids->begin<unsigned int>();
245  it_ids != region_ids->end();
246  ++it_ids) {
247  Region reg;
248  try {
249  reg = region_db_.find_id(*it_ids);
250  } catch(RegionDB::ExcUniqueRegionId &e) {
251  e << region_ids->ei_address();
252  throw;
253  }
254  if (!reg.is_valid()) {
255  std::string label = region_db_.create_label_from_id(*it_ids);
256  reg = region_db_.add_region(*it_ids, label, RegionDB::undefined_dim, rec.address_string() );
257  }
258  set_names.push_back( reg.label() );
259  }
260 
261  }
262 
263  RegionSet region_set = region_db_.union_set(set_names);
264  if (region_set.size() == 0) {
265  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Union") << rec.ei_address() );
266  }
267  region_db_.add_set(name_of_set, region_set);
268 }
269 
270 
271 
273 {
274  return IT::Record("Union", "Defines region (set) as a union of given two or more regions. "
275  "Regions can be given by names or IDs or both ways together.")
278  "Label (name) of the region. Has to be unique in one mesh.\n")
279  .declare_key("region_ids", IT::Array( IT::Integer(0)),
280  "List of region ID numbers that has to be added to the region set.")
281  .declare_key("regions", IT::Array( IT::String() ),
282  "Defines region as a union of given pair of regions.")
283  .close();
284 }
285 
286 
287 
288 const int RegionSetUnion::registrar =
289  Input::register_class< RegionSetUnion, const Input::Record &, Mesh * >("Union") +
291 
292 
293 
294 /*******************************************************************
295  * implementation of RegionSetDifference
296  */
297 
299 : RegionSetBase(mesh)
300 {
301  string name_of_set = rec.val<string>("name");
302  Input::Iterator<Input::Array> labels = rec.find<Input::Array>("regions");
303 
304  std::vector<string> set_names = mesh->region_db().get_and_check_operands(*labels);
305  OLD_ASSERT( set_names.size() == 2, "Wrong number of operands. Expect 2.\n" );
306 
307  RegionSet set_1 = region_db_.get_region_set( set_names[0] );
308  RegionSet set_2 = region_db_.get_region_set( set_names[1] );
309  RegionSet set_diff;
310 
311  std::stable_sort(set_1.begin(), set_1.end(), Region::comp);
312  std::stable_sort(set_2.begin(), set_2.end(), Region::comp);
313  set_diff.resize(set_1.size() + set_2.size());
314 
315  RegionSet::iterator it = std::set_difference(set_1.begin(), set_1.end(), set_2.begin(), set_2.end(), set_diff.begin(), Region::comp);
316  set_diff.resize(it - set_diff.begin());
317 
318  if (set_diff.size() == 0) {
319  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Difference") << rec.ei_address() );
320  }
321  region_db_.add_set(name_of_set, set_diff);
322 }
323 
324 
325 
327 {
328  return IT::Record("Difference", "Defines region (set) as a difference of given pair of regions.")
331  "Label (name) of the region. Has to be unique in one mesh.")
332  .declare_key("regions", IT::Array( IT::String(), 2, 2 ), IT::Default::obligatory(),
333  "List of exactly two regions given by their names.")
334  .close();
335 }
336 
337 
338 
340  Input::register_class< RegionSetDifference, const Input::Record &, Mesh * >("Difference") +
342 
343 
344 
345 /*******************************************************************
346  * implementation of RegionSetIntersection
347  */
348 
350 : RegionSetBase(mesh)
351 {
352  string name_of_set = rec.val<string>("name");
353  Input::Iterator<Input::Array> regions = rec.find<Input::Array>("regions");
354  std::vector<string> set_names = mesh->region_db().get_and_check_operands(*regions);
355 
356  RegionSet region_set = region_db_.get_region_set(set_names[0]);
357  for (unsigned int i=1; i<set_names.size(); i++) {
358  region_set = this->intersection( region_set, set_names[i] );
359  }
360 
361  if (region_set.size() == 0) {
362  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Intersection") << rec.ei_address() );
363  }
364  region_db_.add_set(name_of_set, region_set);
365 }
366 
367 
368 
370 {
371  return IT::Record("Intersection", "Defines region (set) as an intersection of given two or more regions.")
374  "Label (name) of the region. Has to be unique in one mesh.\n")
376  "List of two or more regions given by their names.")
377  .close();
378 }
379 
380 
382  Input::register_class< RegionSetIntersection, const Input::Record &, Mesh * >("Intersection") +
384 
385 
386 RegionSet RegionSetIntersection::intersection( RegionSet target_set, const string & source_set_name) const {
387  RegionSet set_insec;
388  RegionSet source_set = region_db_.get_region_set( source_set_name );
389  RegionSet::iterator it;
390 
391  std::stable_sort(target_set.begin(), target_set.end(), Region::comp);
392  std::stable_sort(source_set.begin(), source_set.end(), Region::comp);
393 
394  set_insec.resize(target_set.size() + source_set.size());
395  it = std::set_intersection(target_set.begin(), target_set.end(), source_set.begin(), source_set.end(), set_insec.begin(), Region::comp);
396  set_insec.resize(it - set_insec.begin());
397 
398  return set_insec;
399 }
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:567
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:598
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:369
RegionSetIntersection(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:349
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:386
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
RegionSet get_region_set(const string &set_name) const
Definition: region.cc:328
Definition: mesh.h:97
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:155
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:489
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:119
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:189
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:345
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: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:272
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:326
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:292
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:490
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:232
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:236
static Input::Type::Abstract & get_input_type()
Definition: region_set.cc:25
RegionSetDifference(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:298
Record type proxy class.
Definition: type_record.hh:182
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:147
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:588
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
string address_string() const
Definition: accessors.cc:184