https://mooseframework.inl.gov
Public Member Functions | Protected Attributes | Private Member Functions | List of all members
ParameterMesh Class Reference

Utility class to use an Exodus mesh to define controllable parameters for optimization problems This class will: More...

#include <ParameterMesh.h>

Public Member Functions

 ParameterMesh (const libMesh::FEType &param_type, const std::string &exodus_mesh, const std::vector< std::string > &var_names={}, const bool find_closest=false, const unsigned int kdtree_candidates=5)
 
dof_id_type size () const
 
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 ParameterMeshFunction. More...
 
void getIndexAndWeight (const Point &pt, std::vector< dof_id_type > &dof_indices, std::vector< RealGradient > &weights) const
 Performs inner products of parameters with functions on the computational mesh getIndexAndWeight is only used by ParameterMeshFunction. More...
 
std::vector< RealgetParameterValues (std::string var_name, unsigned int timestep) const
 Initializes parameter data and sets bounds in the main optmiization application getParameterValues is only used by ParameterMeshOptimization. More...
 

Protected Attributes

libMesh::Parallel::Communicator _communicator
 
libMesh::ReplicatedMesh _mesh
 
const bool _find_closest
 Find closest projection points. More...
 
std::unique_ptr< libMesh::EquationSystems_eq
 
libMesh::System_sys
 
std::unique_ptr< libMesh::PointLocatorBase_point_locator
 
std::unique_ptr< libMesh::ExodusII_IO_exodusII_io
 
dof_id_type _param_dofs
 
std::vector< Point > _mesh_nodes
 Node-based KDTree optimization. More...
 
std::unique_ptr< KDTree_node_kdtree
 
std::unordered_map< dof_id_type, std::set< const libMesh::Elem * > > _node_to_elements
 
unsigned int _kdtree_candidates
 

Private Member Functions

Point projectToMesh (const Point &p) const
 Returns the point on the parameter mesh that is projected from the test point. More...
 
Point closestPoint (const Elem &elem, const Point &p) const
 Find closest point on the element to the given point. More...
 

Detailed Description

Utility class to use an Exodus mesh to define controllable parameters for optimization problems This class will:

Definition at line 42 of file ParameterMesh.h.

Constructor & Destructor Documentation

◆ ParameterMesh()

ParameterMesh::ParameterMesh ( const libMesh::FEType param_type,
const std::string &  exodus_mesh,
const std::vector< std::string > &  var_names = {},
const bool  find_closest = false,
const unsigned int  kdtree_candidates = 5 
)

Definition at line 37 of file ParameterMesh.C.

