Flow123d  release_3.0.0-1106-ga3b2e4c
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 its id.\n"
77  "It allows to create a new region with given id and name, "
78  "or to rename an existing region of given id.")
81  "Name (label) of the region. It has to be unique per single mesh.")
83  "Id of the region to which you assign the name.")
85  "Dimension of the region to which you assign the name.\n"
86  "The value is taken into account only if a 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", "Elementary region declared by its name (label).\n"
126  "It gives a new name to an elementary region "
127  "with the original name (in the mesh file) given by the ```mesh_label.```")
130  "New name (label) of the region. It has to be unique per single mesh.")
131  .declare_key("mesh_label", IT::String(), IT::Default::obligatory(),
132  "The original region name in the input file, e.g. a physical volume name in the GMSH format.")
133  .close();
134 }
135 
136 
137 
139  Input::register_class< RegionSetFromLabel, const Input::Record &, Mesh * >("From_Label") +
141 
142 
143 
144 /*******************************************************************
145  * implementation of RegionSetFromElements
146  */
147 
149 : RegionSetBase(mesh)
150 {
151  unsigned int region_id;
152  string region_label = rec.val<string>("name");
153  Input::Iterator<unsigned int> it = rec.find<unsigned int>("id");
154 
155  if (it) {
156  region_id = (*it);
157  } else {
158  region_id = this->get_max_region_id();
159  }
160 
161  try {
162  region_db_.add_region(region_id, region_label, RegionDB::undefined_dim, rec.address_string() );
163  } catch (RegionDB::ExcNonuniqueLabel &e) {
164  e << rec.ei_address();
165  throw;
166  } catch (RegionDB::ExcAddingIntoClosed &e) {
167  e << rec.ei_address();
168  throw;
169  } catch (RegionDB::ExcCantAdd &e) {
170  e << rec.ei_address();
171  throw;
172  }
173 
174  Input::Array element_list = rec.val<Input::Array>("element_list");
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.\n"
192  "The new region is assigned to the list of elements specified by the key "
193  "```element_list```.")
196  "Name (label) of the region. It has to be unique per single mesh.")
198  "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 a new region (set) as a union of two or more regions. "
275  "The regions can be given by their names or ids or both.")
278  "Name (label) of the new region. It has to be unique per single mesh.")
279  .declare_key("region_ids", IT::Array( IT::Integer(0)),
280  "List of region ids to be added to the new region set.")
281  .declare_key("regions", IT::Array( IT::String() ),
282  "List of region names (labels) to be added to the new region set.")
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 a new region (set) as a difference of two regions (sets), given by their names.")
331  "Name (label) of the new region. It has to be unique per single mesh.")
332  .declare_key("regions", IT::Array( IT::String(), 2, 2 ), IT::Default::obligatory(),
333  "List of exactly two region (set) names.\n"
334  "Supposing region sets r1, r2, the result includes all regions of r1 that are not in r2.")
335  .close();
336 }
337 
338 
339 
341  Input::register_class< RegionSetDifference, const Input::Record &, Mesh * >("Difference") +
343 
344 
345 
346 /*******************************************************************
347  * implementation of RegionSetIntersection
348  */
349 
351 : RegionSetBase(mesh)
352 {
353  string name_of_set = rec.val<string>("name");
354  Input::Iterator<Input::Array> regions = rec.find<Input::Array>("regions");
355  std::vector<string> set_names = mesh->region_db().get_and_check_operands(*regions);
356 
357  RegionSet region_set = region_db_.get_region_set(set_names[0]);
358  for (unsigned int i=1; i<set_names.size(); i++) {
359  region_set = this->intersection( region_set, set_names[i] );
360  }
361 
362  if (region_set.size() == 0) {
363  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Intersection") << rec.ei_address() );
364  }
365  region_db_.add_set(name_of_set, region_set);
366 }
367 
368 
369 
371 {
372  return IT::Record("Intersection", "Defines a new region (set) as an intersection of two or more regions (sets)"
373  ", given by their names.")
376  "Name (label) of the new region. It has to be unique per single mesh.")
378  "List of two or more region (set) names.")
379  .close();
380 }
381 
382 
384  Input::register_class< RegionSetIntersection, const Input::Record &, Mesh * >("Intersection") +
386 
387 
388 RegionSet RegionSetIntersection::intersection( RegionSet target_set, const string & source_set_name) const {
389  RegionSet set_insec;
390  RegionSet source_set = region_db_.get_region_set( source_set_name );
391  RegionSet::iterator it;
392 
393  std::stable_sort(target_set.begin(), target_set.end(), Region::comp);
394  std::stable_sort(source_set.begin(), source_set.end(), Region::comp);
395 
396  set_insec.resize(target_set.size() + source_set.size());
397  it = std::set_intersection(target_set.begin(), target_set.end(), source_set.begin(), source_set.end(), set_insec.begin(), Region::comp);
398  set_insec.resize(it - set_insec.begin());
399 
400  return set_insec;
401 }
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:370
RegionSetIntersection(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:350
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:76
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:143
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: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: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: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: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:232
#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:298
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:148
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:388
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