14 #include "libmesh/cell_hex8.h" 15 #include "libmesh/cell_hex.h" 16 #include "libmesh/edge_edge2.h" 17 #include "libmesh/enum_elem_type.h" 18 #include "libmesh/enum_point_locator_type.h" 19 #include "libmesh/int_range.h" 20 #include "libmesh/dof_map.h" 22 #include "libmesh/elem.h" 23 #include "libmesh/face_quad.h" 24 #include "libmesh/face_quad4.h" 25 #include "libmesh/fe_compute_data.h" 26 #include "libmesh/fe_interface.h" 27 #include "libmesh/id_types.h" 28 #include "libmesh/int_range.h" 29 #include "libmesh/libmesh_common.h" 30 #include "libmesh/numeric_vector.h" 31 #include "libmesh/explicit_system.h" 32 #include "libmesh/plane.h" 33 #include "libmesh/enum_to_string.h" 35 #include "libmesh/quadrature_gauss.h" 36 #include "libmesh/fe_base.h" 41 const std::string & exodus_mesh,
42 const bool find_closest,
43 const unsigned int kdtree_candidates)
44 : _communicator(MPI_COMM_SELF),
46 _find_closest(find_closest),
47 _kdtree_candidates(kdtree_candidates),
58 _eq = std::make_unique<EquationSystems>(
_mesh);
71 std::set<dof_id_type> var_indices;
77 for (
const auto & elem :
_mesh.element_ptr_range())
78 if (elem->default_order() !=
FIRST)
79 mooseError(
"Closet point projection currently does not support second order elements.");
87 for (
const auto & node :
_mesh.node_ptr_range())
91 for (
const auto & elem :
_mesh.element_ptr_range())
93 for (
const auto n :
make_range(elem->n_nodes()))
111 std::vector<dof_id_type> & dof_indices,
112 std::vector<Real> & weights)
const 116 const Elem * elem = (*_point_locator)(test_point);
118 mooseError(
"No element was found to contain point ", test_point);
126 Point coor = FEMap::inverse_map(elem->
dim(), elem, test_point);
129 FEInterface::compute_data(elem->
dim(),
_fe_type, elem, fe_data);
131 weights = fe_data.shape;
133 if (dof_indices.size() != weights.size())
134 mooseError(
"Internal error: weights and DoF indices do not have the same size.");
139 std::vector<dof_id_type> & dof_indices,
140 std::vector<RealGradient> & weights)
const 143 mooseError(
"Internal error: System being read does not contain _parameter_mesh_var.");
146 const Elem * elem = (*_point_locator)(test_point);
154 Point coor = FEMap::inverse_map(elem->
dim(), elem, test_point);
157 fe_data.enable_derivative();
158 FEInterface::compute_data(elem->
dim(),
_fe_type, elem, fe_data);
160 weights = fe_data.dshape;
162 if (dof_indices.size() != weights.size())
163 mooseError(
"Internal error: weights and DoF indices do not have the same size.");
174 auto findClosestElement = [&p,
this](
const auto & elements) ->
Point 176 Real best_d2 = std::numeric_limits<Real>::max();
177 Point best_point = p;
179 for (
const auto * elem : elements)
190 if (best_d2 == std::numeric_limits<Real>::max())
191 mooseError(
"project_to_mesh failed - no candidate elements.");
199 std::vector<std::size_t> nearest_node_indices;
203 std::set<const Elem *> candidate_elements;
204 for (
auto node_idx : nearest_node_indices)
214 const auto & connected_elems = it->second;
215 candidate_elements.insert(connected_elems.begin(), connected_elems.end());
221 std::vector<const Elem *> candidate_vector(candidate_elements.begin(),
222 candidate_elements.end());
223 return findClosestElement(candidate_vector);
228 std::vector<const Elem *> all_elements;
229 for (
const auto & elem :
_mesh.element_ptr_range())
230 all_elements.push_back(elem);
232 return findClosestElement(all_elements);
240 "Points inside of elements shouldn't need to find closestPoint.");
243 auto findClosest = [&p](
auto range,
auto point_func) ->
Point 245 Real min_distance = std::numeric_limits<Real>::max();
248 for (
const auto & item : range)
250 Point candidate = point_func(item);
255 min_point = candidate;
312 Utility::enum_to_string(elem.
type()),
313 " for projection of parameter mesh.");
319 template <
typename T>
326 parameter_values.size(),
327 ") does not match mesh DOFs (",
332 if constexpr (std::is_same_v<T, Real>)
334 else if constexpr (std::is_same_v<T, std::vector<Real>>)
338 for (
const auto & elem :
_mesh.element_ptr_range())
341 std::vector<dof_id_type> dof_indices;
345 const unsigned int dim = elem->dim();
349 std::unique_ptr<FEBase> fe(FEBase::build(
dim,
_fe_type));
350 fe->attach_quadrature_rule(&qrule);
353 const std::vector<Real> & JxW = fe->get_JxW();
354 const std::vector<std::vector<Real>> & phi = fe->get_phi();
355 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
360 for (
const auto qp :
make_range(qrule.n_points()))
362 if constexpr (std::is_same_v<T, Real>)
365 else if constexpr (std::is_same_v<T, std::vector<Real>>)
367 parameter_values, phi, dphi, qp, dof_indices, JxW, reg_type, result);
378 return computeRegularizationLoop<Real>(parameter_values, reg_type);
385 return computeRegularizationLoop<std::vector<Real>>(parameter_values, reg_type);
390 const std::vector<std::vector<Real>> & ,
391 const std::vector<std::vector<RealGradient>> & dphi,
392 const unsigned int qp,
393 const std::vector<dof_id_type> & dof_indices,
394 const std::vector<Real> & JxW,
397 Real objective_contribution = 0.0;
407 param_grad += parameter_values[dof_indices[i]] * dphi[i][qp];
410 objective_contribution = param_grad.
norm_sq() * JxW[qp];
417 return objective_contribution;
422 const std::vector<std::vector<Real>> & ,
423 const std::vector<std::vector<RealGradient>> & dphi,
424 const unsigned int qp,
425 const std::vector<dof_id_type> & dof_indices,
426 const std::vector<Real> & JxW,
428 std::vector<Real> & gradient)
const 438 param_grad += parameter_values[dof_indices[i]] * dphi[i][qp];
442 gradient[dof_indices[
j]] += 2.0 * param_grad * dphi[
j][qp] * JxW[qp];
virtual dof_id_type n_nodes() const override final
const unsigned short int _param_var_id
void local_dof_indices(const unsigned int var, std::set< dof_id_type > &var_indices) const
libMesh::ReplicatedMesh _mesh
RegularizationType
Enumerations for regularization computations.
void allow_renumbering(bool allow)
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
void mooseError(Args &&... args)
std::unique_ptr< libMesh::ExodusII_IO > _exodusII_io
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
ParameterMesh(const libMesh::FEType ¶m_type, const std::string &exodus_mesh, const bool find_closest=false, const unsigned int kdtree_candidates=5)
const bool _find_closest
Find closest projection points.
Order default_quadrature_order() const
std::unique_ptr< libMesh::PointLocatorBase > _point_locator
Point closest_point(const Point &p) const
T computeRegularizationLoop(const std::vector< Real > ¶meter_values, RegularizationType reg_type) const
Template method containing the element loop for regularization computations.
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
Real distance(const Point &p)
unsigned int variable_number(std::string_view var) const
bool has_variable(std::string_view var) const
auto norm_sq() const -> decltype(std::norm(Real()))
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Real computeRegularizationQp(const std::vector< Real > ¶meter_values, const std::vector< std::vector< Real >> &phi, const std::vector< std::vector< RealGradient >> &dphi, const unsigned int qp, const std::vector< dof_id_type > &dof_indices, const std::vector< Real > &JxW, RegularizationType reg_type) const
Compute regularization objective for a single quadrature point This is the main function users should...
virtual Point closest_point(const Point &p) const override
std::unordered_map< dof_id_type, std::set< const libMesh::Elem * > > _node_to_elements
const FEType & variable_type(const unsigned int i) const
std::vector< Real > computeRegularizationGradient(const std::vector< Real > ¶meter_values, RegularizationType reg_type) const
Computes regularization gradient for a given regularization type.
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
unsigned int _kdtree_candidates
Real computeRegularizationObjective(const std::vector< Real > ¶meter_values, RegularizationType reg_type) const
Computes regularization objective value for a given regularization type.
virtual unsigned int n_edges() const=0
std::unique_ptr< libMesh::EquationSystems > _eq
bool absolute_fuzzy_equals(const TypeVector< Real > &rhs, Real tol=TOLERANCE) const
Point closestPoint(const Elem &elem, const Point &p) const
Find closest point on the element to the given point.
std::unique_ptr< KDTree > _node_kdtree
void computeRegularizationGradientQp(const std::vector< Real > ¶meter_values, const std::vector< std::vector< Real >> &phi, const std::vector< std::vector< RealGradient >> &dphi, const unsigned int qp, const std::vector< dof_id_type > &dof_indices, const std::vector< Real > &JxW, RegularizationType reg_type, std::vector< Real > &gradient) const
Compute regularization gradient for a single quadrature point This is the main function users should ...
virtual unsigned int n_sides() const=0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual unsigned short dim() const=0
const Node * node_ptr(const unsigned int i) const
virtual const Node * node_ptr(const dof_id_type i) const override final
IntRange< T > make_range(T beg, T end)
const libMesh::DofMap * _dof_map
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::vector< Point > _mesh_nodes
Node-based KDTree optimization.
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false) override
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
void getIndexAndWeight(const Point &pt, std::vector< dof_id_type > &dof_indices, std::vector< Real > &weights) const
Interpolate parameters onto the computational mesh getIndexAndWeight is only used by ParameterMeshFun...
const DofMap & get_dof_map() const
virtual ElemType type() const=0
Point projectToMesh(const Point &p) const
Returns the point on the parameter mesh that is projected from the test point.
auto index_range(const T &sizable)
const libMesh::FEType _fe_type