42  : _communicator(MPI_COMM_SELF),
44  _find_closest(find_closest),
45  _kdtree_candidates(kdtree_candidates)
46 {
47  _mesh.allow_renumbering(false);
49  _exodusII_io = std::make_unique<ExodusII_IO>(_mesh);
50  _exodusII_io->read(exodus_mesh);
51  _mesh.read(exodus_mesh);
52  // Create system to store parameter values
53  _eq = std::make_unique<EquationSystems>(_mesh);
54  _sys = &_eq->add_system<ExplicitSystem>("_parameter_mesh_sys");
55  _sys->add_variable("_parameter_mesh_var", param_type);
56 
57  // Create point locator
58  _point_locator = PointLocatorBase::build(TREE_LOCAL_ELEMENTS, _mesh);
59  _point_locator->enable_out_of_mesh_mode();
60 
61  if (!var_names.empty())
62  {
63  // Make Exodus vars for equation system
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());
66 
67  std::vector<std::string> nodal_variables;
68  std::vector<std::string> elemental_variables;
69  for (const auto & var_name : var_names)
70  {
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);
75  }
76  if ((elemental_variables.size() + nodal_variables.size()) != var_names.size())
77  {
78  std::string out("\n Parameter Group Variables Requested: ");
79  for (const auto & var : var_names)
80  out += var + " ";
81  out += "\n Exodus Nodal Variables: ";
82  for (const auto & var : all_nodal)
83  out += var + " ";
84  out += "\n Exodus Elemental Variables: ";
85  for (const auto & var : all_elemental)
86  out += var + " ";
87  mooseError("Exodus file did not contain all of the parameter names being intitialized.", out);
88  }
89 
90  if (!nodal_variables.empty() && !elemental_variables.empty())
91  {
92  std::string out("\n Parameter Group Nodal Variables: ");
93  for (const auto & var : nodal_variables)
94  out += var + " ";
95  out += "\n Parameter Group Elemental Variables: ";
96  for (const auto & var : elemental_variables)
97  out += var + " ";
98  mooseError("Parameter group contains nodal and elemental variables, this is "
99  "not allowed. ",
100  out);
101  }
102  // Add the parameter group ics and bounds to the system
103  // All parameters in a group will be the same type, only one of these loops will do anything
104  for (const auto & var_name : nodal_variables)
105  _sys->add_variable(var_name, param_type);
106  for (const auto & var_name : elemental_variables)
107  _sys->add_variable(var_name, param_type);
108  }
109  // Initialize the equations systems
110  _eq->init();
111 
112  const unsigned short int var_id = _sys->variable_number("_parameter_mesh_var");
113  std::set<dof_id_type> var_indices;
114  _sys->local_dof_indices(var_id, var_indices);
115  _param_dofs = var_indices.size();
116 
117  if (_find_closest)
118  {
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.");
122  }
123 
124  // Initialize node-based KDTree optimization
125  _mesh_nodes.clear();
126  _node_to_elements.clear();
127 
128  // Extract all node coordinates
129  for (const auto & node : _mesh.node_ptr_range())
130  _mesh_nodes.push_back(*node);
131 
132  // Build node-to-elements connectivity map
133  for (const auto & elem : _mesh.element_ptr_range())
134  {
135  for (const auto n : make_range(elem->n_nodes()))
136  {
137  dof_id_type node_id = elem->node_id(n);
138  _node_to_elements[node_id].insert(elem);
139  }
140  }
141 
142  // Create KDTree from node coordinates
143  if (!_mesh_nodes.empty())
144  _node_kdtree = std::make_unique<KDTree>(_mesh_nodes, 10);
145 }
void local_dof_indices(const unsigned int var, std::set< dof_id_type > &var_indices) const
libMesh::ReplicatedMesh _mesh
Definition: ParameterMesh.h:86
void allow_renumbering(bool allow)
void mooseError(Args &&... args)
std::unique_ptr< libMesh::ExodusII_IO > _exodusII_io
Definition: ParameterMesh.h:92
FIRST
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
const bool _find_closest
Find closest projection points.
Definition: ParameterMesh.h:88
std::unique_ptr< libMesh::PointLocatorBase > _point_locator
Definition: ParameterMesh.h:91
unsigned int variable_number(std::string_view var) const
libMesh::System * _sys
Definition: ParameterMesh.h:90
libMesh::Parallel::Communicator _communicator
Definition: ParameterMesh.h:85
std::unordered_map< dof_id_type, std::set< const libMesh::Elem * > > _node_to_elements
Definition: ParameterMesh.h:99
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
std::unique_ptr< libMesh::EquationSystems > _eq
Definition: ParameterMesh.h:89
std::unique_ptr< KDTree > _node_kdtree
Definition: ParameterMesh.h:98
dof_id_type _param_dofs
Definition: ParameterMesh.h:94
OStreamProxy out
IntRange< T > make_range(T beg, T end)
std::vector< Point > _mesh_nodes
Node-based KDTree optimization.
Definition: ParameterMesh.h:97
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false) override
uint8_t dof_id_type

Member Function Documentation

◆ closestPoint()

Point ParameterMesh::closestPoint ( const Elem elem,
const Point p 
) const
private

Find closest point on the element to the given point.

Parameters
elem
p
Returns
Point

Definition at line 318 of file ParameterMesh.C.

Referenced by projectToMesh().

