circular_shell_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_CIRCULAR_SHELL_MESH_TEMPLATE_CC
27 #define OOMPH_CIRCULAR_SHELL_MESH_TEMPLATE_CC
28 
29 #include <float.h>
30 
33 
34 
35 namespace oomph
36 {
37  //=======================================================================
38  /// Mesh build fct
39  //=======================================================================
40  template<class ELEMENT>
42  const unsigned& ny,
43  const double& lx,
44  const double& ly)
45  {
46  // Mesh can only be built with 2D Qelements.
47  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
48 
49  // Find out how many nodes there are
50  unsigned n_node = nnode();
51 
52  // Now in this case it is the Lagrangian coordinates that we want to set,
53  // so we have to loop over all nodes and set them to the Eulerian
54  // coordinates that are set by the generic mesh generator
55  for (unsigned i = 0; i < n_node; i++)
56  {
57  node_pt(i)->xi(0) = scaled_x(node_pt(i)->x(0));
58  node_pt(i)->xi(1) = node_pt(i)->x(1);
59  }
60 
61 
62  // Loop over elements and nodes to find out min axial spacing
63  // for all nodes
64 
65  // Initialise map
66  std::map<Node*, double> min_dx;
67  unsigned nnod = nnode();
68  for (unsigned j = 0; j < nnod; j++) min_dx[node_pt(j)] = DBL_MAX;
69 
70  // Loop over elements
71  unsigned nelem = nelement();
72  for (unsigned e = 0; e < nelem; e++)
73  {
74  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(element_pt(e));
75  unsigned n_node = el_pt->nnode();
76  for (unsigned j = 0; j < n_node; j++)
77  {
78  SolidNode* nod_pt = dynamic_cast<SolidNode*>(el_pt->node_pt(j));
79  double x = nod_pt->xi(0);
80  for (unsigned k = 0; k < n_node; k++)
81  {
82  double dx =
83  fabs(x - dynamic_cast<SolidNode*>(el_pt->node_pt(k))->xi(0));
84  if (dx < min_dx[nod_pt])
85  {
86  if (dx != 0.0) min_dx[nod_pt] = dx;
87  }
88  }
89  }
90  }
91 
92 
93  // Assign gradients, etc for the Lagrangian coordinates of
94  // Hermite-type elements
95 
96  // Read out number of position dofs
97  unsigned n_position_type = finite_element_pt(0)->nnodal_position_type();
98 
99  // Assign generalised Lagrangian positions (min slope, c.f. M. Heil's PhD
100  // thesis
101  if (n_position_type > 1)
102  {
103  // Default spacing
104  double xstep = (this->Xmax - this->Xmin) / ((this->Np - 1) * this->Nx);
105  double ystep = (this->Ymax - this->Ymin) / ((this->Np - 1) * this->Ny);
106 
107  // Adjust for non-uniform spacing
108  for (unsigned j = 0; j < n_node; j++)
109  {
110  SolidNode* nod_pt = node_pt(j);
111 
112  // Get min. spacing for non-uniform axial spacing
113  xstep = min_dx[nod_pt];
114 
115  // The factor 0.5 is because our reference element has length 2.0
116  nod_pt->xi_gen(1, 0) = 0.5 * xstep;
117  nod_pt->xi_gen(2, 1) = 0.5 * ystep;
118  }
119  }
120  }
121 
122 
123  //=======================================================================
124  /// Set the undeformed coordinates of the nodes
125  //=======================================================================
126  template<class ELEMENT>
128  GeomObject* const& undeformed_midplane_pt)
129  {
130  // Loop over nodes in elements
131  unsigned nelem = nelement();
132  for (unsigned e = 0; e < nelem; e++)
133  {
134  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(element_pt(e));
135  unsigned n_node = el_pt->nnode();
136  for (unsigned n = 0; n < n_node; n++)
137  {
138  // Get the Lagrangian coordinates
139  Vector<double> xi(2);
140  xi[0] = dynamic_cast<SolidNode*>(el_pt->node_pt(n))->xi(0);
141  xi[1] = dynamic_cast<SolidNode*>(el_pt->node_pt(n))->xi(1);
142 
143  // Assign memory for values of derivatives, etc
144  Vector<double> R(3);
145  DenseMatrix<double> a(2, 3);
146  RankThreeTensor<double> dadxi(2, 2, 3);
147 
148  // Get the geometrical information from the geometric object
149  undeformed_midplane_pt->d2position(xi, R, a, dadxi);
150 
151 
152  // Get derivatives of Lagr coordinates w.r.t. local coords
153  DenseMatrix<double> dxids(2, 2);
154  Vector<double> s(2);
155  el_pt->local_coordinate_of_node(n, s);
156  el_pt->interpolated_dxids(s, dxids);
157  double dxds = dxids(0, 0);
158 
159  // Loop over coordinate directions
160  for (unsigned i = 0; i < 3; i++)
161  {
162  // Set the position
163  el_pt->node_pt(n)->x_gen(0, i) = R[i];
164 
165  // Set generalised positions
166  el_pt->node_pt(n)->x_gen(1, i) = a(0, i) * dxds;
167  el_pt->node_pt(n)->x_gen(2, i) =
168  0.5 * a(1, i) * ((this->Ymax - this->Ymin) / this->Ny);
169 
170  // Set the mixed derivative
171  el_pt->node_pt(n)->x_gen(3, i) = 0.0;
172 
173  // Check for warping
174  if (dadxi(0, 1, i) != 0.0)
175  {
176  std::ostringstream error_stream;
177  error_stream
178  << "Undef. GeomObject for this shell mesh should not be warped!\n"
179  << "It may be possible to generalise the mesh generator to \n"
180  << "deal with this case -- feel free to have a go...\n";
181  throw OomphLibError(error_stream.str(),
182  OOMPH_CURRENT_FUNCTION,
183  OOMPH_EXCEPTION_LOCATION);
184  }
185  }
186  }
187  }
188  }
189 
190 
191 } // namespace oomph
192 
193 
194 // namespace oomph
195 // {
196 
197 
198 // //=======================================================================
199 // /// Mesh constructor
200 // /// Argument list:
201 // /// nx : number of elements in the axial direction
202 // /// ny : number of elements in the azimuthal direction
203 // /// lx : length in the axial direction
204 // /// ly : length in theta direction
205 // //=======================================================================
206 // template <class ELEMENT>
207 // CircularCylindricalShellMesh<ELEMENT>::CircularCylindricalShellMesh(
208 // const unsigned &nx,
209 // const unsigned &ny,
210 // const double &lx,
211 // const double &ly,
212 // TimeStepper* time_stepper_pt) :
213 // RectangularQuadMesh<ELEMENT>(nx,ny,lx,ly,time_stepper_pt)
214 // {
215 // //Find out how many nodes there are
216 // unsigned n_node = nnode();
217 
218 // //Now in this case it is the Lagrangian coordinates that we want to set,
219 // //so we have to loop over all nodes and set them to the Eulerian
220 // //coordinates that are set by the generic mesh generator
221 // for(unsigned i=0;i<n_node;i++)
222 // {
223 // node_pt(i)->xi(0) = node_pt(i)->x(0);
224 // node_pt(i)->xi(1) = node_pt(i)->x(1);
225 // }
226 
227 
228 // //Assign gradients, etc for the Lagrangian coordinates of
229 // //Hermite-type elements
230 
231 // //Read out number of position dofs
232 // unsigned n_position_type = finite_element_pt(0)->nnodal_position_type();
233 
234 // //If this is greater than 1 set the slopes, which are the distances between
235 // //nodes. If the spacing were non-uniform, this part would be more difficult
236 // if(n_position_type > 1)
237 // {
238 // double xstep = (this->Xmax - this->Xmin)/((this->Np-1)*this->Nx);
239 // double ystep = (this->Ymax - this->Ymin)/((this->Np-1)*this->Ny);
240 // for(unsigned n=0;n<n_node;n++)
241 // {
242 // //The factor 0.5 is because our reference element has length 2.0
243 // node_pt(n)->xi_gen(1,0) = 0.5*xstep;
244 // node_pt(n)->xi_gen(2,1) = 0.5*ystep;
245 // }
246 // }
247 // }
248 
249 
250 // //=======================================================================
251 // /// Set the undeformed coordinates of the nodes
252 // //=======================================================================
253 // template <class ELEMENT>
254 // void CircularCylindricalShellMesh<ELEMENT>::assign_undeformed_positions(
255 // GeomObject* const &undeformed_midplane_pt)
256 // {
257 // //Find out how many nodes there are
258 // unsigned n_node = nnode();
259 
260 // //Loop over all the nodes
261 // for(unsigned n=0;n<n_node;n++)
262 // {
263 // //Get the Lagrangian coordinates
264 // Vector<double> xi(2);
265 // xi[0] = node_pt(n)->xi(0);
266 // xi[1] = node_pt(n)->xi(1);
267 
268 // //Assign memory for values of derivatives, etc
269 // Vector<double> R(3);
270 // DenseMatrix<double> a(2,3);
271 // RankThreeTensor<double> dadxi(2,2,3);
272 
273 // //Get the geometrical information from the geometric object
274 // undeformed_midplane_pt->d2position(xi,R,a,dadxi);
275 
276 // //Loop over coordinate directions
277 // for(unsigned i=0;i<3;i++)
278 // {
279 // //Set the position
280 // node_pt(n)->x_gen(0,i) = R[i];
281 
282 // //Set the derivative wrt Lagrangian coordinates
283 // //Note that we need to scale by the length of each element here!!
284 // node_pt(n)->x_gen(1,i) = 0.5*a(0,i)*((this->Xmax -
285 // this->Xmin)/this->Nx); node_pt(n)->x_gen(2,i) = 0.5*a(1,i)*((this->Ymax
286 // - this->Ymin)/this->Ny);
287 
288 // //Set the mixed derivative
289 // //(symmetric so doesn't matter which one we use)
290 // node_pt(n)->x_gen(3,i) = 0.25*dadxi(0,1,i);
291 // }
292 // }
293 // }
294 
295 
296 // }
297 #endif
e
Definition: cfortran.h:571
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
void build_mesh(const unsigned &nx, const unsigned &ny, const double &lx, const double &ly)
Mesh build helper fct.
void assign_undeformed_positions(GeomObject *const &undeformed_midplane_pt)
In all elastic problems, the nodes must be assigned an undeformed, or reference, position,...
/////////////////////////////////////////////////////////////////////
Definition: geom_objects.h:101
virtual void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
2nd derivative of position Vector w.r.t. to coordinates: = ddrdzeta(alpha,beta,i)....
Definition: geom_objects.h:341
An OomphLibError object which should be thrown when an run-time error is encountered....
////////////////////////////////////////////////////////////////// //////////////////////////////////...
Definition: matrices.h:1370
A Class for nodes that deform elastically (i.e. position is an unknown in the problem)....
Definition: nodes.h:1686
double & xi_gen(const unsigned &k, const unsigned &i)
Reference to the generalised Lagrangian position. ‘Type’: k; 'Coordinate direction: i.
Definition: nodes.h:1902
double & xi(const unsigned &i)
Reference to i-th Lagrangian position.
Definition: nodes.h:1883
//////////////////////////////////////////////////////////////////// ////////////////////////////////...