Mantid
Loading...
Searching...
No Matches
Algebra.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#include <algorithm>
8#include <cmath>
9#include <fstream>
10#include <iomanip>
11#include <iterator>
12#include <map>
13#include <set>
14#include <sstream>
15#include <stack>
16#include <vector>
17
21#include "MantidKernel/Logger.h"
23
24namespace Mantid::Geometry {
25namespace {
26Kernel::Logger logger("Algebra");
27}
28
29std::ostream &operator<<(std::ostream &OX, const Algebra &A)
36{
37 OX << A.display();
38 return OX;
39}
40
42 : F(0)
46{}
47
48bool Algebra::operator==(const Algebra &A) const
54{
55 if (this == &A)
56 return true;
57 return (F == A.F);
58}
59
60bool Algebra::operator!=(const Algebra &A) const
66{
67 return (F != A.F);
68}
69
76{
77 F += M.F;
78 return *this;
79}
80
87{
88 F *= M.F;
89 return *this;
90}
91
98{
99 Algebra T(*this);
100 T += M;
101 return T;
102}
103
110{
111 Algebra T(*this);
112 T *= M;
113 return T;
114}
115
121{
122 F.complement();
123}
124
125std::pair<Algebra, Algebra> Algebra::algDiv(const Algebra &D) const
131{
132 Algebra Q;
133 Algebra R;
134 Acomp Tf = F;
135 // std::cerr<<"AlgDiv:"<<'\n';
136 std::pair<Acomp, Acomp> QR = Tf.algDiv(D.F);
137 if (!QR.first.isNull() && !QR.second.isNull()) {
138 Q.setFunction(QR.first);
139 R.setFunction(QR.second);
140 }
141 return std::pair<Algebra, Algebra>(Q, R);
142}
143
144std::string Algebra::writeMCNPX() const
154{
155 std::string Out = F.display();
156 const auto lenOut = static_cast<int>(Out.length());
157 Out += " "; // Guard string
158 std::ostringstream cx;
159 for (int i = 0; i < lenOut; i++) {
160 if (islower(Out[i]) || isupper(Out[i])) {
161 auto vc =
162 find_if(SurfMap.cbegin(), SurfMap.cend(), MapSupport::valEqual<int, std::string>(std::string(1, Out[i])));
163 if (vc == SurfMap.end()) {
164 logger.error() << "SurfMap size == " << SurfMap.size() << '\n';
165 for_each(SurfMap.begin(), SurfMap.end(), MapSupport::mapWrite<int, std::string>());
166 throw Kernel::Exception::NotFoundError("Algebra::writeMCNPX", std::string(1, Out[i]));
167 }
168 if (Out[i + 1] == '\'')
169 cx << " -" << vc->first;
170 else
171 cx << " " << vc->first;
172 } else if (Out[i] == '+') {
173 cx << " :";
174 } else // brackets are constant
175 {
176 cx << " " << Out[i];
177 }
178 }
179 return cx.str();
180}
181
182std::ostream &Algebra::write(std::ostream &Out) const
188{
189 Out << "F == " << F.display() << '\n';
190 // Out<<F.displayDepth(0)<<'\n';
191 return Out;
192}
193
194std::string Algebra::display() const { return F.display(); }
195
196int Algebra::setFunctionObjStr(const std::string &A)
206{
207 // get first item
208 std::ostringstream cx;
209 std::string nLiteral = "a";
210
211 int ipt(0); // start of component
212 int bigFlag(0); // Literals getting big
213 while (ipt < static_cast<int>(A.length())) {
214
215 if (A[ipt] == '(' || A[ipt] == ')') {
216 cx << A[ipt];
217 ipt++;
218 } else if (A[ipt] == '-' || isdigit(A[ipt])) {
219 int N;
220 int nCount = Mantid::Kernel::Strings::convPartNum(A.substr(ipt, std::string::npos), N);
221 if (nCount) {
222 int neg(0);
223 if (N < 0) {
224 N *= -1;
225 neg = 1;
226 }
227 auto mc = SurfMap.find(N);
228 if (mc == SurfMap.end()) {
229 if (!bigFlag) {
230 SurfMap[N] = nLiteral;
231 cx << nLiteral;
232 nLiteral[0] = (nLiteral[0] == 'z') ? 'A' : static_cast<char>(static_cast<int>(nLiteral[0]) + 1);
233 bigFlag = (nLiteral[0] == 'Z') ? 1 : 0;
234 } else {
235 std::ostringstream lcx;
236 lcx << "%" << bigFlag;
237 SurfMap[N] = lcx.str();
238 cx << lcx.str();
239 bigFlag++;
240 }
241 } else {
242 cx << mc->second;
243 }
244 // Add negation note:
245 if (neg)
246 cx << "\'";
247 // Add to the number
248 ipt += nCount;
249 } else {
250 throw std::invalid_argument("Algebra::setFunction: ncount==0");
251 }
252 } else if (A[ipt] == ':') {
253 cx << "+";
254 ipt++;
255 } else if (A[ipt] == '#') {
256 cx << "#";
257 ipt++;
258 } else // Space
259 ipt++;
260 }
261 setFunction(cx.str());
262 return 0;
263}
264
265int Algebra::setFunction(const std::string &A)
272{
273 // Get copy
274 std::string Ln = A;
275 // Strip spaces.
276 std::string::size_type pos;
277 while ((pos = Ln.find(' ')) != std::string::npos)
278 Ln.erase(pos, 1);
279 try {
280 F.setString(Ln);
281 } catch (...) {
282 logger.error() << "Algebra String Error" << A << '\n';
283 return 1;
284 }
285 return 0;
286}
287
295{
296 F = A;
297 return 0;
298}
299
307{
308 std::map<int, int> Lit;
309 F.getLiterals(Lit);
310 return static_cast<int>(Lit.size());
311}
312
320{
321 return F.logicalEqual(A.F);
322}
323
324} // namespace Mantid::Geometry
Holds a state point in the decision tree.
Definition: Acomp.h:43
void getLiterals(std::map< int, int > &) const
Get literals (+/- different)
Definition: Acomp.cpp:731
std::string display() const
Pretty print statment.
Definition: Acomp.cpp:1513
std::pair< Acomp, Acomp > algDiv(const Acomp &)
Carry out Algebric division.
Definition: Acomp.cpp:1207
void complement()
Take complement of component.
Definition: Acomp.cpp:1476
void setString(const std::string &)
Processes a line of type abc'+efg.
Definition: Acomp.cpp:1378
Computes Boolean algebra for simplification.
Definition: Algebra.h:30
std::pair< Algebra, Algebra > algDiv(const Algebra &) const
Divide by D algebrically.
Definition: Algebra.cpp:125
int setFunctionObjStr(const std::string &)
Fill the algebra (AComp) with an object given an MCNPX String.
Definition: Algebra.cpp:196
std::string writeMCNPX() const
Writes out the string in terms of surface numbers for MCNPX.
Definition: Algebra.cpp:144
Algebra()
Constructor.
Definition: Algebra.cpp:41
int setFunction(const std::string &)
Set the function using a basic string (abc etc)
Definition: Algebra.cpp:265
int countLiterals() const
Count the number of different literals in the algebraic function Does this by generating the map of l...
Definition: Algebra.cpp:300
Algebra & operator+=(const Algebra &)
Adds this by M algebrically.
Definition: Algebra.cpp:70
bool operator==(const Algebra &) const
Equality operator.
Definition: Algebra.cpp:48
int logicalEqual(const Algebra &) const
Calculate if two functions are logically equivilent (exhaustive search)
Definition: Algebra.cpp:313
void Complement()
Takes the complement of the algebric function.
Definition: Algebra.cpp:116
Algebra operator+(const Algebra &) const
Addition operator (or construction)
Definition: Algebra.cpp:92
std::ostream & write(std::ostream &) const
Output function.
Definition: Algebra.cpp:182
bool operator!=(const Algebra &) const
Inequality operator.
Definition: Algebra.cpp:60
std::string display() const
Displays the algebra string.
Definition: Algebra.cpp:194
Algebra & operator*=(const Algebra &)
Multiplies this by M algebrically.
Definition: Algebra.cpp:81
Algebra operator*(const Algebra &) const
Addition operator (and construction)
Definition: Algebra.cpp:104
std::map< int, std::string > SurfMap
Internal surface map.
Definition: Algebra.h:32
Exception for when an item is not found in a collection.
Definition: Exception.h:145
Functor quick write out of a map.
Definition: MapSupport.h:149
Functor using second value as equal.
Definition: MapSupport.h:68
MANTID_GEOMETRY_DLL std::ostream & operator<<(std::ostream &stream, const PointGroup &self)
Returns a streamed representation of the PointGroup object.
Definition: PointGroup.cpp:312
int convPartNum(const std::string &A, T &out)
Takes a character string and evaluates the first [typename T] object.
Definition: Strings.cpp:639