319 {
320  mooseAssert(!elem.contains_point(p),
321  "Points inside of elements shouldn't need to find closestPoint.");
322 
323  // Lambda to find closest point from range without storing temporary vectors
324  auto findClosest = [&p](auto range, auto point_func) -> Point
325  {
326  Real min_distance = std::numeric_limits<Real>::max();
327  Point min_point = p;
328 
329  for (const auto & item : range)
330  {
331  Point candidate = point_func(item);
332  Real distance = (candidate - p).norm();
333  if (distance < min_distance)
334  {
335  min_distance = distance;
336  min_point = candidate;
337  }
338  }
339  return min_point;
340  };
341 
342  switch (elem.type())
343  {
344  case EDGE2:
345  {
346  LineSegment ls(*(elem.node_ptr(0)), *(elem.node_ptr(1)));
347  return ls.closest_point(p);
348  }
349 
350  case TRI3:
351  {
352  Point a = *(elem.node_ptr(0));
353  Point b = *(elem.node_ptr(1));
354  Point c = *(elem.node_ptr(2));
355  Plane pl(a, b, c);
356  Point trial = pl.closest_point(p);
357  if (elem.contains_point(trial))
358  return trial;
359 
360  return findClosest(make_range(elem.n_edges()),
361  [&](dof_id_type i) { return closestPoint(*elem.build_edge_ptr(i), p); });
362  }
363  case QUAD4:
364  {
365  Point a = *(elem.node_ptr(0));
366  Point b = *(elem.node_ptr(1));
367  Point c = *(elem.node_ptr(2));
368  Point d = *(elem.node_ptr(3));
369  Plane pl1(a, b, c);
370  Plane pl2(b, c, d);
371  Point trial1 = pl1.closest_point(p);
372  Point trial2 = pl2.closest_point(p);
373  if (!trial1.absolute_fuzzy_equals(trial2, TOLERANCE * TOLERANCE))
374  mooseError("Quad4 element is not coplanar");
375 
376  if (elem.contains_point(trial1))
377  return trial1;
378 
379  return findClosest(make_range(elem.n_edges()),
380  [&](dof_id_type i) { return closestPoint(*elem.build_edge_ptr(i), p); });
381  }
382 
383  default:
384  {
385  if (elem.dim() == 3)
386  {
387  return findClosest(make_range(elem.n_sides()),
388  [&](dof_id_type i) { return closestPoint(*elem.build_side_ptr(i), p); });
389  }
390  else
391  {
392  mooseError("Unsupported element type ",
393  Utility::enum_to_string(elem.type()),
394  " for projection of parameter mesh.");
395  }
396  }
397  }
398 }
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
void mooseError(Args &&... args)
Real distance(const Point &p)
TRI3
QUAD4
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
virtual unsigned int n_edges() const=0
auto norm(const T &a) -> decltype(std::abs(a))
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.
virtual unsigned int n_sides() const=0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
EDGE2
virtual unsigned short dim() const=0
const Node * node_ptr(const unsigned int i) const
IntRange< T > make_range(T beg, T end)
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
virtual ElemType type() const=0
uint8_t dof_id_type

◆ getIndexAndWeight() [1/2]

void ParameterMesh::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 ParameterMeshFunction.

Parameters
ptlocation to compute elemnent dof_indices weights
dof_indicesreturn dof indices for element containing pt
weightsreturns element shape function weights at pt

Referenced by ParameterMeshFunction::gradient(), ParameterMeshFunction::parameterGradient(), ParameterMeshFunction::timeDerivative(), and ParameterMeshFunction::value().

◆ getIndexAndWeight() [2/2]

void ParameterMesh::getIndexAndWeight ( const Point &  pt,
std::vector< dof_id_type > &  dof_indices,
std::vector< RealGradient > &  weights 
) const

Performs inner products of parameters with functions on the computational mesh getIndexAndWeight is only used by ParameterMeshFunction.

Parameters
ptlocation to compute elemnent dof_indices weights
dof_indicesreturn dof indices for element containing pt
weightsreturns element shape function gradient weights at pt

