15 #include "libmesh/parsed_function.h" 16 #include "libmesh/replicated_mesh.h" 17 #include "libmesh/face_quad4.h" 18 #include "libmesh/fparser_ad.hh" 19 #include "libmesh/elem.h" 29 MooseEnum edge_type(
"LINE=1 CIRCARC=2 DISCRETE=3 PARSED=4");
31 params.
addRequiredParam<std::vector<Point>>(
"corners",
"The x,y,z positions of the nodes");
42 "Number of nodes on horizontal edges, including corners");
44 "Number of Nodes on vertical edges, including corners");
47 params.
addParam<std::string>(
"bottom_parameter",
"",
"Bottom side support parameter");
48 params.
addParam<std::string>(
"top_parameter",
"",
"Top side support parameter");
49 params.
addParam<std::string>(
"left_parameter",
"",
"Left side support parameter");
50 params.
addParam<std::string>(
"right_parameter",
"",
"Right side support parameter");
55 "bias_x>=1.0 & bias_x<=2",
56 "The amount by which to grow (or shrink) the cells in the x-direction.");
60 "bias_y>=1.0 & bias_y<=2",
61 "The amount by which to grow (or shrink) the cells in the y-direction.");
64 "Creates a QUAD4 mesh given a set of corner vertices and edge types. " 65 "The edge type can be either LINE, CIRCARC, DISCRETE or PARSED, with " 66 "LINE as the default option. " 67 "For the non-default options the user needs to specify additional " 68 "parameters via the edge_parameter option " 69 "as follows: for CIRCARC the deviation of the midpoint from an " 70 "arccircle, for DISCRETE a set of points, or " 71 "a paramterization via the PARSED option. Opposite edges may have " 72 "different distributions s long as the " 73 "number of points is identical. Along opposite edges a different point " 74 "distribution can be prescribed " 75 "via the options bias_x or bias_y for opposing edges.");
88 _corners(getParam<
std::vector<Point>>(
"corners")),
89 _nx(getParam<unsigned
int>(
"nx")),
90 _ny(getParam<unsigned
int>(
"ny")),
91 _bottom_type(getParam<
MooseEnum>(
"bottom_type")),
92 _top_type(getParam<
MooseEnum>(
"top_type")),
93 _left_type(getParam<
MooseEnum>(
"left_type")),
94 _right_type(getParam<
MooseEnum>(
"right_type")),
95 _bottom_parameter(getParam<
std::string>(
"bottom_parameter")),
96 _top_parameter(getParam<
std::string>(
"top_parameter")),
97 _left_parameter(getParam<
std::string>(
"left_parameter")),
98 _right_parameter(getParam<
std::string>(
"right_parameter")),
99 _bias_x(getParam<
Real>(
"bias_x")),
100 _bias_y(getParam<
Real>(
"bias_y"))
108 mooseAssert((
_nx > 1) && (
_ny > 1),
109 "A minimum of 2 points is needed on each edge, i.e. the user needs to consider edge " 110 "vertices as well.");
112 std::unique_ptr<MeshBase>
117 mesh->set_mesh_dimension(2);
118 mesh->set_spatial_dimension(2);
119 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
130 std::vector<Point> outward_vec(4);
131 outward_vec[0] = Point(0.0, -1.0, 0.0);
132 outward_vec[1] = Point(0.0, 1.0, 0.0);
133 outward_vec[2] = Point(-1.0, 0.0, 0.0);
134 outward_vec[3] = Point(1.0, 0.0, 0.0);
136 const unsigned long int total_nodes =
_nx *
_ny;
139 Real edge_length = 1.0;
143 std::vector<Point> edge_bottom =
145 std::vector<Point> edge_top =
147 std::vector<Point> edge_left =
149 std::vector<Point> edge_right =
154 Real rx_coord, sy_coord;
156 std::vector<Node *> nodes(total_nodes);
157 unsigned int node_id = 0;
160 Real r1_basis, r2_basis, s1_basis, s2_basis;
164 rx_coord = param_x_dir[
idx];
165 r1_basis = 1 - rx_coord;
168 for (
unsigned int idy = 0; idy <
_ny; idy++)
170 sy_coord = param_y_dir[idy];
171 s1_basis = 1 - sy_coord;
175 newPt = r2_basis * edge_right[idy] + r1_basis * edge_left[idy] + s1_basis * edge_bottom[
idx] +
176 s2_basis * edge_top[
idx] - r1_basis * s1_basis * V00 - r1_basis * s2_basis * V01 -
177 r2_basis * s1_basis * V10 - r2_basis * s2_basis * V11;
179 nodes[node_id] =
mesh->add_point(newPt, node_id);
186 for (
unsigned int idy = 0; idy <
_ny - 1; idy++)
188 Elem * elem =
mesh->add_elem(
new Quad4);
189 elem->set_node(0, nodes[idy +
idx *
_ny]);
190 elem->set_node(1, nodes[idy + (
idx + 1) *
_ny]);
191 elem->set_node(2, nodes[idy + 1 + (
idx + 1) *
_ny]);
192 elem->set_node(3, nodes[idy + 1 +
idx *
_ny]);
195 boundary_info.add_side(elem, 0, 0);
198 boundary_info.add_side(elem, 1, 1);
201 boundary_info.add_side(elem, 2, 2);
204 boundary_info.add_side(elem, 3, 3);
208 boundary_info.sideset_name(0) =
"bottom";
209 boundary_info.nodeset_name(0) =
"bottom";
211 boundary_info.sideset_name(1) =
"right";
212 boundary_info.nodeset_name(1) =
"right";
214 boundary_info.sideset_name(2) =
"top";
215 boundary_info.nodeset_name(2) =
"top";
217 boundary_info.sideset_name(3) =
"left";
218 boundary_info.nodeset_name(3) =
"left";
220 mesh->prepare_for_use();
227 const unsigned int np,
229 const std::string & parameter,
230 const Point & outward,
231 const std::vector<Real> & param_vec)
233 std::vector<Point> edge;
241 "The line does not fit the first vertex on the edge.");
243 "The line does not fit the end vertex on the edge.");
250 "No arccircle parametrization can be found to fit the first vertex on the edge.");
252 "No arccircle parametrization can be found to fit the end vertex on the edge.");
259 "The first discrete point does not fit the corresponding edge vertex." 260 "Note: discrete points need to replicate the edge corners.");
262 "The last discrete point does not fit the corresponding edge vertex." 263 "Note: discrete points need to replicate the edge corners.");
270 "The parametrization does not fit the first vertex on the edge.");
272 "The parametrization does not fit the end vertex on the edge.");
276 if (edge.size() != np)
277 mooseError(
"The generated edge does not match the number of points on the" 285 const std::vector<Real> & param_vec)
287 std::vector<Point> edge(param_vec.size());
290 for (
auto rx : param_vec)
292 edge[it] = P1 * (1.0 - rx) + P2 * rx;
300 const std::vector<Real> & param_vec)
302 std::vector<Point> edge(param_vec.size());
303 Real x_coord, y_coord;
305 std::vector<std::string> param_coords;
309 for (
auto rx : param_vec)
315 edge[it] = Point(x_coord, y_coord, 0.0);
325 std::vector<Point> edge(np);
326 std::vector<std::string> string_points;
328 if (string_points.size() != np)
329 mooseError(
"DISCRETE: the number of discrete points does not match the number of points on the" 333 for (
unsigned int iter = 0; iter < string_points.size(); iter++)
335 std::vector<Real> point_vals;
337 edge[it] = Point(point_vals[0], point_vals[1], point_vals[2]);
347 const std::string & parameter,
348 const Point & outward,
349 const std::vector<Real> & param_vec)
351 std::vector<Point> edge(param_vec.size());
353 std::vector<Real> param_coords;
356 if (param_coords.size() == 1)
362 P3 = Point(param_coords[0], param_coords[1], param_coords[2]);
369 Point x0 = (P1 - P0);
370 Point x1 = (P2 - P0);
375 mooseAssert(x0.norm() > 0.0 && x1.norm() > 0.0,
376 "The point provided cannot generate an arc circle on the edge specified");
378 Real arclength = std::acos((x0 * x1) / x0.norm() / x1.norm());
380 Real a = std::atan2(x0(1), x0(0));
381 Real b = std::atan2(x1(1), x1(0));
389 for (
auto rx : param_vec)
394 edge[it] = Point(x, y, 0.0);
403 const Real xab,
const Real a,
const Real b,
const Real c,
const Real d)
const 407 "The input interval [a, b] is empty, check that a and b are not identical.");
408 Real xcd = c + (d - c) / (b - a) * (xab - a);
415 const unsigned int np,
416 const Real bias)
const 418 std::vector<Real> param_vec;
425 param_vec.push_back(rx);
426 for (
unsigned int iter = 1; iter < np; iter++)
430 param_vec.push_back(rx);
435 const Real interval = edge_length /
Real(np - 1);
436 for (
unsigned int iter = 0; iter < np; iter++)
439 param_vec.push_back(rx);
448 Point temp1 = P1 - P2;
449 Real a2 = temp1.norm_sq();
450 Point temp2 = P3 - P1;
451 Real b2 = temp2.norm_sq();
453 const Real rad = a2 / 8.0 / dr + dr / 2.0;
461 const Real a1 = (2 * P3(0) - 2 * P1(0));
462 const Real a2 = (2 * P3(1) - 2 * P1(1));
463 const Real A = P3(1) * P3(1) - P1(0) * P1(0) + P3(0) * P3(0) - P1(1) * P1(1);
464 const Real b1 = (2 * P3(0) - 2 * P2(0));
465 const Real b2 = (2 * P3(1) - 2 * P2(1));
466 const Real B = P3(1) * P3(1) - P2(0) * P2(0) + P3(0) * P3(0) - P2(1) * P2(1);
468 "The point provided cannot generate an arc circle on the edge specified." 469 "The origin of the corresponding circle cannot be computed.");
471 const Real y0 = (a1 *
B - A * b1) / (a1 * b2 - a2 * b1);
472 const Real x0 = (A - y0 * a2) / a1;
475 Point P0 = Point(x0, y0, 0.0);
483 const Point & outward)
const 485 const Real xm = (P1(0) + P2(0)) / 2;
486 const Real ym = (P1(1) + P2(1)) / 2;
492 const int orient = (height >= 0) ? 1 : -1;
497 MidPoint = Point(xm, ym, 0.0) + dist * orient * outward;
504 const Real m = -(P2(0) - P1(0)) / (P2(1) - P1(1));
506 const Real x_temp = dist *
sqrt((m * m + 1)) / (m * m + 1);
507 const Real factor = orient * outward(0) + m * orient * outward(1);
508 int direction = (factor >= 0) ? 1 : -1;
510 MidPoint = Point(direction * x_temp + xm, direction * x_temp * m + ym, 0.0);
Real getMapInterval(const Real xab, const Real a, const Real b, const Real c, const Real d) const
const std::vector< Point > & _corners
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sin(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tan
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
SymFunctionPtr _parsed_func
function parser object describing the combinatorial geometry
const std::string _right_parameter
bool tokenizeAndConvert(const std::string &str, std::vector< T > &tokenized_vector, const std::string &delimiter=" \\\)
tokenizeAndConvert splits a string using delimiter and then converts to type T.
std::vector< Point > getCircarcEdge(const Point &P1, const Point &P2, const std::string ¶meter, const Point &outward, const std::vector< Real > ¶m_vec)
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
static InputParameters validParams()
Point computeMidPoint(const Point &P1, const Point &P2, const Real dist, const Point &outward) const
std::vector< Point > getParsedEdge(const std::string ¶meter, const std::vector< Real > ¶m_vec)
const MooseEnum _top_type
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cos(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cos
std::vector< Point > getDiscreteEdge(const unsigned int np, const std::string ¶meter)
std::vector< Point > getEdge(const Point &P1, const Point &P2, const unsigned int np, const MooseEnum &type, const std::string ¶meter, const Point &outward, const std::vector< Real > ¶m_vec)
TransfiniteMeshGenerator(const InputParameters ¶meters)
const std::string & type() const
Get the type of this class.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Point computeOrigin(const Point &P1, const Point &P2, const Point &P3) const
static InputParameters validParams()
const MooseEnum _left_type
const MooseEnum _bottom_type
const MooseEnum _right_type
std::vector< Point > getLineEdge(const Point &P1, const Point &P2, const std::vector< Real > ¶m_vec)
registerMooseObject("MooseApp", TransfiniteMeshGenerator)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
const std::string _top_parameter
std::vector< GenericReal< is_ad > > _func_params
Array to stage the parameters passed to the functions when calling Eval.
std::vector< Real > getPointsDistribution(const Real edge_length, const unsigned int np, const Real bias) const
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
Real computeRadius(const Point &P1, const Point &P2, const Point &P3) const
const std::string _left_parameter
static InputParameters validParams()
const std::string _bottom_parameter
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
Build a MeshBase object whose underlying type will be determined by the Mesh input file block...
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
MooseUnits pow(const MooseUnits &, int)
MeshGenerators are objects that can modify or add to an existing mesh.
void ErrorVector unsigned int
void setParserFeatureFlags(SymFunctionPtr &) const
apply input parameters to internal feature flags of the parser object
Generates an quadrilateral given all the parameters.