unstructured_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 T-rib reinforced elastic annulus subject to
27 // a nonuniform pressure load.
28 
29 //Oomph-lib includes
30 #include "generic.h"
31 #include "time_harmonic_linear_elasticity.h"
32 
33 //The meshes
34 #include "meshes/triangle_mesh.h"
35 
36 using namespace std;
37 using namespace oomph;
38 
39 /// ////////////////////////////////////////////////////////////////////
40 /// ////////////////////////////////////////////////////////////////////
41 // Straight line as geometric object
42 /// ////////////////////////////////////////////////////////////////////
43 /// ////////////////////////////////////////////////////////////////////
44 
45 
46 
47 //=========================================================================
48 /// Straight 1D line in 2D space
49 //=========================================================================
50 class MyStraightLine : public GeomObject
51 {
52 
53 public:
54 
55  /// Constructor: Pass start and end points
56  MyStraightLine(const Vector<double>& r_start, const Vector<double>& r_end)
57  : GeomObject(1,2), R_start(r_start), R_end(r_end)
58  { }
59 
60 
61  /// Broken copy constructor
63  {
64  BrokenCopy::broken_copy("MyStraightLine");
65  }
66 
67  /// Broken assignment operator
68  void operator=(const MyStraightLine&)
69  {
70  BrokenCopy::broken_assign("MyStraightLine");
71  }
72 
73 
74  /// Destructor: Empty
76 
77  /// Position Vector at Lagrangian coordinate zeta
78  void position(const Vector<double>& zeta, Vector<double>& r) const
79  {
80  // Position Vector
81  r[0] = R_start[0]+(R_end[0]-R_start[0])*zeta[0];
82  r[1] = R_start[1]+(R_end[1]-R_start[1])*zeta[0];
83  }
84 
85 private:
86 
87  /// Start point of line
88  Vector<double> R_start;
89 
90  /// End point of line
91  Vector<double> R_end;
92 
93 };
94 
95 
96 
97 /// ///////////////////////////////////////////////////////////////////
98 /// ///////////////////////////////////////////////////////////////////
99 /// ///////////////////////////////////////////////////////////////////
100 
101 
102 //=======start_namespace==========================================
103 /// Global variables
104 //================================================================
105 namespace Global_Parameters
106 {
107 
108  /// Poisson's ratio
109  double Nu=0.3;
110 
111  /// Square of non-dim frequency
112  double Omega_sq=10.0;
113 
114  /// Square of non-dim frequency for the two regions
115  Vector<double> Omega_sq_region(2,Omega_sq);
116 
117  /// The elasticity tensors for the two regions
118  Vector<TimeHarmonicIsotropicElasticityTensor*> E_pt;
119 
120  /// Thickness of annulus
121  double H_annulus=0.1;
122 
123  /// Uniform pressure
124  double P = 0.1;
125 
126  /// Peakiness parameter for pressure load
127  double Alpha=200.0;
128 
129  /// Constant pressure load (real and imag part)
130  void pressure_load(const Vector<double> &x,
131  const Vector<double> &n,
132  Vector<std::complex<double> >&traction)
133  {
134  double phi=atan2(x[1],x[0]);
135  double magnitude=exp(-Alpha*pow(phi-0.25*MathematicalConstants::Pi,2));
136 
137  unsigned dim = traction.size();
138  for(unsigned i=0;i<dim;i++)
139  {
140  traction[i] = complex<double>(-magnitude*P*n[i],magnitude*P*n[i]);
141  }
142  } // end_of_pressure_load
143 
144  /// Output directory
145  string Directory="RESLT";
146 
147 } //end namespace
148 
149 
150 
151 //=============begin_problem============================================
152 /// Annular disk
153 //======================================================================
154 template<class ELASTICITY_ELEMENT>
155 class RingWithTRibProblem : public Problem
156 {
157 
158 public:
159 
160  /// Constructor:
162 
163  /// Update function (empty)
165 
166  /// Update function (empty)
168 
169  /// Actions before adapt: Wipe the mesh of traction elements
170  void actions_before_adapt();
171 
172  /// Actions after adapt: Rebuild the mesh of traction elements
173  void actions_after_adapt();
174 
175  /// Doc the solution
176  void doc_solution();
177 
178 private:
179 
180  /// Create traction elements
181  void create_traction_elements();
182 
183  /// Delete traction elements
184  void delete_traction_elements();
185 
186  /// Helper function to complete problem setup
187  void complete_problem_setup();
188 
189 #ifdef ADAPTIVE
190 
191  /// Pointer to refineable solid mesh
192  RefineableTriangleMesh<ELASTICITY_ELEMENT>* Solid_mesh_pt;
193 
194 #else
195 
196  /// Pointer to solid mesh
197  TriangleMesh<ELASTICITY_ELEMENT>* Solid_mesh_pt;
198 
199 #endif
200 
201  /// Pointer to mesh of traction elements
203 
204  /// DocInfo object for output
205  DocInfo Doc_info;
206 
207  /// Boundary ID of upper symmetry boundary
209 
210  /// Boundary ID of lower symmetry boundary
212 
213  /// Boundary ID of outer boundary
215 
216 };
217 
218 
219 //===========start_of_constructor=======================================
220 /// Constructor:
221 //======================================================================
222 template<class ELASTICITY_ELEMENT>
224 {
225 
226  // Solid mesh
227  //-----------
228 
229  // Start and end coordinates
230  Vector<double> r_start(2);
231  Vector<double> r_end(2);
232 
233  // Outer radius of hull
234  double r_outer = 1.0;
235 
236  // Inner radius of hull
237  double r_inner = r_outer-Global_Parameters::H_annulus;
238 
239  // Thickness of rib
240  double rib_thick=0.05;
241 
242  // Depth of rib
243  double rib_depth=0.2;
244 
245  // Total width of T
246  double t_width=0.2;
247 
248  // Thickness of T
249  double t_thick=0.05;
250 
251  // Half-opening angle of rib
252  double half_phi_rib=asin(0.5*rib_thick/r_inner);
253 
254  // Pointer to the closed curve that defines the outer boundary
255  TriangleMeshClosedCurve* closed_curve_pt=0;
256 
257  // Provide storage for pointers to the parts of the curvilinear boundary
258  Vector<TriangleMeshCurveSection*> curvilinear_boundary_pt;
259 
260  // Outer boundary
261  //---------------
262  Ellipse* outer_boundary_circle_pt = new Ellipse(r_outer,r_outer);
263  double zeta_start=-0.5*MathematicalConstants::Pi;
264  double zeta_end=0.5*MathematicalConstants::Pi;
265  unsigned nsegment=50;
266  unsigned boundary_id=curvilinear_boundary_pt.size();
267  curvilinear_boundary_pt.push_back(
268  new TriangleMeshCurviLine(
269  outer_boundary_circle_pt,zeta_start,zeta_end,nsegment,boundary_id));
270 
271  // Remember it
272  Outer_boundary_id=boundary_id;
273 
274 
275  // Upper straight line segment on symmetry axis
276  //---------------------------------------------
277  r_start[0]=0.0;
278  r_start[1]=r_outer;
279  r_end[0]=0.0;
280  r_end[1]=r_inner;
281  MyStraightLine* upper_sym_pt = new MyStraightLine(r_start,r_end);
282  zeta_start=0.0;
283  zeta_end=1.0;
284  nsegment=1;
285  boundary_id=curvilinear_boundary_pt.size();
286  curvilinear_boundary_pt.push_back(
287  new TriangleMeshCurviLine(
288  upper_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
289 
290  // Remember it
291  Upper_symmetry_boundary_id=boundary_id;
292 
293  // Upper part of inner boundary
294  //-----------------------------
295  Ellipse* upper_inner_boundary_pt =
296  new Ellipse(r_inner,r_inner);
297  zeta_start=0.5*MathematicalConstants::Pi;
298  zeta_end=half_phi_rib;
299  nsegment=20;
300  boundary_id=curvilinear_boundary_pt.size();
301  curvilinear_boundary_pt.push_back(
302  new TriangleMeshCurviLine(
303  upper_inner_boundary_pt,
304  zeta_start,zeta_end,nsegment,boundary_id));
305 
306  // Upper half of inward rib
307  //-------------------------
308  r_start[0]=r_inner*cos(half_phi_rib);
309  r_start[1]=r_inner*sin(half_phi_rib);
310  r_end[0]=r_start[0]-rib_depth;
311  r_end[1]=r_start[1];
312  MyStraightLine* upper_inward_rib_pt = new MyStraightLine(r_start,r_end);
313  zeta_start=0.0;
314  zeta_end=1.0;
315  nsegment=1;
316  boundary_id=curvilinear_boundary_pt.size();
317  TriangleMeshCurviLine* upper_inward_rib_curviline_pt=
318  new TriangleMeshCurviLine(
319  upper_inward_rib_pt,zeta_start,zeta_end,nsegment,boundary_id);
320  curvilinear_boundary_pt.push_back(upper_inward_rib_curviline_pt);
321 
322  // Vertical upper bit of T
323  //------------------------
324  r_start[0]=r_end[0];
325  r_start[1]=r_end[1];
326  r_end[0]=r_start[0];
327  r_end[1]=r_start[1]+0.5*(t_width-rib_thick);
328  MyStraightLine* vertical_upper_t_rib_pt = new MyStraightLine(r_start,r_end);
329  zeta_start=0.0;
330  zeta_end=1.0;
331  nsegment=1;
332  boundary_id=curvilinear_boundary_pt.size();
333  curvilinear_boundary_pt.push_back(
334  new TriangleMeshCurviLine(
335  vertical_upper_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
336 
337 
338  // Horizontal upper bit of T
339  //-----------==-------------
340  r_start[0]=r_end[0];
341  r_start[1]=r_end[1];
342  r_end[0]=r_start[0]-t_thick;
343  r_end[1]=r_start[1];
344  MyStraightLine* horizontal_upper_t_rib_pt = new MyStraightLine(r_start,r_end);
345  zeta_start=0.0;
346  zeta_end=1.0;
347  nsegment=1;
348  boundary_id=curvilinear_boundary_pt.size();
349  curvilinear_boundary_pt.push_back(
350  new TriangleMeshCurviLine(
351  horizontal_upper_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
352 
353  // Vertical end of rib end
354  //------------------------
355  r_start[0]=r_end[0];
356  r_start[1]=r_end[1];
357  r_end[0]=r_start[0];
358  r_end[1]=-r_start[1];
359  MyStraightLine* inner_vertical_rib_pt = new MyStraightLine(r_start,r_end);
360  zeta_start=0.0;
361  zeta_end=1.0;
362  nsegment=1;
363  boundary_id=curvilinear_boundary_pt.size();
364  curvilinear_boundary_pt.push_back(
365  new TriangleMeshCurviLine(
366  inner_vertical_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
367 
368 
369  // Horizontal lower bit of T
370  //-----------==-------------
371  r_start[0]=r_end[0];
372  r_start[1]=r_end[1];
373  r_end[0]=r_start[0]+t_thick;
374  r_end[1]=r_start[1];
375  MyStraightLine* horizontal_lower_t_rib_pt = new MyStraightLine(r_start,r_end);
376  zeta_start=0.0;
377  zeta_end=1.0;
378  nsegment=1;
379  boundary_id=curvilinear_boundary_pt.size();
380  curvilinear_boundary_pt.push_back(
381  new TriangleMeshCurviLine(
382  horizontal_lower_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
383 
384 
385  // Vertical lower bit of T
386  //------------------------
387  r_start[0]=r_end[0];
388  r_start[1]=r_end[1];
389  r_end[0]=r_start[0];
390  r_end[1]=r_start[1]+0.5*(t_width-rib_thick);
391  MyStraightLine* vertical_lower_t_rib_pt = new MyStraightLine(r_start,r_end);
392  zeta_start=0.0;
393  zeta_end=1.0;
394  nsegment=1;
395  boundary_id=curvilinear_boundary_pt.size();
396  curvilinear_boundary_pt.push_back(
397  new TriangleMeshCurviLine(
398  vertical_lower_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
399 
400 
401  // Lower half of inward rib
402  //-------------------------
403  r_end[0]=r_inner*cos(half_phi_rib);
404  r_end[1]=-r_inner*sin(half_phi_rib);
405  r_start[0]=r_end[0]-rib_depth;
406  r_start[1]=r_end[1];
407  MyStraightLine* lower_inward_rib_pt = new MyStraightLine(r_start,r_end);
408  zeta_start=0.0;
409  zeta_end=1.0;
410  nsegment=1;
411  boundary_id=curvilinear_boundary_pt.size();
412  TriangleMeshCurviLine* lower_inward_rib_curviline_pt=
413  new TriangleMeshCurviLine(
414  lower_inward_rib_pt,zeta_start,zeta_end,nsegment,boundary_id);
415  curvilinear_boundary_pt.push_back(lower_inward_rib_curviline_pt);
416 
417 
418  // Lower part of inner boundary
419  //-----------------------------
420  Ellipse* lower_inner_boundary_circle_pt = new Ellipse(r_inner,r_inner);
421  zeta_start=-half_phi_rib;
422  zeta_end=-0.5*MathematicalConstants::Pi;
423  nsegment=20;
424  boundary_id=curvilinear_boundary_pt.size();
425  curvilinear_boundary_pt.push_back(
426  new TriangleMeshCurviLine(
427  lower_inner_boundary_circle_pt,zeta_start,zeta_end,nsegment,boundary_id));
428 
429 
430  // Lower straight line segment on symmetry axis
431  //---------------------------------------------
432  r_start[0]=0.0;
433  r_start[1]=-r_inner;
434  r_end[0]=0.0;
435  r_end[1]=-r_outer;
436  MyStraightLine* lower_sym_pt = new MyStraightLine(r_start,r_end);
437  zeta_start=0.0;
438  zeta_end=1.0;
439  nsegment=1;
440  boundary_id=curvilinear_boundary_pt.size();
441  curvilinear_boundary_pt.push_back(
442  new TriangleMeshCurviLine(
443  lower_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
444 
445  // Remember it
446  Lower_symmetry_boundary_id=boundary_id;
447 
448  // Combine to curvilinear boundary
449  //--------------------------------
450  closed_curve_pt=
451  new TriangleMeshClosedCurve(curvilinear_boundary_pt);
452 
453  // Vertical dividing line across base of T-rib
454  //--------------------------------------------
455  Vector<TriangleMeshCurveSection*> internal_polyline_pt(1);
456  r_start[0]=r_inner*cos(half_phi_rib);
457  r_start[1]=r_inner*sin(half_phi_rib);
458  r_end[0]=r_inner*cos(half_phi_rib);
459  r_end[1]=-r_inner*sin(half_phi_rib);
460 
461  Vector<Vector<double> > boundary_vertices(2);
462  boundary_vertices[0]=r_start;
463  boundary_vertices[1]=r_end;
464  boundary_id=100;
465  TriangleMeshPolyLine* rib_divider_pt=
466  new TriangleMeshPolyLine(boundary_vertices,boundary_id);
467  internal_polyline_pt[0]=rib_divider_pt;
468 
469  // Make connection
470  double s_connect=0.0;
471  internal_polyline_pt[0]->connect_initial_vertex_to_curviline(
472  upper_inward_rib_curviline_pt,s_connect);
473 
474  // Make connection
475  s_connect=1.0;
476  internal_polyline_pt[0]->connect_final_vertex_to_curviline(
477  lower_inward_rib_curviline_pt,s_connect);
478 
479  // Create open curve that defines internal bondary
480  Vector<TriangleMeshOpenCurve*> inner_boundary_pt;
481  inner_boundary_pt.push_back(new TriangleMeshOpenCurve(internal_polyline_pt));
482 
483  // Define coordinates of a point inside the rib
484  Vector<double> rib_center(2);
485  rib_center[0]=r_inner-rib_depth;
486  rib_center[1]=0.0;
487 
488  // Now build the mesh
489  //===================
490 
491 
492  // Use the TriangleMeshParameters object for helping on the manage of the
493  // TriangleMesh parameters. The only parameter that needs to take is the
494  // outer boundary.
495  TriangleMeshParameters triangle_mesh_parameters(closed_curve_pt);
496 
497  // Target area
498  triangle_mesh_parameters.element_area()=0.2;
499 
500  // Specify the internal open boundary
501  triangle_mesh_parameters.internal_open_curves_pt()=inner_boundary_pt;
502 
503  // Define the region
504  triangle_mesh_parameters.add_region_coordinates(1,rib_center);
505 
506 #ifdef ADAPTIVE
507 
508  // Build the mesh
509  Solid_mesh_pt=new
510  RefineableTriangleMesh<ELASTICITY_ELEMENT>(triangle_mesh_parameters);
511 
512  // Set error estimator
513  Solid_mesh_pt->spatial_error_estimator_pt()=new Z2ErrorEstimator;
514 
515 #else
516 
517  // Build the mesh
518  Solid_mesh_pt=new
519  TriangleMesh<ELASTICITY_ELEMENT>(triangle_mesh_parameters);
520 
521 #endif
522 
523 
524  // Let's have a look where the boundaries are
525  Solid_mesh_pt->output("solid_mesh.dat");
526  Solid_mesh_pt->output_boundaries("solid_mesh_boundary.dat");
527 
528  // Construct the traction element mesh
529  Traction_mesh_pt=new Mesh;
530  create_traction_elements();
531 
532  // Solid mesh is first sub-mesh
533  add_sub_mesh(Solid_mesh_pt);
534 
535  // Add traction sub-mesh
536  add_sub_mesh(Traction_mesh_pt);
537 
538  // Build combined "global" mesh
539  build_global_mesh();
540 
541  // Create elasticity tensors
542  Global_Parameters::E_pt.resize(2);
543  Global_Parameters::E_pt[0]=new TimeHarmonicIsotropicElasticityTensor(
545  Global_Parameters::E_pt[1]=new TimeHarmonicIsotropicElasticityTensor(
547 
548  // Complete problem setup
549  complete_problem_setup();
550 
551  //Assign equation numbers
552  cout << assign_eqn_numbers() << std::endl;
553 
554  // Set output directory
555  Doc_info.set_directory(Global_Parameters::Directory);
556 
557 } //end_of_constructor
558 
559 
560 
561 
562 //=====================start_of_complete_problem_setup====================
563 /// Complete problem setup
564 //========================================================================
565 template<class ELASTICITY_ELEMENT>
567 {
568 
569 #ifdef ADAPTIVE
570 
571  // Min element size allowed during adaptation
572  if (!CommandLineArgs::command_line_flag_has_been_set("--validation"))
573  {
574  Solid_mesh_pt->min_element_size()=1.0e-5;
575  }
576 
577 #endif
578 
579  //Assign the physical properties to the elements
580  //----------------------------------------------
581  unsigned nreg=Solid_mesh_pt->nregion();
582  for (unsigned r=0;r<nreg;r++)
583  {
584  unsigned nel=Solid_mesh_pt->nregion_element(r);
585  for (unsigned e=0;e<nel;e++)
586  {
587  //Cast to a solid element
588  ELASTICITY_ELEMENT *el_pt =
589  dynamic_cast<ELASTICITY_ELEMENT*>(Solid_mesh_pt->region_element_pt(r,e));
590 
591  // Set the constitutive law
592  el_pt->elasticity_tensor_pt() = Global_Parameters::E_pt[r];
593 
594  // Square of non-dim frequency
595  el_pt->omega_sq_pt()= &Global_Parameters::Omega_sq_region[r];
596  }
597  }
598 
599 
600  // Solid boundary conditions:
601  //---------------------------
602  // Pin real and imag part of horizontal displacement components
603  //-------------------------------------------------------------
604  // on vertical boundaries
605  //-----------------------
606  {
607  //Loop over the nodes to pin and assign boundary displacements on
608  //solid boundary
609  unsigned n_node = Solid_mesh_pt->nboundary_node(Upper_symmetry_boundary_id);
610  for(unsigned i=0;i<n_node;i++)
611  {
612  Node* nod_pt=Solid_mesh_pt->boundary_node_pt(Upper_symmetry_boundary_id,i);
613 
614  // Real part of x-displacement
615  nod_pt->pin(0);
616  nod_pt->set_value(0,0.0);
617 
618  // Imag part of x-displacement
619  nod_pt->pin(2);
620  nod_pt->set_value(2,0.0);
621  }
622  }
623  {
624  //Loop over the nodes to pin and assign boundary displacements on
625  //solid boundary
626  unsigned n_node = Solid_mesh_pt->nboundary_node(Lower_symmetry_boundary_id);
627  for(unsigned i=0;i<n_node;i++)
628  {
629  Node* nod_pt=Solid_mesh_pt->boundary_node_pt(Lower_symmetry_boundary_id,i);
630 
631  // Real part of x-displacement
632  nod_pt->pin(0);
633  nod_pt->set_value(0,0.0);
634 
635  // Imag part of x-displacement
636  nod_pt->pin(2);
637  nod_pt->set_value(2,0.0);
638  }
639  }
640 }
641 
642 
643 
644 //=====================start_of_actions_before_adapt======================
645 /// Actions before adapt: Wipe the mesh of traction elements
646 //========================================================================
647 template<class ELASTICITY_ELEMENT>
649 {
650  // Kill the traction elements and wipe surface mesh
651  delete_traction_elements();
652 
653  // Rebuild the Problem's global mesh from its various sub-meshes
654  rebuild_global_mesh();
655 
656 }// end of actions_before_adapt
657 
658 
659 
660 //=====================start_of_actions_after_adapt=======================
661 /// Actions after adapt: Rebuild the mesh of traction elements
662 //========================================================================
663 template<class ELASTICITY_ELEMENT>
665 {
666  // Create traction elements from all elements that are
667  // adjacent to FSI boundaries and add them to surface meshes
668  create_traction_elements();
669 
670  // Rebuild the Problem's global mesh from its various sub-meshes
671  rebuild_global_mesh();
672 
673  // Complete problem setup
674  complete_problem_setup();
675 
676 }// end of actions_after_adapt
677 
678 
679 //============start_of_create_traction_elements==============================
680 /// Create traction elements
681 //=======================================================================
682 template<class ELASTICITY_ELEMENT>
684 {
685 
686  unsigned b=Outer_boundary_id;
687  {
688  // How many bulk elements are adjacent to boundary b?
689  unsigned n_element = Solid_mesh_pt->nboundary_element(b);
690 
691  // Loop over the bulk elements adjacent to boundary b
692  for(unsigned e=0;e<n_element;e++)
693  {
694  // Get pointer to the bulk element that is adjacent to boundary b
695  ELASTICITY_ELEMENT* bulk_elem_pt = dynamic_cast<ELASTICITY_ELEMENT*>(
696  Solid_mesh_pt->boundary_element_pt(b,e));
697 
698  //Find the index of the face of element e along boundary b
699  int face_index = Solid_mesh_pt->face_index_at_boundary(b,e);
700 
701  // Create element
702  TimeHarmonicLinearElasticityTractionElement<ELASTICITY_ELEMENT>* el_pt=
703  new TimeHarmonicLinearElasticityTractionElement<ELASTICITY_ELEMENT>
704  (bulk_elem_pt,face_index);
705 
706  // Add to mesh
707  Traction_mesh_pt->add_element_pt(el_pt);
708 
709  // Associate element with bulk boundary (to allow it to access
710  // the boundary coordinates in the bulk mesh)
711  el_pt->set_boundary_number_in_bulk_mesh(b);
712 
713  //Set the traction function
714  el_pt->traction_fct_pt() = Global_Parameters::pressure_load;
715 
716  }
717  }
718 
719 } // end_of_create_traction_elements
720 
721 
722 
723 
724 //============start_of_delete_traction_elements==============================
725 /// Delete traction elements and wipe the traction meshes
726 //=======================================================================
727 template<class ELASTICITY_ELEMENT>
729 {
730  // How many surface elements are in the surface mesh
731  unsigned n_element = Traction_mesh_pt->nelement();
732 
733  // Loop over the surface elements
734  for(unsigned e=0;e<n_element;e++)
735  {
736  // Kill surface element
737  delete Traction_mesh_pt->element_pt(e);
738  }
739 
740  // Wipe the mesh
741  Traction_mesh_pt->flush_element_and_node_storage();
742 
743 } // end of delete_traction_elements
744 
745 
746 
747 
748 
749 //==============start_doc===========================================
750 /// Doc the solution
751 //==================================================================
752 template<class ELASTICITY_ELEMENT>
754 {
755 
756  ofstream some_file;
757  char filename[100];
758 
759  // Number of plot points
760  unsigned n_plot=5;
761 
762  // Output displacement field
763  //--------------------------
764  sprintf(filename,"%s/elast_soln%i.dat",Doc_info.directory().c_str(),
765  Doc_info.number());
766  some_file.open(filename);
767  Solid_mesh_pt->output(some_file,n_plot);
768  some_file.close();
769 
770  // Output traction elements
771  //-------------------------
772  sprintf(filename,"%s/traction_soln%i.dat",Doc_info.directory().c_str(),
773  Doc_info.number());
774  some_file.open(filename);
775  Traction_mesh_pt->output(some_file,n_plot);
776  some_file.close();
777 
778  // Output regions
779  //---------------
780  unsigned nreg=Solid_mesh_pt->nregion();
781  for (unsigned r=0;r<nreg;r++)
782  {
783  sprintf(filename,"%s/region%i_%i.dat",Doc_info.directory().c_str(),
784  r,Doc_info.number());
785  some_file.open(filename);
786  unsigned nel=Solid_mesh_pt->nregion_element(r);
787  for (unsigned e=0;e<nel;e++)
788  {
789  FiniteElement* el_pt=Solid_mesh_pt->region_element_pt(r,e);
790  el_pt->output(some_file,n_plot);
791  }
792  some_file.close();
793  }
794 
795  // Output norm of solution (to allow validation of solution even
796  // if triangle generates a slightly different mesh)
797  sprintf(filename,"%s/norm%i.dat",Doc_info.directory().c_str(),
798  Doc_info.number());
799  some_file.open(filename);
800  double norm=0.0;
801  unsigned nel=Solid_mesh_pt->nelement();
802  for (unsigned e=0;e<nel;e++)
803  {
804  double el_norm=0.0;
805  Solid_mesh_pt->compute_norm(el_norm);
806  norm+=el_norm;
807  }
808  some_file << norm << std::endl;
809 
810  // Increment label for output files
811  Doc_info.number()++;
812 
813 } //end doc
814 
815 
816 
817 //=======start_of_main==================================================
818 /// Driver for annular disk loaded by pressure
819 //======================================================================
820 int main(int argc, char **argv)
821 {
822 
823  // Store command line arguments
824  CommandLineArgs::setup(argc,argv);
825 
826  // Define possible command line arguments and parse the ones that
827  // were actually specified
828 
829 #ifdef ADAPTIVE
830 
831  // Max. number of adaptations
832  unsigned max_adapt=3;
833  CommandLineArgs::specify_command_line_flag("--max_adapt",&max_adapt);
834 
835 #endif
836 
837  // Peakiness parameter for loading
838  CommandLineArgs::specify_command_line_flag("--alpha",
840 
841  // Validation run?
842  CommandLineArgs::specify_command_line_flag("--validation");
843 
844  // Parse command line
845  CommandLineArgs::parse_and_assign();
846 
847  // Doc what has actually been specified on the command line
848  CommandLineArgs::doc_specified_flags();
849 
850 #ifdef ADAPTIVE
851 
852  //Set up the problem
853  RingWithTRibProblem<ProjectableTimeHarmonicLinearElasticityElement
854  <TTimeHarmonicLinearElasticityElement<2,3> > >
855  problem;
856 
857 #else
858 
859  //Set up the problem
861 
862 #endif
863 
864 
865  // Initial values for parameter values
867 
868  //Parameter incrementation
869  unsigned nstep=2;
870  for(unsigned i=0;i<nstep;i++)
871  {
872 
873 #ifdef ADAPTIVE
874 
875  // Solve the problem with Newton's method, allowing
876  // up to max_adapt mesh adaptations after every solve.
877  problem.newton_solve(max_adapt);
878 
879 #else
880 
881  // Solve the problem using Newton's method
882  problem.newton_solve();
883 
884 #endif
885 
886  // Doc solution
887  problem.doc_solution();
888 
889  // Now reduce the stiffness of the rib and set its inertia to
890  // zero, then re-solve. Resulting displacement field should
891  // be approximately axisymmetric in the annular region.
892  Global_Parameters::E_pt[1]->update_constitutive_parameters(
893  Global_Parameters::Nu,1.0e-10);
895 
896  }
897 
898 } //end of main
899 
900 
901 
902 
903 
904 
905 
906 
////////////////////////////////////////////////////////////////////
Vector< double > R_start
Start point of line.
MyStraightLine(const Vector< double > &r_start, const Vector< double > &r_end)
Constructor: Pass start and end points.
MyStraightLine(const MyStraightLine &dummy)
Broken copy constructor.
void operator=(const MyStraightLine &)
Broken assignment operator.
void position(const Vector< double > &zeta, Vector< double > &r) const
Position Vector at Lagrangian coordinate zeta.
Vector< double > R_end
End point of line.
DocInfo Doc_info
DocInfo object for output.
void actions_after_newton_solve()
Update function (empty)
void actions_before_adapt()
Actions before adapt: Wipe the mesh of traction elements.
void complete_problem_setup()
Helper function to complete problem setup.
void actions_after_adapt()
Actions after adapt: Rebuild the mesh of traction elements.
unsigned Outer_boundary_id
Boundary ID of outer boundary.
RefineableTriangleMesh< ELASTICITY_ELEMENT > * Solid_mesh_pt
Pointer to refineable solid mesh.
unsigned Lower_symmetry_boundary_id
Boundary ID of lower symmetry boundary.
void actions_before_newton_solve()
Update function (empty)
void delete_traction_elements()
Delete traction elements.
Mesh * Traction_mesh_pt
Pointer to mesh of traction elements.
void create_traction_elements()
Create traction elements.
TriangleMesh< ELASTICITY_ELEMENT > * Solid_mesh_pt
Pointer to solid mesh.
unsigned Upper_symmetry_boundary_id
Boundary ID of upper symmetry boundary.
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
double H_annulus
Thickness of annulus.
void pressure_load(const Vector< double > &x, const Vector< double > &n, Vector< std::complex< double > > &traction)
Constant pressure load (real and imag part)
string Directory
Output directory.
double P
Uniform pressure.
Vector< double > Omega_sq_region(2, Omega_sq)
Square of non-dim frequency for the two regions.
Vector< TimeHarmonicIsotropicElasticityTensor * > E_pt
The elasticity tensors for the two regions.
double Omega_sq
Square of non-dim frequency.
double Alpha
Peakiness parameter for pressure load.
int main(int argc, char **argv)
Driver for annular disk loaded by pressure.