◆ getParameterValues()

std::vector< Real > ParameterMesh::getParameterValues ( std::string  var_name,
unsigned int  timestep 
) const

Initializes parameter data and sets bounds in the main optmiization application getParameterValues is only used by ParameterMeshOptimization.

Parameters
var_namevariable to read off mesh
timesteptimestep to read variable off mesh
Returns
vector of variables read off mesh at timestep

Definition at line 211 of file ParameterMesh.C.

Referenced by ParameterMeshOptimization::parseExodusData().

212 {
213  if (!_sys->has_variable(var_name))
214  mooseError("Exodus file being read does not contain ", var_name, ".");
215  // get the exodus variable and put it into the equation system.
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 "
221  "less than ",
222  _exodusII_io->get_num_time_steps(),
223  ", received ",
224  time_step);
225 
226  // determine what kind of variable you are trying to read from mesh
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())
230  _exodusII_io->copy_nodal_solution(*_sys, var_name, var_name, step_to_read);
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);
233 
234  // Update the equations systems
235  _sys->update();
236 
237  const unsigned short int var_id = _sys->variable_number(var_name);
238  std::set<dof_id_type> var_indices;
239  _sys->local_dof_indices(var_id, var_indices); // Everything is local so this is fine
240  std::vector<dof_id_type> var_indices_vector(var_indices.begin(), var_indices.end());
241 
242  std::vector<Real> parameter_values;
243  _sys->solution->localize(parameter_values, var_indices_vector);
244  return parameter_values;
245 }
void local_dof_indices(const unsigned int var, std::set< dof_id_type > &var_indices) const
void mooseError(Args &&... args)
std::unique_ptr< libMesh::ExodusII_IO > _exodusII_io
Definition: ParameterMesh.h:92
unsigned int variable_number(std::string_view var) const
bool has_variable(std::string_view var) const
libMesh::System * _sys
Definition: ParameterMesh.h:90
std::unique_ptr< NumericVector< Number > > solution
virtual void update()

◆ projectToMesh()

Point ParameterMesh::projectToMesh ( const Point p) const
private

Returns the point on the parameter mesh that is projected from the test point.

Parameters
ptest point
Returns
Point

Definition at line 248 of file ParameterMesh.C.

249 {
250  // quick path: p already inside an element
251  if ((*_point_locator)(p))
252  return p;
253 
254  // Lambda to find closest point from elements using squared distance for efficiency
255  auto findClosestElement = [&p, this](const auto & elements) -> Point
256  {
257  Real best_d2 = std::numeric_limits<Real>::max();
258  Point best_point = p;
259 
260  for (const auto * elem : elements)
261  {
262  Point trial = closestPoint(*elem, p);
263  Real d2 = (trial - p).norm_sq();
264  if (d2 < best_d2)
265  {
266  best_d2 = d2;
267  best_point = trial;
268  }
269  }
270 
271  if (best_d2 == std::numeric_limits<Real>::max())
272  mooseError("project_to_mesh failed - no candidate elements.");
273  return best_point;
274  };
275 
276  // Use KDTree optimization if available
277  if (_node_kdtree && !_mesh_nodes.empty())
278  {
279  // Find K nearest nodes using KDTree
280  std::vector<std::size_t> nearest_node_indices;
281  _node_kdtree->neighborSearch(p, _kdtree_candidates, nearest_node_indices);
282 
283  // Collect all elements connected to these nodes
284  std::set<const Elem *> candidate_elements;
285  for (auto node_idx : nearest_node_indices)
286  {
287  // Get the actual node from the mesh using the index
288  if (node_idx < _mesh.n_nodes())
289  {
290  const Node * node = _mesh.node_ptr(node_idx);
291  dof_id_type node_id = node->id();
292  auto it = _node_to_elements.find(node_id);
293  if (it != _node_to_elements.end())
294  {
295  const auto & connected_elems = it->second;
296  candidate_elements.insert(connected_elems.begin(), connected_elems.end());
297  }
298  }
299  }
300 
301  // Convert set to vector for consistent type
302  std::vector<const Elem *> candidate_vector(candidate_elements.begin(),
303  candidate_elements.end());
304  return findClosestElement(candidate_vector);
305  }
306  else
307  {
308  // Fallback to original O(n) method if KDTree not available
309  std::vector<const Elem *> all_elements;
310  for (const auto & elem : _mesh.element_ptr_range())
311  all_elements.push_back(elem);
312 
313  return findClosestElement(all_elements);
314  }
315 }
virtual dof_id_type n_nodes() const override final
libMesh::ReplicatedMesh _mesh
Definition: ParameterMesh.h:86
void mooseError(Args &&... args)
std::unique_ptr< libMesh::PointLocatorBase > _point_locator
Definition: ParameterMesh.h:91
dof_id_type id() const
std::unordered_map< dof_id_type, std::set< const libMesh::Elem * > > _node_to_elements
Definition: ParameterMesh.h:99
unsigned int _kdtree_candidates
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
Definition: ParameterMesh.h:98
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
auto norm_sq(const T &a) -> decltype(std::norm(a))
virtual const Node * node_ptr(const dof_id_type i) const override final
std::vector< Point > _mesh_nodes
Node-based KDTree optimization.
Definition: ParameterMesh.h:97
uint8_t dof_id_type

