unstructured_fourier_decomposed_acoustic_fsi.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 // Driver for Helmholtz/TimeHarmonicTimeHarmonicLinElast coupling
27 #include <complex>
28 #include <cmath>
29 
30 //Oomph-lib includes
31 #include "generic.h"
32 
33 //The Helmholtz equation
34 #include "fourier_decomposed_helmholtz.h"
35 
36 //The Elasticity equation
37 #include "time_harmonic_fourier_decomposed_linear_elasticity.h"
38 
39 // The interaction elements
40 #include "multi_physics.h"
41 
42 // The meshes
43 #include "meshes/annular_mesh.h"
44 #include "meshes/triangle_mesh.h"
45 
46 // Get the Bessel functions
47 #include "oomph_crbond_bessel.h"
48 
49 using namespace oomph;
50 using namespace std;
51 
52 
53 /// ////////////////////////////////////////////////////////////////////
54 /// ////////////////////////////////////////////////////////////////////
55 // Straight line as geometric object
56 /// ////////////////////////////////////////////////////////////////////
57 /// ////////////////////////////////////////////////////////////////////
58 
59 
60 
61 //=========================================================================
62 /// Straight 1D line in 2D space
63 //=========================================================================
64 class MyStraightLine : public GeomObject
65 {
66 
67 public:
68 
69  /// Constructor: Pass start and end points
70  MyStraightLine(const Vector<double>& r_start, const Vector<double>& r_end)
71  : GeomObject(1,2), R_start(r_start), R_end(r_end)
72  { }
73 
74 
75  /// Broken copy constructor
77  {
78  BrokenCopy::broken_copy("MyStraightLine");
79  }
80 
81  /// Destructor: Empty
83 
84  /// Position Vector at Lagrangian coordinate zeta
85  void position(const Vector<double>& zeta, Vector<double>& r) const
86  {
87  // Position Vector
88  r[0] = R_start[0]+(R_end[0]-R_start[0])*zeta[0];
89  r[1] = R_start[1]+(R_end[1]-R_start[1])*zeta[0];
90  }
91 
92 private:
93 
94  /// Start point of line
95  Vector<double> R_start;
96 
97  /// End point of line
98  Vector<double> R_end;
99 
100 };
101 
102 
103 /// ///////////////////////////////////////////////////////////////////
104 /// ///////////////////////////////////////////////////////////////////
105 /// ///////////////////////////////////////////////////////////////////
106 
107 
108 //=======start_of_namespace==========================================
109 /// Global variables
110 //===================================================================
111 namespace Global_Parameters
112 {
113 
114  /// Square of wavenumber for the Helmholtz equation
115  double K_squared=10.0;
116 
117  /// Radius of outer boundary of Helmholtz domain
118  double Outer_radius=2.0;
119 
120  /// FSI parameter
121  double Q=10.0;
122 
123  /// Non-dim thickness of elastic coating
124  double H_coating=0.1;
125 
126  /// Define azimuthal Fourier wavenumber
127  int Fourier_wavenumber=0;
128 
129  /// Poisson's ratio Nu
130  std::complex<double> Nu(std::complex<double>(0.3,0.0));
131 
132  /// Define the non-dimensional Young's modulus
133  Vector<std::complex<double> > E(2,std::complex<double>(1.0,0.0));
134 
135  /// Non-dim square of frequency for solid -- dependent variable!
136  Vector<std::complex<double> > Omega_sq(2,std::complex<double>(100.0,0.0));
137 
138  /// Density ratio: solid to fluid
139 Vector<double> Density_ratio(2,1.0);
140 
141  /// Function to update dependent parameter values
143  {
144  Omega_sq[0]=Density_ratio[0]*Q;
145  Omega_sq[1]=Density_ratio[1]*Q;
146  }
147 
148  /// Uniform pressure
149  double P = 0.1;
150 
151  /// Peakiness parameter for pressure load
152  double Alpha=0.0;
153 
154  /// Pressure load (real and imag part)
155  void pressure_load(const Vector<double> &x,
156  const Vector<double> &n,
157  Vector<std::complex<double> >&traction)
158  {
159  double phi=atan2(x[1],x[0]);
160  double magnitude=exp(-Alpha*pow(phi-0.25*MathematicalConstants::Pi,2));
161 
162  unsigned dim = 2;
163  for(unsigned i=0;i<dim;i++)
164  {
165  traction[i] = complex<double>(-magnitude*P*n[i],magnitude*P*n[i]);
166  }
167  } // end_of_pressure_load
168 
169  /// Output directory
170  string Directory="RESLT";
171 
172 } //end_of_namespace
173 
174 
175 
176 //=============start_of_problem_class===================================
177 /// Coated sphere FSI
178 //======================================================================
179 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
180 class CoatedSphereProblem : public Problem
181 {
182 
183 public:
184 
185  /// Constructor:
187 
188  /// Update function (empty)
190 
191  /// Update function (empty)
193 
194  /// Actions before adapt: Wipe the face meshes
195  void actions_before_adapt();
196 
197  /// Actions after adapt: Rebuild the face meshes
198  void actions_after_adapt();
199 
200  /// Recompute gamma integral before checking Newton residuals
202  {
203  Helmholtz_DtN_mesh_pt->setup_gamma();
204  }
205 
206  /// Doc the solution
207  void doc_solution(DocInfo& doc_info);
208 
209 private:
210 
211  /// Create FSI traction elements
213 
214  /// Create Helmholtz FSI flux elements
216 
217  /// Setup interaction
219 
220  /// Create DtN elements on outer boundary
222 
223  /// Create solid traction elements
224  void create_solid_traction_elements();
225 
226  /// Delete (face) elements in specified mesh
227  void delete_face_elements(Mesh* const & boundary_mesh_pt);
228 
229  // Complete problem setup
230  void complete_problem_setup();
231 
232  /// Boundary ID of upper symmetry boundary
234 
235  /// Boundary ID of lower symmetry boundary
237 
238  /// Boundary ID of upper inner boundary
240 
241  /// Boundary ID of lower inner boundary
243 
244  /// Boundary ID of outer boundary
246 
247  /// Boundary ID of rib divider
249 
250  /// Boundary ID of outer boundary in Helmholtz mesh
252 
253  /// Boundary ID of inner boundary in Helmholtz mesh
255 
256  /// Boundary ID of upper boundary in Helmholtz mesh
258 
259  /// Boundary ID of lower boundary in Helmholtz mesh
261 
262 #ifdef ADAPTIVE
263 
264  /// Pointer to solid mesh
265  RefineableTriangleMesh<ELASTICITY_ELEMENT>* Solid_mesh_pt;
266 
267 #else
268 
269  /// Pointer to solid mesh
270  TriangleMesh<ELASTICITY_ELEMENT>* Solid_mesh_pt;
271 
272 #endif
273 
274 
275  /// Pointer to mesh of solid traction elements
277 
278  /// Pointer to mesh of FSI traction elements
279  Mesh* FSI_traction_mesh_pt;
280 
281 #ifdef ADAPTIVE
282 
283  /// Pointer to Helmholtz mesh
284  RefineableTriangleMesh<HELMHOLTZ_ELEMENT>* Helmholtz_mesh_pt;
285 
286 #else
287 
288  /// Pointer to Helmholtz mesh
289  TriangleMesh<HELMHOLTZ_ELEMENT>* Helmholtz_mesh_pt;
290 
291 #endif
292 
293  /// Pointer to mesh of Helmholtz FSI flux elements
294  Mesh* Helmholtz_fsi_flux_mesh_pt;
295 
296  /// Pointer to mesh containing the DtN elements
297  FourierDecomposedHelmholtzDtNMesh<HELMHOLTZ_ELEMENT>* Helmholtz_DtN_mesh_pt;
298 
299  /// Trace file
300  ofstream Trace_file;
301 
302 };// end_of_problem_class
303 
304 
305 //===========start_of_constructor=======================================
306 /// Constructor:
307 //======================================================================
308 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
311 {
312 
313  // Solid mesh
314  //-----------
315  {
316 
317  // Start and end coordinates
318  Vector<double> r_start(2);
319  Vector<double> r_end(2);
320 
321  // Outer radius of hull
322  double r_outer = 1.0;
323 
324  // Inner radius of hull
325  double r_inner = r_outer-Global_Parameters::H_coating;
326 
327  // Thickness of rib
328  double rib_thick=0.05;
329 
330  // Depth of rib
331  double rib_depth=0.2;
332 
333  // Total width of T
334  double t_width=0.2;
335 
336  // Thickness of T
337  double t_thick=0.05;
338 
339  // Half-opening angle of rib
340  double half_phi_rib=asin(0.5*rib_thick/r_inner);
341 
342  // Pointer to the closed curve that defines the outer boundary
343  TriangleMeshClosedCurve* closed_curve_pt=0;
344 
345  // Provide storage for pointers to the parts of the curvilinear boundary
346  Vector<TriangleMeshCurveSection*> curvilinear_boundary_pt;
347 
348  // Outer boundary
349  //---------------
350  Ellipse* outer_boundary_circle_pt = new Ellipse(r_outer,r_outer);
351  double zeta_start=-0.5*MathematicalConstants::Pi;
352  double zeta_end=0.5*MathematicalConstants::Pi;
353  unsigned nsegment=50;
354  unsigned boundary_id=curvilinear_boundary_pt.size();
355  curvilinear_boundary_pt.push_back(
356  new TriangleMeshCurviLine(
357  outer_boundary_circle_pt,zeta_start,zeta_end,nsegment,boundary_id));
358 
359  // Remember it
360  Outer_boundary_id=boundary_id;
361 
362 
363  // Upper straight line segment on symmetry axis
364  //---------------------------------------------
365  r_start[0]=0.0;
366  r_start[1]=r_outer;
367  r_end[0]=0.0;
368  r_end[1]=r_inner;
369  MyStraightLine* upper_sym_pt = new MyStraightLine(r_start,r_end);
370  zeta_start=0.0;
371  zeta_end=1.0;
372  nsegment=1;
373  boundary_id=curvilinear_boundary_pt.size();
374  curvilinear_boundary_pt.push_back(
375  new TriangleMeshCurviLine(
376  upper_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
377 
378  // Remember it
379  Upper_symmetry_boundary_id=boundary_id;
380 
381  // Upper part of inner boundary
382  //-----------------------------
383  Ellipse* upper_inner_boundary_pt =
384  new Ellipse(r_inner,r_inner);
385  zeta_start=0.5*MathematicalConstants::Pi;
386  zeta_end=half_phi_rib;
387  nsegment=20;
388  boundary_id=curvilinear_boundary_pt.size();
389  curvilinear_boundary_pt.push_back(
390  new TriangleMeshCurviLine(
391  upper_inner_boundary_pt,
392  zeta_start,zeta_end,nsegment,boundary_id));
393 
394  // Remember it
395  Upper_inner_boundary_id=boundary_id;
396 
397  // Data associated with rib
398  MyStraightLine* upper_inward_rib_pt=0;
399  MyStraightLine* lower_inward_rib_pt=0;
400  TriangleMeshCurviLine* upper_inward_rib_curviline_pt=0;
401  Vector<TriangleMeshOpenCurve*> inner_boundary_pt;
402  TriangleMeshCurviLine* lower_inward_rib_curviline_pt=0;
403  Vector<double> rib_center(2);
404 
405  // Upper half of inward rib
406  //-------------------------
407  r_start[0]=r_inner*cos(half_phi_rib);
408  r_start[1]=r_inner*sin(half_phi_rib);
409  r_end[0]=r_start[0]-rib_depth;
410  r_end[1]=r_start[1];
411  upper_inward_rib_pt = new MyStraightLine(r_start,r_end);
412  zeta_start=0.0;
413  zeta_end=1.0;
414  nsegment=1;
415  boundary_id=curvilinear_boundary_pt.size();
416  upper_inward_rib_curviline_pt=
417  new TriangleMeshCurviLine(
418  upper_inward_rib_pt,zeta_start,zeta_end,nsegment,boundary_id);
419  curvilinear_boundary_pt.push_back(upper_inward_rib_curviline_pt);
420 
421  // Vertical upper bit of T
422  //------------------------
423  r_start[0]=r_end[0];
424  r_start[1]=r_end[1];
425  r_end[0]=r_start[0];
426  r_end[1]=r_start[1]+0.5*(t_width-rib_thick);
427  MyStraightLine* vertical_upper_t_rib_pt = new MyStraightLine(r_start,r_end);
428  zeta_start=0.0;
429  zeta_end=1.0;
430  nsegment=1;
431  boundary_id=curvilinear_boundary_pt.size();
432  curvilinear_boundary_pt.push_back(
433  new TriangleMeshCurviLine(
434  vertical_upper_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
435 
436 
437  // Horizontal upper bit of T
438  //-----------==-------------
439  r_start[0]=r_end[0];
440  r_start[1]=r_end[1];
441  r_end[0]=r_start[0]-t_thick;
442  r_end[1]=r_start[1];
443  MyStraightLine* horizontal_upper_t_rib_pt = new MyStraightLine(r_start,r_end);
444  zeta_start=0.0;
445  zeta_end=1.0;
446  nsegment=1;
447  boundary_id=curvilinear_boundary_pt.size();
448  curvilinear_boundary_pt.push_back(
449  new TriangleMeshCurviLine(
450  horizontal_upper_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
451 
452  // Vertical end of rib end
453  //------------------------
454  r_start[0]=r_end[0];
455  r_start[1]=r_end[1];
456  r_end[0]=r_start[0];
457  r_end[1]=-r_start[1];
458  MyStraightLine* inner_vertical_rib_pt = new MyStraightLine(r_start,r_end);
459  zeta_start=0.0;
460  zeta_end=1.0;
461  nsegment=1;
462  boundary_id=curvilinear_boundary_pt.size();
463  curvilinear_boundary_pt.push_back(
464  new TriangleMeshCurviLine(
465  inner_vertical_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
466 
467 
468  // Horizontal lower bit of T
469  //-----------==-------------
470  r_start[0]=r_end[0];
471  r_start[1]=r_end[1];
472  r_end[0]=r_start[0]+t_thick;
473  r_end[1]=r_start[1];
474  MyStraightLine* horizontal_lower_t_rib_pt = new MyStraightLine(r_start,r_end);
475  zeta_start=0.0;
476  zeta_end=1.0;
477  nsegment=1;
478  boundary_id=curvilinear_boundary_pt.size();
479  curvilinear_boundary_pt.push_back(
480  new TriangleMeshCurviLine(
481  horizontal_lower_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
482 
483 
484  // Vertical lower bit of T
485  //------------------------
486  r_start[0]=r_end[0];
487  r_start[1]=r_end[1];
488  r_end[0]=r_start[0];
489  r_end[1]=r_start[1]+0.5*(t_width-rib_thick);
490  MyStraightLine* vertical_lower_t_rib_pt = new MyStraightLine(r_start,r_end);
491  zeta_start=0.0;
492  zeta_end=1.0;
493  nsegment=1;
494  boundary_id=curvilinear_boundary_pt.size();
495  curvilinear_boundary_pt.push_back(
496  new TriangleMeshCurviLine(
497  vertical_lower_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
498 
499 
500  // Lower half of inward rib
501  //-------------------------
502  r_end[0]=r_inner*cos(half_phi_rib);
503  r_end[1]=-r_inner*sin(half_phi_rib);
504  r_start[0]=r_end[0]-rib_depth;
505  r_start[1]=r_end[1];
506  lower_inward_rib_pt = new MyStraightLine(r_start,r_end);
507  zeta_start=0.0;
508  zeta_end=1.0;
509  nsegment=1;
510  boundary_id=curvilinear_boundary_pt.size();
511  lower_inward_rib_curviline_pt=
512  new TriangleMeshCurviLine(
513  lower_inward_rib_pt,zeta_start,zeta_end,nsegment,boundary_id);
514  curvilinear_boundary_pt.push_back(lower_inward_rib_curviline_pt);
515 
516 
517  // Lower part of inner boundary
518  //-----------------------------
519  Ellipse* lower_inner_boundary_circle_pt = new Ellipse(r_inner,r_inner);
520  zeta_start=-half_phi_rib;
521  zeta_end=-0.5*MathematicalConstants::Pi;
522  nsegment=20;
523  boundary_id=curvilinear_boundary_pt.size();
524  curvilinear_boundary_pt.push_back(
525  new TriangleMeshCurviLine(
526  lower_inner_boundary_circle_pt,zeta_start,zeta_end,nsegment,boundary_id));
527 
528  // Remember it
529  Lower_inner_boundary_id=boundary_id;
530 
531  // Lower straight line segment on symmetry axis
532  //---------------------------------------------
533  r_start[0]=0.0;
534  r_start[1]=-r_inner;
535  r_end[0]=0.0;
536  r_end[1]=-r_outer;
537  MyStraightLine* lower_sym_pt = new MyStraightLine(r_start,r_end);
538  zeta_start=0.0;
539  zeta_end=1.0;
540  nsegment=1;
541  boundary_id=curvilinear_boundary_pt.size();
542  curvilinear_boundary_pt.push_back(
543  new TriangleMeshCurviLine(
544  lower_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
545 
546  // Remember it
547  Lower_symmetry_boundary_id=boundary_id;
548 
549  // Combine to curvilinear boundary
550  //--------------------------------
551  closed_curve_pt=
552  new TriangleMeshClosedCurve(curvilinear_boundary_pt);
553 
554  // Vertical dividing line across base of T-rib
555  //--------------------------------------------
556  Vector<TriangleMeshCurveSection*> internal_polyline_pt(1);
557  r_start[0]=r_inner*cos(half_phi_rib);
558  r_start[1]=r_inner*sin(half_phi_rib);
559  r_end[0]=r_inner*cos(half_phi_rib);
560  r_end[1]=-r_inner*sin(half_phi_rib);
561 
562  Vector<Vector<double> > boundary_vertices(2);
563  boundary_vertices[0]=r_start;
564  boundary_vertices[1]=r_end;
565  boundary_id=100;
566  TriangleMeshPolyLine* rib_divider_pt=
567  new TriangleMeshPolyLine(boundary_vertices,boundary_id);
568  internal_polyline_pt[0]=rib_divider_pt;
569 
570  // Remember it
571  Rib_divider_boundary_id=boundary_id;
572 
573  // Make connection
574  double s_connect=0.0;
575  internal_polyline_pt[0]->connect_initial_vertex_to_curviline(
576  upper_inward_rib_curviline_pt,s_connect);
577 
578  // Make connection
579  s_connect=1.0;
580  internal_polyline_pt[0]->connect_final_vertex_to_curviline(
581  lower_inward_rib_curviline_pt,s_connect);
582 
583  // Create open curve that defines internal bondary
584  inner_boundary_pt.push_back(new TriangleMeshOpenCurve(internal_polyline_pt));
585 
586  // Define coordinates of a point inside the rib
587  rib_center[0]=r_inner-rib_depth;
588  rib_center[1]=0.0;
589 
590 
591  // Now build the mesh
592  //===================
593 
594  // Use the TriangleMeshParameters object for helping on the manage of the
595  // TriangleMesh parameters. The only parameter that needs to take is the
596  // outer boundary.
597  TriangleMeshParameters triangle_mesh_parameters(closed_curve_pt);
598 
599  // Target area
600  triangle_mesh_parameters.element_area()=0.2;
601 
602  // Specify the internal open boundary
603  triangle_mesh_parameters.internal_open_curves_pt()=inner_boundary_pt;
604 
605  // Define the region
606  triangle_mesh_parameters.add_region_coordinates(1,rib_center);
607 
608 #ifdef ADAPTIVE
609 
610  // Build the mesh
611  Solid_mesh_pt=new
612  RefineableTriangleMesh<ELASTICITY_ELEMENT>(triangle_mesh_parameters);
613 
614 #else
615 
616  // Build the mesh
617  Solid_mesh_pt=new
618  TriangleMesh<ELASTICITY_ELEMENT>(triangle_mesh_parameters);
619 
620 #endif
621 
622  }
623 
624  // Helmholtz mesh
625  //---------------
626  {
627  // Start and end coordinates
628  Vector<double> r_start(2);
629  Vector<double> r_end(2);
630 
631  // Inner radius of helmholtz region
632  double r_inner = 1.0;
633 
634  // Outer radius of Helmholtz region
635  double r_outer = Global_Parameters::Outer_radius;
636 
637  // Pointer to the closed curve that defines the outer boundary
638  TriangleMeshClosedCurve* closed_curve_pt=0;
639 
640  // Provide storage for pointers to the parts of the curvilinear boundary
641  Vector<TriangleMeshCurveSection*> curvilinear_boundary_pt;
642 
643  // Outer boundary
644  //---------------
645  Ellipse* outer_boundary_circle_pt = new Ellipse(r_outer,r_outer);
646  double zeta_start=-0.5*MathematicalConstants::Pi;
647  double zeta_end=0.5*MathematicalConstants::Pi;
648  unsigned nsegment=50;
649  unsigned boundary_id=curvilinear_boundary_pt.size();
650  curvilinear_boundary_pt.push_back(
651  new TriangleMeshCurviLine(
652  outer_boundary_circle_pt,zeta_start,zeta_end,nsegment,boundary_id));
653 
654  // Remember it
655  HH_outer_boundary_id=boundary_id;
656 
657 
658  // Upper straight line segment on symmetry axis
659  //---------------------------------------------
660  r_start[0]=0.0;
661  r_start[1]=r_outer;
662  r_end[0]=0.0;
663  r_end[1]=r_inner;
664  MyStraightLine* upper_sym_pt = new MyStraightLine(r_start,r_end);
665  zeta_start=0.0;
666  zeta_end=1.0;
667  nsegment=1;
668  boundary_id=curvilinear_boundary_pt.size();
669  curvilinear_boundary_pt.push_back(
670  new TriangleMeshCurviLine(
671  upper_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
672 
673  // Remember it
674  HH_upper_symmetry_boundary_id=boundary_id;
675 
676  // Inner boundary
677  //---------------
678  Ellipse* upper_inner_boundary_pt =
679  new Ellipse(r_inner,r_inner);
680  zeta_start=0.5*MathematicalConstants::Pi;
681  zeta_end=-0.5*MathematicalConstants::Pi;
682  nsegment=40;
683  boundary_id=curvilinear_boundary_pt.size();
684  curvilinear_boundary_pt.push_back(
685  new TriangleMeshCurviLine(
686  upper_inner_boundary_pt,
687  zeta_start,zeta_end,nsegment,boundary_id));
688 
689  // Remember it
690  HH_inner_boundary_id=boundary_id;
691 
692  // Lower straight line segment on symmetry axis
693  //---------------------------------------------
694  r_start[0]=0.0;
695  r_start[1]=-r_inner;
696  r_end[0]=0.0;
697  r_end[1]=-r_outer;
698  MyStraightLine* lower_sym_pt = new MyStraightLine(r_start,r_end);
699  zeta_start=0.0;
700  zeta_end=1.0;
701  nsegment=1;
702  boundary_id=curvilinear_boundary_pt.size();
703  curvilinear_boundary_pt.push_back(
704  new TriangleMeshCurviLine(
705  lower_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
706 
707  // Remember it
708  HH_lower_symmetry_boundary_id=boundary_id;
709 
710  // Combine to curvilinear boundary
711  //--------------------------------
712  closed_curve_pt=
713  new TriangleMeshClosedCurve(curvilinear_boundary_pt);
714 
715  // Now build the mesh
716  //===================
717 
718  // Use the TriangleMeshParameters object for helping on the manage of the
719  // TriangleMesh parameters. The only parameter that needs to take is the
720  // outer boundary.
721  TriangleMeshParameters triangle_mesh_parameters(closed_curve_pt);
722 
723  // Target area
724  triangle_mesh_parameters.element_area()=0.2;
725 
726 #ifdef ADAPTIVE
727 
728  // Build the mesh
729  Helmholtz_mesh_pt=new
730  RefineableTriangleMesh<HELMHOLTZ_ELEMENT>(triangle_mesh_parameters);
731 
732 #else
733 
734  // Build the mesh
735  Helmholtz_mesh_pt=new
736  TriangleMesh<HELMHOLTZ_ELEMENT>(triangle_mesh_parameters);
737 
738 #endif
739 
740  }
741 
742  // Create mesh for DtN elements on outer boundary
743  unsigned nfourier=20;
744  Helmholtz_DtN_mesh_pt=
745  new FourierDecomposedHelmholtzDtNMesh<HELMHOLTZ_ELEMENT>(
747 
748 
749 #ifdef ADAPTIVE
750 
751  // Set error estimators
752  Solid_mesh_pt->spatial_error_estimator_pt()=new Z2ErrorEstimator;
753  Helmholtz_mesh_pt->spatial_error_estimator_pt()=new Z2ErrorEstimator;
754 
755 #endif
756 
757  // Output meshes and their boundaries so far so we can double
758  // check the boundary enumeration
759  Solid_mesh_pt->output("solid_mesh.dat");
760  Helmholtz_mesh_pt->output("helmholtz_mesh.dat");
761  Solid_mesh_pt->output_boundaries("solid_mesh_boundary.dat");
762  Helmholtz_mesh_pt->output_boundaries("helmholtz_mesh_boundary.dat");
763 
764  // Create FaceElement meshes for boundary conditions
765  //--------------------------------------------------
766 
767  // Construct the solid traction element mesh
768  Solid_traction_mesh_pt=new Mesh;
769  create_solid_traction_elements();
770 
771  // Construct the fsi traction element mesh
772  FSI_traction_mesh_pt=new Mesh;
773  create_fsi_traction_elements();
774 
775  // Construct the Helmholtz fsi flux element mesh
776  Helmholtz_fsi_flux_mesh_pt=new Mesh;
777  create_helmholtz_fsi_flux_elements();
778 
779  // Create DtN elements
780  create_helmholtz_DtN_elements();
781 
782  // Combine sub meshes
783  //-------------------
784  add_sub_mesh(Solid_mesh_pt);
785  add_sub_mesh(Solid_traction_mesh_pt);
786  add_sub_mesh(FSI_traction_mesh_pt);
787  add_sub_mesh(Helmholtz_mesh_pt);
788  add_sub_mesh(Helmholtz_fsi_flux_mesh_pt);
789  add_sub_mesh(Helmholtz_DtN_mesh_pt);
790 
791  // Build the Problem's global mesh from its various sub-meshes
792  build_global_mesh();
793 
794  // Complete problem setup
795  complete_problem_setup();
796 
797  // Setup fluid-structure interaction
798  //----------------------------------
799  setup_interaction();
800 
801  // Open trace file
802  char filename[100];
803  sprintf(filename,"%s/trace.dat",Global_Parameters::Directory.c_str());
804  Trace_file.open(filename);
805 
806  // Setup equation numbering scheme
807  cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
808 
809 }//end_of_constructor
810 
811 
812 //=====================start_of_actions_before_adapt======================
813 /// Actions before adapt: Wipe the meshes face elements
814 //========================================================================
815 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
818 {
819  // Kill the solid traction elements and wipe surface mesh
820  delete_face_elements(Solid_traction_mesh_pt);
821 
822  // Kill the fsi traction elements and wipe surface mesh
823  delete_face_elements(FSI_traction_mesh_pt);
824 
825  // Kill Helmholtz FSI flux elements
826  delete_face_elements(Helmholtz_fsi_flux_mesh_pt);
827 
828  // Kill Helmholtz BC elements
829  delete_face_elements(Helmholtz_DtN_mesh_pt);
830 
831  // Rebuild the Problem's global mesh from its various sub-meshes
832  rebuild_global_mesh();
833 
834 }// end of actions_before_adapt
835 
836 
837 
838 //=====================start_of_actions_after_adapt=======================
839 /// Actions after adapt: Rebuild the meshes of face elements
840 //========================================================================
841 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
844 {
845  // Complete problem setup
846  complete_problem_setup();
847 
848  // Construct the solid traction elements
849  create_solid_traction_elements();
850 
851  // Create fsi traction elements from all elements that are
852  // adjacent to FSI boundaries and add them to surface meshes
853  create_fsi_traction_elements();
854 
855  // Create Helmholtz fsi flux elements
856  create_helmholtz_fsi_flux_elements();
857 
858  // Create DtN elements from all elements that are
859  // adjacent to the outer boundary of Helmholtz mesh
860  create_helmholtz_DtN_elements();
861 
862  // Setup interaction
863  setup_interaction();
864 
865  // Rebuild the Problem's global mesh from its various sub-meshes
866  rebuild_global_mesh();
867 
868 }// end of actions_after_adapt
869 
870 
871 
872 //=====================start_of_actions_after_adapt=======================
873 /// Complete problem setup: Apply boundary conditions and set
874 /// physical properties
875 //========================================================================
876 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
879 {
880 
881  // Solid boundary conditions:
882  //---------------------------
883  // Pin real and imag part of horizontal and azimuthal displacement components
884  //---------------------------------------------------------------------------
885  // on vertical boundaries
886  //-----------------------
887  {
888  //Loop over the nodes to pin and assign boundary displacements on
889  //solid boundary
890  unsigned n_node = Solid_mesh_pt->nboundary_node(Upper_symmetry_boundary_id);
891  for(unsigned i=0;i<n_node;i++)
892  {
893  Node* nod_pt=Solid_mesh_pt->boundary_node_pt(Upper_symmetry_boundary_id,i);
894 
895  // Real part of r-displacement
896  nod_pt->pin(0);
897  nod_pt->set_value(0,0.0);
898 
899  // Imag part of r-displacement
900  nod_pt->pin(3);
901  nod_pt->set_value(3,0.0);
902 
903  // Real part of phi-displacement
904  nod_pt->pin(2);
905  nod_pt->set_value(2,0.0);
906 
907  // Imag part of phi-displacement
908  nod_pt->pin(5);
909  nod_pt->set_value(5,0.0);
910  }
911  }
912  {
913  //Loop over the nodes to pin and assign boundary displacements on
914  //solid boundary
915  unsigned n_node = Solid_mesh_pt->nboundary_node(Lower_symmetry_boundary_id);
916  for(unsigned i=0;i<n_node;i++)
917  {
918  Node* nod_pt=Solid_mesh_pt->boundary_node_pt(Lower_symmetry_boundary_id,i);
919 
920  // Real part of r-displacement
921  nod_pt->pin(0);
922  nod_pt->set_value(0,0.0);
923 
924  // Imag part of r-displacement
925  nod_pt->pin(3);
926  nod_pt->set_value(3,0.0);
927 
928  // Real part of phi-displacement
929  nod_pt->pin(2);
930  nod_pt->set_value(2,0.0);
931 
932  // Imag part of phi-displacement
933  nod_pt->pin(5);
934  nod_pt->set_value(5,0.0);
935  }
936  }
937 
938 
939  //Assign the physical properties to the elements
940  //----------------------------------------------
941  unsigned nreg=Solid_mesh_pt->nregion();
942  for (unsigned r=0;r<nreg;r++)
943  {
944  unsigned nel=Solid_mesh_pt->nregion_element(r);
945  for (unsigned e=0;e<nel;e++)
946  {
947  //Cast to a solid element
948  ELASTICITY_ELEMENT *el_pt =
949  dynamic_cast<ELASTICITY_ELEMENT*>(Solid_mesh_pt->
950  region_element_pt(r,e));
951 
952  // Set the pointer to Fourier wavenumber
953  el_pt->fourier_wavenumber_pt() = &Global_Parameters::Fourier_wavenumber;
954 
955  // Set the pointer to Poisson's ratio
956  el_pt->nu_pt() = &Global_Parameters::Nu;
957 
958  // Square of non-dim frequency
959  el_pt->omega_sq_pt()= &Global_Parameters::Omega_sq[r];
960 
961  // Set the pointer to non-dim Young's modulus
962  el_pt->youngs_modulus_pt() = &Global_Parameters::E[r];
963 
964  }
965  }
966 
967 
968  // Complete the build of all Helmholtz elements so they are fully functional
969  unsigned n_element = Helmholtz_mesh_pt->nelement();
970  for(unsigned i=0;i<n_element;i++)
971  {
972  // Upcast from GeneralsedElement to the present element
973  HELMHOLTZ_ELEMENT *el_pt = dynamic_cast<HELMHOLTZ_ELEMENT*>(
974  Helmholtz_mesh_pt->element_pt(i));
975 
976  //Set the k_squared pointer
977  el_pt->k_squared_pt()=&Global_Parameters::K_squared;
978 
979  // Set pointer to Fourier wave number
980  el_pt->fourier_wavenumber_pt()=&Global_Parameters::Fourier_wavenumber;
981  }
982 
983 }
984 
985 
986 
987 //============start_of_delete_face_elements================
988 /// Delete face elements and wipe the mesh
989 //==========================================================
990 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
992 delete_face_elements(Mesh* const & boundary_mesh_pt)
993 {
994  // How many surface elements are in the surface mesh
995  unsigned n_element = boundary_mesh_pt->nelement();
996 
997  // Loop over the surface elements
998  for(unsigned e=0;e<n_element;e++)
999  {
1000  // Kill surface element
1001  delete boundary_mesh_pt->element_pt(e);
1002  }
1003 
1004  // Wipe the mesh
1005  boundary_mesh_pt->flush_element_and_node_storage();
1006 
1007 } // end of delete_face_elements
1008 
1009 
1010 
1011 //============start_of_create_outer_bc_elements===========================
1012 /// Create BC elements on outer boundary
1013 //========================================================================
1014 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
1017 {
1018  // Outer boundary:
1019  unsigned b=HH_outer_boundary_id;
1020 
1021  // Loop over the bulk elements adjacent to boundary b?
1022  unsigned n_element = Helmholtz_mesh_pt->nboundary_element(b);
1023  for(unsigned e=0;e<n_element;e++)
1024  {
1025  // Get pointer to the bulk element that is adjacent to boundary b
1026  HELMHOLTZ_ELEMENT* bulk_elem_pt = dynamic_cast<HELMHOLTZ_ELEMENT*>(
1027  Helmholtz_mesh_pt->boundary_element_pt(b,e));
1028 
1029  //Find the index of the face of element e along boundary b
1030  int face_index = Helmholtz_mesh_pt->face_index_at_boundary(b,e);
1031 
1032  // Build the corresponding DtN element
1033  FourierDecomposedHelmholtzDtNBoundaryElement<HELMHOLTZ_ELEMENT>*
1034  flux_element_pt = new
1035  FourierDecomposedHelmholtzDtNBoundaryElement<HELMHOLTZ_ELEMENT>
1036  (bulk_elem_pt,face_index);
1037 
1038  //Add the flux boundary element to the helmholtz_DtN_mesh
1039  Helmholtz_DtN_mesh_pt->add_element_pt(flux_element_pt);
1040 
1041  // Set pointer to the mesh that contains all the boundary condition
1042  // elements on this boundary
1043  flux_element_pt->set_outer_boundary_mesh_pt(Helmholtz_DtN_mesh_pt);
1044  }
1045 
1046 } // end_of_create_outer_bc_elements
1047 
1048 
1049 
1050 
1051 
1052 //=====================start_of_setup_interaction======================
1053 /// Setup interaction between two fields
1054 //========================================================================
1055 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
1058 {
1059 
1060  // Setup Helmholtz "pressure" load on traction elements
1061  unsigned boundary_in_helmholtz_mesh=HH_inner_boundary_id;
1062 
1063  // Doc boundary coordinate for Helmholtz
1064  ofstream the_file;
1065  the_file.open("boundary_coordinate_hh.dat");
1066  Helmholtz_mesh_pt->Mesh::template doc_boundary_coordinates<HELMHOLTZ_ELEMENT>
1067  (boundary_in_helmholtz_mesh, the_file);
1068  the_file.close();
1069 
1070  // Setup interaction
1071  Multi_domain_functions::setup_bulk_elements_adjacent_to_face_mesh
1072  <HELMHOLTZ_ELEMENT,2>
1073  (this,boundary_in_helmholtz_mesh,Helmholtz_mesh_pt,FSI_traction_mesh_pt);
1074 
1075  // Setup Helmholtz flux from normal displacement interaction
1076  unsigned boundary_in_solid_mesh=Outer_boundary_id;
1077 
1078  // Doc boundary coordinate for solid mesh
1079  the_file.open("boundary_coordinate_solid.dat");
1080  Solid_mesh_pt->Mesh::template doc_boundary_coordinates<ELASTICITY_ELEMENT>
1081  (boundary_in_solid_mesh, the_file);
1082  the_file.close();
1083 
1084  // Setup interaction
1085  Multi_domain_functions::setup_bulk_elements_adjacent_to_face_mesh
1086  <ELASTICITY_ELEMENT,2>(
1087  this,boundary_in_solid_mesh,Solid_mesh_pt,Helmholtz_fsi_flux_mesh_pt);
1088 
1089 }// end_of_setup_interaction
1090 
1091 
1092 
1093 
1094 
1095 //============start_of_create_fsi_traction_elements======================
1096 /// Create fsi traction elements
1097 //=======================================================================
1098 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
1101 {
1102  // We're on outer boundary of the solid mesh
1103  unsigned b=Outer_boundary_id;
1104 
1105  // How many bulk elements are adjacent to boundary b?
1106  unsigned n_element = Solid_mesh_pt->nboundary_element(b);
1107 
1108  // Loop over the bulk elements adjacent to boundary b
1109  for(unsigned e=0;e<n_element;e++)
1110  {
1111  // Get pointer to the bulk element that is adjacent to boundary b
1112  ELASTICITY_ELEMENT* bulk_elem_pt = dynamic_cast<ELASTICITY_ELEMENT*>(
1113  Solid_mesh_pt->boundary_element_pt(b,e));
1114 
1115  //Find the index of the face of element e along boundary b
1116  int face_index = Solid_mesh_pt->face_index_at_boundary(b,e);
1117 
1118  // Create element
1119  FourierDecomposedTimeHarmonicLinElastLoadedByHelmholtzPressureBCElement
1120  <ELASTICITY_ELEMENT,HELMHOLTZ_ELEMENT>* el_pt=
1121  new FourierDecomposedTimeHarmonicLinElastLoadedByHelmholtzPressureBCElement
1122  <ELASTICITY_ELEMENT,HELMHOLTZ_ELEMENT>(bulk_elem_pt,
1123  face_index);
1124  // Add to mesh
1125  FSI_traction_mesh_pt->add_element_pt(el_pt);
1126 
1127  // Associate element with bulk boundary (to allow it to access
1128  // the boundary coordinates in the bulk mesh)
1129  el_pt->set_boundary_number_in_bulk_mesh(b);
1130 
1131  // Set FSI parameter
1132  el_pt->q_pt()=&Global_Parameters::Q;
1133  }
1134 
1135 } // end_of_create_fsi_traction_elements
1136 
1137 
1138 
1139 //============start_of_create_helmholtz_fsi_flux_elements================
1140 /// Create Helmholtz fsi flux elements
1141 //=======================================================================
1142 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
1145 {
1146 
1147  // Attach to inner boundary of Helmholtz mesh
1148  unsigned b=HH_inner_boundary_id;
1149 
1150  // How many bulk elements are adjacent to boundary b?
1151  unsigned n_element = Helmholtz_mesh_pt->nboundary_element(b);
1152 
1153  // Loop over the bulk elements adjacent to boundary b
1154  for(unsigned e=0;e<n_element;e++)
1155  {
1156  // Get pointer to the bulk element that is adjacent to boundary b
1157  HELMHOLTZ_ELEMENT* bulk_elem_pt = dynamic_cast<HELMHOLTZ_ELEMENT*>(
1158  Helmholtz_mesh_pt->boundary_element_pt(b,e));
1159 
1160  //Find the index of the face of element e along boundary b
1161  int face_index = Helmholtz_mesh_pt->face_index_at_boundary(b,e);
1162 
1163  // Create element
1164  FourierDecomposedHelmholtzFluxFromNormalDisplacementBCElement
1165  <HELMHOLTZ_ELEMENT,ELASTICITY_ELEMENT>* el_pt=
1166  new FourierDecomposedHelmholtzFluxFromNormalDisplacementBCElement
1167  <HELMHOLTZ_ELEMENT,ELASTICITY_ELEMENT>(bulk_elem_pt,
1168  face_index);
1169 
1170  // Add to mesh
1171  Helmholtz_fsi_flux_mesh_pt->add_element_pt(el_pt);
1172 
1173  // Associate element with bulk boundary (to allow it to access
1174  // the boundary coordinates in the bulk mesh)
1175  el_pt->set_boundary_number_in_bulk_mesh(b);
1176  }
1177 
1178 } // end_of_create_helmholtz_fsi_flux_elements
1179 
1180 
1181 //============start_of_create_solid_traction_elements====================
1182 /// Create solid traction elements
1183 //=======================================================================
1184 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
1187 {
1188  // Loop over pressure loaded boundaries
1189  unsigned b=0;
1190  unsigned nb=3;
1191  for (unsigned i=0;i<nb;i++)
1192  {
1193  switch(i)
1194  {
1195  case 0:
1196  b=Upper_inner_boundary_id;
1197  break;
1198 
1199  case 1:
1200  b=Lower_inner_boundary_id;
1201  break;
1202 
1203  case 2:
1204  b=Rib_divider_boundary_id;
1205  break;
1206  }
1207 
1208  // We're attaching face elements to region 0
1209  unsigned r=0;
1210 
1211  // How many bulk elements are adjacent to boundary b?
1212  unsigned n_element = Solid_mesh_pt->nboundary_element_in_region(b,r);
1213 
1214  // Loop over the bulk elements adjacent to boundary b
1215  for(unsigned e=0;e<n_element;e++)
1216  {
1217  // Get pointer to the bulk element that is adjacent to boundary b
1218  ELASTICITY_ELEMENT* bulk_elem_pt = dynamic_cast<ELASTICITY_ELEMENT*>(
1219  Solid_mesh_pt->boundary_element_in_region_pt(b,r,e));
1220 
1221  //Find the index of the face of element e along boundary b
1222  int face_index = Solid_mesh_pt->face_index_at_boundary_in_region(b,r,e);
1223 
1224  // Create element
1225  TimeHarmonicFourierDecomposedLinearElasticityTractionElement
1226  <ELASTICITY_ELEMENT>* el_pt=
1227  new TimeHarmonicFourierDecomposedLinearElasticityTractionElement
1228  <ELASTICITY_ELEMENT>(bulk_elem_pt,face_index);
1229 
1230  // Add to mesh
1231  Solid_traction_mesh_pt->add_element_pt(el_pt);
1232 
1233  // Associate element with bulk boundary (to allow it to access
1234  // the boundary coordinates in the bulk mesh)
1235  el_pt->set_boundary_number_in_bulk_mesh(b);
1236 
1237  //Set the traction function
1238  el_pt->traction_fct_pt() = Global_Parameters::pressure_load;
1239  }
1240  }
1241 } // end of create_traction_elements
1242 
1243 
1244 
1245 
1246 //==============start_of_doc_solution===============================
1247 /// Doc the solution
1248 //==================================================================
1249 template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
1251 doc_solution(DocInfo& doc_info)
1252 {
1253 
1254  // Doc parameters
1255  oomph_info << "Writing result for step " << doc_info.number()
1256  << ". Parameters: "<< std::endl;
1257  oomph_info << "Fourier mode number : N = "
1258  << Global_Parameters::Fourier_wavenumber << std::endl;
1259  oomph_info << "FSI parameter : Q = " << Global_Parameters::Q << std::endl;
1260  oomph_info << "Fluid outer radius : R = " << Global_Parameters::Outer_radius
1261  << std::endl;
1262  oomph_info << "Fluid wavenumber : k^2 = " << Global_Parameters::K_squared
1263  << std::endl;
1264  oomph_info << "Solid wavenumber : Omega_sq = "
1265  << Global_Parameters::Omega_sq[0] << std::endl;
1266  oomph_info << "Solid wavenumber : Omega_sq = "
1268  << std::endl << std::endl;
1269 
1270 
1271  ofstream some_file,some_file2;
1272  char filename[100];
1273 
1274  // Number of plot points
1275  unsigned n_plot=5;
1276 
1277  // Compute/output the radiated power
1278  //----------------------------------
1279  sprintf(filename,"%s/power%i.dat",doc_info.directory().c_str(),
1280  doc_info.number());
1281  some_file.open(filename);
1282 
1283  // Accumulate contribution from elements
1284  double power=0.0;
1285  unsigned nn_element=Helmholtz_DtN_mesh_pt->nelement();
1286  for(unsigned e=0;e<nn_element;e++)
1287  {
1288  FourierDecomposedHelmholtzBCElementBase<HELMHOLTZ_ELEMENT> *el_pt =
1289  dynamic_cast<FourierDecomposedHelmholtzBCElementBase<HELMHOLTZ_ELEMENT>*>(
1290  Helmholtz_DtN_mesh_pt->element_pt(e));
1291  power += el_pt->global_power_contribution(some_file);
1292  }
1293  some_file.close();
1294  oomph_info << "Radiated power: " << power << std::endl;
1295 
1296  // Output displacement field
1297  //--------------------------
1298  sprintf(filename,"%s/elast_soln%i.dat",doc_info.directory().c_str(),
1299  doc_info.number());
1300  some_file.open(filename);
1301  Solid_mesh_pt->output(some_file,n_plot);
1302  some_file.close();
1303 
1304  // Output Helmholtz
1305  //-----------------
1306  sprintf(filename,"%s/helmholtz_soln%i.dat",doc_info.directory().c_str(),
1307  doc_info.number());
1308  some_file.open(filename);
1309  Helmholtz_mesh_pt->output(some_file,n_plot);
1310  some_file.close();
1311 
1312 
1313  // Output fsi traction elements
1314  //-----------------------------
1315  sprintf(filename,"%s/fsi_traction_soln%i.dat",doc_info.directory().c_str(),
1316  doc_info.number());
1317  some_file.open(filename);
1318  FSI_traction_mesh_pt->output(some_file,n_plot);
1319  some_file.close();
1320 
1321 
1322  // Output Helmholtz fsi flux elements
1323  //-----------------------------------
1324  sprintf(filename,"%s/fsi_flux_bc_soln%i.dat",doc_info.directory().c_str(),
1325  doc_info.number());
1326  some_file.open(filename);
1327  Helmholtz_fsi_flux_mesh_pt->output(some_file,n_plot);
1328  some_file.close();
1329 
1330  // Write trace file
1331  Trace_file << Global_Parameters::Q << " "
1335  << Global_Parameters::Omega_sq[0].real() << " "
1336  << Global_Parameters::Omega_sq[1].real() << " "
1337  << power << " "
1338  << std::endl;
1339 
1340  // Bump up counter
1341  doc_info.number()++;
1342 
1343 } //end_of_doc_solution
1344 
1345 
1346 
1347 //=======start_of_main==================================================
1348 /// Driver for coated sphere loaded by lineared fluid loading
1349 //======================================================================
1350 int main(int argc, char **argv)
1351 {
1352 
1353  // Store command line arguments
1354  CommandLineArgs::setup(argc,argv);
1355 
1356  // Define possible command line arguments and parse the ones that
1357  // were actually specified
1358 
1359  // Output directory
1360  CommandLineArgs::specify_command_line_flag("--dir",
1362 
1363  // Parameter controlling the sharpness of the pressure load
1364  CommandLineArgs::specify_command_line_flag("--alpha",
1366 
1367  // Parse command line
1368  CommandLineArgs::parse_and_assign();
1369 
1370  // Doc what has actually been specified on the command line
1371  CommandLineArgs::doc_specified_flags();
1372 
1373 
1374 
1375  // Set values for parameter values
1376  Global_Parameters::Q=5.0;
1380 
1381  // Update dependent parameters values
1383 
1384  // Set up doc info
1385  DocInfo doc_info;
1386 
1387  // Set output directory
1388  doc_info.set_directory(Global_Parameters::Directory);
1389 
1390 #ifdef ADAPTIVE
1391 
1392  // Set up the problem
1394  ProjectableTimeHarmonicFourierDecomposedLinearElasticityElement
1395  <TTimeHarmonicFourierDecomposedLinearElasticityElement<3> >,
1396  ProjectableFourierDecomposedHelmholtzElement
1397  <TFourierDecomposedHelmholtzElement<3> > > problem;
1398 
1399 #else
1400 
1401  // Set up the problem
1403  TFourierDecomposedHelmholtzElement<3> > problem;
1404 
1405 #endif
1406 
1407 
1408  //Parameter incrementation
1409  unsigned nstep=3;
1410  for(unsigned i=0;i<nstep;i++)
1411  {
1412 
1413 #ifdef ADAPTIVE
1414 
1415  // Solve the problem with Newton's method, allowing
1416  // up to max_adapt mesh adaptations after every solve.
1417  unsigned max_adapt=3;
1418  problem.newton_solve(max_adapt);
1419 
1420 #else
1421 
1422  // Solve the problem with Newton's method
1423  problem.newton_solve();
1424 
1425 #endif
1426 
1427  // Doc solution
1428  problem.doc_solution(doc_info);
1429 
1430  // Make rib a lot heavier but keep its stiffness
1431  if (i==0)
1432  {
1433  Global_Parameters::E[1]=1.0;
1436  }
1437 
1438  // Make rib very soft and inertia-less
1439  if (i==1)
1440  {
1441  Global_Parameters::E[1]=1.0e-16;
1444  }
1445  }
1446 
1447 } //end_of_main
1448 
1449 
1450 
1451 
1452 
1453 
1454 
1455 
unsigned HH_upper_symmetry_boundary_id
Boundary ID of upper boundary in Helmholtz mesh.
RefineableTriangleMesh< ELASTICITY_ELEMENT > * Solid_mesh_pt
Pointer to solid mesh.
void actions_before_adapt()
Actions before adapt: Wipe the face meshes.
void delete_face_elements(Mesh *const &boundary_mesh_pt)
Delete (face) elements in specified mesh.
void create_fsi_traction_elements()
Create FSI traction elements.
unsigned HH_inner_boundary_id
Boundary ID of inner boundary in Helmholtz mesh.
void actions_before_newton_convergence_check()
Recompute gamma integral before checking Newton residuals.
unsigned Rib_divider_boundary_id
Boundary ID of rib divider.
RefineableTriangleMesh< HELMHOLTZ_ELEMENT > * Helmholtz_mesh_pt
Pointer to Helmholtz mesh.
TriangleMesh< ELASTICITY_ELEMENT > * Solid_mesh_pt
Pointer to solid mesh.
void complete_problem_setup()
Complete problem setup: Apply boundary conditions and set physical properties.
unsigned HH_outer_boundary_id
Boundary ID of outer boundary in Helmholtz mesh.
void actions_after_adapt()
Actions after adapt: Rebuild the face meshes.
void create_helmholtz_DtN_elements()
Create DtN elements on outer boundary.
unsigned HH_lower_symmetry_boundary_id
Boundary ID of lower boundary in Helmholtz mesh.
void create_solid_traction_elements()
Create solid traction elements.
void create_helmholtz_fsi_flux_elements()
Create Helmholtz FSI flux elements.
unsigned Lower_symmetry_boundary_id
Boundary ID of lower symmetry boundary.
void actions_before_newton_solve()
Update function (empty)
Mesh * Solid_traction_mesh_pt
Pointer to mesh of solid traction elements.
TriangleMesh< HELMHOLTZ_ELEMENT > * Helmholtz_mesh_pt
Pointer to Helmholtz mesh.
void doc_solution(DocInfo &doc_info)
Doc the solution.
CoatedSphereProblem()
Constructor:
unsigned Upper_inner_boundary_id
Boundary ID of upper inner boundary.
unsigned Outer_boundary_id
Boundary ID of outer boundary.
unsigned Lower_inner_boundary_id
Boundary ID of lower inner boundary.
unsigned Upper_symmetry_boundary_id
Boundary ID of upper symmetry boundary.
void actions_after_newton_solve()
Update function (empty)
void setup_interaction()
Setup interaction.
////////////////////////////////////////////////////////////////////
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 position(const Vector< double > &zeta, Vector< double > &r) const
Position Vector at Lagrangian coordinate zeta.
Vector< double > R_end
End point of line.
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
void pressure_load(const Vector< double > &x, const Vector< double > &n, Vector< std::complex< double > > &traction)
Pressure load (real and imag part)
string Directory
Output directory.
std::complex< double > Nu(std::complex< double >(0.3, 0.0))
Poisson's ratio Nu.
Vector< std::complex< double > > Omega_sq(2, std::complex< double >(100.0, 0.0))
Non-dim square of frequency for solid – dependent variable!
double Density_ratio
Density ratio: solid to fluid.
Vector< double > Density_ratio(2, 1.0)
Density ratio: solid to fluid.
double Outer_radius
Radius of outer boundary of Helmholtz domain.
std::complex< double > Omega_sq(std::complex< double >(100.0, 0.0))
Non-dim square of frequency for solid – dependent variable!
double K_squared
Square of wavenumber for the Helmholtz equation.
Vector< std::complex< double > > E(2, std::complex< double >(1.0, 0.0))
Define the non-dimensional Young's modulus.
void update_parameter_values()
Function to update dependent parameter values.
int Fourier_wavenumber
Define azimuthal Fourier wavenumber.
double H_coating
Non-dim thickness of elastic coating.
double Alpha
Peakiness parameter for pressure load.
int main(int argc, char **argv)
Driver for coated sphere loaded by lineared fluid loading.