https://mooseframework.inl.gov
CSGRegion.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "CSGRegion.h"
11 
12 namespace CSG
13 {
14 
16 {
17  _region_str = "";
18  _region_type = "EMPTY";
19 }
20 
21 // halfspace constructor
23 {
24  _region_type = "HALFSPACE";
25  _region_str = ((halfspace == CSGSurface::Halfspace::POSITIVE) ? "+" : "-") + surf.getName();
26  _surfaces.push_back(surf);
27 }
28 
29 // intersection and union constructor
31  const CSGRegion & region_b,
32  const std::string & region_type)
33 {
34  _region_type = region_type;
36  mooseError("Region type " + getRegionTypeString() + " is not supported for two regions.");
37  if (region_a.getRegionType() == RegionType::EMPTY ||
38  region_b.getRegionType() == RegionType::EMPTY)
39  mooseError("Region operation " + getRegionTypeString() +
40  " cannot be performed on an empty region.");
41 
42  std::string op = (getRegionType() == RegionType::UNION) ? " | " : " & ";
43  auto a_string = stripRegionString(region_a.toString(), op);
44  auto b_string = stripRegionString(region_b.toString(), op);
45 
46  _region_str = "(" + a_string + op + b_string + ")";
47  const auto & a_surfs = region_a.getSurfaces();
48  const auto & b_surfs = region_b.getSurfaces();
49  _surfaces.insert(_surfaces.end(), a_surfs.begin(), a_surfs.end());
50  _surfaces.insert(_surfaces.end(), b_surfs.begin(), b_surfs.end());
51 }
52 
53 // complement or explicitly empty constructor
54 CSGRegion::CSGRegion(const CSGRegion & region, const std::string & region_type)
55 {
56  _region_type = region_type;
58  mooseError("Region type " + getRegionTypeString() + " is not supported for a single region.");
59 
61  {
62  // no change to surfaces, but update string
63  if (region.toString()[0] == '(')
64  _region_str = "~" + region.toString();
65  else
66  _region_str = "~(" + region.toString() + ")";
67  _surfaces = region.getSurfaces();
68  }
69  else if (getRegionType() == RegionType::EMPTY)
70  {
71  // reset the region and make it empty
72  _region_str = "";
73  _surfaces.clear();
74  }
75 }
76 
77 CSGRegion &
78 CSGRegion::operator&=(const CSGRegion & other_region)
79 {
80  if (this != &other_region)
81  *this = CSGRegion(*this, other_region, "INTERSECTION");
82  return *this;
83 }
84 
85 CSGRegion &
86 CSGRegion::operator|=(const CSGRegion & other_region)
87 {
88  if (this != &other_region)
89  *this = CSGRegion(*this, other_region, "UNION");
90  return *this;
91 }
92 
93 const std::string
94 stripRegionString(std::string region_str, std::string op)
95 {
96  // add expected spacing around operator if not provided
97  if (op == "|")
98  op = " | ";
99  if (op == "&")
100  op = " & ";
101 
102  std::vector<std::string> ops_list = {" | ", " & ", "~"};
103  if (op.compare(" | ") && op.compare(" & "))
104  { // compare() returns non zero if strings are not equal
105  mooseError(
106  "Region string can only be simplified based on intersection (&) and union (|) operations.");
107  }
108 
109  // find if there are any operators in string already that are not the op of interest
110  // if not, then remove parentheses:
111  bool remove_par = true; // assume parentheses can be removed unless otherwise
112  for (auto opi : ops_list)
113  if (opi != op)
114  // only look for strings that are not of the current op type
115  if (region_str.find(opi) != std::string::npos)
116  {
117  remove_par = false;
118  break;
119  }
120 
121  if (remove_par)
122  region_str.erase(std::remove_if(region_str.begin(),
123  region_str.end(),
124  [](char c) { return c == '(' || c == ')'; }),
125  region_str.end());
126  return region_str;
127 }
128 
129 // Operators for region construction
130 
131 // positive halfspace
132 const CSGRegion
133 operator+(const CSGSurface & surf)
134 {
136 }
137 
138 // negative halfspace
139 const CSGRegion
140 operator-(const CSGSurface & surf)
141 {
143 }
144 
145 // intersection
146 const CSGRegion
147 operator&(const CSGRegion & region_a, const CSGRegion & region_b)
148 {
149  return CSGRegion(region_a, region_b, "INTERSECTION");
150 }
151 
152 // union
153 const CSGRegion
154 operator|(const CSGRegion & region_a, const CSGRegion & region_b)
155 {
156  return CSGRegion(region_a, region_b, "UNION");
157 }
158 
159 // complement
160 const CSGRegion
161 operator~(const CSGRegion & region)
162 {
163  return CSGRegion(region, "COMPLEMENT");
164 }
165 
166 bool
167 CSGRegion::operator==(const CSGRegion & other) const
168 {
169  const bool region_type_eq = this->getRegionType() == other.getRegionType();
170  const bool region_str_eq = this->toString() == other.toString();
171  if (region_type_eq && region_str_eq)
172  {
173  const auto & all_surfs = getSurfaces();
174  const auto & other_surfs = other.getSurfaces();
175  const bool num_cells_eq = all_surfs.size() == other_surfs.size();
176  if (num_cells_eq)
177  {
178  for (const auto i : index_range(all_surfs))
179  if (all_surfs[i].get() != other_surfs[i].get())
180  return false;
181  return true;
182  }
183  else
184  return false;
185  }
186  else
187  return false;
188 }
189 
190 bool
191 CSGRegion::operator!=(const CSGRegion & other) const
192 {
193  return !(*this == other);
194 }
195 
196 } // namespace CSG
std::string _region_str
String representation of region - defaults to empty string.
Definition: CSGRegion.h:116
const std::string & getName() const
Get the name of surface.
Definition: CSGSurface.h:95
CSGRegions creates an internal representation of a CSG region, which can refer to an intersection...
Definition: CSGRegion.h:21
CSGRegion()
Default Constructor.
Definition: CSGRegion.C:15
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:323
const std::string & toString() const
gets the string representation of the region
Definition: CSGRegion.h:76
Halfspace
Enum for the sign of the half-space being represented by a point and surface.
Definition: CSGSurface.h:30
const CSGRegion operator|(const CSGRegion &region_a, const CSGRegion &region_b)
Overload for creating a region from the union (|) of two regions.
Definition: CSGRegion.C:154
bool operator!=(const CSGRegion &other) const
Operator overload for checking if two CSGRegion objects are not equal.
Definition: CSGRegion.C:191
const CSGRegion operator+(const CSGSurface &surf)
Operation overloads for operation based region construction.
Definition: CSGRegion.C:133
CSGRegion & operator|=(const CSGRegion &other_region)
Operator overload for |= which creates a union of the current region with the other_region.
Definition: CSGRegion.C:86
bool operator==(const CSGRegion &other) const
Operator overload for checking if two CSGRegion objects are equal.
Definition: CSGRegion.C:167
const CSGRegion operator &(const CSGRegion &region_a, const CSGRegion &region_b)
Overload for creating a region from the the intersection (&) of two regions.
Definition: CSGRegion.C:147
RegionType getRegionType() const
Get the region type.
Definition: CSGRegion.h:83
CSGRegion & operator &=(const CSGRegion &other_region)
Operator overload for &= which creates an intersection between the current region and the other_regio...
const std::vector< std::reference_wrapper< const CSGSurface > > & getSurfaces() const
Get the list of surfaces associated with the region.
Definition: CSGRegion.h:97
MooseEnum _region_type
An enum for type of type of operation that defines region.
Definition: CSGRegion.h:119
CSGSurface creates an internal representation of a Constructive Solid Geometry (CSG) surface...
Definition: CSGSurface.h:26
std::vector< std::reference_wrapper< const CSGSurface > > _surfaces
Surface list associated with the region.
Definition: CSGRegion.h:122
const CSGRegion operator~(const CSGRegion &region)
Overload for creating a region from the complement (~) of another region.
Definition: CSGRegion.C:161
auto index_range(const T &sizable)
const std::string stripRegionString(std::string region_str, std::string op)
strip the leading and trailing parentheses from the string if only the specified operator is present ...
Definition: CSGRegion.C:94
const std::string getRegionTypeString() const
Get the region type as a string.
Definition: CSGRegion.h:90
const CSGRegion operator-(const CSGSurface &surf)
Overload for creating a region from the negative half-space (-) of a surface.
Definition: CSGRegion.C:140