35 #include "axisym_linear_elasticity.h" 38 #include "meshes/rectangular_quadmesh.h" 42 using namespace oomph;
57 double Mu = E/2.0/(1.0+
Nu);
88 const Vector<double> &x,
89 const Vector<double> &n,
90 Vector<double> &result)
92 result[0] = cos(time)*(-6.0*pow(x[0],2)*Mu*cos(x[1])-
93 Lambda*(4.0*pow(x[0],2)+pow(x[0],3))*cos(x[1]));
94 result[1] = cos(time)*(-Mu*(3.0*pow(x[0],2)-pow(x[0],3))*sin(x[1]));
95 result[2] = cos(time)*(-Mu*pow(x[0],2)*(2*pow(x[1],3)));
101 const Vector<double> &x,
102 Vector<double> &result)
104 result[0] = cos(time)*(
106 (Lambda*(8.0+3.0*x[0])-
107 Mu*(-16.0+x[0]*(x[0]-3.0))+pow(x[0],2)*
Omega_sq)));
108 result[1] = cos(time)*(
109 x[0]*sin(x[1])*(Mu*(-9.0)+
110 4.0*x[0]*(Lambda+
Mu)+pow(x[0],2)*
112 result[2] = cos(time)*(
113 -x[0]*(8.0*Mu*pow(x[1],3)+pow(x[0],2)*(pow(x[1],3)*Omega_sq+6.0*Mu*x[1])));
123 u[0] = pow(x[0],3)*cos(x[1]);
124 u[1] = pow(x[0],3)*sin(x[1]);
125 u[2] = pow(x[0],3)*pow(x[1],3);
134 double u_r(
const double &time,
const Vector<double> &x)
136 Vector<double> displ(3);
138 return cos(time)*displ[0];
142 double u_z(
const double &time,
const Vector<double> &x)
144 Vector<double> displ(3);
146 return cos(time)*displ[1];
150 double u_theta(
const double &time,
const Vector<double> &x)
152 Vector<double> displ(3);
154 return cos(time)*displ[2];
158 double d_u_r_dt(
const double &time,
const Vector<double> &x)
160 Vector<double> displ(3);
162 return -sin(time)*displ[0];
166 double d_u_z_dt(
const double &time,
const Vector<double> &x)
168 Vector<double> displ(3);
170 return -sin(time)*displ[1];
176 Vector<double> displ(3);
178 return -sin(time)*displ[2];
182 double d2_u_r_dt2(
const double &time,
const Vector<double> &x)
184 Vector<double> displ(3);
186 return -cos(time)*displ[0];
190 double d2_u_z_dt2(
const double &time,
const Vector<double> &x)
192 Vector<double> displ(3);
194 return -cos(time)*displ[1];
200 Vector<double> displ(3);
202 return -cos(time)*displ[2];
208 const Vector<double> &x,
230 template<
class ELEMENT,
class TIMESTEPPER>
249 set_boundary_conditions();
254 void set_initial_conditions();
257 void set_boundary_conditions();
260 void doc_solution(DocInfo& doc_info);
265 void assign_traction_elements();
279 template<
class ELEMENT,
class TIMESTEPPER>
284 add_time_stepper_pt(
new TIMESTEPPER());
287 Bulk_mesh_pt =
new RectangularQuadMesh<ELEMENT>(
297 Surface_mesh_pt=
new Mesh;
298 assign_traction_elements();
301 set_boundary_conditions();
306 unsigned n_el = Bulk_mesh_pt->nelement();
307 for(
unsigned e=0;e<n_el;e++)
310 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
327 unsigned n_traction = Surface_mesh_pt->nelement();
328 for(
unsigned e=0;e<n_traction;e++)
331 AxisymmetricLinearElasticityTractionElement<ELEMENT>*
333 dynamic_cast<AxisymmetricLinearElasticityTractionElement
334 <ELEMENT
>* >(Surface_mesh_pt->element_pt(e));
342 add_sub_mesh(Bulk_mesh_pt);
343 add_sub_mesh(Surface_mesh_pt);
349 cout << assign_eqn_numbers() <<
" equations assigned" << std::endl;
390 template<
class ELEMENT,
class TIMESTEPPER>
394 unsigned bound, n_neigh;
398 n_neigh = Bulk_mesh_pt->nboundary_element(bound);
401 for(
unsigned n=0;n<n_neigh;n++)
404 FiniteElement *traction_element_pt
405 =
new AxisymmetricLinearElasticityTractionElement<ELEMENT>
406 (Bulk_mesh_pt->boundary_element_pt(bound,n),
407 Bulk_mesh_pt->face_index_at_boundary(bound,n));
410 Surface_mesh_pt->add_element_pt(traction_element_pt);
418 template<
class ELEMENT,
class TIMESTEPPER>
423 TIMESTEPPER* timestepper_pt =
424 dynamic_cast<TIMESTEPPER*
>(time_stepper_pt());
427 bool impulsive_start=
false;
432 unsigned n_node = Bulk_mesh_pt->nnode();
435 for(
unsigned inod=0;inod<n_node;inod++)
438 Node* nod_pt = Bulk_mesh_pt->node_pt(inod);
446 nod_pt->set_value(0,0);
447 nod_pt->set_value(1,0);
448 nod_pt->set_value(2,0);
451 timestepper_pt->assign_initial_values_impulsive(nod_pt);
458 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
459 initial_value_fct(3);
460 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
461 initial_veloc_fct(3);
462 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
463 initial_accel_fct(3);
481 unsigned n_node = Bulk_mesh_pt->nnode();
484 for(
unsigned inod=0;inod<n_node;inod++)
487 Node* nod_pt = Bulk_mesh_pt->node_pt(inod);
490 timestepper_pt->assign_initial_data_values(nod_pt,
500 for(
unsigned jnod=0;jnod<n_node;jnod++)
503 Node* nod_pt=Bulk_mesh_pt->node_pt(jnod);
515 double u_theta_exact=
519 double d_u_r_dt_exact=
521 double d_u_z_dt_exact=
523 double d_u_theta_dt_exact=
527 double d2_u_r_dt2_exact=
529 double d2_u_z_dt2_exact=
531 double d2_u_theta_dt2_exact=
536 double u_r_fe=timestepper_pt->time_derivative(0,nod_pt,0);
537 double u_z_fe=timestepper_pt->time_derivative(0,nod_pt,1);
538 double u_theta_fe=timestepper_pt->time_derivative(0,nod_pt,2);
541 double d_u_r_dt_fe=timestepper_pt->time_derivative(1,nod_pt,0);
542 double d_u_z_dt_fe=timestepper_pt->time_derivative(1,nod_pt,1);
543 double d_u_theta_dt_fe=timestepper_pt->time_derivative(1,nod_pt,2);
546 double d2_u_r_dt2_fe=timestepper_pt->time_derivative(2,nod_pt,0);
547 double d2_u_z_dt2_fe=timestepper_pt->time_derivative(2,nod_pt,1);
548 double d2_u_theta_dt2_fe=timestepper_pt->time_derivative(2,nod_pt,2);
552 double error=sqrt(pow(u_r_exact-u_r_fe,2)+
553 pow(u_z_exact-u_z_fe,2)+
554 pow(u_theta_exact-u_theta_fe,2)+
555 pow(d_u_r_dt_exact-d_u_r_dt_fe,2)+
556 pow(d_u_z_dt_exact-d_u_z_dt_fe,2)+
557 pow(d_u_theta_dt_exact-d_u_theta_dt_fe,2)+
558 pow(d2_u_r_dt2_exact-d2_u_r_dt2_fe,2)+
559 pow(d2_u_z_dt2_exact-d2_u_z_dt2_fe,2)+
560 pow(d2_u_theta_dt2_exact-d2_u_theta_dt2_fe,2));
568 std::cout <<
"Max error in assignment of initial conditions " 569 << err_max << std::endl;
576 template<
class ELEMENT,
class TIMESTEPPER>
592 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
593 initial_value_fct(3);
594 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
595 initial_veloc_fct(3);
596 Vector<typename TIMESTEPPER::NodeInitialConditionFctPt>
597 initial_accel_fct(3);
619 for (
unsigned ibound=0;ibound<=2;ibound++)
621 unsigned num_nod=Bulk_mesh_pt->nboundary_node(ibound);
622 for (
unsigned inod=0;inod<num_nod;inod++)
625 Node* nod_pt=Bulk_mesh_pt->boundary_node_pt(ibound,inod);
628 nod_pt->pin(0);nod_pt->pin(1);nod_pt->pin(2);
631 bool use_direct_assigment=
true;
632 if (use_direct_assigment)
642 nod_pt->set_value(0,u[0]);
643 nod_pt->set_value(1,u[1]);
644 nod_pt->set_value(2,u[2]);
650 TIMESTEPPER* timestepper_pt =
651 dynamic_cast<TIMESTEPPER*
>(time_stepper_pt());
654 timestepper_pt->assign_initial_data_values(nod_pt,
666 template<
class ELEMENT,
class TIMESTEPPER>
677 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
679 some_file.open(filename);
680 Bulk_mesh_pt->output(some_file,npts);
684 sprintf(filename,
"%s/exact_soln%i.dat",doc_info.directory().c_str(),
686 some_file.open(filename);
687 Bulk_mesh_pt->output_fct(some_file,npts,time_pt()->time(),
694 sprintf(filename,
"%s/error%i.dat",doc_info.directory().c_str(),
696 some_file.open(filename);
697 Bulk_mesh_pt->compute_error(some_file,
704 cout <<
"\nNorm of error: " << sqrt(error) << std::endl;
705 cout <<
"Norm of solution: " << sqrt(norm) << std::endl << std::endl;
718 int main(
int argc,
char* argv[])
721 CommandLineArgs::setup(argc,argv);
727 CommandLineArgs::specify_command_line_flag(
"--validation");
730 CommandLineArgs::parse_and_assign();
733 CommandLineArgs::doc_specified_flags();
739 doc_info.set_directory(
"RESLT");
743 <QAxisymmetricLinearElasticityElement<3>, Newmark<1> > problem;
746 problem.time_pt()->time()=0.0;
753 if(CommandLineArgs::command_line_flag_has_been_set(
"--validation"))
761 problem.time_pt()->initialise_dt(dt);
767 problem.doc_solution(doc_info);
774 if(CommandLineArgs::command_line_flag_has_been_set(
"--validation"))
781 double t_max=2*MathematicalConstants::Pi;
783 nstep=unsigned(t_max/dt);
787 for(
unsigned istep=0;istep<nstep;istep++)
790 problem.unsteady_newton_solve(dt);
793 problem.doc_solution(doc_info);
double Omega_sq
Square of the frequency of the time dependence.
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_r_dt2(const double &time, const Vector< double > &x)
Calculate the time dependent form of the r-component of acceleration.
double d_u_r_dt(const double &time, const Vector< double > &x)
Calculate the time dependent form of the r-component of velocity.
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) ...
double u_z(const double &time, const Vector< double > &x)
Calculate the time dependent form of the z-component of displacement.
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)
AxisymmetricLinearElasticityProblem()
Constructor: Pass number of elements in r and z directions, boundary locations and whether we are doi...
double Rmin
Set up min r coordinate.
unsigned Nr
Number of elements in r-direction.
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 d2_u_z_dt2(const double &time, const Vector< double > &x)
Calculate the time dependent form of the z-component of acceleration.
double E
Define the non-dimensional Young's modulus.
void exact_solution(const double &time, const Vector< double > &x, Vector< double > &u)
void assign_traction_elements()
Allocate traction elements on the bottom surface.
Namespace for global parameters.
double d2_u_theta_dt2(const double &time, const Vector< double > &x)
Calculate the time dependent form of the theta-component of acceleration.
void set_initial_conditions()
Set the initial conditions, either for an impulsive start or with history values for the time stepper...
void actions_after_newton_solve()
Update after solve is empty.
void actions_before_newton_solve()
Update before solve is empty.
unsigned Nz
Number of elements in z-direction.
double Lr
Length of domain in r direction.
double Zmax
Set up max z coordinate.
void set_boundary_conditions()
Set the boundary conditions.
Mesh * Surface_mesh_pt
Pointer to the mesh of traction elements.
double u_r(const double &time, const Vector< double > &x)
Calculate the time dependent form of the r-component of displacement.
double Lz
Length of domain in z-direction.
double Nu
Define Poisson's ratio Nu.
double Lambda
Lame parameters.
void actions_before_implicit_timestep()
Actions before implicit timestep.
double Rmax
Set up max 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.
void doc_solution(DocInfo &doc_info)
Doc the solution.
int main(int argc, char *argv[])
Driver code.
Mesh * Bulk_mesh_pt
Pointer to the bulk mesh.
double u_theta(const double &time, const Vector< double > &x)
Calculate the time dependent form of the theta-component of displacement.
double Zmin
Set up min z coordinate.