Flow123d  release_2.2.1-10-gb9fad4d
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  std::vector<unsigned int> element_ids;
176  for (Input::Iterator<unsigned int> it_element = element_list.begin<unsigned int>();
177  it_element != element_list.end();
178  ++it_element) {
180  if (it_map != el_to_reg_map_.end()) {
181  WarningOut().fmt("Region assigned to element with id {} will be rewritten.\n", (*it_element));
182  }
183  el_to_reg_map_.insert( std::make_pair((*it_element), region_id) );
184 
185  }
186 }
187 
188 
189 
191 {
192  return IT::Record("From_Elements", "Elementary region declared by a list of elements.\n"
193  "The new region is assigned to the list of elements specified by the key "
194  "```element_list```.")
197  "Name (label) of the region. It has to be unique per single mesh.")
199  "Id of the region. "
200  "If unset, a unique id will be generated automatically.")
201  .declare_key("element_list", IT::Array( IT::Integer(0), 1 ), IT::Default::obligatory(),
202  "List of ids of elements.")
203  .close();
204 }
205 
206 
207 
209  Input::register_class< RegionSetFromElements, const Input::Record &, Mesh * >("From_Elements") +
211 
212 
213 
214 /*******************************************************************
215  * implementation of RegionSetBoundary
216  * Need new implementation, will be solved later.
217  */
218 
219 // RegionSetBoundary::RegionSetBoundary(const Input::Record &rec, Mesh *mesh) : RegionSetBase(mesh) {}
220 
221 // const IT::Record & RegionSetBoundary::get_region_input_type() {}
222 
223 //const int RegionSetBoundary::registrar =
224 // Input::register_class< RegionSetBoundary, const Input::Record &, Mesh * >("Region_Boundary") +
225 // RegionSetBoundary::get_region_input_type().size();
226 
227 
228 
229 /*******************************************************************
230  * implementation of RegionSetUnion
231  */
232 
234 : RegionSetBase(mesh)
235 {
236  string name_of_set = rec.val<string>("name");
237  Input::Iterator<Input::Array> region_ids = rec.find<Input::Array>("region_ids");
238  Input::Iterator<Input::Array> regions = rec.find<Input::Array>("regions");
239  std::vector<string> set_names;
240 
241  if (regions) {
242  set_names = region_db_.get_and_check_operands(*regions);
243  }
244  if (region_ids) {
245  for (Input::Iterator<unsigned int> it_ids = region_ids->begin<unsigned int>();
246  it_ids != region_ids->end();
247  ++it_ids) {
248  Region reg;
249  try {
250  reg = region_db_.find_id(*it_ids);
251  } catch(RegionDB::ExcUniqueRegionId &e) {
252  e << region_ids->ei_address();
253  throw;
254  }
255  if (!reg.is_valid()) {
256  std::string label = region_db_.create_label_from_id(*it_ids);
257  reg = region_db_.add_region(*it_ids, label, RegionDB::undefined_dim, rec.address_string() );
258  }
259  set_names.push_back( reg.label() );
260  }
261 
262  }
263 
264  RegionSet region_set = region_db_.union_set(set_names);
265  if (region_set.size() == 0) {
266  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Union") << rec.ei_address() );
267  }
268  region_db_.add_set(name_of_set, region_set);
269 }
270 
271 
272 
274 {
275  return IT::Record("Union", "Defines a new region (set) as a union of two or more regions. "
276  "The regions can be given by their names or ids or both.")
279  "Name (label) of the new region. It has to be unique per single mesh.")
280  .declare_key("region_ids", IT::Array( IT::Integer(0)),
281  "List of region ids to be added to the new region set.")
282  .declare_key("regions", IT::Array( IT::String() ),
283  "List of region names (labels) to be added to the new region set.")
284  .close();
285 }
286 
287 
288 
289 const int RegionSetUnion::registrar =
290  Input::register_class< RegionSetUnion, const Input::Record &, Mesh * >("Union") +
292 
293 
294 
295 /*******************************************************************
296  * implementation of RegionSetDifference
297  */
298 
300 : RegionSetBase(mesh)
301 {
302  string name_of_set = rec.val<string>("name");
303  Input::Iterator<Input::Array> labels = rec.find<Input::Array>("regions");
304 
305  std::vector<string> set_names = mesh->region_db().get_and_check_operands(*labels);
306  OLD_ASSERT( set_names.size() == 2, "Wrong number of operands. Expect 2.\n" );
307 
308  RegionSet set_1 = region_db_.get_region_set( set_names[0] );
309  RegionSet set_2 = region_db_.get_region_set( set_names[1] );
310  RegionSet set_diff;
311 
312  std::stable_sort(set_1.begin(), set_1.end(), Region::comp);
313  std::stable_sort(set_2.begin(), set_2.end(), Region::comp);
314  set_diff.resize(set_1.size() + set_2.size());
315 
316  RegionSet::iterator it = std::set_difference(set_1.begin(), set_1.end(), set_2.begin(), set_2.end(), set_diff.begin(), Region::comp);
317  set_diff.resize(it - set_diff.begin());
318 
319  if (set_diff.size() == 0) {
320  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Difference") << rec.ei_address() );
321  }
322  region_db_.add_set(name_of_set, set_diff);
323 }
324 
325 
326 
328 {
329  return IT::Record("Difference", "Defines a new region (set) as a difference of two regions (sets), given by their names.")
332  "Name (label) of the new region. It has to be unique per single mesh.")
333  .declare_key("regions", IT::Array( IT::String(), 2, 2 ), IT::Default::obligatory(),
334  "List of exactly two region (set) names.\n"
335  "Supposing region sets r1, r2, the result includes all regions of r1 that are not in r2.")
336  .close();
337 }
338 
339 
340 
342  Input::register_class< RegionSetDifference, const Input::Record &, Mesh * >("Difference") +
344 
345 
346 
347 /*******************************************************************
348  * implementation of RegionSetIntersection
349  */
350 
352 : RegionSetBase(mesh)
353 {
354  string name_of_set = rec.val<string>("name");
355  Input::Iterator<Input::Array> regions = rec.find<Input::Array>("regions");
356  std::vector<string> set_names = mesh->region_db().get_and_check_operands(*regions);
357 
358  RegionSet region_set = region_db_.get_region_set(set_names[0]);
359  for (unsigned int i=1; i<set_names.size(); i++) {
360  region_set = this->intersection( region_set, set_names[i] );
361  }
362 
363  if (region_set.size() == 0) {
364  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Intersection") << rec.ei_address() );
365  }
366  region_db_.add_set(name_of_set, region_set);
367 }
368 
369 
370 
372 {
373  return IT::Record("Intersection", "Defines a new region (set) as an intersection of two or more regions (sets)"
374  ", given by their names.")
377  "Name (label) of the new region. It has to be unique per single mesh.")
379  "List of two or more region (set) names.")
380  .close();
381 }
382 
383 
385  Input::register_class< RegionSetIntersection, const Input::Record &, Mesh * >("Intersection") +
387 
388 
389 RegionSet RegionSetIntersection::intersection( RegionSet target_set, const string & source_set_name) const {
390  RegionSet set_insec;
391  RegionSet source_set = region_db_.get_region_set( source_set_name );
392  RegionSet::iterator it;
393 
394  std::stable_sort(target_set.begin(), target_set.end(), Region::comp);
395  std::stable_sort(source_set.begin(), source_set.end(), Region::comp);
396 
397  set_insec.resize(target_set.size() + source_set.size());
398  it = std::set_intersection(target_set.begin(), target_set.end(), source_set.begin(), source_set.end(), set_insec.begin(), Region::comp);
399  set_insec.resize(it - set_insec.begin());
400 
401  return set_insec;
402 }
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:371
RegionSetIntersection(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:351
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:389
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:190
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:273
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:327
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:233
#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:299
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:148
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