mesh_as_geometric_object.h
Go to the documentation of this file.
1 // LIC// ====================================================================
2 // LIC// This file forms part of oomph-lib, the object-oriented,
3 // LIC// multi-physics finite-element library, available
4 // LIC// at http://www.oomph-lib.org.
5 // LIC//
6 // LIC// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 // Header file for a class that is used to represent a mesh
27 // as a geometric object
28 
29 // Include guards to prevent multiple inclusion of the header
30 #ifndef OOMPH_MESH_AS_GEOMETRIC_OBJECT_HEADER
31 #define OOMPH_MESH_AS_GEOMETRIC_OBJECT_HEADER
32 
33 // Config header generated by autoconfig
34 #ifdef HAVE_CONFIG_H
35 #include <oomph-lib-config.h>
36 #endif
37 
38 #include <float.h>
39 #include <limits.h>
40 
41 // Include the geometric object header file
42 #include "geom_objects.h"
43 
44 // Sample point container
45 #include "sample_point_container.h"
46 
47 
49 
50 namespace oomph
51 {
55 
56  //========================================================================
60  //========================================================================
61  namespace MeshAsGeomObject_Helper
62  {
65 
69  Mesh* mesh_pt,
70  SamplePointContainerParameters*& sample_point_container_parameters_pt);
71 
72  } // namespace MeshAsGeomObject_Helper
73 
74 
78 
79 
80  //========================================================================
91  //========================================================================
93  {
94  private:
96  void build_it(
97  SamplePointContainerParameters* sample_point_container_parameters_pt)
98  {
99  Mesh_pt = sample_point_container_parameters_pt->mesh_pt();
100  if (dynamic_cast<RefineableBinArrayParameters*>(
101  sample_point_container_parameters_pt) != 0)
102  {
104  }
105  else if (dynamic_cast<NonRefineableBinArrayParameters*>(
106  sample_point_container_parameters_pt) != 0)
107  {
109  }
110 #ifdef OOMPH_HAS_CGAL
111  else if (dynamic_cast<CGALSamplePointContainerParameters*>(
112  sample_point_container_parameters_pt) != 0)
113  {
114  Sample_point_container_version = UseCGALSamplePointContainer;
115  }
116 #endif
117  else
118  {
119  throw OomphLibError("Wrong sample_point_container_parameters_pt",
122  }
123 
124 #ifdef OOMPH_HAS_MPI
125 
126  // Set communicator
127  Communicator_pt = Mesh_pt->communicator_pt();
128 
129 #endif
130 
131 
132  // Storage for the Lagrangian and Eulerian dimension
133  int dim[2] = {0, 0};
134 
135  // Set the Lagrangian dimension from the dimension of the first element
136  // if it exists (if not the Lagrangian dimension will be zero)
137  if (Mesh_pt->nelement() != 0)
138  {
139  dim[0] = Mesh_pt->finite_element_pt(0)->dim();
140  }
141 
142  // Read out the Eulerian dimension from the first node, if it exists.
143  //(if not the Eulerian dimension will be zero);
144  if (Mesh_pt->nnode() != 0)
145  {
146  dim[1] = Mesh_pt->node_pt(0)->ndim();
147  }
148 
149  // Need to do an Allreduce to ensure that the dimension is consistent
150  // even when no elements are assigned to a certain processor
151 #ifdef OOMPH_HAS_MPI
152 
153  // Only a problem if the mesh has been distributed
155  {
156  // Need a non-null communicator
157  if (Communicator_pt != 0)
158  {
159  int n_proc = Communicator_pt->nproc();
160  if (n_proc > 1)
161  {
162  int dim_reduce[2];
163  MPI_Allreduce(&dim,
164  &dim_reduce,
165  2,
166  MPI_INT,
167  MPI_MAX,
168  Communicator_pt->mpi_comm());
169 
170  dim[0] = dim_reduce[0];
171  dim[1] = dim_reduce[1];
172  }
173  }
174  }
175 #endif
176 
177  // Set the Lagrangian and Eulerian dimensions within this geometric object
178  this->set_nlagrangian_and_ndim(static_cast<unsigned>(dim[0]),
179  static_cast<unsigned>(dim[1]));
180 
181  // Create temporary storage for geometric Data (don't count
182  // Data twice!
183  std::set<Data*> tmp_geom_data;
184 
185  // Copy all the elements in the mesh into local storage
186  // N.B. elements must be able to have a geometric object representation.
187  unsigned n_sub_object = Mesh_pt->nelement();
188  Sub_geom_object_pt.resize(n_sub_object);
189  for (unsigned e = 0; e < n_sub_object; e++)
190  {
191  // (Try to) cast to a finite element:
193  dynamic_cast<FiniteElement*>(Mesh_pt->element_pt(e));
194 
195 #ifdef PARANOID
196  if (Sub_geom_object_pt[e] == 0)
197  {
198  std::ostringstream error_message;
199  error_message << "Unable to dynamic cast element: " << std::endl
200  << "into a FiniteElement: GeomObject representation is "
201  "not possible\n";
202  throw OomphLibError(error_message.str(),
205  }
206 #endif
207 
208  // Add the geometric Data of each element into set
209  unsigned ngeom_data = Sub_geom_object_pt[e]->ngeom_data();
210  for (unsigned i = 0; i < ngeom_data; i++)
211  {
212  tmp_geom_data.insert(Sub_geom_object_pt[e]->geom_data_pt(i));
213  }
214  }
215 
216  // Now copy unique geom Data values across into vector
217  unsigned ngeom = tmp_geom_data.size();
218  Geom_data_pt.resize(ngeom);
219  typedef std::set<Data*>::iterator IT;
220  unsigned count = 0;
221  for (IT it = tmp_geom_data.begin(); it != tmp_geom_data.end(); it++)
222  {
223  Geom_data_pt[count] = *it;
224  count++;
225  }
226 
227  // Build the right type of bin array
229  {
231 
233  new RefineableBinArray(sample_point_container_parameters_pt);
234  break;
235 
237 
239  new NonRefineableBinArray(sample_point_container_parameters_pt);
240  break;
241 
242 #ifdef OOMPH_HAS_CGAL
243 
244  case UseCGALSamplePointContainer:
245 
247  new CGALSamplePointContainer(sample_point_container_parameters_pt);
248  break;
249 
250 #endif
251 
252  default:
253 
254  oomph_info << "Sample_point_container_version = "
255  << Sample_point_container_version << std::endl;
256  throw OomphLibError("Sample_point_container_version",
259  }
260  }
261 
262 
265 
268 
271 
272 #ifdef OOMPH_HAS_MPI
273 
275  OomphCommunicator* Communicator_pt;
276 
277 #endif
278 
281 
285 
286  public:
289  {
291  }
292 
295  {
296  return Sub_geom_object_pt[e];
297  }
298 
299 
303  {
305  }
306 
308  unsigned nelement()
309  {
310  return Sub_geom_object_pt.size();
311  }
312 
314  MeshAsGeomObject(Mesh* const& mesh_pt) : GeomObject()
315  {
316  // Create default parameters
317  SamplePointContainerParameters* sample_point_container_parameters_pt = 0;
319  mesh_pt, sample_point_container_parameters_pt);
320 
321  // Build the bastard
322  build_it(sample_point_container_parameters_pt);
323  delete sample_point_container_parameters_pt;
324  }
325 
326 
329  SamplePointContainerParameters* sample_point_container_parameters_pt)
330  : GeomObject()
331  {
332  build_it(sample_point_container_parameters_pt);
333  }
334 
337 
340  {
342  }
343 
346 
348  void operator=(const MeshAsGeomObject&) = delete;
349 
351  unsigned ngeom_data() const
352  {
353  return Geom_data_pt.size();
354  }
355 
358  Data* geom_data_pt(const unsigned& j)
359  {
360  return Geom_data_pt[j];
361  }
362 
374  GeomObject*& sub_geom_object_pt,
375  Vector<double>& s,
376  const bool& use_coordinate_as_initial_guess = false)
377  {
378 #ifdef PARANOID
379  if (use_coordinate_as_initial_guess)
380  {
382  "Ignoring the use_coordinate_as_initial_guess argument.",
383  "MeshAsGeomObject::locate_zeta()",
385  }
386 #endif
387 
388 
389  // Do locate in sample point container
390  Sample_point_container_pt->locate_zeta(zeta, sub_geom_object_pt, s);
391  }
392 
398  {
399  // Call position function at current timestep:
400  unsigned t = 0;
401  position(t, zeta, r);
402  }
403 
409  void position(const unsigned& t,
410  const Vector<double>& zeta,
411  Vector<double>& r) const
412  {
413  // Storage for the GeomObject that contains the zeta coordinate
414  // and the intrinsic coordinate within it.
415  GeomObject* sub_geom_object_pt;
416  const unsigned n_lagrangian = this->nlagrangian();
417  Vector<double> s(n_lagrangian);
418 
419  // Find the sub object containing zeta, and the local intrinsic coordinate
420  // within it
421  const_cast<MeshAsGeomObject*>(this)->locate_zeta(
422  zeta, sub_geom_object_pt, s);
423  if (sub_geom_object_pt == 0)
424  {
425  std::ostringstream error_message;
426  error_message << "Cannot locate zeta ";
427  for (unsigned i = 0; i < n_lagrangian; i++)
428  {
429  error_message << zeta[i] << " ";
430  }
431  error_message << std::endl;
432  Mesh_pt->output("most_recent_mesh.dat");
433  throw OomphLibError(error_message.str(),
436  }
437  // Call that sub-object's position function
438  sub_geom_object_pt->position(t, s, r);
439 
440  } // end of position
441 
443  void dposition(const Vector<double>& xi, DenseMatrix<double>& drdxi) const
444  {
445  throw OomphLibError("dposition() not implemented",
448  }
449  };
450 
451 } // namespace oomph
452 
453 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
NonRefineableBinArray class.
Definition: sample_point_container.h:819
RefineableBinArray class.
Definition: sample_point_container.h:521
Base class for all sample point containers.
Definition: sample_point_container.h:206
virtual void locate_zeta(const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s)=0
Definition: nodes.h:86
Definition: elements.h:1313
unsigned dim() const
Definition: elements.h:2611
Definition: geom_objects.h:101
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
void set_nlagrangian_and_ndim(const unsigned &n_lagrangian, const unsigned &n_dim)
Set # of Lagrangian and Eulerian coordinates.
Definition: geom_objects.h:183
unsigned nlagrangian() const
Access function to # of Lagrangian coordinates.
Definition: geom_objects.h:171
Definition: mesh_as_geometric_object.h:93
MeshAsGeomObject()
Empty Constructor.
Definition: mesh_as_geometric_object.h:336
unsigned Sample_point_container_version
Definition: mesh_as_geometric_object.h:284
unsigned sample_point_container_version() const
Definition: mesh_as_geometric_object.h:302
SamplePointContainer * Sample_point_container_pt
Pointer to the sample point container.
Definition: mesh_as_geometric_object.h:270
void build_it(SamplePointContainerParameters *sample_point_container_parameters_pt)
Helper function to actually build the thing.
Definition: mesh_as_geometric_object.h:96
unsigned nelement()
Number of elements in the underlying mesh.
Definition: mesh_as_geometric_object.h:308
void operator=(const MeshAsGeomObject &)=delete
Broken assignment operator.
unsigned ngeom_data() const
How many items of Data does the shape of the object depend on?
Definition: mesh_as_geometric_object.h:351
Vector< FiniteElement * > Sub_geom_object_pt
Internal storage for the elements that constitute the object.
Definition: mesh_as_geometric_object.h:267
FiniteElement * finite_element_pt(const unsigned &e)
Return pointer to e-th finite element.
Definition: mesh_as_geometric_object.h:294
MeshAsGeomObject(Mesh *const &mesh_pt)
Constructor.
Definition: mesh_as_geometric_object.h:314
~MeshAsGeomObject()
Destructor.
Definition: mesh_as_geometric_object.h:339
void locate_zeta(const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
Definition: mesh_as_geometric_object.h:373
Data * geom_data_pt(const unsigned &j)
Definition: mesh_as_geometric_object.h:358
MeshAsGeomObject(const MeshAsGeomObject &)=delete
Broken copy constructor.
MeshAsGeomObject(SamplePointContainerParameters *sample_point_container_parameters_pt)
Constructor.
Definition: mesh_as_geometric_object.h:328
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Definition: mesh_as_geometric_object.h:409
Mesh * Mesh_pt
Pointer to mesh.
Definition: mesh_as_geometric_object.h:280
void position(const Vector< double > &zeta, Vector< double > &r) const
Definition: mesh_as_geometric_object.h:397
SamplePointContainer * sample_point_container_pt() const
Pointer to the sample point container.
Definition: mesh_as_geometric_object.h:288
void dposition(const Vector< double > &xi, DenseMatrix< double > &drdxi) const
Return the derivative of the position.
Definition: mesh_as_geometric_object.h:443
Vector< Data * > Geom_data_pt
Vector of pointers to Data items that affects the object's shape.
Definition: mesh_as_geometric_object.h:264
Definition: mesh.h:67
bool is_mesh_distributed() const
Boolean to indicate if Mesh has been distributed.
Definition: mesh.h:1588
OomphCommunicator * communicator_pt() const
Definition: mesh.h:1600
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
Definition: mesh.h:448
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
void output(std::ostream &outfile)
Output for all elements.
Definition: mesh.cc:2027
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Definition: mesh.h:436
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:1054
Definition: sample_point_parameters.h:456
Definition: communicator.h:54
Definition: oomph_definitions.h:222
Definition: oomph_definitions.h:267
Definition: sample_point_parameters.h:322
Definition: sample_point_parameters.h:70
Mesh * mesh_pt() const
Pointer to mesh from whose FiniteElements sample points are created.
Definition: sample_point_parameters.h:92
RealScalar s
Definition: level1_cplx_impl.h:130
EIGEN_STRONG_INLINE const Eigen::CwiseBinaryOp< Eigen::internal::scalar_zeta_op< typename DerivedX::Scalar >, const DerivedX, const DerivedQ > zeta(const Eigen::ArrayBase< DerivedX > &x, const Eigen::ArrayBase< DerivedQ > &q)
Definition: SpecialFunctionsArrayAPI.h:152
r
Definition: UniformPSDSelfTest.py:20
unsigned Default_sample_point_container_version
Default sample point container type.
Definition: mesh_as_geometric_object.cc:58
void create_sample_point_container_parameters(Mesh *mesh_pt, SamplePointContainerParameters *&sample_point_container_parameters_pt)
Definition: mesh_as_geometric_object.cc:64
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
@ UseRefineableBinArray
Definition: sample_point_parameters.h:41
@ UseNonRefineableBinArray
Definition: sample_point_parameters.h:42
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
t
Definition: plotPSD.py:36
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2