14#include "libmesh/equation_systems.h"
15#include "libmesh/fe_type.h"
16#include "libmesh/parallel.h"
17#include "libmesh/point_locator_base.h"
18#include "libmesh/replicated_mesh.h"
29class LinearImplicitSystem;
71 const std::map<dof_id_type, Real> & boundary_tangent_angles);
84 Real
theta(
const Point & point)
const;
90 std::pair<Point, Point>
crossFrame(
const Point & point)
const;
Solves for a cross field, the smooth field of 4-fold symmetric directions that gives XYFrontalDelauna...
std::pair< Point, Point > crossFrame(const Point &point) const
static void assembleSystem(libMesh::EquationSystems &es, const std::string &system_name)
libMesh assembly callback; forwards to assembleLaplace() on the solver stashed in es.
std::map< dof_id_type, std::complex< Real > > NodalCrossField
Values of the complex cross field z at the nodes of the background mesh, keyed by node id.
const libMesh::FEType _fe_type
Linear Lagrange, the discretization of both components of z.
const std::vector< dof_id_type > & singularNodes() const
void solve()
Assemble and solve the two Laplace problems, then normalize the nodal field and collect the singular ...
unsigned int _real_variable
Variable number of the real part of z.
std::unique_ptr< libMesh::PointLocatorBase > _point_locator
Locates the element containing a query point.
NodalCrossField _nodal_cross_field
Unit-magnitude nodal values of z, keyed by node id.
const NodalCrossField & nodalCrossField() const
std::unique_ptr< libMesh::EquationSystems > _equation_systems
Holds the solve; kept past solve() because shape function evaluation needs it.
void assembleLaplace()
Assemble the Laplace operator for both variables and the nodal penalty Dirichlet conditions.
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.
bool _solved
Whether solve() has produced the results the queries read.
void extractNodalCrossField()
Normalize the solved nodal values of z and record the nodes where z vanishes.
libMesh::LinearImplicitSystem * _system
System holding both components of z; owned by _equation_systems.
libMesh::Parallel::Communicator _communicator
Serial communicator, so that the solve is reproducible independent of the process count.
std::complex< Real > interpolatedCrossField(const Point &point) const
std::vector< dof_id_type > _singular_nodes
Ascending ids of the nodes where z vanishes.
unsigned int _imaginary_variable
Variable number of the imaginary part of z.
Real theta(const Point &point) const
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...