#include <deal.II/base/quadrature_lib.h>
#include <deal.II/base/function.h>
#include <deal.II/base/tensor.h>
#include <deal.II/lac/vector.h>
#include <deal.II/lac/full_matrix.h>
#include <deal.II/lac/sparse_matrix.h>
#include <deal.II/lac/dynamic_sparsity_pattern.h>
#include <deal.II/lac/solver_cg.h>
#include <deal.II/lac/precondition.h>
#include <deal.II/lac/constraint_matrix.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_refinement.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_accessor.h>
#include <deal.II/dofs/dof_tools.h>
#include <deal.II/fe/fe_values.h>
#include <deal.II/numerics/vector_tools.h>
#include <deal.II/numerics/matrix_tools.h>
#include <deal.II/numerics/data_out.h>
#include <deal.II/numerics/error_estimator.h>
#include <deal.II/fe/fe_system.h>
#include <deal.II/fe/fe_q.h>
#include <fstream>
#include <iostream>
#include <cmath>
namespace Step8
{
using namespace dealii;
template <int dim>
class ElasticProblem
{
public:
ElasticProblem ();
~ElasticProblem ();
void run ();
private:
void setup_system ();
void assemble_system ();
void solve ();
void refine_grid ();
void output_results (const unsigned int cycle) const;
Triangulation<dim> triangulation;
DoFHandler<dim> dof_handler;
FESystem<dim> fe;
ConstraintMatrix hanging_node_constraints;
SparsityPattern sparsity_pattern;
SparseMatrix<double> system_matrix;
Vector<double> solution;
Vector<double> system_rhs;
};
/
/
/
/
/
//此处添加右端项 ,如果是本征应变问题,同样在这里添加。
/
/
/
/
/
template <int dim>
ElasticProblem<dim>::ElasticProblem ():
dof_handler (triangulation),
fe (FE_Q<dim>(1), dim)
{}
template <int dim>
ElasticProblem<dim>::~ElasticProblem ()
{
dof_handler.clear ();
}
/
/
/
/
template <int dim>
void ElasticProblem<dim>::setup_system ()
{
dof_handler.distribute_dofs (fe);
hanging_node_constraints.clear ();
DoFTools::make_hanging_node_constraints (dof_handler,
hanging_node_constraints);
hanging_node_constraints.close ();
DynamicSparsityPattern dsp(dof_handler.n_dofs(), dof_handler.n_dofs());
DoFTools::make_sparsity_pattern(dof_handler,
dsp,
hanging_node_constraints,
/*keep_constrained_dofs = */ true);
sparsity_pattern.copy_from (dsp);
system_matrix.reinit (sparsity_pattern);
solution.reinit (dof_handler.n_dofs());
system_rhs.reinit (dof_handler.n_dofs());
}
/
/
/
/
/
/
//有限元组装矩阵,右端项等部分模块
template <int dim>
void ElasticProblem<dim>::assemble_system ()
{
QGauss<dim> quadrature_formula(2);//选取高斯积分点
FEValues<dim> fe_values (fe, quadrature_formula,
update_values | update_gradients |
update_quadrature_points | update_JxW_values);//更新形函数梯度等
const unsigned int dofs_per_cell = fe.dofs_per_cell;//每个单元的自由度。
const unsigned int n_q_points = quadrature_formula.size();//获取高斯积分点个数
FullMatrix<double> cell_matrix (dofs_per_cell, dofs_per_cell);//建立单元矩阵。
Vector<double> cell_rhs (dofs_per_cell);//建立右手边向量。
std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);//获取全局节点编号。
double nu=0.3,mu=100000000000;
double lambda=2*mu*nu/(1-2*nu);
std::vector<Tensor<1, dim> > rhs_values (n_q_points);//将高斯积分点传入右手边计算函数,积分得到右手边的高斯积分点处的值。
typename DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
endc = dof_handler.end();//单元迭代器。
long double min=0;
long double temp=0.1;
long double temp1;
for (; cell!=endc; ++cell)
{
cell_matrix = 0;//单元矩阵赋值为0.
cell_rhs = 0;//单元右边项赋值为0.
fe_values.reinit (cell);//初始化当前单元。
std::vector<Point<dim> > points=fe_values.get_quadrature_points();
for (unsigned int i=0; i<dofs_per_cell; ++i)
{
const unsigned int
component_i = fe.system_to_component_index(i).first;
for (unsigned int j=0; j<dofs_per_cell; ++j)
{
const unsigned int
component_j = fe.system_to_component_index(j).first;
for (unsigned int q_point=0; q_point<n_q_points;
++q_point)
{
cell_matrix(i,j)
+=
(
(fe_values.shape_grad(i,q_point)[component_i] *
fe_values.shape_grad(j,q_point)[component_j] *
lambda)
+
(fe_values.shape_grad(i,q_point)[component_j] *
fe_values.shape_grad(j,q_point)[component_i] *
mu)
+
((component_i == component_j) ?
(fe_values.shape_grad(i,q_point) *
fe_values.shape_grad(j,q_point) *
mu) :
0)
)
*
fe_values.JxW(q_point);
}
}
}
for (unsigned int i=0; i<dofs_per_cell; ++i)
{
int comp=0;
if(i%2==0)
{
comp=1;
}
for(unsigned int q_point=0; q_point<n_q_points; ++q_point)
{
temp1=points[q_point][0]-0;
if(temp1>=0&&temp1<temp)
{
min=points[q_point][0];
temp=temp1;
}
if(points[q_point][0]<0&&points[q_point][1]>-0.0000000005&&points[q_point][1]<0.0000000005)
{
cell_rhs(i) +=2*mu*fe_values.shape_grad(i,q_point)[comp]*fe_values.JxW(q_point);
}
}
}
cell->get_dof_indices (local_dof_indices);
for (unsigned int i=0; i<dofs_per_cell; ++i)
{
for (unsigned int j=0; j<dofs_per_cell; ++j)
system_matrix.add (local_dof_indices[i],
local_dof_indices[j],
cell_matrix(i,j));
system_rhs(local_dof_indices[i]) += cell_rhs(i);
}
}
for(int i=0;i<dof_handler.n_dofs();i++){
if(system_rhs(i)!=0)
{
std::cout<<"successful add inner force"<<std::endl;
break;
}
}
std::cout<<"min="<<min<<std::endl;
hanging_node_constraints.condense (system_matrix);
hanging_node_constraints.condense (system_rhs);
std::map<types::global_dof_index,double> boundary_values;
VectorTools::interpolate_boundary_values (dof_handler,
0,
ZeroFunction<dim>(dim),
boundary_values);
MatrixTools::apply_boundary_values (boundary_values,
system_matrix,
solution,
system_rhs);
}
/
/
/
/
/
template <int dim>
void ElasticProblem<dim>::solve ()
{
SolverControl solver_control (2000, 1e-13);
SolverCG<> cg (solver_control);
PreconditionSSOR<> preconditioner;
preconditioner.initialize(system_matrix, 1.2);
cg.solve (system_matrix, solution, system_rhs,
preconditioner);
hanging_node_constraints.distribute (solution);
}
/
/
/
/
/
///有限元误差评估模块
template <int dim>
void ElasticProblem<dim>::refine_grid ()
{
Vector<float> estimated_error_per_cell (triangulation.n_active_cells());
KellyErrorEstimator<dim>::estimate (dof_handler,
QGauss<dim-1>(2),
typename FunctionMap<dim>::type(),
solution,
estimated_error_per_cell);
GridRefinement::refine_and_coarsen_fixed_number (triangulation,
estimated_error_per_cell,
0.3, 0.03);
triangulation.execute_coarsening_and_refinement ();
}
/
/
/
/
/
下面有限元后处理模块
template <int dim>
void ElasticProblem<dim>::output_results (const unsigned int cycle) const
{
std::string filename = "solution-";
filename += ('0' + cycle);
Assert (cycle < 10, ExcInternalError());
filename += ".vtk";
std::ofstream output (filename.c_str());
DataOut<dim> data_out;
data_out.attach_dof_handler (dof_handler);
std::vector<std::string> solution_names;
switch (dim)
{
case 1:
solution_names.push_back ("displacement");
break;
case 2:
solution_names.push_back ("x_displacement");
solution_names.push_back ("y_displacement");
break;
case 3:
solution_names.push_back ("x_displacement");
solution_names.push_back ("y_displacement");
solution_names.push_back ("z_displacement");
break;
default:
Assert (false, ExcNotImplemented());
}
data_out.add_data_vector (solution, solution_names);
data_out.build_patches ();
data_out.write_vtk (output);
//
//
QGauss<dim> quadrature_formula(2);
FEValues<dim> fe_values (fe, quadrature_formula,
update_values | update_gradients |
update_quadrature_points | update_JxW_values);
const unsigned int dofs_per_cell = fe.dofs_per_cell;
const unsigned int n_q_points = quadrature_formula.size();
double nu=0.3,mu=100000000000;
double lambda=2*mu*nu/(1-2*nu);
typename DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
endc = dof_handler.end();
std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
//
FullMatrix<double> C(3,3);
C=0;
C(0,0)=2*mu+lambda;
C(1,1)=2*mu+lambda;
C(2,2)=mu;
C(0,1)=lambda;
C(1,0)=lambda;
Vector<double> nodle_displace(dofs_per_cell);
FullMatrix<double> B(3,dofs_per_cell);//定义B矩阵。define B matrix
FullMatrix<double> quadrature_strain(n_q_points,3);//定义所有高斯点处的应变。 for one cell
FullMatrix<double> quadrature_stress(n_q_points,3);
std::string stress_data = "stress_data-";
std::string strain_data = "strain_data-";
stress_data += ('0' + cycle);
strain_data += ('0' + cycle);
Assert (cycle < 10, ExcInternalError());
stress_data += ".txt";
strain_data += ".txt";
std::ofstream stress(stress_data.c_str());
std::ofstream strain(strain_data.c_str());
for (; cell!=endc; ++cell)
{
fe_values.reinit (cell);
cell->get_dof_indices (local_dof_indices);
//下面开始进行单元内的节点应力应变还原。
//首先第一步,取出节点处的位移 节点位移的矩阵用如下表示。
nodle_displace=0;
for (unsigned int i=0; i<dofs_per_cell; ++i)//对自由度进行了循环。
{
nodle_displace(i)=solution(local_dof_indices[i]);
}
B=0;//定义B矩阵。
quadrature_strain=0;//定义所有高斯点处的应变。
quadrature_stress=0;
//
std::vector<Point<dim> > points=fe_values.get_quadrature_points();
//上面都是单元内定义的
for (unsigned int q_point=0; q_point<n_q_points; ++q_point){
for(int ii=1;ii<=4;ii++){
B(0,2*ii-2)=fe_values.shape_grad(2*ii-1,q_point)[0];
B(1,2*ii-1)=fe_values.shape_grad(2*ii-1,q_point)[1];
B(2,2*ii-2)=fe_values.shape_grad(2*ii-1,q_point)[1];
B(2,2*ii-1)=fe_values.shape_grad(2*ii-1,q_point)[0];
}
//上面求得了高斯点处的B矩阵,下面将其乘以节点位移。便可以获得高斯点处的应变。
for (int k=0;k<3;k++){
double sum=0;
for(int j=0;j<dofs_per_cell;j++){
sum+=B(k,j)*nodle_displace(j);
}
quadrature_strain(q_point,k)=sum;
}
if(fabs(points[q_point][0]-0.0000000000825488)<=0.00000000001){
strain<<points[q_point][0]<<" "<<points[q_point][1]<<" "<<" "<<quadrature_strain(q_point,0)<<" "<<quadrature_strain(q_point,1)<<" "<<quadrature_strain(q_point,2)<<" "<<std::endl;
}//上面求得了高斯点处的应变。下面求高斯点处的应力
for (int i=0;i<3;i++){
double sum=0;
for (int j=0;j<3;j++){
sum+=C(i,j)*(quadrature_strain(q_point,j));
}
quadrature_stress(q_point,i)=sum;
}
if(fabs(points[q_point][0]-0.0000000000825488)<=0.00000000001){
stress<<points[q_point][0]<<" "<<points[q_point][1]<<" "<<quadrature_stress(q_point,0)<<" "<<quadrature_stress(q_point,1)<<" "<<quadrature_stress(q_point,2)<<" "<<std::endl;
}
}
}
}
/
/
//下面划分网格并且控制自适应划分。
template <int dim>
void ElasticProblem<dim>::run ()
{
for (unsigned int cycle=0; cycle<1; ++cycle)
{
std::cout << "Cycle " << cycle << ':' << std::endl;
if (cycle == 0)
{
GridGenerator::hyper_cube (triangulation, -0.0000001,0.0000001);
triangulation.refine_global (9);
}
else
refine_grid ();
std::cout << " Number of active cells: "
<< triangulation.n_active_cells()
<< std::endl;
setup_system ();
std::cout << " Number of degrees of freedom: "
<< dof_handler.n_dofs()
<< std::endl;
assemble_system ();
solve ();
output_results (cycle);
}
}
}
/
/
int main ()
{
try
{
Step8::ElasticProblem<2> elastic_problem_2d;
elastic_problem_2d.run ();
}
catch (std::exception &exc)
{
std::cerr << std::endl << std::endl
<< "----------------------------------------------------"
<< std::endl;
std::cerr << "Exception on processing: " << std::endl
<< exc.what() << std::endl
<< "Aborting!" << std::endl
<< "----------------------------------------------------"
<< std::endl;
return 1;
}
catch (...)
{
std::cerr << std::endl << std::endl
<< "----------------------------------------------------"
<< std::endl;
std::cerr << "Unknown exception!" << std::endl
<< "Aborting!" << std::endl
<< "----------------------------------------------------"
<< std::endl;
return 1;
}
return 0;
}
处理数据程序
clear
clc
stress_data=load("stress_data-0.txt");
strain_data=load("strain_data-0.txt");
a=strain_data(1,1);
x2=strain_data(:,2);
b=10^(-9);
nu=0.3;
mu=10^11;
data_sigma={};
data_epsilon={};
n=length(x2);
%下面作的是解析解。
for i=1:n
data_sigma{1}(i)=(b*mu*x2(i)*(3*a^2 + x2(i)^2))/(2*pi*(a^2 + x2(i)^2)^2*(nu - 1));
data_sigma{2}(i)=-(b*mu*x2(i)*(a^2 - x2(i)^2))/(2*pi*(a^2 + x2(i)^2)^2*(nu - 1));
data_sigma{4}(i)= -(b*mu*a*(a^2 - x2(i)^2))/(2*pi*(a^2 + x2(i)^2)^2*(nu - 1));
data_sigma{3}(i)=(b*mu*nu*x2(i))/(pi*(a^2 + x2(i)^2)*(nu - 1));
data_epsilon{1}(i)=-(b*x2(i)*(2*nu*a^2 + 2*nu*x2(i)^2 - 3*a^2 - x2(i)^2))/(4*pi*(a^2 + x2(i)^2)^2*(nu - 1));
data_epsilon{3}(i)=-(b*a*(a^2 - x2(i)^2))/(4*pi*(a^2 + x2(i)^2)^2*(nu - 1));
data_epsilon{2}(i)=-(b*x2(i)*(2*nu*a^2 + 2*nu*x2(i)^2 + a^2 - x2(i)^2))/(4*pi*(a^2 + x2(i)^2)^2*(nu - 1));
end