Flow123d  JS_before_hm-2208-g558930b9a
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  bool allow_empty = rec.val<bool>("allow_empty");
108 
109  Region reg = mesh->region_db().find_label(mesh_label);
110  if ( reg.is_valid() ) {
111  try {
112  region_db_.rename_region(reg, new_name);
113  } catch (RegionDB::ExcNonuniqueLabel &e) {
114  e << rec.ei_address();
115  throw;
116  }
117  } else {
118  if(allow_empty){
119  try
120  {
121  uint new_region_id = this->get_max_region_id();
122  region_db_.add_region(new_region_id, new_name, 0, rec.address_string());
123  }
124  catch (RegionDB::ExcNonuniqueLabel &e) {
125  e << rec.ei_address();
126  throw;
127  } catch (RegionDB::ExcAddingIntoClosed &e) {
128  e << rec.ei_address();
129  throw;
130  } catch (RegionDB::ExcCantAdd &e) {
131  e << rec.ei_address();
132  throw;
133  }
134  }
135  else
136  WarningOut().fmt("Unknown region in mesh with label '{}'\n", mesh_label);
137  }
138 }
139 
140 
141 
143 {
144  return IT::Record("From_Label", "Elementary region declared by its name (label).\n"
145  "It gives a new name to an elementary region "
146  "with the original name (in the mesh file) given by the ```mesh_label.```")
149  "New name (label) of the region. It has to be unique per single mesh.")
150  .declare_key("mesh_label", IT::String(), IT::Default::obligatory(),
151  "The original region name in the input file, e.g. a physical volume name in the GMSH format.")
152  .declare_key("allow_empty", IT::Bool(), IT::Default("false"),
153  "If true it allows to the region set to be empty (no elements).")
154  .close();
155 }
156 
157 
158 
160  Input::register_class< RegionSetFromLabel, const Input::Record &, Mesh * >("From_Label") +
162 
163 
164 
165 /*******************************************************************
166  * implementation of RegionSetFromElements
167  */
168 
170 : RegionSetBase(mesh)
171 {
172  unsigned int region_id;
173  string region_label = rec.val<string>("name");
174  Input::Iterator<unsigned int> it = rec.find<unsigned int>("id");
175 
176  if (it) {
177  region_id = (*it);
178  } else {
179  region_id = this->get_max_region_id();
180  }
181 
182  try {
183  region_db_.add_region(region_id, region_label, RegionDB::undefined_dim, rec.address_string() );
184  } catch (RegionDB::ExcNonuniqueLabel &e) {
185  e << rec.ei_address();
186  throw;
187  } catch (RegionDB::ExcAddingIntoClosed &e) {
188  e << rec.ei_address();
189  throw;
190  } catch (RegionDB::ExcCantAdd &e) {
191  e << rec.ei_address();
192  throw;
193  }
194 
195  Input::Array element_list = rec.val<Input::Array>("element_list");
196  for (Input::Iterator<unsigned int> it_element = element_list.begin<unsigned int>();
197  it_element != element_list.end();
198  ++it_element) {
200  if (it_map != el_to_reg_map_.end()) {
201  WarningOut().fmt("Region assigned to element with id {} will be rewritten.\n", (*it_element));
202  }
203  el_to_reg_map_.insert( std::make_pair((*it_element), region_id) );
204 
205  }
206 }
207 
208 
209 
211 {
212  return IT::Record("From_Elements", "Elementary region declared by a list of elements.\n"
213  "The new region is assigned to the list of elements specified by the key "
214  "```element_list```.")
217  "Name (label) of the region. It has to be unique per single mesh.")
219  "Id of the region. "
220  "If unset, a unique id will be generated automatically.")
221  .declare_key("element_list", IT::Array( IT::Integer(0), 1 ), IT::Default::obligatory(),
222  "List of ids of elements.")
223  .close();
224 }
225 
226 
227 
229  Input::register_class< RegionSetFromElements, const Input::Record &, Mesh * >("From_Elements") +
231 
232 
233 
234 /*******************************************************************
235  * implementation of RegionSetBoundary
236  * Need new implementation, will be solved later.
237  */
238 
239 // RegionSetBoundary::RegionSetBoundary(const Input::Record &rec, Mesh *mesh) : RegionSetBase(mesh) {}
240 
241 // const IT::Record & RegionSetBoundary::get_region_input_type() {}
242 
243 //const int RegionSetBoundary::registrar =
244 // Input::register_class< RegionSetBoundary, const Input::Record &, Mesh * >("Region_Boundary") +
245 // RegionSetBoundary::get_region_input_type().size();
246 
247 
248 
249 /*******************************************************************
250  * implementation of RegionSetUnion
251  */
252 
254 : RegionSetBase(mesh)
255 {
256  string name_of_set = rec.val<string>("name");
257  Input::Iterator<Input::Array> region_ids = rec.find<Input::Array>("region_ids");
258  Input::Iterator<Input::Array> regions = rec.find<Input::Array>("regions");
259  std::vector<string> set_names;
260 
261  if (regions) {
262  set_names = region_db_.get_and_check_operands(*regions);
263  }
264  if (region_ids) {
265  for (Input::Iterator<unsigned int> it_ids = region_ids->begin<unsigned int>();
266  it_ids != region_ids->end();
267  ++it_ids) {
268  Region reg;
269  try {
270  reg = region_db_.find_id(*it_ids);
271  } catch(RegionDB::ExcUniqueRegionId &e) {
272  e << region_ids->ei_address();
273  throw;
274  }
275  if (!reg.is_valid()) {
276  std::string label = region_db_.create_label_from_id(*it_ids);
277  reg = region_db_.add_region(*it_ids, label, RegionDB::undefined_dim, rec.address_string() );
278  }
279  set_names.push_back( reg.label() );
280  }
281 
282  }
283 
284  RegionSet region_set = region_db_.union_set(set_names);
285  if (region_set.size() == 0) {
286  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Union") << rec.ei_address() );
287  }
288  region_db_.add_set(name_of_set, region_set);
289 }
290 
291 
292 
294 {
295  return IT::Record("Union", "Defines a new region (set) as a union of two or more regions. "
296  "The regions can be given by their names or ids or both.")
299  "Name (label) of the new region. It has to be unique per single mesh.")
300  .declare_key("region_ids", IT::Array( IT::Integer(0)),
301  "List of region ids to be added to the new region set.")
302  .declare_key("regions", IT::Array( IT::String() ),
303  "List of region names (labels) to be added to the new region set.")
304  .close();
305 }
306 
307 
308 
309 const int RegionSetUnion::registrar =
310  Input::register_class< RegionSetUnion, const Input::Record &, Mesh * >("Union") +
312 
313 
314 
315 /*******************************************************************
316  * implementation of RegionSetDifference
317  */
318 
320 : RegionSetBase(mesh)
321 {
322  string name_of_set = rec.val<string>("name");
323  Input::Iterator<Input::Array> labels = rec.find<Input::Array>("regions");
324 
325  std::vector<string> set_names = mesh->region_db().get_and_check_operands(*labels);
326  ASSERT_PERMANENT_EQ(set_names.size(), 2).error("Wrong number of operands. Expect 2.\n" );
327 
328  RegionSet set_1 = region_db_.get_region_set( set_names[0] );
329  RegionSet set_2 = region_db_.get_region_set( set_names[1] );
330  RegionSet set_diff;
331 
332  std::stable_sort(set_1.begin(), set_1.end(), Region::comp);
333  std::stable_sort(set_2.begin(), set_2.end(), Region::comp);
334  set_diff.resize(set_1.size() + set_2.size());
335 
336  RegionSet::iterator it = std::set_difference(set_1.begin(), set_1.end(), set_2.begin(), set_2.end(), set_diff.begin(), Region::comp);
337  set_diff.resize(it - set_diff.begin());
338 
339  if (set_diff.size() == 0) {
340  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Difference") << rec.ei_address() );
341  }
342  region_db_.add_set(name_of_set, set_diff);
343 }
344 
345 
346 
348 {
349  return IT::Record("Difference", "Defines a new region (set) as a difference of two regions (sets), given by their names.")
352  "Name (label) of the new region. It has to be unique per single mesh.")
353  .declare_key("regions", IT::Array( IT::String(), 2, 2 ), IT::Default::obligatory(),
354  "List of exactly two region (set) names.\n"
355  "Supposing region sets r1, r2, the result includes all regions of r1 that are not in r2.")
356  .close();
357 }
358 
359 
360 
362  Input::register_class< RegionSetDifference, const Input::Record &, Mesh * >("Difference") +
364 
365 
366 
367 /*******************************************************************
368  * implementation of RegionSetIntersection
369  */
370 
372 : RegionSetBase(mesh)
373 {
374  string name_of_set = rec.val<string>("name");
375  Input::Iterator<Input::Array> regions = rec.find<Input::Array>("regions");
376  std::vector<string> set_names = mesh->region_db().get_and_check_operands(*regions);
377 
378  RegionSet region_set = region_db_.get_region_set(set_names[0]);
379  for (unsigned int i=1; i<set_names.size(); i++) {
380  region_set = this->intersection( region_set, set_names[i] );
381  }
382 
383  if (region_set.size() == 0) {
384  THROW( ExcEmptyRegionSetResult() << EI_Operation_Type("Intersection") << rec.ei_address() );
385  }
386  region_db_.add_set(name_of_set, region_set);
387 }
388 
389 
390 
392 {
393  return IT::Record("Intersection", "Defines a new region (set) as an intersection of two or more regions (sets)"
394  ", given by their names.")
397  "Name (label) of the new region. It has to be unique per single mesh.")
399  "List of two or more region (set) names.")
400  .close();
401 }
402 
403 
405  Input::register_class< RegionSetIntersection, const Input::Record &, Mesh * >("Intersection") +
407 
408 
409 RegionSet RegionSetIntersection::intersection( RegionSet target_set, const string & source_set_name) const {
410  RegionSet set_insec;
411  RegionSet source_set = region_db_.get_region_set( source_set_name );
412  RegionSet::iterator it;
413 
414  std::stable_sort(target_set.begin(), target_set.end(), Region::comp);
415  std::stable_sort(source_set.begin(), source_set.end(), Region::comp);
416 
417  set_insec.resize(target_set.size() + source_set.size());
418  it = std::set_intersection(target_set.begin(), target_set.end(), source_set.begin(), source_set.end(), set_insec.begin(), Region::comp);
419  set_insec.resize(it - set_insec.begin());
420 
421  return set_insec;
422 }
Input::Type::Bool
Class for declaration of the input of type Bool.
Definition: type_base.hh:452
RegionSetBase::get_max_region_id
unsigned int get_max_region_id()
Definition: region_set.hh:53
RegionSetIntersection::RegionSetIntersection
RegionSetIntersection(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:371
RegionSetBase::RegionSetBase
RegionSetBase(Mesh *mesh)
Constructor.
Definition: region_set.cc:21
Region::comp
static bool comp(const Region &a, const Region &b)
Comparative method of two regions.
Definition: region.hh:173
Region::label
std::string label() const
Returns label of the region (using RegionDB)
Definition: region.cc:32
RegionSetBase::el_to_reg_map_
RegionDB::MapElementIDToRegionID & el_to_reg_map_
Reference to map stored relevance of elements to regions.
Definition: region_set.hh:51
MeshBase::region_db
const RegionDB & region_db() const
Definition: mesh.h:175
RegionSetBase::get_input_type
static Input::Type::Abstract & get_input_type()
Definition: region_set.cc:25
RegionSetFromId::registrar
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:80
Input::Type::Integer
Class for declaration of the integral input data.
Definition: type_base.hh:483
Input::Record::val
const Ret val(const string &key) const
Definition: accessors_impl.hh:31
RegionIdx::is_valid
bool is_valid() const
Returns false if the region has undefined/invalid value.
Definition: region.hh:78
RegionSetIntersection::intersection
RegionSet intersection(RegionSet target_set, const std::string &source_set_name) const
Definition: region_set.cc:409
THROW
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
std::vector
Definition: doxy_dummy_defs.hh:7
RegionSetUnion::RegionSetUnion
RegionSetUnion(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:253
RegionSetFromElements::registrar
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:128
RegionSetFromLabel::RegionSetFromLabel
RegionSetFromLabel(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:102
uint
unsigned int uint
Definition: mh_dofhandler.hh:101
Input::Array::begin
Iterator< ValueType > begin() const
Definition: accessors_impl.hh:145
RegionDB::create_label_from_id
std::string create_label_from_id(unsigned int id) const
Definition: region.cc:337
Input::Record::address_string
string address_string() const
Definition: accessors.cc:184
Region
Definition: region.hh:146
Input::Iterator
Definition: accessors.hh:143
RegionSetFromElements::RegionSetFromElements
RegionSetFromElements(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:169
RegionSetBase
Definition: region_set.hh:35
Input::Type::Record::size
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:602
Input::Type::Default
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
RegionDB::undefined_dim
static const unsigned int undefined_dim
Definition: region.hh:332
Input::Type::Record::derive_from
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:196
RegionSetFromElements::get_region_input_type
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:210
Input::Record
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
RegionSetFromLabel::get_region_input_type
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:142
RegionDB::rename_region
Region rename_region(Region reg, const std::string &new_label)
Definition: region.cc:109
Input::Type::Default::obligatory
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
Input::Type::Abstract
Class for declaration of polymorphic Record.
Definition: type_abstract.hh:62
RegionSetBase::region_db_
RegionDB & region_db_
Reference to region_db_ of Mesh.
Definition: region_set.hh:49
Input::Record::ei_address
EI_Address ei_address() const
Definition: accessors.cc:178
RegionDB::get_region_set
RegionSet get_region_set(const std::string &set_name) const
Definition: region.cc:328
RegionSetIntersection::registrar
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:223
RegionDB::find_id
Region find_id(unsigned int id, unsigned int dim) const
Definition: region.cc:180
Input::Type::Record::declare_key
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:503
RegionSetFromLabel::registrar
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:103
RegionDB::add_set
void add_set(const std::string &set_name, const RegionSet &set)
Definition: region.cc:293
mesh.h
std::map
Definition: doxy_dummy_defs.hh:11
RegionDB::get_and_check_operands
std::vector< std::string > get_and_check_operands(const Input::Array &operands) const
Definition: region.cc:312
Input::Record::find
Iterator< Ret > find(const string &key) const
Definition: accessors_impl.hh:91
Input::Type::Record::close
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:304
Input::Type
Definition: balance.hh:41
ASSERT_PERMANENT_EQ
#define ASSERT_PERMANENT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:328
Input::Type::Record
Record type proxy class.
Definition: type_record.hh:182
Mesh
Definition: mesh.h:359
Input::Type::Array
Class for declaration of inputs sequences.
Definition: type_base.hh:339
RegionSetDifference::RegionSetDifference
RegionSetDifference(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:319
Input::Type::String
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
Input::Array
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
WarningOut
#define WarningOut()
Macro defining 'warning' record of log.
Definition: logger.hh:278
region_set.hh
RegionSetFromId::get_region_input_type
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:74
RegionSetDifference::get_region_input_type
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:347
RegionDB::add_region
Region add_region(unsigned int id, const std::string &label, unsigned int dim, const std::string &address="implicit")
Definition: region.cc:85
RegionSetDifference::registrar
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:199
RegionSetIntersection::get_region_input_type
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:391
RegionDB::find_label
Region find_label(const std::string &label) const
Definition: region.cc:169
Input::Type::Default::optional
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
RegionSetFromId::RegionSetFromId
RegionSetFromId(const Input::Record &rec, Mesh *mesh)
Constructor.
Definition: region_set.cc:36
Input::Array::end
IteratorBase end() const
Definition: accessors_impl.hh:157
Input::Type::Abstract::close
Abstract & close()
Close the Abstract and add its to type repository (see TypeRepository::add_type).
Definition: type_abstract.cc:190
RegionSetUnion::registrar
static const int registrar
Registrar of class to factory.
Definition: region_set.hh:175
RegionDB::union_set
RegionSet union_set(std::vector< std::string > set_names) const
Definition: region.cc:482
RegionSetUnion::get_region_input_type
static const Input::Type::Record & get_region_input_type()
Definition: region_set.cc:293