31 #include "axisym_linear_elasticity.h"
34 #include "meshes/rectangular_quadmesh.h"
38 using namespace oomph;
84 const Vector<double> &x,
85 const Vector<double> &n,
86 Vector<double> &result)
88 result[0] = cos(time)*(-6.0*pow(x[0],2)*
Mu*cos(x[1])-
89 Lambda*(4.0*pow(x[0],2)+pow(x[0],3))*cos(x[1]));
90 result[1] = cos(time)*(-
Mu*(3.0*pow(x[0],2)-pow(x[0],3))*sin(x[1]));
91 result[2] = cos(time)*(-
Mu*pow(x[0],2)*(2*pow(x[1],3)));
97 const Vector<double> &x,
98 Vector<double> &result)
100 result[0] = cos(time)*(
103 Mu*(-16.0+x[0]*(x[0]-3.0))+pow(x[0],2)*
Omega_sq)));
104 result[1] = cos(time)*(
105 x[0]*sin(x[1])*(
Mu*(-9.0)+
108 result[2] = cos(time)*(
109 -x[0]*(8.0*
Mu*pow(x[1],3)+pow(x[0],2)*(pow(x[1],3)*
Omega_sq+6.0*
Mu*x[1])));
119 u[0] = pow(x[0],3)*cos(x[1]);
120 u[1] = pow(x[0],3)*sin(x[1]);
121 u[2] = pow(x[0],3)*pow(x[1],3);
130 double u_r(
const double &time,
const Vector<double> &x)
132 Vector<double> displ(3);
134 return cos(time)*displ[0];
138 double u_z(
const double &time,
const Vector<double> &x)
140 Vector<double> displ(3);
142 return cos(time)*displ[1];
146 double u_theta(
const double &time,
const Vector<double> &x)
148 Vector<double> displ(3);
150 return cos(time)*displ[2];
154 double d_u_r_dt(
const double &time,
const Vector<double> &x)
156 Vector<double> displ(3);
158 return -sin(time)*displ[0];
162 double d_u_z_dt(
const double &time,
const Vector<double> &x)
164 Vector<double> displ(3);
166 return -sin(time)*displ[1];
172 Vector<double> displ(3);
174 return -sin(time)*displ[2];
178 double d2_u_r_dt2(
const double &time,
const Vector<double> &x)
180 Vector<double> displ(3);
182 return -cos(time)*displ[0];
186 double d2_u_z_dt2(
const double &time,
const Vector<double> &x)
188 Vector<double> displ(3);
190 return -cos(time)*displ[1];
196 Vector<double> displ(3);
198 return -cos(time)*displ[2];
204 const Vector<double> &x,
226 template<
class ELEMENT,
class TIMESTEPPER>
245 set_boundary_conditions();
250 void set_initial_conditions();
253 void set_boundary_conditions();
256 void doc_solution(DocInfo& doc_info);
261 void assign_traction_elements();
275 template<
class ELEMENT,
class TIMESTEPPER>
280 add_time_stepper_pt(
new TIMESTEPPER());
283 Bulk_mesh_pt =
new RectangularQuadMesh<ELEMENT>(
293 Surface_mesh_pt=
new Mesh;
294 assign_traction_elements();
297 set_boundary_conditions();
302 unsigned n_el = Bulk_mesh_pt->nelement();
303 for(
unsigned e=0;e<n_el;e++)
306 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
323 unsigned n_traction = Surface_mesh_pt->nelement();
324 for(
unsigned e=0;e<n_traction;e++)
327 AxisymmetricLinearElasticityTractionElement<ELEMENT>*
329 dynamic_cast<AxisymmetricLinearElasticityTractionElement
330 <ELEMENT
>* >(Surface_mesh_pt->element_pt(e));
338 add_sub_mesh(Bulk_mesh_pt);
339 add_sub_mesh(Surface_mesh_pt);
345 cout << assign_eqn_numbers() <<
" equations assigned" << std::endl;
386 template<
class ELEMENT,
class TIMESTEPPER>
390 unsigned bound, n_neigh;
394 n_neigh = Bulk_mesh_pt->nboundary_element(bound);
397 for(
unsigned n=0;n<n_neigh;n++)
400 FiniteElement *traction_element_pt
401 =
new AxisymmetricLinearElasticityTractionElement<ELEMENT>
402 (Bulk_mesh_pt->boundary_element_pt(bound,n),
403 Bulk_mesh_pt->face_index_at_boundary(bound,n));
406 Surface_mesh_pt->add_element_pt(traction_element_pt);
414 template<
class ELEMENT,
class TIMESTEPPER>
419 TIMESTEPPER* timestepper_pt =
420 dynamic_cast<TIMESTEPPER*
>(time_stepper_pt());
423 bool impulsive_start=
false;
428 unsigned n_node = Bulk_mesh_pt->nnode();
431 for(
unsigned inod=0;inod<n_node;inod++)
434 Node* nod_pt = Bulk_mesh_pt->node_pt(inod);
442 nod_pt->set_value(0,0);
443 nod_pt->set_value(1,0);
444 nod_pt->set_value(2,0);
447 timestepper_pt->assign_initial_values_impulsive(nod_pt);
454 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
455 initial_value_fct(3);
456 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
457 initial_veloc_fct(3);
458 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
459 initial_accel_fct(3);
477 unsigned n_node = Bulk_mesh_pt->nnode();
480 for(
unsigned inod=0;inod<n_node;inod++)
483 Node* nod_pt = Bulk_mesh_pt->node_pt(inod);
486 timestepper_pt->assign_initial_data_values(nod_pt,
496 for(
unsigned jnod=0;jnod<n_node;jnod++)
499 Node* nod_pt=Bulk_mesh_pt->node_pt(jnod);
511 double u_theta_exact=
515 double d_u_r_dt_exact=
517 double d_u_z_dt_exact=
519 double d_u_theta_dt_exact=
523 double d2_u_r_dt2_exact=
525 double d2_u_z_dt2_exact=
527 double d2_u_theta_dt2_exact=
532 double u_r_fe=timestepper_pt->time_derivative(0,nod_pt,0);
533 double u_z_fe=timestepper_pt->time_derivative(0,nod_pt,1);
534 double u_theta_fe=timestepper_pt->time_derivative(0,nod_pt,2);
537 double d_u_r_dt_fe=timestepper_pt->time_derivative(1,nod_pt,0);
538 double d_u_z_dt_fe=timestepper_pt->time_derivative(1,nod_pt,1);
539 double d_u_theta_dt_fe=timestepper_pt->time_derivative(1,nod_pt,2);
542 double d2_u_r_dt2_fe=timestepper_pt->time_derivative(2,nod_pt,0);
543 double d2_u_z_dt2_fe=timestepper_pt->time_derivative(2,nod_pt,1);
544 double d2_u_theta_dt2_fe=timestepper_pt->time_derivative(2,nod_pt,2);
548 double error=sqrt(pow(u_r_exact-u_r_fe,2)+
549 pow(u_z_exact-u_z_fe,2)+
550 pow(u_theta_exact-u_theta_fe,2)+
551 pow(d_u_r_dt_exact-d_u_r_dt_fe,2)+
552 pow(d_u_z_dt_exact-d_u_z_dt_fe,2)+
553 pow(d_u_theta_dt_exact-d_u_theta_dt_fe,2)+
554 pow(d2_u_r_dt2_exact-d2_u_r_dt2_fe,2)+
555 pow(d2_u_z_dt2_exact-d2_u_z_dt2_fe,2)+
556 pow(d2_u_theta_dt2_exact-d2_u_theta_dt2_fe,2));
564 std::cout <<
"Max error in assignment of initial conditions "
565 << err_max << std::endl;
572 template<
class ELEMENT,
class TIMESTEPPER>
588 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
589 initial_value_fct(3);
590 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
591 initial_veloc_fct(3);
592 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
593 initial_accel_fct(3);
615 for (
unsigned ibound=0;ibound<=2;ibound++)
617 unsigned num_nod=Bulk_mesh_pt->nboundary_node(ibound);
618 for (
unsigned inod=0;inod<num_nod;inod++)
621 Node* nod_pt=Bulk_mesh_pt->boundary_node_pt(ibound,inod);
624 nod_pt->pin(0);nod_pt->pin(1);nod_pt->pin(2);
627 bool use_direct_assigment=
true;
628 if (use_direct_assigment)
638 nod_pt->set_value(0,u[0]);
639 nod_pt->set_value(1,u[1]);
640 nod_pt->set_value(2,u[2]);
646 TIMESTEPPER* timestepper_pt =
647 dynamic_cast<TIMESTEPPER*
>(time_stepper_pt());
650 timestepper_pt->assign_initial_data_values(nod_pt,
662 template<
class ELEMENT,
class TIMESTEPPER>
673 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
675 some_file.open(filename);
676 Bulk_mesh_pt->output(some_file,npts);
680 sprintf(filename,
"%s/exact_soln%i.dat",doc_info.directory().c_str(),
682 some_file.open(filename);
683 Bulk_mesh_pt->output_fct(some_file,npts,time_pt()->time(),
690 sprintf(filename,
"%s/error%i.dat",doc_info.directory().c_str(),
692 some_file.open(filename);
693 Bulk_mesh_pt->compute_error(some_file,
700 cout <<
"\nNorm of error: " << sqrt(error) << std::endl;
701 cout <<
"Norm of solution: " << sqrt(norm) << std::endl << std::endl;
714 int main(
int argc,
char* argv[])
717 CommandLineArgs::setup(argc,argv);
723 CommandLineArgs::specify_command_line_flag(
"--validation");
726 CommandLineArgs::parse_and_assign();
729 CommandLineArgs::doc_specified_flags();
735 doc_info.set_directory(
"RESLT");
739 <QAxisymmetricLinearElasticityElement<3>, Newmark<1> > problem;
742 problem.time_pt()->time()=0.0;
749 if(CommandLineArgs::command_line_flag_has_been_set(
"--validation"))
757 problem.time_pt()->initialise_dt(dt);
763 problem.doc_solution(doc_info);
770 if(CommandLineArgs::command_line_flag_has_been_set(
"--validation"))
777 double t_max=2*MathematicalConstants::Pi;
779 nstep=unsigned(t_max/dt);
783 for(
unsigned istep=0;istep<nstep;istep++)
786 problem.unsteady_newton_solve(dt);
789 problem.doc_solution(doc_info);
Class to validate time harmonic linear elasticity (Fourier decomposed)
void actions_before_newton_solve()
Update before solve is empty.
void doc_solution(DocInfo &doc_info)
Doc the solution.
Mesh * Bulk_mesh_pt
Pointer to the bulk mesh.
Mesh * Surface_mesh_pt
Pointer to the mesh of traction elements.
void set_initial_conditions()
Set the initial conditions, either for an impulsive start or with history values for the time stepper...
void actions_before_implicit_timestep()
Actions before implicit timestep.
AxisymmetricLinearElasticityProblem()
Constructor: Pass number of elements in r and z directions, boundary locations and whether we are doi...
void assign_traction_elements()
Allocate traction elements on the bottom surface.
void set_boundary_conditions()
Set the boundary conditions.
void actions_after_newton_solve()
Update after solve is empty.
int main(int argc, char *argv[])
Driver code.
Namespace for global parameters.
double Rmax
Set up max r coordinate.
double Zmin
Set up min z coordinate.
unsigned Nz
Number of elements in z-direction.
double Nu
Define Poisson's ratio Nu.
double d2_u_z_dt2(const double &time, const Vector< double > &x)
Calculate the time dependent form of the z-component of acceleration.
double Lz
Length of domain in z-direction.
double Zmax
Set up max z coordinate.
double d2_u_r_dt2(const double &time, const Vector< double > &x)
Calculate the time dependent form of the r-component of acceleration.
void exact_solution_th(const Vector< double > &x, Vector< double > &u)
Helper function - spatial components of the exact solution in a vector. This is necessary because we ...
double Lr
Length of domain in r direction.
void boundary_traction(const double &time, const Vector< double > &x, const Vector< double > &n, Vector< double > &result)
The traction function at r=Rmin: (t_r, t_z, t_theta)
void body_force(const double &time, const Vector< double > &x, Vector< double > &result)
The body force function; returns vector of doubles in the order (b_r, b_z, b_theta)
void exact_solution(const double &time, const Vector< double > &x, Vector< double > &u)
The exact solution in a vector: 0: u_r, 1: u_z, 2: u_theta and their 1st and 2nd derivs.
double d_u_theta_dt(const double &time, const Vector< double > &x)
Calculate the time dependent form of the theta-component of velocity.
double d2_u_theta_dt2(const double &time, const Vector< double > &x)
Calculate the time dependent form of the theta-component of acceleration.
double E
Define the non-dimensional Young's modulus.
double d_u_r_dt(const double &time, const Vector< double > &x)
Calculate the time dependent form of the r-component of velocity.
double Rmin
Set up min r coordinate.
double d_u_z_dt(const double &time, const Vector< double > &x)
Calculate the time dependent form of the z-component of velocity.
double u_z(const double &time, const Vector< double > &x)
Calculate the time dependent form of the z-component of displacement.
double Lambda
Lame parameters.
double u_r(const double &time, const Vector< double > &x)
Calculate the time dependent form of the r-component of displacement.
double u_theta(const double &time, const Vector< double > &x)
Calculate the time dependent form of the theta-component of displacement.
unsigned Nr
Number of elements in r-direction.
double Omega_sq
Square of the frequency of the time dependence.