In this document we discuss the spatially-adaptive solution of 3D time-harmonic acoustic fluid-structure interaction problems in cylindrical polar coordinates on unstructured meshes.
The sketch below shows the problem setup: An elastic sphere which is reinforced with an azimuthal T-rib is immersed in a compressible fluid and subjected to a time-periodic pressure load of magnitude
The figure below shows an animation of the structure's time-harmonic oscillation. The blue shaded region shows the shape of the oscillating structure while the pink region shows its undeformed configuration. The left half of the plot is used to show the (mirror image of the) adaptive unstructured mesh on which the displacement field was computed:
Here is a plot of the corresponding fluid displacement potential, a measure of the fluid pressure:
This looks very pretty and shows that we can solve acoustic FSI problems in non-trivial geometries but should you believe the results? Here's an attempt to convince you: If we make the rib much softer than the sphere and set its inertia to zero, the rib will not offer much structural resistance and the sphere will deform as if the rib was not present. If we then set we apply a spherically symmetric forcing onto the structure and would expect the resulting displacement field (at least in the sphere) to be spherically symmetric, too.
The animation of the displacement field for this case, shown below, shows that this is indeed the case:
Here is a plot of the corresponding fluid displacement potential, a measure of the fluid pressure:
#include <complex>
#include <cmath>
#include "generic.h"
#include "fourier_decomposed_helmholtz.h"
#include "time_harmonic_fourier_decomposed_linear_elasticity.h"
#include "multi_physics.h"
#include "meshes/annular_mesh.h"
#include "meshes/triangle_mesh.h"
#include "oomph_crbond_bessel.h"
using namespace oomph;
using namespace std;
{
public:
MyStraightLine(
const Vector<double>& r_start,
const Vector<double>& r_end)
: GeomObject(1,2), R_start(r_start), R_end(r_end)
{ }
{
BrokenCopy::broken_copy("MyStraightLine");
}
void position(const Vector<double>& zeta, Vector<double>& r) const
{
r[0] = R_start[0]+(R_end[0]-R_start[0])*zeta[0];
r[1] = R_start[1]+(R_end[1]-R_start[1])*zeta[0];
}
private:
Vector<double> R_start;
Vector<double> R_end;
};
{
std::complex<double>
Nu(std::complex<double>(0.3,0.0));
Vector<std::complex<double> >
E(2,std::complex<double>(1.0,0.0));
Vector<std::complex<double> >
Omega_sq(2,std::complex<double>(100.0,0.0));
{
}
const Vector<double> &n,
Vector<std::complex<double> >&traction)
{
double phi=atan2(x[1],x[0]);
double magnitude=exp(-
Alpha*pow(phi-0.25*MathematicalConstants::Pi,2));
unsigned dim = 2;
for(unsigned i=0;i<dim;i++)
{
traction[i] = complex<double>(-magnitude*
P*n[i],magnitude*
P*n[i]);
}
}
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
public:
void actions_before_newton_solve(){}
void actions_after_newton_solve() {}
void actions_before_adapt();
void actions_after_adapt();
void actions_before_newton_convergence_check()
{
Helmholtz_DtN_mesh_pt->setup_gamma();
}
void doc_solution(DocInfo& doc_info);
private:
void create_fsi_traction_elements();
void create_helmholtz_fsi_flux_elements();
void setup_interaction();
void create_helmholtz_DtN_elements();
void create_solid_traction_elements();
void delete_face_elements(Mesh* const & boundary_mesh_pt);
void complete_problem_setup();
unsigned Upper_symmetry_boundary_id;
unsigned Lower_symmetry_boundary_id;
unsigned Upper_inner_boundary_id;
unsigned Lower_inner_boundary_id;
unsigned Outer_boundary_id;
unsigned Rib_divider_boundary_id;
unsigned HH_outer_boundary_id;
unsigned HH_inner_boundary_id;
unsigned HH_upper_symmetry_boundary_id;
unsigned HH_lower_symmetry_boundary_id;
#ifdef ADAPTIVE
RefineableTriangleMesh<ELASTICITY_ELEMENT>* Solid_mesh_pt;
#else
TriangleMesh<ELASTICITY_ELEMENT>* Solid_mesh_pt;
#endif
Mesh* Solid_traction_mesh_pt;
Mesh* FSI_traction_mesh_pt;
#ifdef ADAPTIVE
RefineableTriangleMesh<HELMHOLTZ_ELEMENT>* Helmholtz_mesh_pt;
#else
TriangleMesh<HELMHOLTZ_ELEMENT>* Helmholtz_mesh_pt;
#endif
Mesh* Helmholtz_fsi_flux_mesh_pt;
FourierDecomposedHelmholtzDtNMesh<HELMHOLTZ_ELEMENT>* Helmholtz_DtN_mesh_pt;
ofstream Trace_file;
};
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
{
Vector<double> r_start(2);
Vector<double> r_end(2);
double r_outer = 1.0;
double rib_thick=0.05;
double rib_depth=0.2;
double t_width=0.2;
double t_thick=0.05;
double half_phi_rib=asin(0.5*rib_thick/r_inner);
TriangleMeshClosedCurve* closed_curve_pt=0;
Vector<TriangleMeshCurveSection*> curvilinear_boundary_pt;
Ellipse* outer_boundary_circle_pt = new Ellipse(r_outer,r_outer);
double zeta_start=-0.5*MathematicalConstants::Pi;
double zeta_end=0.5*MathematicalConstants::Pi;
unsigned nsegment=50;
unsigned boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
outer_boundary_circle_pt,zeta_start,zeta_end,nsegment,boundary_id));
Outer_boundary_id=boundary_id;
r_start[0]=0.0;
r_start[1]=r_outer;
r_end[0]=0.0;
r_end[1]=r_inner;
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
upper_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
Upper_symmetry_boundary_id=boundary_id;
Ellipse* upper_inner_boundary_pt =
new Ellipse(r_inner,r_inner);
zeta_start=0.5*MathematicalConstants::Pi;
zeta_end=half_phi_rib;
nsegment=20;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
upper_inner_boundary_pt,
zeta_start,zeta_end,nsegment,boundary_id));
Upper_inner_boundary_id=boundary_id;
TriangleMeshCurviLine* upper_inward_rib_curviline_pt=0;
Vector<TriangleMeshOpenCurve*> inner_boundary_pt;
TriangleMeshCurviLine* lower_inward_rib_curviline_pt=0;
Vector<double> rib_center(2);
r_start[0]=r_inner*cos(half_phi_rib);
r_start[1]=r_inner*sin(half_phi_rib);
r_end[0]=r_start[0]-rib_depth;
r_end[1]=r_start[1];
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
upper_inward_rib_curviline_pt=
new TriangleMeshCurviLine(
upper_inward_rib_pt,zeta_start,zeta_end,nsegment,boundary_id);
curvilinear_boundary_pt.push_back(upper_inward_rib_curviline_pt);
r_start[0]=r_end[0];
r_start[1]=r_end[1];
r_end[0]=r_start[0];
r_end[1]=r_start[1]+0.5*(t_width-rib_thick);
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
vertical_upper_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
r_start[0]=r_end[0];
r_start[1]=r_end[1];
r_end[0]=r_start[0]-t_thick;
r_end[1]=r_start[1];
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
horizontal_upper_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
r_start[0]=r_end[0];
r_start[1]=r_end[1];
r_end[0]=r_start[0];
r_end[1]=-r_start[1];
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
inner_vertical_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
r_start[0]=r_end[0];
r_start[1]=r_end[1];
r_end[0]=r_start[0]+t_thick;
r_end[1]=r_start[1];
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
horizontal_lower_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
r_start[0]=r_end[0];
r_start[1]=r_end[1];
r_end[0]=r_start[0];
r_end[1]=r_start[1]+0.5*(t_width-rib_thick);
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
vertical_lower_t_rib_pt,zeta_start,zeta_end,nsegment,boundary_id));
r_end[0]=r_inner*cos(half_phi_rib);
r_end[1]=-r_inner*sin(half_phi_rib);
r_start[0]=r_end[0]-rib_depth;
r_start[1]=r_end[1];
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
lower_inward_rib_curviline_pt=
new TriangleMeshCurviLine(
lower_inward_rib_pt,zeta_start,zeta_end,nsegment,boundary_id);
curvilinear_boundary_pt.push_back(lower_inward_rib_curviline_pt);
Ellipse* lower_inner_boundary_circle_pt = new Ellipse(r_inner,r_inner);
zeta_start=-half_phi_rib;
zeta_end=-0.5*MathematicalConstants::Pi;
nsegment=20;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
lower_inner_boundary_circle_pt,zeta_start,zeta_end,nsegment,boundary_id));
Lower_inner_boundary_id=boundary_id;
r_start[0]=0.0;
r_start[1]=-r_inner;
r_end[0]=0.0;
r_end[1]=-r_outer;
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
lower_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
Lower_symmetry_boundary_id=boundary_id;
closed_curve_pt=
new TriangleMeshClosedCurve(curvilinear_boundary_pt);
Vector<TriangleMeshCurveSection*> internal_polyline_pt(1);
r_start[0]=r_inner*cos(half_phi_rib);
r_start[1]=r_inner*sin(half_phi_rib);
r_end[0]=r_inner*cos(half_phi_rib);
r_end[1]=-r_inner*sin(half_phi_rib);
Vector<Vector<double> > boundary_vertices(2);
boundary_vertices[0]=r_start;
boundary_vertices[1]=r_end;
boundary_id=100;
TriangleMeshPolyLine* rib_divider_pt=
new TriangleMeshPolyLine(boundary_vertices,boundary_id);
internal_polyline_pt[0]=rib_divider_pt;
Rib_divider_boundary_id=boundary_id;
double s_connect=0.0;
internal_polyline_pt[0]->connect_initial_vertex_to_curviline(
upper_inward_rib_curviline_pt,s_connect);
s_connect=1.0;
internal_polyline_pt[0]->connect_final_vertex_to_curviline(
lower_inward_rib_curviline_pt,s_connect);
inner_boundary_pt.push_back(new TriangleMeshOpenCurve(internal_polyline_pt));
rib_center[0]=r_inner-rib_depth;
rib_center[1]=0.0;
TriangleMeshParameters triangle_mesh_parameters(closed_curve_pt);
triangle_mesh_parameters.element_area()=0.2;
triangle_mesh_parameters.internal_open_curves_pt()=inner_boundary_pt;
triangle_mesh_parameters.add_region_coordinates(1,rib_center);
#ifdef ADAPTIVE
Solid_mesh_pt=new
RefineableTriangleMesh<ELASTICITY_ELEMENT>(triangle_mesh_parameters);
#else
Solid_mesh_pt=new
TriangleMesh<ELASTICITY_ELEMENT>(triangle_mesh_parameters);
#endif
}
{
Vector<double> r_start(2);
Vector<double> r_end(2);
double r_inner = 1.0;
TriangleMeshClosedCurve* closed_curve_pt=0;
Vector<TriangleMeshCurveSection*> curvilinear_boundary_pt;
Ellipse* outer_boundary_circle_pt = new Ellipse(r_outer,r_outer);
double zeta_start=-0.5*MathematicalConstants::Pi;
double zeta_end=0.5*MathematicalConstants::Pi;
unsigned nsegment=50;
unsigned boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
outer_boundary_circle_pt,zeta_start,zeta_end,nsegment,boundary_id));
HH_outer_boundary_id=boundary_id;
r_start[0]=0.0;
r_start[1]=r_outer;
r_end[0]=0.0;
r_end[1]=r_inner;
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
upper_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
HH_upper_symmetry_boundary_id=boundary_id;
Ellipse* upper_inner_boundary_pt =
new Ellipse(r_inner,r_inner);
zeta_start=0.5*MathematicalConstants::Pi;
zeta_end=-0.5*MathematicalConstants::Pi;
nsegment=40;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
upper_inner_boundary_pt,
zeta_start,zeta_end,nsegment,boundary_id));
HH_inner_boundary_id=boundary_id;
r_start[0]=0.0;
r_start[1]=-r_inner;
r_end[0]=0.0;
r_end[1]=-r_outer;
zeta_start=0.0;
zeta_end=1.0;
nsegment=1;
boundary_id=curvilinear_boundary_pt.size();
curvilinear_boundary_pt.push_back(
new TriangleMeshCurviLine(
lower_sym_pt,zeta_start,zeta_end,nsegment,boundary_id));
HH_lower_symmetry_boundary_id=boundary_id;
closed_curve_pt=
new TriangleMeshClosedCurve(curvilinear_boundary_pt);
TriangleMeshParameters triangle_mesh_parameters(closed_curve_pt);
triangle_mesh_parameters.element_area()=0.2;
#ifdef ADAPTIVE
Helmholtz_mesh_pt=new
RefineableTriangleMesh<HELMHOLTZ_ELEMENT>(triangle_mesh_parameters);
#else
Helmholtz_mesh_pt=new
TriangleMesh<HELMHOLTZ_ELEMENT>(triangle_mesh_parameters);
#endif
}
unsigned nfourier=20;
Helmholtz_DtN_mesh_pt=
new FourierDecomposedHelmholtzDtNMesh<HELMHOLTZ_ELEMENT>(
#ifdef ADAPTIVE
Solid_mesh_pt->spatial_error_estimator_pt()=new Z2ErrorEstimator;
Helmholtz_mesh_pt->spatial_error_estimator_pt()=new Z2ErrorEstimator;
#endif
Solid_mesh_pt->output("solid_mesh.dat");
Helmholtz_mesh_pt->output("helmholtz_mesh.dat");
Solid_mesh_pt->output_boundaries("solid_mesh_boundary.dat");
Helmholtz_mesh_pt->output_boundaries("helmholtz_mesh_boundary.dat");
Solid_traction_mesh_pt=new Mesh;
create_solid_traction_elements();
FSI_traction_mesh_pt=new Mesh;
create_fsi_traction_elements();
Helmholtz_fsi_flux_mesh_pt=new Mesh;
create_helmholtz_fsi_flux_elements();
create_helmholtz_DtN_elements();
add_sub_mesh(Solid_mesh_pt);
add_sub_mesh(Solid_traction_mesh_pt);
add_sub_mesh(FSI_traction_mesh_pt);
add_sub_mesh(Helmholtz_mesh_pt);
add_sub_mesh(Helmholtz_fsi_flux_mesh_pt);
add_sub_mesh(Helmholtz_DtN_mesh_pt);
build_global_mesh();
complete_problem_setup();
setup_interaction();
char filename[100];
Trace_file.open(filename);
cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
delete_face_elements(Solid_traction_mesh_pt);
delete_face_elements(FSI_traction_mesh_pt);
delete_face_elements(Helmholtz_fsi_flux_mesh_pt);
delete_face_elements(Helmholtz_DtN_mesh_pt);
rebuild_global_mesh();
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
complete_problem_setup();
create_solid_traction_elements();
create_fsi_traction_elements();
create_helmholtz_fsi_flux_elements();
create_helmholtz_DtN_elements();
setup_interaction();
rebuild_global_mesh();
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
{
unsigned n_node = Solid_mesh_pt->nboundary_node(Upper_symmetry_boundary_id);
for(unsigned i=0;i<n_node;i++)
{
Node* nod_pt=Solid_mesh_pt->boundary_node_pt(Upper_symmetry_boundary_id,i);
nod_pt->pin(0);
nod_pt->set_value(0,0.0);
nod_pt->pin(3);
nod_pt->set_value(3,0.0);
nod_pt->pin(2);
nod_pt->set_value(2,0.0);
nod_pt->pin(5);
nod_pt->set_value(5,0.0);
}
}
{
unsigned n_node = Solid_mesh_pt->nboundary_node(Lower_symmetry_boundary_id);
for(unsigned i=0;i<n_node;i++)
{
Node* nod_pt=Solid_mesh_pt->boundary_node_pt(Lower_symmetry_boundary_id,i);
nod_pt->pin(0);
nod_pt->set_value(0,0.0);
nod_pt->pin(3);
nod_pt->set_value(3,0.0);
nod_pt->pin(2);
nod_pt->set_value(2,0.0);
nod_pt->pin(5);
nod_pt->set_value(5,0.0);
}
}
unsigned nreg=Solid_mesh_pt->nregion();
for (unsigned r=0;r<nreg;r++)
{
unsigned nel=Solid_mesh_pt->nregion_element(r);
for (unsigned e=0;e<nel;e++)
{
ELASTICITY_ELEMENT *el_pt =
dynamic_cast<ELASTICITY_ELEMENT*>(Solid_mesh_pt->
region_element_pt(r,e));
}
}
unsigned n_element = Helmholtz_mesh_pt->nelement();
for(unsigned i=0;i<n_element;i++)
{
HELMHOLTZ_ELEMENT *el_pt = dynamic_cast<HELMHOLTZ_ELEMENT*>(
Helmholtz_mesh_pt->element_pt(i));
}
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
unsigned n_element = boundary_mesh_pt->nelement();
for(unsigned e=0;e<n_element;e++)
{
delete boundary_mesh_pt->element_pt(e);
}
boundary_mesh_pt->flush_element_and_node_storage();
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
unsigned b=HH_outer_boundary_id;
unsigned n_element = Helmholtz_mesh_pt->nboundary_element(b);
for(unsigned e=0;e<n_element;e++)
{
HELMHOLTZ_ELEMENT* bulk_elem_pt = dynamic_cast<HELMHOLTZ_ELEMENT*>(
Helmholtz_mesh_pt->boundary_element_pt(b,e));
int face_index = Helmholtz_mesh_pt->face_index_at_boundary(b,e);
FourierDecomposedHelmholtzDtNBoundaryElement<HELMHOLTZ_ELEMENT>*
flux_element_pt = new
FourierDecomposedHelmholtzDtNBoundaryElement<HELMHOLTZ_ELEMENT>
(bulk_elem_pt,face_index);
Helmholtz_DtN_mesh_pt->add_element_pt(flux_element_pt);
flux_element_pt->set_outer_boundary_mesh_pt(Helmholtz_DtN_mesh_pt);
}
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
unsigned boundary_in_helmholtz_mesh=HH_inner_boundary_id;
ofstream the_file;
the_file.open("boundary_coordinate_hh.dat");
Helmholtz_mesh_pt->Mesh::template doc_boundary_coordinates<HELMHOLTZ_ELEMENT>
(boundary_in_helmholtz_mesh, the_file);
the_file.close();
Multi_domain_functions::setup_bulk_elements_adjacent_to_face_mesh
<HELMHOLTZ_ELEMENT,2>
(this,boundary_in_helmholtz_mesh,Helmholtz_mesh_pt,FSI_traction_mesh_pt);
unsigned boundary_in_solid_mesh=Outer_boundary_id;
the_file.open("boundary_coordinate_solid.dat");
Solid_mesh_pt->Mesh::template doc_boundary_coordinates<ELASTICITY_ELEMENT>
(boundary_in_solid_mesh, the_file);
the_file.close();
Multi_domain_functions::setup_bulk_elements_adjacent_to_face_mesh
<ELASTICITY_ELEMENT,2>(
this,boundary_in_solid_mesh,Solid_mesh_pt,Helmholtz_fsi_flux_mesh_pt);
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
unsigned b=Outer_boundary_id;
unsigned n_element = Solid_mesh_pt->nboundary_element(b);
for(unsigned e=0;e<n_element;e++)
{
ELASTICITY_ELEMENT* bulk_elem_pt = dynamic_cast<ELASTICITY_ELEMENT*>(
Solid_mesh_pt->boundary_element_pt(b,e));
int face_index = Solid_mesh_pt->face_index_at_boundary(b,e);
FourierDecomposedTimeHarmonicLinElastLoadedByHelmholtzPressureBCElement
<ELASTICITY_ELEMENT,HELMHOLTZ_ELEMENT>* el_pt=
new FourierDecomposedTimeHarmonicLinElastLoadedByHelmholtzPressureBCElement
<ELASTICITY_ELEMENT,HELMHOLTZ_ELEMENT>(bulk_elem_pt,
face_index);
FSI_traction_mesh_pt->add_element_pt(el_pt);
el_pt->set_boundary_number_in_bulk_mesh(b);
}
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
unsigned b=HH_inner_boundary_id;
unsigned n_element = Helmholtz_mesh_pt->nboundary_element(b);
for(unsigned e=0;e<n_element;e++)
{
HELMHOLTZ_ELEMENT* bulk_elem_pt = dynamic_cast<HELMHOLTZ_ELEMENT*>(
Helmholtz_mesh_pt->boundary_element_pt(b,e));
int face_index = Helmholtz_mesh_pt->face_index_at_boundary(b,e);
FourierDecomposedHelmholtzFluxFromNormalDisplacementBCElement
<HELMHOLTZ_ELEMENT,ELASTICITY_ELEMENT>* el_pt=
new FourierDecomposedHelmholtzFluxFromNormalDisplacementBCElement
<HELMHOLTZ_ELEMENT,ELASTICITY_ELEMENT>(bulk_elem_pt,
face_index);
Helmholtz_fsi_flux_mesh_pt->add_element_pt(el_pt);
el_pt->set_boundary_number_in_bulk_mesh(b);
}
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
unsigned b=0;
unsigned nb=3;
for (unsigned i=0;i<nb;i++)
{
switch(i)
{
case 0:
b=Upper_inner_boundary_id;
break;
case 1:
b=Lower_inner_boundary_id;
break;
case 2:
b=Rib_divider_boundary_id;
break;
}
unsigned r=0;
unsigned n_element = Solid_mesh_pt->nboundary_element_in_region(b,r);
for(unsigned e=0;e<n_element;e++)
{
ELASTICITY_ELEMENT* bulk_elem_pt = dynamic_cast<ELASTICITY_ELEMENT*>(
Solid_mesh_pt->boundary_element_in_region_pt(b,r,e));
int face_index = Solid_mesh_pt->face_index_at_boundary_in_region(b,r,e);
TimeHarmonicFourierDecomposedLinearElasticityTractionElement
<ELASTICITY_ELEMENT>* el_pt=
new TimeHarmonicFourierDecomposedLinearElasticityTractionElement
<ELASTICITY_ELEMENT>(bulk_elem_pt,face_index);
Solid_traction_mesh_pt->add_element_pt(el_pt);
el_pt->set_boundary_number_in_bulk_mesh(b);
}
}
}
template<class ELASTICITY_ELEMENT, class HELMHOLTZ_ELEMENT>
{
oomph_info << "Writing result for step " << doc_info.number()
<< ". Parameters: "<< std::endl;
oomph_info << "Fourier mode number : N = "
<< std::endl;
<< std::endl;
oomph_info << "Solid wavenumber : Omega_sq = "
oomph_info << "Solid wavenumber : Omega_sq = "
<< std::endl << std::endl;
ofstream some_file,some_file2;
char filename[100];
unsigned n_plot=5;
sprintf(filename,"%s/power%i.dat",doc_info.directory().c_str(),
doc_info.number());
some_file.open(filename);
double power=0.0;
unsigned nn_element=Helmholtz_DtN_mesh_pt->nelement();
for(unsigned e=0;e<nn_element;e++)
{
FourierDecomposedHelmholtzBCElementBase<HELMHOLTZ_ELEMENT> *el_pt =
dynamic_cast<FourierDecomposedHelmholtzBCElementBase<HELMHOLTZ_ELEMENT>*>(
Helmholtz_DtN_mesh_pt->element_pt(e));
power += el_pt->global_power_contribution(some_file);
}
some_file.close();
oomph_info << "Radiated power: " << power << std::endl;
sprintf(filename,"%s/elast_soln%i.dat",doc_info.directory().c_str(),
doc_info.number());
some_file.open(filename);
Solid_mesh_pt->output(some_file,n_plot);
some_file.close();
sprintf(filename,"%s/helmholtz_soln%i.dat",doc_info.directory().c_str(),
doc_info.number());
some_file.open(filename);
Helmholtz_mesh_pt->output(some_file,n_plot);
some_file.close();
sprintf(filename,"%s/fsi_traction_soln%i.dat",doc_info.directory().c_str(),
doc_info.number());
some_file.open(filename);
FSI_traction_mesh_pt->output(some_file,n_plot);
some_file.close();
sprintf(filename,"%s/fsi_flux_bc_soln%i.dat",doc_info.directory().c_str(),
doc_info.number());
some_file.open(filename);
Helmholtz_fsi_flux_mesh_pt->output(some_file,n_plot);
some_file.close();
<< power << " "
<< std::endl;
doc_info.number()++;
}
int main(
int argc,
char **argv)
{
CommandLineArgs::setup(argc,argv);
CommandLineArgs::specify_command_line_flag("--dir",
CommandLineArgs::specify_command_line_flag("--alpha",
CommandLineArgs::parse_and_assign();
CommandLineArgs::doc_specified_flags();
DocInfo doc_info;
#ifdef ADAPTIVE
ProjectableTimeHarmonicFourierDecomposedLinearElasticityElement
<TTimeHarmonicFourierDecomposedLinearElasticityElement<3> >,
ProjectableFourierDecomposedHelmholtzElement
<TFourierDecomposedHelmholtzElement<3> > > problem;
#else
TFourierDecomposedHelmholtzElement<3> > problem;
#endif
unsigned nstep=3;
for(unsigned i=0;i<nstep;i++)
{
#ifdef ADAPTIVE
unsigned max_adapt=3;
problem.newton_solve(max_adapt);
#else
problem.newton_solve();
#endif
if (i==0)
{
}
if (i==1)
{
}
}
}
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.
void complete_problem_setup()
Complete problem setup: Apply boundary conditions and set physical properties.
void actions_after_adapt()
Actions after adapt: Rebuild the face meshes.
void create_helmholtz_DtN_elements()
Create DtN elements on outer boundary.
void create_solid_traction_elements()
Create solid traction elements.
void create_helmholtz_fsi_flux_elements()
Create Helmholtz FSI flux elements.
void doc_solution(DocInfo &doc_info)
Doc the solution.
CoatedSphereProblem()
Constructor:
void setup_interaction()
Setup interaction.
////////////////////////////////////////////////////////////////////
int main(int argc, char **argv)
Driver for coated sphere loaded by lineared fluid loading.
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
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.
double P
Uniform pressure.
std::complex< double > Nu(std::complex< double >(0.3, 0.0))
Poisson's ratio Nu.
double Density_ratio
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.