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 and optionally a file path to the top-level block p...
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.