one_d_lagrangian_mesh.template.cc
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-2023 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 #ifndef OOMPH_ONE_D_LAGRANGIAN_MESH_TEMPLATE_CC
27 #define OOMPH_ONE_D_LAGRANGIAN_MESH_TEMPLATE_CC
28 
29 // The templated member functions of OneDLagrangianMesh
31 
32 // Include the templated member functions of the OneDMesh
33 #include "one_d_mesh.template.cc"
34 
35 
36 namespace oomph
37 {
38  //=======================================================================
39  /// Constructor for 1D mesh:
40  /// n_element : number of elements
41  /// length : length of domain
42  /// undef_eulerian_posn_pt: pointer to geom object that describes
43  /// the initial Eulerian position of the mesh.
44  /// time_stepper_pt : timestepper
45  //=======================================================================
46  template<class ELEMENT>
48  const unsigned& n_element,
49  const double& length,
50  GeomObject* undef_eulerian_posn_pt,
51  TimeStepper* time_stepper_pt)
52  : OneDMesh<ELEMENT>(n_element, length, time_stepper_pt),
53  Undef_eulerian_posn_pt(undef_eulerian_posn_pt)
54  {
55  // Mesh can only be built with 1D Qelements.
56  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(1);
57 
58  // Now set the lagrangian coordinates of the nodes
59  set_lagrangian_nodal_coordinates();
60 
61  // Set the default slopes
63 
64  // Now set up the Eulerian position of the nodal points
66  }
67 
68  //==================================================
69  /// Constructor for 1D mesh:
70  /// n_element : number of elements
71  /// xmin : minimum coordinate value (LH end)
72  /// xmax : maximum coordinate value (RH end)
73  /// undef_eulerian_posn_pt: pointer to geom object that describes
74  /// the initial Eulerian position of the mesh.
75  /// time_stepper_pt : timestepper
76  //==================================================
77  template<class ELEMENT>
79  const unsigned& n_element,
80  const double& xmin,
81  const double& xmax,
82  GeomObject* undef_eulerian_posn_pt,
83  TimeStepper* time_stepper_pt)
84  : OneDMesh<ELEMENT>(n_element, xmin, xmax, time_stepper_pt),
85  Undef_eulerian_posn_pt(undef_eulerian_posn_pt)
86  {
87  // Mesh can only be built with 1D Qelements.
88  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(1);
89 
90  // Now set the lagrangian coordinates of the nodes
91  set_lagrangian_nodal_coordinates();
92 
93  // Set the default slopes
95 
96  // Now set up the Eulerian position of the nodal points
98  }
99 
100 
101  //=====================================================================
102  /// Set the default (initial) gradients within each element, which
103  /// are merely the distances between the nodes, scaled by 0.5 because
104  /// the elements have length 2 in local coordinates.
105  /// N.B. This only works for QHermiteElements at the moment
106  //=====================================================================
107  template<class ELEMENT>
109  {
110  // Find cast pointer to first element
111  ELEMENT* cast_element_pt = dynamic_cast<ELEMENT*>(finite_element_pt(0));
112  // Do we need to worry about the slopes
113  // Read out number of position dofs
114  unsigned n_lagrangian_type = cast_element_pt->nnodal_lagrangian_type();
115 
116  // If this is greater than 1 set the slopes, which are the distances between
117  // nodes
118  if (n_lagrangian_type > 1)
119  {
120  // Read out the number of linear points in the element
121  unsigned n_p = cast_element_pt->nnode_1d();
122  // Set the values of the distance between each node
123  double xstep =
124  OneDMesh<ELEMENT>::Length / double((n_p - 1) * OneDMesh<ELEMENT>::N);
125  // Loop over the nodes and set the slopes
126  unsigned long n_node = nnode();
127  for (unsigned long n = 0; n < n_node; n++)
128  {
129  node_pt(n)->xi_gen(1, 0) = 0.5 * xstep;
130  }
131  }
132  }
133 
134  //======================================================================
135  /// Set the initial (2D Eulerian!) positions of the nodes
136  //======================================================================
137  template<class ELEMENT>
139  {
140  // Lagrangian coordinate
141  Vector<double> xi(1);
142 
143  // Find the number Eulerian coordinates, assume same for all nodes
144  unsigned n_dim = node_pt(0)->ndim();
145 
146  // Find cast pointer to first element
147  ELEMENT* cast_element_pt = dynamic_cast<ELEMENT*>(finite_element_pt(0));
148 
149  // Do we need to worry about the slopes
150  // Read out number of position dofs
151  unsigned n_lagrangian_type = cast_element_pt->nnodal_lagrangian_type();
152 
153  // Setup position Vector and derivatives (they *should* dimension themselves
154  // in call to position() etc)
155  Vector<double> R(n_dim);
156  // Derivative wrt Lagrangian coordinate
157  DenseMatrix<double> a(1, n_dim);
158  // Second derivative wrt Lagrangian coordinate
159  RankThreeTensor<double> dadxi(1, 1, n_dim);
160 
161  // Find out how many nodes there are
162  unsigned long n_node = nnode();
163 
164  // Loop over all the nodes
165  for (unsigned long n = 0; n < n_node; n++)
166  {
167  // Lagrangian coordinate of node
168  xi[0] = node_pt(n)->xi(0);
169 
170  // Get the undeformed midplane
171  Undef_eulerian_posn_pt->d2position(xi, R, a, dadxi);
172 
173  // Loop over coordinate directions
174  for (unsigned i = 0; i < n_dim; i++)
175  {
176  // Set the position
177  node_pt(n)->x_gen(0, i) = R[i];
178 
179  if (n_lagrangian_type > 1)
180  {
181  // Set the derivative wrt Lagrangian coordinates
182  // Note that we need to scale by the length of each element here!!
183  // and the 0.5 comes from the fact that our reference element has
184  // length 2.0
185  node_pt(n)->x_gen(1, i) =
186  0.5 * a(0, i) *
188  }
189  }
190  }
191  }
192 
193 
194 } // namespace oomph
195 #endif
void assign_undeformed_positions()
Assign the undeformed Eulerian positions to the nodes.
OneDLagrangianMesh(const unsigned &n_element, const double &length, GeomObject *undef_eulerian_posn_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements, length, pointer to GeomObject that defines the undeformed Euler...
void assign_default_element_gradients()
Set the default gradients of the elements.
1D mesh consisting of N one-dimensional elements from the QElement family.
////////////////////////////////////////////////////////////////////// //////////////////////////////...