Detailed documentation to be written. Here's the already fairly well documented driver code...
#include <iostream>
#include <fstream>
#include <cmath>
#include "generic.h"
#include "solid.h"
#include "meshes/quarter_circle_sector_mesh.h"
using namespace std;
using namespace oomph;
{
const Vector<double> &n, Vector<double> &traction)
{
unsigned dim = traction.size();
for(unsigned i=0;i<dim;i++)
{
}
}
}
template <class ELEMENT>
public virtual RefineableQuarterCircleSectorMesh<ELEMENT>,
public virtual SolidMesh
{
public:
const double& xi_lo,
const double& fract_mid,
const double& xi_hi,
TimeStepper* time_stepper_pt=
&Mesh::Default_TimeStepper) :
RefineableQuarterCircleSectorMesh<ELEMENT>(wall_pt,xi_lo,fract_mid,xi_hi,
time_stepper_pt)
{
#ifdef PARANOID
SolidFiniteElement* el_pt=dynamic_cast<SolidFiniteElement*>
(finite_element_pt(0));
if (el_pt==0)
{
throw OomphLibError(
"Element needs to be derived from SolidFiniteElement\n",
OOMPH_CURRENT_FUNCTION,
OOMPH_EXCEPTION_LOCATION);
}
#endif
set_lagrangian_nodal_coordinates();
}
void make_traction_element_mesh(SolidMesh*& traction_mesh_pt)
{
traction_mesh_pt=new SolidMesh;
unsigned b=1;
unsigned n_element = this->nboundary_element(b);
for (unsigned e=0;e<n_element;e++)
{
FiniteElement* fe_pt = this->boundary_element_pt(b,e);
int face_index = this->face_index_at_boundary(b,e);
traction_mesh_pt->add_element_pt(new SolidTractionElement<ELEMENT>
(fe_pt,face_index));
}
}
void remake_traction_element_mesh(SolidMesh*& traction_mesh_pt)
{
traction_mesh_pt->flush_element_and_node_storage();
unsigned b=1;
unsigned n_element = this->nboundary_element(b);
for (unsigned e=0;e<n_element;e++)
{
FiniteElement* fe_pt = this->boundary_element_pt(b,e);
int face_index = this->face_index_at_boundary(b,e);
traction_mesh_pt->add_element_pt(new SolidTractionElement<ELEMENT>
(fe_pt,face_index));
}
}
};
template<class ELEMENT, class TIMESTEPPER>
{
public:
void run(const unsigned& case_number);
{
return Solid_mesh_pt;
}
SolidMesh*& traction_mesh_pt()
{
return Traction_mesh_pt;
}
void doc_solution();
void actions_after_newton_solve() {}
void actions_before_newton_solve() {}
void actions_after_adapt();
void doc_displ_and_veloc(const int& stage=0);
void dump_it(ofstream& dump_file);
void restart(ifstream& restart_file);
private:
DocInfo Doc_info;
ofstream Trace_file;
Vector<Node*> Trace_node_pt;
SolidMesh* Traction_mesh_pt;
};
template<class ELEMENT, class TIMESTEPPER>
{
add_time_stepper_pt(new TIMESTEPPER);
double x_c=0.0;
double y_c=0.0;
double r=1.0;
GeomObject* curved_boundary_pt=new Circle(x_c,y_c,r,time_stepper_pt());
double xi_lo=0.0;
double xi_hi=2.0*atan(1.0);
double fract_mid=0.5;
curved_boundary_pt,xi_lo,fract_mid,xi_hi,time_stepper_pt());
unsigned nnod0=solid_mesh_pt()->nboundary_node(0);
unsigned nnod1=solid_mesh_pt()->nboundary_node(1);
Trace_node_pt.resize(nnod0+nnod1);
for (unsigned j=0;j<nnod0;j++)
{
Trace_node_pt[j]=solid_mesh_pt()->boundary_node_pt(0,j);
}
for (unsigned j=0;j<nnod1;j++)
{
Trace_node_pt[j+nnod0]=solid_mesh_pt()->boundary_node_pt(1,j);
}
solid_mesh_pt()->make_traction_element_mesh(traction_mesh_pt());
add_sub_mesh(solid_mesh_pt());
add_sub_mesh(traction_mesh_pt());
build_global_mesh();
solid_mesh_pt()->spatial_error_estimator_pt()=new Z2ErrorEstimator;
solid_mesh_pt()->max_permitted_error()=0.006;
solid_mesh_pt()->min_permitted_error()=0.0006;
solid_mesh_pt()->doc_adaptivity_targets(cout);
unsigned n_bottom = solid_mesh_pt()->nboundary_node(0);
for(unsigned i=0;i<n_bottom;i++)
{
solid_mesh_pt()->boundary_node_pt(0,i)->pin_position(1);
}
unsigned n_side = solid_mesh_pt()->nboundary_node(2);
for(unsigned i=0;i<n_side;i++)
{
solid_mesh_pt()->boundary_node_pt(2,i)->pin_position(0);
}
unsigned n_element =solid_mesh_pt()->nelement();
for(unsigned i=0;i<n_element;i++)
{
ELEMENT *el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
el_pt->constitutive_law_pt() =
el_pt->enable_inertia();
}
PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
solid_mesh_pt()->element_pt());
n_element=traction_mesh_pt()->nelement();
for(unsigned i=0;i<n_element;i++)
{
SolidTractionElement<ELEMENT> *el_pt =
dynamic_cast<SolidTractionElement<ELEMENT>*>
(traction_mesh_pt()->element_pt(i));
}
cout << assign_eqn_numbers() << std::endl;
refine_uniformly();
refine_uniformly();
refine_uniformly();
bool update_all_solid_nodes=true;
solid_mesh_pt()->node_update(update_all_solid_nodes);
solid_mesh_pt()->set_lagrangian_nodal_coordinates();
}
template<class ELEMENT, class TIMESTEPPER>
{
solid_mesh_pt()->remake_traction_element_mesh(traction_mesh_pt());
rebuild_global_mesh();
unsigned n_element=traction_mesh_pt()->nelement();
for(unsigned i=0;i<n_element;i++)
{
SolidTractionElement<ELEMENT> *el_pt =
dynamic_cast<SolidTractionElement<ELEMENT>*>
(traction_mesh_pt()->element_pt(i));
}
PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
solid_mesh_pt()->element_pt());
cout << assign_eqn_numbers() << std::endl;
}
template<class ELEMENT, class TIMESTEPPER>
{
unsigned npts;
npts=5;
ofstream some_file;
char filename[100];
sprintf(filename,"%s/soln%i.dat",Doc_info.directory().c_str(),
Doc_info.number());
some_file.open(filename);
solid_mesh_pt()->output(some_file,npts);
some_file.close();
unsigned nel=traction_mesh_pt()->nelement();
sprintf(filename,"%s/traction%i.dat",Doc_info.directory().c_str(),
Doc_info.number());
some_file.open(filename);
Vector<double> unit_normal(2);
Vector<double> traction(2);
Vector<double> x_dummy(2);
Vector<double> s_dummy(1);
for (unsigned e=0;e<nel;e++)
{
some_file << "ZONE " << std::endl;
for (unsigned i=0;i<npts;i++)
{
s_dummy[0]=-1.0+2.0*double(i)/double(npts-1);
SolidTractionElement<ELEMENT>* el_pt=
dynamic_cast<SolidTractionElement<ELEMENT>*>(
traction_mesh_pt()->finite_element_pt(e));
el_pt->outer_unit_normal(s_dummy,unit_normal);
el_pt->traction(s_dummy,traction);
el_pt->interpolated_x(s_dummy,x_dummy);
some_file << x_dummy[0] << " " << x_dummy[1] << " "
<< traction[0] << " " << traction[1] << " "
<< std::endl;
}
}
some_file.close();
doc_displ_and_veloc();
{
unsigned nelem=solid_mesh_pt()->nboundary_element(0);
sprintf(filename,"%s/displ%i.dat",Doc_info.directory().c_str(),
Doc_info.number());
some_file.open(filename);
Vector<double> s(2);
Vector<double> x(2);
Vector<double> dxdt(2);
Vector<double> xi(2);
Vector<double> r_exact(2);
Vector<double> v_exact(2);
for (unsigned e=0;e<nelem;e++)
{
some_file << "ZONE " << std::endl;
for (unsigned i=0;i<npts;i++)
{
s[0]=-1.0+2.0*double(i)/double(npts-1);
s[1]=-1.0;
SolidFiniteElement* el_pt=dynamic_cast<SolidFiniteElement*>
(solid_mesh_pt()->boundary_element_pt(0,e));
el_pt->interpolated_xi(s,xi);
el_pt->interpolated_x(s,x);
el_pt->interpolated_dxdt(s,1,dxdt);
some_file << xi[0] << " " << x[0]-xi[0] << " "
<< dxdt[0] << std::endl;
}
}
some_file.close();
}
Trace_file << time_pt()->time() << " ";
unsigned ntrace_node=Trace_node_pt.size();
for (unsigned j=0;j<ntrace_node;j++)
{
Trace_file << sqrt(pow(Trace_node_pt[j]->x(0),2)+
pow(Trace_node_pt[j]->x(1),2)) << " ";
}
Trace_file << std::endl;
cout << "Doced solution for step "
<< Doc_info.number()
<< std::endl << std::endl << std::endl;
}
template<class ELEMENT, class TIMESTEPPER>
const int& stage)
{
ofstream some_file;
char filename[100];
unsigned npts;
npts=5;
if (stage==-1)
{
sprintf(filename,"%s/displ_and_veloc_before%i.dat",
Doc_info.directory().c_str(),Doc_info.number());
}
else if (stage==1)
{
sprintf(filename,"%s/displ_and_veloc_after%i.dat",
Doc_info.directory().c_str(),Doc_info.number());
}
else
{
sprintf(filename,"%s/displ_and_veloc%i.dat",
Doc_info.directory().c_str(),Doc_info.number());
}
some_file.open(filename);
Vector<double> s(2),x(2),dxdt(2),xi(2),displ(2);
unsigned nel=solid_mesh_pt()->nelement();
for (unsigned e=0;e<nel;e++)
{
some_file << "ZONE I=" << npts << ", J=" << npts << std::endl;
for (unsigned i=0;i<npts;i++)
{
s[0]=-1.0+2.0*double(i)/double(npts-1);
for (unsigned j=0;j<npts;j++)
{
s[1]=-1.0+2.0*double(j)/double(npts-1);
ELEMENT* el_pt=dynamic_cast<ELEMENT*>(solid_mesh_pt()->
finite_element_pt(e));
el_pt->interpolated_x(s,x);
el_pt->interpolated_xi(s,xi);
displ[0]=x[0]-xi[0];
displ[1]=x[1]-xi[1];
el_pt->interpolated_dxdt(s,1,dxdt);
some_file << x[0] << " " << x[1] << " "
<< displ[0] << " " << displ[1] << " "
<< dxdt[0] << " " << dxdt[1] << " "
<< std::endl;
}
}
}
some_file.close();
}
template<class ELEMENT, class TIMESTEPPER>
{
Problem::dump(dump_file);
}
template<class ELEMENT, class TIMESTEPPER>
{
Problem::read(restart_file);
}
template<class ELEMENT, class TIMESTEPPER>
const unsigned& case_number)
{
unsigned nstep=400;
if (CommandLineArgs::Argc!=1)
{
nstep=3;
}
char dirname[100];
sprintf(dirname,"RESLT%i",case_number);
Doc_info.set_directory(dirname);
Doc_info.number()=0;
char filename[100];
sprintf(filename,"%s/trace.dat",Doc_info.directory().c_str());
Trace_file.open(filename);
unsigned nnod0=solid_mesh_pt()->nboundary_node(0);
unsigned nnod1=solid_mesh_pt()->nboundary_node(1);
Trace_file << "VARIABLES=\"time\"";
for (unsigned j=0;j<nnod0;j++)
{
Trace_file << ", \"radial node " << j << "\" ";
}
for (unsigned j=0;j<nnod1;j++)
{
Trace_file << ", \"azimuthal node " << j << "\" ";
}
Trace_file << std::endl;
double time0=0.0;
time_pt()->time()=time0;
double dt=0.01;
assign_initial_values_impulsive(dt);
doc_solution();
Doc_info.number()++;
unsteady_newton_solve(dt);
doc_solution();
Doc_info.number()++;
unsigned max_adapt=1;
for(unsigned i=1;i<nstep;i++)
{
unsteady_newton_solve(dt,max_adapt,false);
doc_solution();
Doc_info.number()++;
}
}
int main(
int argc,
char* argv[])
{
CommandLineArgs::setup(argc,argv);
unsigned case_number=0;
{
cout << "Running case " << case_number
<< ": Pure displacement formulation" << std::endl;
problem.
run(case_number);
case_number++;
}
{
cout << "Running case " << case_number
<< ": Pressure/displacement with Crouzeix-Raviart pressure" << std::endl;
problem;
problem.
run(case_number);
case_number++;
}
{
cout << "Running case " << case_number
<< ": Pressure/displacement with Taylor-Hood pressure" << std::endl;
Newmark<1> > problem;
problem.
run(case_number);
case_number++;
}
}
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void dump_it(ofstream &dump_file)
Dump problem-specific parameters values, then dump generic problem data.
void doc_displ_and_veloc(const int &stage=0)
Doc displacement and velocity: label file with before and after.
void doc_solution()
Doc the solution.
void actions_after_adapt()
Actions after adaption: Kill and then re-build the traction elements on boundary 1 and re-assign the ...
DiskShockWaveProblem()
Constructor:
void restart(ifstream &restart_file)
Read problem-specific parameter values, then recover generic problem data.
void run(const unsigned &case_number)
Run the problem; specify case_number to label output directory.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
void constant_pressure(const Vector< double > &xi, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Constant pressure load.
double P
Uniform pressure.
ConstitutiveLaw * Constitutive_law_pt
Pointer to constitutive law.
double Nu
Poisson's ratio.
int main(int argc, char *argv[])
Driver for simple elastic problem.