◆ size()

dof_id_type ParameterMesh::size ( ) const
inline

Member Data Documentation

◆ _communicator

libMesh::Parallel::Communicator ParameterMesh::_communicator
protected

Definition at line 85 of file ParameterMesh.h.

◆ _eq

std::unique_ptr<libMesh::EquationSystems> ParameterMesh::_eq
protected

Definition at line 89 of file ParameterMesh.h.

Referenced by ParameterMesh().

◆ _exodusII_io

std::unique_ptr<libMesh::ExodusII_IO> ParameterMesh::_exodusII_io
protected

Definition at line 92 of file ParameterMesh.h.

Referenced by getParameterValues(), and ParameterMesh().

◆ _find_closest

const bool ParameterMesh::_find_closest
protected

Find closest projection points.

Definition at line 88 of file ParameterMesh.h.

Referenced by ParameterMesh().

◆ _kdtree_candidates

unsigned int ParameterMesh::_kdtree_candidates
protected

Definition at line 100 of file ParameterMesh.h.

Referenced by projectToMesh().

◆ _mesh

libMesh::ReplicatedMesh ParameterMesh::_mesh
protected

Definition at line 86 of file ParameterMesh.h.

Referenced by ParameterMesh(), and projectToMesh().

◆ _mesh_nodes

std::vector<Point> ParameterMesh::_mesh_nodes
protected

Node-based KDTree optimization.

Definition at line 97 of file ParameterMesh.h.

Referenced by ParameterMesh(), and projectToMesh().

◆ _node_kdtree

std::unique_ptr<KDTree> ParameterMesh::_node_kdtree
protected

Definition at line 98 of file ParameterMesh.h.

Referenced by ParameterMesh(), and projectToMesh().

◆ _node_to_elements

std::unordered_map<dof_id_type, std::set<const libMesh::Elem *> > ParameterMesh::_node_to_elements
protected

Definition at line 99 of file ParameterMesh.h.

Referenced by ParameterMesh(), and projectToMesh().

◆ _param_dofs

dof_id_type ParameterMesh::_param_dofs
protected

Definition at line 94 of file ParameterMesh.h.

Referenced by ParameterMesh(), and size().

◆ _point_locator

std::unique_ptr<libMesh::PointLocatorBase> ParameterMesh::_point_locator
protected

Definition at line 91 of file ParameterMesh.h.

Referenced by ParameterMesh(), and projectToMesh().

◆ _sys

libMesh::System* ParameterMesh::_sys
protected

Definition at line 90 of file ParameterMesh.h.

Referenced by getParameterValues(), and ParameterMesh().


The documentation for this class was generated from the following files: