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/dof_map.h" 21 #include "libmesh/elem.h" 22 #include "libmesh/face_quad.h" 23 #include "libmesh/face_quad4.h" 24 #include "libmesh/fe_compute_data.h" 25 #include "libmesh/fe_interface.h" 26 #include "libmesh/id_types.h" 27 #include "libmesh/int_range.h" 28 #include "libmesh/libmesh_common.h" 29 #include "libmesh/numeric_vector.h" 30 #include "libmesh/explicit_system.h" 31 #include "libmesh/plane.h" 32 #include "libmesh/enum_to_string.h" 38 const std::string & exodus_mesh,
39 const std::vector<std::string> & var_names,
40 const bool find_closest,
41 const unsigned int kdtree_candidates)
42 : _communicator(MPI_COMM_SELF),
44 _find_closest(find_closest),
45 _kdtree_candidates(kdtree_candidates)
53 _eq = std::make_unique<EquationSystems>(
_mesh);
61 if (!var_names.empty())
64 const std::vector<std::string> & all_nodal(
_exodusII_io->get_nodal_var_names());
65 const std::vector<std::string> & all_elemental(
_exodusII_io->get_elem_var_names());
67 std::vector<std::string> nodal_variables;
68 std::vector<std::string> elemental_variables;
69 for (
const auto & var_name : var_names)
71 if (std::find(all_nodal.begin(), all_nodal.end(), var_name) != all_nodal.end())
72 nodal_variables.push_back(var_name);
73 if (std::find(all_elemental.begin(), all_elemental.end(), var_name) != all_elemental.end())
74 elemental_variables.push_back(var_name);
76 if ((elemental_variables.size() + nodal_variables.size()) != var_names.size())
78 std::string
out(
"\n Parameter Group Variables Requested: ");
79 for (
const auto & var : var_names)
81 out +=
"\n Exodus Nodal Variables: ";
82 for (
const auto & var : all_nodal)
84 out +=
"\n Exodus Elemental Variables: ";
85 for (
const auto & var : all_elemental)
87 mooseError(
"Exodus file did not contain all of the parameter names being intitialized.",
out);
90 if (!nodal_variables.empty() && !elemental_variables.empty())
92 std::string
out(
"\n Parameter Group Nodal Variables: ");
93 for (
const auto & var : nodal_variables)
95 out +=
"\n Parameter Group Elemental Variables: ";
96 for (
const auto & var : elemental_variables)
98 mooseError(
"Parameter group contains nodal and elemental variables, this is " 104 for (
const auto & var_name : nodal_variables)
106 for (
const auto & var_name : elemental_variables)
113 std::set<dof_id_type> var_indices;
119 for (
const auto & elem :
_mesh.element_ptr_range())
120 if (elem->default_order() !=
FIRST)
121 mooseError(
"Closet point projection currently does not support second order elements.");
129 for (
const auto & node :
_mesh.node_ptr_range())
133 for (
const auto & elem :
_mesh.element_ptr_range())
135 for (
const auto n :
make_range(elem->n_nodes()))
149 std::vector<dof_id_type> & dof_indices,
150 std::vector<Real> & weights)
const 154 const Elem * elem = (*_point_locator)(test_point);
156 mooseError(
"No element was found to contain point ", test_point);
166 Point coor = FEMap::inverse_map(elem->
dim(), elem, test_point);
170 FEInterface::compute_data(elem->
dim(), fe_type, elem, fe_data);
172 weights = fe_data.shape;
174 if (dof_indices.size() != weights.size())
175 mooseError(
"Internal error: weights and DoF indices do not have the same size.");
180 std::vector<dof_id_type> & dof_indices,
181 std::vector<RealGradient> & weights)
const 184 mooseError(
"Internal error: System being read does not contain _parameter_mesh_var.");
187 const Elem * elem = (*_point_locator)(test_point);
197 Point coor = FEMap::inverse_map(elem->
dim(), elem, test_point);
201 fe_data.enable_derivative();
202 FEInterface::compute_data(elem->
dim(), fe_type, elem, fe_data);
204 weights = fe_data.dshape;
206 if (dof_indices.size() != weights.size())
207 mooseError(
"Internal error: weights and DoF indices do not have the same size.");
214 mooseError(
"Exodus file being read does not contain ", var_name,
".");
216 unsigned int step_to_read =
_exodusII_io->get_num_time_steps();
217 if (time_step <= step_to_read)
218 step_to_read = time_step;
219 else if (time_step != std::numeric_limits<unsigned int>::max())
220 mooseError(
"Invalid value passed as \"time_step\". Expected a valid integer " 227 const std::vector<std::string> & all_nodal(
_exodusII_io->get_nodal_var_names());
228 const std::vector<std::string> & all_elemental(
_exodusII_io->get_elem_var_names());
229 if (std::find(all_nodal.begin(), all_nodal.end(), var_name) != all_nodal.end())
231 else if (std::find(all_elemental.begin(), all_elemental.end(), var_name) != all_elemental.end())
232 _exodusII_io->copy_elemental_solution(*
_sys, var_name, var_name, step_to_read);
238 std::set<dof_id_type> var_indices;
240 std::vector<dof_id_type> var_indices_vector(var_indices.begin(), var_indices.end());
242 std::vector<Real> parameter_values;
243 _sys->
solution->localize(parameter_values, var_indices_vector);
244 return parameter_values;
255 auto findClosestElement = [&p,
this](
const auto & elements) ->
Point 257 Real best_d2 = std::numeric_limits<Real>::max();
258 Point best_point = p;
260 for (
const auto * elem : elements)
271 if (best_d2 == std::numeric_limits<Real>::max())
272 mooseError(
"project_to_mesh failed - no candidate elements.");
280 std::vector<std::size_t> nearest_node_indices;
284 std::set<const Elem *> candidate_elements;
285 for (
auto node_idx : nearest_node_indices)
295 const auto & connected_elems = it->second;
296 candidate_elements.insert(connected_elems.begin(), connected_elems.end());
302 std::vector<const Elem *> candidate_vector(candidate_elements.begin(),
303 candidate_elements.end());
304 return findClosestElement(candidate_vector);
309 std::vector<const Elem *> all_elements;
310 for (
const auto & elem :
_mesh.element_ptr_range())
311 all_elements.push_back(elem);
313 return findClosestElement(all_elements);
321 "Points inside of elements shouldn't need to find closestPoint.");
324 auto findClosest = [&p](
auto range,
auto point_func) ->
Point 326 Real min_distance = std::numeric_limits<Real>::max();
329 for (
const auto & item : range)
331 Point candidate = point_func(item);
336 min_point = candidate;
393 Utility::enum_to_string(elem.
type()),
394 " for projection of parameter mesh.");
virtual dof_id_type n_nodes() const override final
void local_dof_indices(const unsigned int var, std::set< dof_id_type > &var_indices) const
libMesh::ReplicatedMesh _mesh
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)
const FEType & variable_type(const unsigned int c) const
const bool _find_closest
Find closest projection points.
std::unique_ptr< libMesh::PointLocatorBase > _point_locator
Point closest_point(const Point &p) const
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
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
virtual Point closest_point(const Point &p) const override
std::unique_ptr< NumericVector< Number > > solution
std::unordered_map< dof_id_type, std::set< const libMesh::Elem * > > _node_to_elements
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
virtual unsigned int n_edges() const=0
std::unique_ptr< libMesh::EquationSystems > _eq
ParameterMesh(const libMesh::FEType ¶m_type, const std::string &exodus_mesh, const std::vector< std::string > &var_names={}, const bool find_closest=false, const unsigned int kdtree_candidates=5)
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
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)
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
std::vector< Real > getParameterValues(std::string var_name, unsigned int timestep) const
Initializes parameter data and sets bounds in the main optmiization application getParameterValues is...
Point projectToMesh(const Point &p) const
Returns the point on the parameter mesh that is projected from the test point.