deal-II计算刃位错周围弹性场程序与数据处理程序

#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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值