time_harmonic_elastic_annulus.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 // Time-harmonic deformation of an elastic annulus subject to
27 // displacement and pressure
28 
29 //Oomph-lib includes
30 #include "generic.h"
31 #include "time_harmonic_linear_elasticity.h"
32 #include "oomph_crbond_bessel.h"
33 
34 //The meshes
35 #include "meshes/annular_mesh.h"
36 
37 using namespace std;
38 using namespace oomph;
39 
40 
41 /// ///////////////////////////////////////////////////////////////////
42 /// ///////////////////////////////////////////////////////////////////
43 /// ///////////////////////////////////////////////////////////////////
44 
45 
46 //=======start_namespace==========================================
47 /// Global variables
48 //================================================================
50 {
51 
52  /// Poisson's ratio
53  double Nu = 0.3;
54 
55  /// Square of non-dim frequency
56  double Omega_sq=100.0;
57 
58  /// The elasticity tensor
59  TimeHarmonicIsotropicElasticityTensor E(Nu);
60 
61  /// Thickness of annulus
62  double H_annulus=0.5;
63 
64  /// Displacement amplitude on inner radius
66 
67  /// Real-valued, radial displacement field on inner boundary
68  void solid_boundary_displacement(const Vector<double>& x,
69  Vector<double>& u)
70  {
71  Vector<double> normal(2);
72  double norm=sqrt(x[0]*x[0]+x[1]*x[1]);
73  normal[0]=x[0]/norm;
74  normal[1]=x[1]/norm;
75 
76  u[0]=Displacement_amplitude*normal[0];
77  u[1]=Displacement_amplitude*normal[1];
78  }
79 
80  /// Uniform pressure
81  double P = 0.0;
82 
83  /// Constant pressure load (real and imag part)
84  void constant_pressure(const Vector<double> &x,
85  const Vector<double> &n,
86  Vector<std::complex<double> >&traction)
87  {
88  unsigned dim = traction.size();
89  for(unsigned i=0;i<dim;i++)
90  {
91  traction[i] = complex<double>(-P*n[i],P*n[i]);
92  }
93  } // end_of_pressure_load
94 
95 
96  /// Output directory
97  string Directory="RESLT";
98 
99  /// Number of elements in azimuthal direction
100  unsigned Ntheta=20;
101 
102  /// Number of elements in radial direction
103  unsigned Nr=10;
104 
105  /// Helper function to evaluate Y_n(x) from bloody maple output
106  double BesselY(const double& n, const double& x)
107  {
108  // Bessel fcts J_0(x), J_1(x), Y_0(x), Y_1(x) and their derivatives
109  double j0,j1,y0,y1,j0p,j1p,y0p,y1p;
110  CRBond_Bessel::bessjy01a(x,j0,j1,y0,y1,j0p,j1p,y0p,y1p);
111 
112  if (n==0.0)
113  {
114  return y0;
115  }
116  else if (n==1.0)
117  {
118  return y1;
119  }
120  else
121  {
122  cout << "Never get here...";
123  abort();
124  }
125 
126  }
127 
128 
129  /// Helper function to evaluate J_n(x) from bloody maple output
130  double BesselJ(const double& n, const double& x)
131  {
132 
133  // Bessel fcts J_0(x), J_1(x), Y_0(x), Y_1(x) and their derivatives
134  double j0,j1,y0,y1,j0p,j1p,y0p,y1p;
135  CRBond_Bessel::bessjy01a(x,j0,j1,y0,y1,j0p,j1p,y0p,y1p);
136 
137  if (n==0.0)
138  {
139  return j0;
140  }
141  else if (n==1.0)
142  {
143  return j1;
144  }
145  else
146  {
147  cout << "Never get here...";
148  abort();
149  }
150  }
151 
152  /// Exact solution as a Vector
153  void exact_u(const Vector<double>& x, Vector<double>& u)
154  {
155  double r=sqrt(x[0]*x[0]+x[1]*x[1]);
156 
157  double MapleGenVar1;
158  double MapleGenVar2;
159  double MapleGenVar3;
160  double MapleGenVar4;
161  double MapleGenVar5;
162  double MapleGenVar6;
163  double MapleGenVar7;
164  double t0;
165 
166  double omega=sqrt(Omega_sq);
167 
168  MapleGenVar3 = Displacement_amplitude*Nu*omega*BesselY(0.0,omega/sqrt(Nu/
169 (1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))+Displacement_amplitude
170 *Nu*omega*BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(
171 1.0+H_annulus))*H_annulus-Displacement_amplitude*BesselY(0.0,omega/sqrt(Nu/(1.0
172 +Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega-
173 Displacement_amplitude*BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0
174 +2.0*Nu))*(1.0+H_annulus))*omega*H_annulus+Displacement_amplitude*sqrt(-(1.0-Nu
175 )/(-1.0+Nu+2.0*Nu*Nu))*BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0
176 +2.0*Nu))*(1.0+H_annulus))-2.0*Displacement_amplitude*sqrt(-(1.0-Nu)/(-1.0+Nu+
177 2.0*Nu*Nu))*BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(
178 1.0+H_annulus))*Nu;
179  MapleGenVar2 = MapleGenVar3-BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
180 Nu)+2.0/(2.0+2.0*Nu)))*P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))-BesselY(1.0,omega/
181 sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))*P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*
182 Nu*Nu))*H_annulus+BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*
183 Nu)))*P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*Nu+BesselY(1.0,omega/sqrt(Nu/(1.0+
184 Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))*P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*Nu*
185 H_annulus+2.0*BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))
186 )*P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*Nu*Nu+2.0*BesselY(1.0,omega/sqrt(Nu/(
187 1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))*P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*
188 Nu*Nu*H_annulus;
189  MapleGenVar7 = Nu*omega*BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+
190 2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
191 Nu)+2.0/(2.0+2.0*Nu)))+Nu*omega*BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)
192 +2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*H_annulus*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu
193 )/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))-BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
194 Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)
195 /(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)));
196  MapleGenVar6 = MapleGenVar7-BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
197 Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*H_annulus*BesselJ(1.0,omega/sqrt(
198 Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))
199 *BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+
200 H_annulus))*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))
201 -2.0*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(
202 1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*Nu*BesselJ(1.0,omega/sqrt(Nu/(
203 1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)));
204  MapleGenVar7 = MapleGenVar6+BesselJ(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
205 Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)
206 /(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+BesselJ(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu
207 )+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*H_annulus*BesselY(1.0,omega/sqrt(Nu/
208 (1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)));
209  MapleGenVar5 = MapleGenVar7-sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*BesselJ(
210 1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*
211 BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))-Nu*omega*
212 BesselJ(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+
213 H_annulus))*BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+
214 2.0*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0
215 -2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*Nu*BesselY(1.0,omega/sqrt(Nu/(1.0+
216 Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))-Nu*omega*BesselJ(0.0,omega/sqrt(Nu/(1.0+Nu)
217 /(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*H_annulus*BesselY(1.0,omega/
218 sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)));
219  MapleGenVar4 = 1/MapleGenVar5;
220  MapleGenVar5 = BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+
221 2.0*Nu))*r);
222  MapleGenVar3 = MapleGenVar4*MapleGenVar5;
223  MapleGenVar1 = MapleGenVar2*MapleGenVar3;
224  MapleGenVar6 = -Nu*omega*BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+
225 2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
226 Nu)+2.0/(2.0+2.0*Nu)))-Nu*omega*BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)
227 +2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*H_annulus*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu
228 )/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
229 Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)
230 /(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)));
231  MapleGenVar5 = MapleGenVar6+BesselY(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
232 Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*H_annulus*BesselJ(1.0,omega/sqrt(
233 Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))-sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))
234 *BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+
235 H_annulus))*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+
236 2.0*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0
237 -2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*Nu*BesselJ(1.0,omega/sqrt(Nu/(1.0+
238 Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)));
239  MapleGenVar6 = MapleGenVar5-BesselJ(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
240 Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)
241 /(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))-BesselJ(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu
242 )+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*H_annulus*BesselY(1.0,omega/sqrt(Nu/
243 (1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)));
244  MapleGenVar4 = MapleGenVar6+sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*BesselJ(
245 1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*
246 BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+Nu*omega*
247 BesselJ(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+
248 H_annulus))*BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))
249 -2.0*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(
250 1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*Nu*BesselY(1.0,omega/sqrt(Nu/(
251 1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+Nu*omega*BesselJ(0.0,omega/sqrt(Nu/(1.0
252 +Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*H_annulus*BesselY(1.0,
253 omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)));
254  MapleGenVar3 = 1/MapleGenVar4;
255  MapleGenVar6 = -P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*BesselJ(1.0,omega/
256 sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))-P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*
257 Nu*Nu))*H_annulus*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*
258 Nu)))+P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*Nu*BesselJ(1.0,omega/sqrt(Nu/(1.0+
259 Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*Nu*
260 H_annulus*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+
261 2.0*P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*Nu*Nu*BesselJ(1.0,omega/sqrt(Nu/(1.0+
262 Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu)))+2.0*P*sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*
263 Nu*Nu*H_annulus*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu
264 )));
265  MapleGenVar7 = MapleGenVar6-BesselJ(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*
266 Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*Displacement_amplitude-BesselJ(0.0
267 ,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*omega*
269  MapleGenVar5 = MapleGenVar7+sqrt(-(1.0-Nu)/(-1.0+Nu+2.0*Nu*Nu))*BesselJ(
270 1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*
271 Displacement_amplitude+Nu*omega*BesselJ(0.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)
272 +2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*Displacement_amplitude-2.0*sqrt(-(1.0-Nu)/(
273 -1.0+Nu+2.0*Nu*Nu))*BesselJ(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+
274 2.0*Nu))*(1.0+H_annulus))*Nu*Displacement_amplitude+Nu*omega*BesselJ(0.0,omega/
275 sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+2.0*Nu))*(1.0+H_annulus))*H_annulus*
277  MapleGenVar6 = BesselY(1.0,omega/sqrt(Nu/(1.0+Nu)/(1.0-2.0*Nu)+2.0/(2.0+
278 2.0*Nu))*r);
279  MapleGenVar4 = MapleGenVar5*MapleGenVar6;
280  MapleGenVar2 = MapleGenVar3*MapleGenVar4;
281  t0 = MapleGenVar1+MapleGenVar2;
282 
283 
284  u[0]=t0*x[0]/r;
285  u[1]=t0*x[1]/r;
286 
287  u[2]=-t0*x[0]/r;
288  u[3]=-t0*x[1]/r;
289 
290  }
291 
292 } //end namespace
293 
294 
295 
296 //=============begin_problem============================================
297 /// Annular disk
298 //======================================================================
299 template<class ELASTICITY_ELEMENT>
300 class AnnularDiskProblem : public Problem
301 {
302 
303 public:
304 
305  /// Constructor:
307 
308  /// Update function (empty)
310 
311  /// Update function (empty)
313 
314  /// Actions before adapt: Wipe the mesh of traction elements
315  void actions_before_adapt();
316 
317  /// Actions after adapt: Rebuild the mesh of traction elements
318  void actions_after_adapt();
319 
320  /// Doc the solution
321  void doc_solution();
322 
323 private:
324 
325  /// Create traction elements
326  void create_traction_elements();
327 
328  /// Delete traction elements
329  void delete_traction_elements();
330 
331 #ifdef ADAPTIVE
332 
333  /// Pointer to refineable solid mesh
334  TreeBasedRefineableMeshBase* Solid_mesh_pt;
335 
336 #else
337 
338  /// Pointer to solid mesh
340 
341 #endif
342 
343  /// Pointer to mesh of traction elements
345 
346  /// DocInfo object for output
347  DocInfo Doc_info;
348 
349 };
350 
351 
352 //===========start_of_constructor=======================================
353 /// Constructor:
354 //======================================================================
355 template<class ELASTICITY_ELEMENT>
357 {
358 
359  // Solid mesh
360  //-----------
361 
362  // The mesh is periodic
363  bool periodic=true;
364 
365  // Azimuthal fraction of elastic coating
366  double azimuthal_fraction_of_coating=1.0;
367 
368  // Innermost radius for solid mesh
369  double a=1.0;
370 
371  // Gap in annulus?
372  if (CommandLineArgs::command_line_flag_has_been_set("--have_gap"))
373  {
374  periodic=false;
375  azimuthal_fraction_of_coating=0.9;
376  }
377 
378 #ifdef ADAPTIVE
379 
380  // Build solid mesh
381  Solid_mesh_pt = new
382  RefineableTwoDAnnularMesh<ELASTICITY_ELEMENT>(
383  periodic,azimuthal_fraction_of_coating,
387 
388  // Set error estimators
389  Solid_mesh_pt->spatial_error_estimator_pt()=new Z2ErrorEstimator;
390 
391  // Set some refinement targets
392  Solid_mesh_pt->max_refinement_level()=2;
393 
394 #else
395 
396  // Build solid mesh
397  Solid_mesh_pt = new
398  TwoDAnnularMesh<ELASTICITY_ELEMENT>(
399  periodic,azimuthal_fraction_of_coating,
403 
404 #endif
405 
406  // Let's have a look where the boundaries are
407  Solid_mesh_pt->output("solid_mesh.dat");
408  Solid_mesh_pt->output_boundaries("solid_mesh_boundary.dat");
409 
410 
411  //Assign the physical properties to the elements
412  //Loop over the elements in the main mesh
413  unsigned n_element =Solid_mesh_pt->nelement();
414  for(unsigned i=0;i<n_element;i++)
415  {
416  //Cast to a solid element
417  ELASTICITY_ELEMENT *el_pt =
418  dynamic_cast<ELASTICITY_ELEMENT*>(Solid_mesh_pt->element_pt(i));
419 
420  // Set the constitutive law
421  el_pt->elasticity_tensor_pt() = &Global_Parameters::E;
422 
423  // Square of non-dim frequency
424  el_pt->omega_sq_pt()= &Global_Parameters::Omega_sq;
425  }
426 
427  // Construct the traction element mesh
428  Traction_mesh_pt=new Mesh;
429  create_traction_elements();
430 
431  // Solid mesh is first sub-mesh
432  add_sub_mesh(Solid_mesh_pt);
433 
434  // Add traction sub-mesh
435  add_sub_mesh(Traction_mesh_pt);
436 
437  // Build combined "global" mesh
438  build_global_mesh();
439 
440  // Solid boundary conditions:
441  //---------------------------
442 
443  // Pin real and imag part of both displacement components
444  // on the inner (boundary 0)
445  unsigned b_inner=0;
446  unsigned n_node = Solid_mesh_pt->nboundary_node(b_inner);
447 
448  //Loop over the nodes to pin and assign boundary displacements on
449  //solid boundary
450  Vector<double> u(2);
451  Vector<double> x(2);
452  for(unsigned i=0;i<n_node;i++)
453  {
454  Node* nod_pt=Solid_mesh_pt->boundary_node_pt(b_inner,i);
455  nod_pt->pin(0);
456  nod_pt->pin(1);
457  nod_pt->pin(2);
458  nod_pt->pin(3);
459 
460  // Assign displacements
461  x[0]=nod_pt->x(0);
462  x[1]=nod_pt->x(1);
464 
465  // Real part of x-displacement
466  nod_pt->set_value(0,u[0]);
467  // Real part of y-displacement
468  nod_pt->set_value(1,u[1]);
469  // Imag part of x-displacement
470  nod_pt->set_value(2,-u[0]);
471  // Imag part of y-displacement
472  nod_pt->set_value(3,-u[1]);
473  }
474 
475  //Assign equation numbers
476  cout << assign_eqn_numbers() << std::endl;
477 
478  // Set output directory
479  Doc_info.set_directory(Global_Parameters::Directory);
480 
481 } //end_of_constructor
482 
483 
484 
485 
486 //=====================start_of_actions_before_adapt======================
487 /// Actions before adapt: Wipe the mesh of traction elements
488 //========================================================================
489 template<class ELASTICITY_ELEMENT>
491 {
492  // Kill the traction elements and wipe surface mesh
493  delete_traction_elements();
494 
495  // Rebuild the Problem's global mesh from its various sub-meshes
496  rebuild_global_mesh();
497 
498 }// end of actions_before_adapt
499 
500 
501 
502 //=====================start_of_actions_after_adapt=======================
503 /// Actions after adapt: Rebuild the mesh of traction elements
504 //========================================================================
505 template<class ELASTICITY_ELEMENT>
507 {
508  // Create traction elements from all elements that are
509  // adjacent to FSI boundaries and add them to surface meshes
510  create_traction_elements();
511 
512  // Rebuild the Problem's global mesh from its various sub-meshes
513  rebuild_global_mesh();
514 
515 }// end of actions_after_adapt
516 
517 
518 //============start_of_create_traction_elements==============================
519 /// Create traction elements
520 //=======================================================================
521 template<class ELASTICITY_ELEMENT>
523 {
524 
525  // Load outer surface (2) and both "ends" (1 and 3) if there's a gap
526  unsigned b_lo=1;
527  unsigned b_hi=3;
528 
529  // ...otherwise load only the outside (2)
530  if (!CommandLineArgs::command_line_flag_has_been_set("--have_gap"))
531  {
532  b_lo=2;
533  b_hi=2;
534  }
535 
536  for (unsigned b=b_lo;b<=b_hi;b++)
537  {
538  // How many bulk elements are adjacent to boundary b?
539  unsigned n_element = Solid_mesh_pt->nboundary_element(b);
540 
541  // Loop over the bulk elements adjacent to boundary b
542  for(unsigned e=0;e<n_element;e++)
543  {
544  // Get pointer to the bulk element that is adjacent to boundary b
545  ELASTICITY_ELEMENT* bulk_elem_pt = dynamic_cast<ELASTICITY_ELEMENT*>(
546  Solid_mesh_pt->boundary_element_pt(b,e));
547 
548  //Find the index of the face of element e along boundary b
549  int face_index = Solid_mesh_pt->face_index_at_boundary(b,e);
550 
551  // Create element
552  TimeHarmonicLinearElasticityTractionElement<ELASTICITY_ELEMENT>* el_pt=
553  new TimeHarmonicLinearElasticityTractionElement<ELASTICITY_ELEMENT>
554  (bulk_elem_pt,face_index);
555 
556  // Add to mesh
557  Traction_mesh_pt->add_element_pt(el_pt);
558 
559  // Associate element with bulk boundary (to allow it to access
560  // the boundary coordinates in the bulk mesh)
561  el_pt->set_boundary_number_in_bulk_mesh(b);
562 
563  //Set the traction function
564  el_pt->traction_fct_pt() = Global_Parameters::constant_pressure;
565  }
566  }
567 
568 } // end_of_create_traction_elements
569 
570 
571 
572 
573 //============start_of_delete_traction_elements==============================
574 /// Delete traction elements and wipe the traction meshes
575 //=======================================================================
576 template<class ELASTICITY_ELEMENT>
578 {
579  // How many surface elements are in the surface mesh
580  unsigned n_element = Traction_mesh_pt->nelement();
581 
582  // Loop over the surface elements
583  for(unsigned e=0;e<n_element;e++)
584  {
585  // Kill surface element
586  delete Traction_mesh_pt->element_pt(e);
587  }
588 
589  // Wipe the mesh
590  Traction_mesh_pt->flush_element_and_node_storage();
591 
592 } // end of delete_traction_elements
593 
594 
595 
596 
597 
598 //==============start_doc===========================================
599 /// Doc the solution
600 //==================================================================
601 template<class ELASTICITY_ELEMENT>
603 {
604 
605  ofstream some_file;
606  char filename[100];
607 
608  // Number of plot points
609  unsigned n_plot=5;
610 
611  // Output displacement field
612  //--------------------------
613  sprintf(filename,"%s/elast_soln%i.dat",Doc_info.directory().c_str(),
614  Doc_info.number());
615  some_file.open(filename);
616  Solid_mesh_pt->output(some_file,n_plot);
617  some_file.close();
618 
619 
620  // Output traction elements
621  //-------------------------
622  sprintf(filename,"%s/traction_soln%i.dat",Doc_info.directory().c_str(),
623  Doc_info.number());
624  some_file.open(filename);
625  Traction_mesh_pt->output(some_file,n_plot);
626  some_file.close();
627 
628  // Output exact solution
629  //----------------------
630  sprintf(filename,"%s/exact_soln%i.dat",Doc_info.directory().c_str(),
631  Doc_info.number());
632  some_file.open(filename);
633  Solid_mesh_pt->output_fct(some_file,n_plot,Global_Parameters::exact_u);
634  some_file.close();
635 
636  // Increment label for output files
637  Doc_info.number()++;
638 
639 } //end doc
640 
641 
642 
643 //=======start_of_main==================================================
644 /// Driver for annular disk loaded by pressure
645 //======================================================================
646 int main(int argc, char **argv)
647 {
648 
649  // Store command line arguments
650  CommandLineArgs::setup(argc,argv);
651 
652  // Define possible command line arguments and parse the ones that
653  // were actually specified
654 
655  // Number of elements in azimuthal direction
656  CommandLineArgs::specify_command_line_flag(
657  "--ntheta",
659 
660  // Number of elements in radial direction
661  CommandLineArgs::specify_command_line_flag(
662  "--nr",
664 
665  // Do have a gap in the annulus?
666  CommandLineArgs::specify_command_line_flag("--have_gap");
667 
668 #ifdef ADAPTIVE
669 
670  // Max. number of adaptations
671  unsigned max_adapt=3;
672  CommandLineArgs::specify_command_line_flag("--max_adapt",&max_adapt);
673 
674  // Number of uniform refinements
675  unsigned nrefine=0;
676  CommandLineArgs::specify_command_line_flag("--nrefine",&nrefine);
677 
678 #endif
679 
680  // P increment
681  double p_increment=0.1;
682  CommandLineArgs::specify_command_line_flag("--p_increment",&p_increment);
683 
684  // Number of steps
685  unsigned nstep=3;
686  CommandLineArgs::specify_command_line_flag("--nstep",&nstep);
687 
688  // Parse command line
689  CommandLineArgs::parse_and_assign();
690 
691  // Doc what has actually been specified on the command line
692  CommandLineArgs::doc_specified_flags();
693 
694 #ifdef ADAPTIVE
695 
696  //Set up the problem
698  problem;
699 
700  // Refine unformly
701  for (unsigned i=0;i<nrefine;i++)
702  {
703  problem.refine_uniformly();
704  }
705 
706 #else
707 
708  //Set up the problem
710 
711 #endif
712 
713 
714  // Initial values for parameter values
716 
717  //Parameter incrementation
718  for(unsigned i=0;i<nstep;i++)
719  {
720 
721 #ifdef ADAPTIVE
722 
723  // Solve the problem with Newton's method, allowing
724  // up to max_adapt mesh adaptations after every solve.
725  problem.newton_solve(max_adapt);
726 
727 #else
728 
729  // Solve the problem using Newton's method
730  problem.newton_solve();
731 
732 #endif
733 
734  // Doc solution
735  problem.doc_solution();
736 
737  // Increment pressure
738  Global_Parameters::P+=p_increment;
739  }
740 
741 } //end of main
742 
743 
744 
745 
746 
747 
748 
749 
void actions_before_newton_solve()
Update function (empty)
Mesh * Solid_mesh_pt
Pointer to solid mesh.
void actions_after_newton_solve()
Update function (empty)
void actions_after_adapt()
Actions after adapt: Rebuild the mesh of traction elements.
TreeBasedRefineableMeshBase * Solid_mesh_pt
Pointer to refineable solid mesh.
void doc_solution()
Doc the solution.
void actions_before_adapt()
Actions before adapt: Wipe the mesh of traction elements.
DocInfo Doc_info
DocInfo object for output.
Mesh * Traction_mesh_pt
Pointer to mesh of traction elements.
void delete_traction_elements()
Delete traction elements.
void create_traction_elements()
Create traction elements.
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
double Displacement_amplitude
Displacement amplitude on inner radius.
double H_annulus
Thickness of annulus.
unsigned Ntheta
Number of elements in azimuthal direction.
string Directory
Output directory.
double P
Uniform pressure.
double BesselY(const double &n, const double &x)
Helper function to evaluate Y_n(x) from bloody maple output.
void constant_pressure(const Vector< double > &x, const Vector< double > &n, Vector< std::complex< double > > &traction)
Constant pressure load (real and imag part)
void solid_boundary_displacement(const Vector< double > &x, Vector< double > &u)
Real-valued, radial displacement field on inner boundary.
void exact_u(const Vector< double > &x, Vector< double > &u)
Exact solution as a Vector.
double BesselJ(const double &n, const double &x)
Helper function to evaluate J_n(x) from bloody maple output.
TimeHarmonicIsotropicElasticityTensor E(Nu)
The elasticity tensor.
unsigned Nr
Number of elements in radial direction.
double Omega_sq
Square of non-dim frequency.
int main(int argc, char **argv)
Driver for annular disk loaded by pressure.