Solves for a cross field, the smooth field of 4-fold symmetric directions that gives XYFrontalDelaunayGenerator the local frame in which it measures the target size ahead of the front. More...
#include <XYCrossFieldSolver.h>
Public Types | |
| using | NodalCrossField = std::map< dof_id_type, std::complex< Real > > |
| Values of the complex cross field z at the nodes of the background mesh, keyed by node id. | |
Public Member Functions | |
| XYCrossFieldSolver (const libMesh::MeshBase &background_mesh, const std::map< dof_id_type, Real > &boundary_tangent_angles) | |
| Build a cross field solver on a background triangulation. | |
| void | solve () |
| Assemble and solve the two Laplace problems, then normalize the nodal field and collect the singular nodes. | |
| Real | theta (const Point &point) const |
| std::pair< Point, Point > | crossFrame (const Point &point) const |
| const NodalCrossField & | nodalCrossField () const |
| const std::vector< dof_id_type > & | singularNodes () const |
Private Member Functions | |
| void | assembleLaplace () |
| Assemble the Laplace operator for both variables and the nodal penalty Dirichlet conditions. | |
| void | extractNodalCrossField () |
| Normalize the solved nodal values of z and record the nodes where z vanishes. | |
| std::complex< Real > | interpolatedCrossField (const Point &point) const |
Static Private Member Functions | |
| static void | assembleSystem (libMesh::EquationSystems &es, const std::string &system_name) |
libMesh assembly callback; forwards to assembleLaplace() on the solver stashed in es. | |
Private Attributes | |
| libMesh::Parallel::Communicator | _communicator |
| Serial communicator, so that the solve is reproducible independent of the process count. | |
| libMesh::ReplicatedMesh | _mesh |
| Private copy of the background triangulation, sharing the caller's node ids. | |
| const NodalCrossField | _boundary_cross_field |
| Dirichlet value exp(4 i theta_t) of each boundary node, keyed by node id. | |
| const libMesh::FEType | _fe_type |
| Linear Lagrange, the discretization of both components of z. | |
| std::unique_ptr< libMesh::EquationSystems > | _equation_systems |
| Holds the solve; kept past solve() because shape function evaluation needs it. | |
| libMesh::LinearImplicitSystem * | _system |
| System holding both components of z; owned by _equation_systems. | |
| unsigned int | _real_variable |
| Variable number of the real part of z. | |
| unsigned int | _imaginary_variable |
| Variable number of the imaginary part of z. | |
| std::unique_ptr< libMesh::PointLocatorBase > | _point_locator |
| Locates the element containing a query point. | |
| bool | _solved |
| Whether solve() has produced the results the queries read. | |
| NodalCrossField | _nodal_cross_field |
| Unit-magnitude nodal values of z, keyed by node id. | |
| std::vector< dof_id_type > | _singular_nodes |
| Ascending ids of the nodes where z vanishes. | |
Solves for a cross field, the smooth field of 4-fold symmetric directions that gives XYFrontalDelaunayGenerator the local frame in which it measures the target size ahead of the front.
The cross field is represented by the complex field z whose argument carries the 4-fold symmetry,
Laplace(z) = 0, z = exp(4 i theta_t) on the boundary, theta = arg(z) / 4
where theta_t is the boundary tangent angle and theta is the angle of one of the four directions of the cross at any point of the domain, which is theta_t itself on the boundary. Working with z instead of theta makes the problem linear and single valued: theta itself is only defined modulo pi/2, so it can neither be solved for nor interpolated directly. Zeros of z are the singularities of the field, the points where it has no direction; the frame is discontinuous around them, and singularNodes() reports the nodes where the solve found one.
The solve is a pair of real Laplace problems (one for the real part of z, one for the imaginary part) discretized with linear Lagrange finite elements on the background triangulation. It runs on a private serial communicator so that the field is identical on every process and for every process count.
Definition at line 53 of file XYCrossFieldSolver.h.
| using XYCrossFieldSolver::NodalCrossField = std::map<dof_id_type, std::complex<Real> > |
Values of the complex cross field z at the nodes of the background mesh, keyed by node id.
Definition at line 57 of file XYCrossFieldSolver.h.
| XYCrossFieldSolver::XYCrossFieldSolver | ( | const libMesh::MeshBase & | background_mesh, |
| const std::map< dof_id_type, Real > & | boundary_tangent_angles | ||
| ) |
Build a cross field solver on a background triangulation.
| background_mesh | Replicated background mesh of TRI3 elements covering the domain. The mesh is copied internally with its node ids preserved, so it need not outlive this object, and its node ids are the ids used by both boundary_tangent_angles and every result this class reports. |
| boundary_tangent_angles | Boundary tangent angle theta_t, in radians, for each boundary node of background_mesh, keyed by node id. Every node on the domain boundary must appear; nodes absent from this map are treated as interior. |
Definition at line 66 of file XYCrossFieldSolver.C.
|
private |
Assemble the Laplace operator for both variables and the nodal penalty Dirichlet conditions.
Definition at line 135 of file XYCrossFieldSolver.C.
Referenced by assembleSystem().
|
staticprivate |
libMesh assembly callback; forwards to assembleLaplace() on the solver stashed in es.
Definition at line 129 of file XYCrossFieldSolver.C.
Referenced by XYCrossFieldSolver().
point as the pair (u, v), with u = (cos theta, sin theta) and v the in-plane perpendicular of u. Definition at line 260 of file XYCrossFieldSolver.C.
|
private |
Normalize the solved nodal values of z and record the nodes where z vanishes.
Definition at line 197 of file XYCrossFieldSolver.C.
Referenced by solve().
|
private |
point. Definition at line 226 of file XYCrossFieldSolver.C.
Referenced by theta().
|
inline |
Definition at line 97 of file XYCrossFieldSolver.h.
|
inline |
Definition at line 104 of file XYCrossFieldSolver.h.
| void XYCrossFieldSolver::solve | ( | ) |
Assemble and solve the two Laplace problems, then normalize the nodal field and collect the singular nodes.
Must be called before any query below.
Definition at line 114 of file XYCrossFieldSolver.C.
| Real XYCrossFieldSolver::theta | ( | const Point & | point | ) | const |
point, in radians, obtained by interpolating z over the containing element and taking arg(z) / 4. Since arg() returns a value in (-pi, pi], theta lands in (-pi/4, pi/4], the canonical representative of the cross direction modulo pi/2. Definition at line 254 of file XYCrossFieldSolver.C.
Referenced by crossFrame().
|
private |
Dirichlet value exp(4 i theta_t) of each boundary node, keyed by node id.
Definition at line 126 of file XYCrossFieldSolver.h.
Referenced by assembleLaplace(), and XYCrossFieldSolver().
|
private |
Serial communicator, so that the solve is reproducible independent of the process count.
Definition at line 120 of file XYCrossFieldSolver.h.
|
private |
Holds the solve; kept past solve() because shape function evaluation needs it.
Definition at line 132 of file XYCrossFieldSolver.h.
Referenced by interpolatedCrossField(), solve(), and XYCrossFieldSolver().
|
private |
Linear Lagrange, the discretization of both components of z.
Definition at line 129 of file XYCrossFieldSolver.h.
Referenced by assembleLaplace(), interpolatedCrossField(), and XYCrossFieldSolver().
|
private |
Variable number of the imaginary part of z.
Definition at line 141 of file XYCrossFieldSolver.h.
Referenced by assembleLaplace(), extractNodalCrossField(), and XYCrossFieldSolver().
|
private |
Private copy of the background triangulation, sharing the caller's node ids.
Definition at line 123 of file XYCrossFieldSolver.h.
Referenced by assembleLaplace(), extractNodalCrossField(), and XYCrossFieldSolver().
|
private |
Unit-magnitude nodal values of z, keyed by node id.
Definition at line 150 of file XYCrossFieldSolver.h.
Referenced by extractNodalCrossField(), interpolatedCrossField(), and nodalCrossField().
|
private |
Locates the element containing a query point.
Definition at line 144 of file XYCrossFieldSolver.h.
Referenced by XYCrossFieldSolver().
|
private |
Variable number of the real part of z.
Definition at line 138 of file XYCrossFieldSolver.h.
Referenced by assembleLaplace(), extractNodalCrossField(), and XYCrossFieldSolver().
|
private |
Ascending ids of the nodes where z vanishes.
Definition at line 153 of file XYCrossFieldSolver.h.
Referenced by extractNodalCrossField(), and singularNodes().
|
private |
Whether solve() has produced the results the queries read.
Definition at line 147 of file XYCrossFieldSolver.h.
Referenced by interpolatedCrossField(), and solve().
|
private |
System holding both components of z; owned by _equation_systems.
Definition at line 135 of file XYCrossFieldSolver.h.
Referenced by assembleLaplace(), extractNodalCrossField(), solve(), and XYCrossFieldSolver().