FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
parsed_hit_test_factory.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5#pragma once
6
7// includes, FEAT
8#include <kernel/geometry/hit_test_factory.hpp>
9#include <kernel/analytic/function.hpp>
11#include <kernel/util/tiny_algebra.hpp>
12#include <kernel/analytic/parsed_function.hpp>
13
14// includes, system
15#include<vector>
16
17// The contents of this file require the 'fparser' third-party library.
18#if defined(FEAT_HAVE_FPARSER) || defined(DOXYGEN)
19#include <fparser.hh>
20
21namespace FEAT
22{
23 namespace Geometry
24 {
37 template<typename Mesh_>
39 public Factory< MeshPart<Mesh_> >
40 {
41 public:
43 typedef typename Mesh_::ShapeType ShapeType;
45 typedef typename Mesh_::VertexType PointType;
50
52 static constexpr int world_dim = Mesh_::world_dim;
53
54 protected:
56 {
57 public:
58 // mutable is mandatory! It cancels the const in ParsedHitTestFactory.
59 mutable::FunctionParser _parser;
60
62 _parser()
63 {
64 _parser.AddConstant("pi", Math::pi<double>());
65 }
66
76 void parse(const String& formula)
77 {
78 // add variables to our parser
79 String vars("x");
80 if (world_dim > 1) vars += ",y";
81 if (world_dim > 2) vars += ",z";
82
83 // try to parse the function
84 const int ret = _parser.Parse(formula.c_str(), vars.c_str());
85 if (ret >= 0)
86 {
87 String msg(_parser.ErrorMsg());
88 msg.append("\n>>> '");
89 msg.append(formula);
90 msg.append("'");
91 if (ret < int(formula.size()))
92 {
93 // ret contains the index of the first invalid character in the input string
94 // append an additional line to mark the faulty character
95 msg.append("\n>>>");
96 msg.append(String(std::size_t(ret + 2), '-'));
97 msg.append("^");
98 }
99
100 throw ParseError(msg);
101 } //end : can't parse function
102
103 // optimize the parsed function
104 _parser.Optimize();
105 }
106
107 bool operator()(const PointType& point) const
108 {
109 //convert DataType to double
110 const Tiny::Vector<double, world_dim> vars(point);
111
112 // evaluate the parser
113 const double val= _parser.Eval(vars.v);
114
115 // check for errors
116 switch (_parser.EvalError())
117 {
118 case 0: // no error
119 break;
120
121 case 1: // division by zero
122 throw ParseError("Error in ParsedScalarFunction evaluation: division by zero");
123
124 case 2: // sqrt error
125 throw ParseError("Error in ParsedScalarFunction evaluation: sqrt of negative value");
126
127 case 3: // log error
128 throw ParseError("Error in ParsedScalarFunction evaluation:logarithm of a negative value");
129
130 case 4: // trigonometric error
131 throw ParseError("Error in ParsedScalarFunction evaluation: illegal input value");
132
133 case 5: // recursion error
134 throw ParseError("Error in ParsedScalarFunction evaluation: maximum recursion depth reached");
135
136 default: // ???
137 throw ParseError("Error in ParsedScalarFunction evaluation: unknown error");
138 }
139
140 // return true, if point is in the "inner" part of the mesh, otherwise return false
141 return (val > 0.0);
142 }
143 };
144
145 //Member Variables of ParsedHitTestFactory
149 const Mesh_& _mesh;
151 std::vector<std::vector<Index>> _target_data;
152
153 public:
154 explicit ParsedHitTestFactory(const Mesh_& mesh) :
155 _mesh(mesh),
156 _target_data(std::size_t(_mesh.shape_dim + 1))
157 {
158 }
159
173 explicit ParsedHitTestFactory(const Mesh_& mesh, const String& formula) :
174 _hit_func(),
175 _mesh(mesh),
176 _target_data(std::size_t(_mesh.shape_dim + 1))
177 {
178 parse(formula);
179 }
180
198 explicit ParsedHitTestFactory(const Mesh_& mesh, const MeshType& filter, const String& formula) :
199 _hit_func(),
200 _mesh(mesh),
201 _target_data(std::size_t(_mesh.shape_dim + 1))
202 {
203 parse_filtered(formula, filter);
204 }
205
206 void parse(const String& formula)
207 {
208 _hit_func.parse(formula);
209 Intern::hittest_compute_target_data<ParsedHitFunction, Mesh_>(_target_data, _mesh, _hit_func);
210 }
211
212 void parse_filtered(const String& formula, const MeshType& filter)
213 {
214 _hit_func.parse(formula);
215 Intern::hittest_compute_filtered_target_data<ParsedHitFunction, Mesh_>(_target_data, _mesh, filter, _hit_func);
216 }
217
219 virtual Index get_num_entities(int dim) override
220 {
221 return Index(_target_data.at(std::size_t(dim)).size());
222 }
223
224 virtual void fill_target_sets(TargetSetHolderType& target_set_holder) override
225 {
226 Intern::write_to_target_set<ShapeType>(target_set_holder, _target_data);
227 }
228
229 virtual void fill_attribute_sets(typename MeshType::AttributeSetContainer&) override
230 {
231 // do nothing as the object has no attribute sets
232 }
233
234 virtual void fill_index_sets(std::unique_ptr<typename MeshType::IndexSetHolderType>&) override
235 {
236 // do nothing as the object has no index sets
237 }
238 }; // class ParsedHitTestFactory
239
252 template<typename Mesh_>
254 {
255 ParsedHitTestFactory<Mesh_> factory(mesh, formula);
256 return factory.make();
257 }
258
275 template<typename Mesh_>
277 {
278 ParsedHitTestFactory<Mesh_> factory(mesh, filter, formula);
279 return factory.make();
280 }
281
294 template<typename Mesh_>
295 std::unique_ptr<MeshPart<Mesh_>> make_unique_meshpart_by_formula_hit_test(const Mesh_& mesh, const String& formula)
296 {
297 ParsedHitTestFactory<Mesh_> factory(mesh, formula);
298 return factory.make_unique();
299 }
300
317 template<typename Mesh_>
318 std::unique_ptr<MeshPart<Mesh_>> make_unique_meshpart_by_filtered_formula_hit_test(const Mesh_& mesh, const MeshPart<Mesh_>& filter, const String& formula)
319 {
320 ParsedHitTestFactory<Mesh_> factory(mesh, filter, formula);
321 return factory.make_unique();
322 }
323 } // namespace Geometry
324} //namespace FEAT
325#endif // defined(FEAT_HAVE_FPARSER) || defined(DOXYGEN)
Mesh Factory class template.
Definition: factory.hpp:33
Class template for partial meshes.
Definition: mesh_part.hpp:90
TargetSetHolder< ShapeType > TargetSetHolderType
Target set holder type.
Definition: mesh_part.hpp:101
std::map< String, std::unique_ptr< AttributeSetType > > AttributeSetContainer
submesh node bin container type
Definition: mesh_part.hpp:138
void parse(const String &formula)
Creates a ParsedHitFunction.
Parsed-Hit-Test Factory class template.
ParsedHitFunction _hit_func
class for parsed_hit_fuction
ParsedHitTestFactory(const Mesh_ &mesh, const MeshType &filter, const String &formula)
Creates the ParsedHitTestFactory.
Mesh_::VertexType PointType
mesh part type
MeshType::TargetSetHolderType TargetSetHolderType
target set holder type
virtual Index get_num_entities(int dim) override
ParsedHitTestFactory(const Mesh_ &mesh, const String &formula)
Creates the ParsedHitTestFactory.
const Mesh_ & _mesh
reference to the input mesh
MeshPart< Mesh_ > MeshType
mesh part type
Mesh_::ShapeType ShapeType
The shape type of the mesh.
std::vector< std::vector< Index > > _target_data
internal data storing the indices
static constexpr int world_dim
mesh world dimension
Class for parser related errors.
Definition: exception.hpp:132
String class implementation.
Definition: string.hpp:47
Tiny Vector class template.
MeshPart< Mesh_ > make_meshpart_by_filtered_formula_hit_test(const Mesh_ &mesh, const MeshPart< Mesh_ > &filter, const String &formula)
Creates a new mesh-part from a formula hit-test function.
std::unique_ptr< MeshPart< Mesh_ > > make_unique_meshpart_by_formula_hit_test(const Mesh_ &mesh, const String &formula)
Creates a new mesh-part from a formula hit-test function.
std::unique_ptr< MeshPart< Mesh_ > > make_unique_meshpart_by_filtered_formula_hit_test(const Mesh_ &mesh, const MeshPart< Mesh_ > &filter, const String &formula)
Creates a new mesh-part from a formula hit-test function.
MeshPart< Mesh_ > make_meshpart_by_formula_hit_test(const Mesh_ &mesh, const String &formula)
Creates a new mesh-part from a formula hit-test function.
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.