hermite_elements.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 functions for classes that define Hermite elements
27 
28 // Include guards to prevent multiple inclusions of the header
29 #ifndef OOMPH_HERMITE_ELEMENT_HEADER
30 #define OOMPH_HERMITE_ELEMENT_HEADER
31 
32 // Config header generated by autoconfig
33 #ifdef HAVE_CONFIG_H
34 #include <oomph-lib-config.h>
35 #endif
36 
37 #ifdef OOMPH_HAS_MPI
38 #include "mpi.h"
39 #endif
40 
41 // oomph-lib headers
42 #include "Vector.h"
43 #include "shape.h"
44 #include "integral.h"
45 #include "elements.h"
46 #include "Qelements.h"
47 
48 
49 namespace oomph
50 {
51  //========================================================================
55  //========================================================================
57  {
58  public:
61 
64 
66  void operator=(const QHermiteElementBase&) = delete;
67  };
68 
69 
73 
74 
75  //=======================================================================
83  //=======================================================================
84  template<unsigned DIM>
85  class QHermiteElement : public virtual QHermiteElementBase
86  {
87  private:
90  // This is sort of optimal, because it means that the integration is exact
91  // for the shape functions. Can overwrite this in specific element
92  // definition.
93  // static Gauss_Rescaled<DIM,3> Default_integration_scheme;
95 
96  public:
99  {
100  // Calculate the number of nodes
101  unsigned n_node = static_cast<unsigned>(pow(2.0, static_cast<int>(DIM)));
102  // Set the number of nodes
103  this->set_n_node(n_node);
104  // Set the elemental and nodal dimensions
105  this->set_dimension(DIM);
106  // Set the number of interpolated position types (always n_node)
107  this->set_nnodal_position_type(n_node);
108  // Assign pointer to default integration scheme
109  this->set_integration_scheme(&Default_integration_scheme);
110  }
111 
112 
114  QHermiteElement(const QHermiteElement& dummy) = delete;
115 
117  void operator=(const QHermiteElement&) = delete;
118 
121  {
122  unsigned ncoord = dim();
123  for (unsigned i = 0; i < ncoord; i++)
124  {
125  // We're outside
126  if ((s[i] - s_max() > 0.0) || (s_min() - s[i] > 0.0))
127  {
128  return false;
129  }
130  }
131  return true;
132  }
133 
137  {
138  unsigned ncoord = dim();
139  for (unsigned i = 0; i < ncoord; i++)
140  {
141  // Adjust to move it onto the boundary
142  if (s[i] > s_max()) s[i] = s_max();
143  if (s[i] < s_min()) s[i] = s_min();
144  }
145  }
146 
149  void shape(const Vector<double>& s, Shape& psi) const;
150 
154  Shape& psi,
155  DShape& dpsids) const;
156 
175  Shape& psi,
176  DShape& dpsids,
177  DShape& d2psids) const;
178 
179 
184  DenseMatrix<double>& inverse_jacobian) const
185  {
186  return invert_jacobian<DIM>(jacobian, inverse_jacobian);
187  }
188 
193  const DenseMatrix<double>& jacobian,
194  const DenseMatrix<double>& inverse_jacobian,
195  const DenseMatrix<double>& jacobian2,
196  DShape& dbasis,
197  DShape& d2basis) const
198  {
199  transform_second_derivatives_template<DIM>(
200  jacobian, inverse_jacobian, jacobian2, dbasis, d2basis);
201  }
202 
204  double s_min() const
205  {
206  return -1.0;
207  }
208 
210  double s_max() const
211  {
212  return 1.0;
213  }
214 
215 
217  void local_coordinate_of_node(const unsigned& j, Vector<double>& s) const
218  {
219  s.resize(DIM);
220  Vector<unsigned> j_sub(DIM);
221  unsigned j_copy = j;
222  unsigned NNODE_1D = 2;
223  const double S_min = this->s_min();
224  const double S_range = this->s_max() - S_min;
225  for (unsigned i = 0; i < DIM; i++)
226  {
227  j_sub[i] = j_copy % NNODE_1D;
228  j_copy = (j_copy - j_sub[i]) / NNODE_1D;
229  s[i] = S_min + double(j_sub[i]) / (double)(NNODE_1D - 1) * S_range;
230  }
231  }
232 
234  void local_fraction_of_node(const unsigned& j, Vector<double>& s_fraction)
235  {
236  s_fraction.resize(DIM);
237  Vector<unsigned> j_sub(DIM);
238  unsigned j_copy = j;
239  unsigned NNODE_1D = 2;
240  for (unsigned i = 0; i < DIM; i++)
241  {
242  j_sub[i] = j_copy % NNODE_1D;
243  j_copy = (j_copy - j_sub[i]) / NNODE_1D;
244  s_fraction[i] = j_sub[i];
245  }
246  }
247 
250  double local_one_d_fraction_of_node(const unsigned& n1d, const unsigned& i)
251  {
252  // The spacing is just the node number because there are only two
253  // nodes
254  return n1d;
255  }
256 
258  unsigned nnode_1d() const
259  {
260  return 2;
261  }
262 
264  void output(std::ostream& outfile);
265 
267  void output(std::ostream& outfile, const unsigned& n_plot);
268 
270  void output(FILE* file_pt);
271 
273  void output(FILE* file_pt, const unsigned& n_plot);
274 
278  const unsigned& i,
279  const unsigned& nplot,
280  Vector<double>& s,
281  const bool& use_equally_spaced_interior_sample_points = false) const;
282 
285  std::string tecplot_zone_string(const unsigned& nplot) const;
286 
289  unsigned nplot_points(const unsigned& nplot) const;
290 
312  void build_face_element(const int& face_index,
313  FaceElement* face_element_pt);
314  };
315 
316  // Inline functions:
317  //=======================================================================
320  //=======================================================================
321  template<>
323  const unsigned& i,
324  const unsigned& nplot,
325  Vector<double>& s,
326  const bool& use_equally_spaced_interior_sample_points) const
327  {
328  if (nplot > 1)
329  {
330  s[0] = -1.0 + 2.0 * double(i) / double(nplot - 1);
331  if (use_equally_spaced_interior_sample_points)
332  {
333  double range = 2.0;
334  double dx_new = range / double(nplot);
335  double range_new = double(nplot - 1) * dx_new;
336  s[0] = -1.0 + 0.5 * dx_new + range_new * (1.0 + s[0]) / range;
337  }
338  }
339  else
340  {
341  s[0] = 0.0;
342  }
343  }
344 
345  //=======================================================================
348  //=======================================================================
349  template<>
351  const unsigned& nplot) const
352  {
353  std::ostringstream header;
354  header << "ZONE I=" << nplot << "\n";
355  return header.str();
356  }
357 
358  //========================================================================
361  //========================================================================
362  template<>
363  inline unsigned QHermiteElement<1>::nplot_points(const unsigned& nplot) const
364  {
365  return nplot;
366  }
367 
368 
369  //=======================================================================
372  //=======================================================================
373  template<>
375  const unsigned& i,
376  const unsigned& nplot,
377  Vector<double>& s,
378  const bool& use_equally_spaced_interior_sample_points) const
379  {
380  if (nplot > 1)
381  {
382  unsigned i0 = i % nplot;
383  unsigned i1 = (i - i0) / nplot;
384 
385  s[0] = -1.0 + 2.0 * double(i0) / double(nplot - 1);
386  s[1] = -1.0 + 2.0 * double(i1) / double(nplot - 1);
387 
388  if (use_equally_spaced_interior_sample_points)
389  {
390  double range = 2.0;
391  double dx_new = range / double(nplot);
392  double range_new = double(nplot - 1) * dx_new;
393  s[0] = -1.0 + 0.5 * dx_new + range_new * (1.0 + s[0]) / range;
394  s[1] = -1.0 + 0.5 * dx_new + range_new * (1.0 + s[1]) / range;
395  }
396  }
397  else
398  {
399  s[0] = 0.0;
400  s[1] = 0.0;
401  }
402  }
403 
404  //=======================================================================
407  //=======================================================================
408  template<>
410  const unsigned& nplot) const
411  {
412  std::ostringstream header;
413  header << "ZONE I=" << nplot << ", J=" << nplot << "\n";
414  return header.str();
415  }
416 
417  //=======================================================================
420  //=======================================================================
421  template<>
422  inline unsigned QHermiteElement<2>::nplot_points(const unsigned& nplot) const
423  {
424  return nplot * nplot;
425  }
426 
427  //=====================================================================
432  //=====================================================================
433  template<unsigned DIM>
434  class DiagQHermiteElement : public virtual QHermiteElement<DIM>
435  {
436  protected:
441  DenseMatrix<double>& inverse_jacobian) const
442  {
443  return FiniteElement::invert_jacobian<DIM>(jacobian, inverse_jacobian);
444  }
445 
449  const DShape& dpsids,
450  DenseMatrix<double>& jacobian,
451  DenseMatrix<double>& inverse_jacobian) const
452  {
454  dpsids, jacobian, inverse_jacobian);
455  }
456 
459  void transform_derivatives(const DenseMatrix<double>& inverse_jacobian,
460  DShape& dbasis) const
461  {
462  FiniteElement::transform_derivatives_diagonal(inverse_jacobian, dbasis);
463  }
464 
468  const DenseMatrix<double>& jacobian,
469  const DenseMatrix<double>& inverse_jacobian,
470  const DenseMatrix<double>& jacobian2,
471  DShape& dbasis,
472  DShape& d2basis) const
473  {
474  FiniteElement::transform_second_derivatives_diagonal<DIM>(
475  jacobian, inverse_jacobian, jacobian2, dbasis, d2basis);
476  }
477 
478 
479  public:
482 
484  DiagQHermiteElement(const DiagQHermiteElement& dummy) = delete;
485 
487  void operator=(const DiagQHermiteElement&) = delete;
488  };
489 
492 
493 
494  //=======================================================================
500  //=======================================================================
501  template<unsigned DIM>
502  class SolidQHermiteElement : public virtual QHermiteElement<DIM>,
503  public virtual SolidFiniteElement
504  {
505  public:
508  {
509  // Get the number of nodes (alloactaed in the QHermiteElement<DIM> class)
510  unsigned n_node = nnode();
511  // Set the lagrangian dimension
513  // Set the number of interpolated lagrangian types (always n_node)
514  this->set_nnodal_lagrangian_type(n_node);
515  }
516 
519 
521  void operator=(const SolidQHermiteElement&) = delete;
522 
524  void output(std::ostream& outfile);
525 
527  void output(std::ostream& outfile, const unsigned& n_plot);
528 
530  void output(FILE* file_pt);
531 
533  void output(FILE* file_pt, const unsigned& n_plot);
534 
556  void build_face_element(const int& face_index,
557  FaceElement* face_element_pt);
558  };
559 
560  //============================================================================
566  //============================================================================
567  template<unsigned DIM>
568  class SolidDiagQHermiteElement : public virtual DiagQHermiteElement<DIM>,
569  public virtual SolidQHermiteElement<DIM>
570  {
571  public:
575  {
576  }
577 
580 
582  void operator=(const SolidDiagQHermiteElement&) = delete;
583 
587  const DShape& dpsids,
588  DenseMatrix<double>& jacobian,
589  DenseMatrix<double>& inverse_jacobian) const
590  {
592  dpsids, jacobian, inverse_jacobian);
593  }
594  };
595 
596 } // namespace oomph
597 
598 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Definition: shape.h:278
Definition: hermite_elements.h:435
double invert_jacobian_mapping(const DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Definition: hermite_elements.h:440
double local_to_eulerian_mapping(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Definition: hermite_elements.h:448
DiagQHermiteElement()
Constructor.
Definition: hermite_elements.h:481
void operator=(const DiagQHermiteElement &)=delete
Broken assignment operator.
void transform_second_derivatives(const DenseMatrix< double > &jacobian, const DenseMatrix< double > &inverse_jacobian, const DenseMatrix< double > &jacobian2, DShape &dbasis, DShape &d2basis) const
Definition: hermite_elements.h:467
DiagQHermiteElement(const DiagQHermiteElement &dummy)=delete
Broken copy constructor.
void transform_derivatives(const DenseMatrix< double > &inverse_jacobian, DShape &dbasis) const
Definition: hermite_elements.h:459
Definition: elements.h:4338
void set_nnodal_position_type(const unsigned &nposition_type)
Set the number of types required to interpolate the coordinate.
Definition: elements.h:1396
void set_dimension(const unsigned &dim)
Definition: elements.h:1380
unsigned dim() const
Definition: elements.h:2611
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
void transform_derivatives_diagonal(const DenseMatrix< double > &inverse_jacobian, DShape &dbasis) const
Definition: elements.cc:2877
void set_n_node(const unsigned &n)
Definition: elements.h:1404
virtual void set_integration_scheme(Integral *const &integral_pt)
Set the spatial integration scheme.
Definition: elements.cc:3210
virtual double local_to_eulerian_mapping_diagonal(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Definition: elements.cc:2588
Definition: Qelements.h:64
Definition: hermite_elements.h:57
QHermiteElementBase()
Empty default constructor.
Definition: hermite_elements.h:60
void operator=(const QHermiteElementBase &)=delete
Broken assignment operator.
QHermiteElementBase(const QHermiteElementBase &)=delete
Broken copy constructor.
Definition: hermite_elements.h:86
double local_one_d_fraction_of_node(const unsigned &n1d, const unsigned &i)
Definition: hermite_elements.h:250
void shape(const Vector< double > &s, Shape &psi) const
void transform_second_derivatives(const DenseMatrix< double > &jacobian, const DenseMatrix< double > &inverse_jacobian, const DenseMatrix< double > &jacobian2, DShape &dbasis, DShape &d2basis) const
Definition: hermite_elements.h:192
void output(FILE *file_pt, const unsigned &n_plot)
C_style output at n_plot points.
double invert_jacobian_mapping(const DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Definition: hermite_elements.h:183
QHermiteElement()
Constructor.
Definition: hermite_elements.h:98
std::string tecplot_zone_string(const unsigned &nplot) const
bool local_coord_is_valid(const Vector< double > &s)
Check whether the local coordinate are valid or not.
Definition: hermite_elements.h:120
void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &use_equally_spaced_interior_sample_points=false) const
void move_local_coord_back_into_element(Vector< double > &s) const
Definition: hermite_elements.h:136
unsigned nnode_1d() const
Return number of nodes along each element edge.
Definition: hermite_elements.h:258
void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size.
Definition: hermite_elements.h:217
unsigned nplot_points(const unsigned &nplot) const
void operator=(const QHermiteElement &)=delete
Broken assignment operator.
static Gauss< DIM, 3 > Default_integration_scheme
Assign the static Default_integration_scheme.
Definition: hermite_elements.h:94
void local_fraction_of_node(const unsigned &j, Vector< double > &s_fraction)
Get local fraction of node j in the element; vector sets its own size.
Definition: hermite_elements.h:234
void build_face_element(const int &face_index, FaceElement *face_element_pt)
void output(std::ostream &outfile, const unsigned &n_plot)
Output at n_plot points.
void dshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
double s_min() const
Min. value of local coordinate.
Definition: hermite_elements.h:204
double s_max() const
Max. value of local coordinate.
Definition: hermite_elements.h:210
void output(FILE *file_pt)
C-style output.
void output(std::ostream &outfile)
Output.
void d2shape_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
QHermiteElement(const QHermiteElement &dummy)=delete
Broken copy constructor.
Definition: shape.h:76
Definition: hermite_elements.h:570
void operator=(const SolidDiagQHermiteElement &)=delete
Broken assignment operator.
double local_to_lagrangian_mapping(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Definition: hermite_elements.h:586
SolidDiagQHermiteElement()
Constructor.
Definition: hermite_elements.h:573
SolidDiagQHermiteElement(const SolidDiagQHermiteElement &dummy)=delete
Broken copy constructor.
Definition: elements.h:3561
void set_nnodal_lagrangian_type(const unsigned &nlagrangian_type)
Definition: elements.h:4070
virtual double local_to_lagrangian_mapping_diagonal(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Definition: elements.cc:6643
void set_lagrangian_dimension(const unsigned &lagrangian_dimension)
Definition: elements.h:3565
Definition: hermite_elements.h:504
void output(FILE *file_pt, const unsigned &n_plot)
C_style output at n_plot points.
SolidQHermiteElement(const SolidQHermiteElement &dummy)=delete
Broken copy constructor.
void build_face_element(const int &face_index, FaceElement *face_element_pt)
Definition: hermite_elements.cc:1270
void output(std::ostream &outfile)
Overload the output function.
Definition: hermite_elements.cc:1072
void operator=(const SolidQHermiteElement &)=delete
Broken assignment operator.
SolidQHermiteElement()
Constructor.
Definition: hermite_elements.h:507
void output(std::ostream &outfile, const unsigned &n_plot)
Output at n_plot points.
RealScalar s
Definition: level1_cplx_impl.h:130
#define DIM
Definition: linearised_navier_stokes_elements.h:44
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2