Hello guys,

I wrote this program for an elasticity axisimmetric problem of concentric
pipes. I took the example 4 of system equations as basis and made some
changes. The problem is that the result is completely wrong: even thought I
had imposed internal and external pressures and self weight in the right
hand side my output in displacements is constant all over the pipe. At this
point I can only think that I've messed up with the matrix assembling.
Someone knows how can I print the stiffness matrix once assembled?

I've attached a document with the weak formulation of the problem (2D) I'm
trying to solve - it's the equation 9 without the thermal contribute.

Thanks,

rod12

Here it goes:


// C++ include files that we need
#include <iostream>
#include <algorithm>
#include <math.h>

// libMesh includes
#include "libmesh/libmesh.h"
#include "libmesh/mesh.h"
#include "libmesh/mesh_generation.h"
#include "libmesh/exodusII_io.h"
#include "libmesh/gnuplot_io.h"
#include "libmesh/linear_implicit_system.h"
#include "libmesh/equation_systems.h"
#include "libmesh/fe.h"
#include "libmesh/quadrature_gauss.h"
#include "libmesh/dof_map.h"
#include "libmesh/sparse_matrix.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/dense_matrix.h"
#include "libmesh/dense_submatrix.h"
#include "libmesh/dense_vector.h"
#include "libmesh/dense_subvector.h"
#include "libmesh/perf_log.h"
#include "libmesh/elem.h"
#include "libmesh/boundary_info.h"
#include "libmesh/zero_function.h"
#include "libmesh/dirichlet_boundaries.h"
#include "libmesh/string_to_enum.h"
#include "libmesh/getpot.h"

//Handling errors
void error (std::string & str){
    std::cerr<<str<<std::endl;
    exit(1);

    }

using namespace libMesh;

Real mu (const Real x);

Real lambda (const Real x);

Real rho (const Real x);

Real PressurexR (const Real x,const Real y);
// Bring in everything from the libMesh namespace

// Matrix and right-hand side assemble
void assemble_elasticity(EquationSystems& es,
                         const std::string& system_name);


// Begin the main program.
int main (int argc, char** argv)
{
  // Initialize libMesh and any dependent libaries
  LibMeshInit init (argc, argv);

  GetPot command_line (argc, argv);

  // Initialize the cantilever mesh
  const unsigned int dim = 2;

  // Skip this 2D example if libMesh was compiled as 1D-only.
  //libmesh_example_assert(dim <= LIBMESH_DIM, "2D support");

    int psr = 50;
    if ( command_line.search(1, "-nx") )
        psr = command_line.next(psr);

    int psl = 50;
    if ( command_line.search(1, "-ny") )
        psl = command_line.next(psl);


    const Real R_i = 0.12;
    const Real R_e = 0.30;
    const Real L = 10.0;

  // Create a 2D mesh distributed across the default MPI communicator.
  Mesh mesh(init.comm(), dim);
  MeshTools::Generation::build_square (mesh,
                                       psr, psl,
                                       R_i, R_e,
                                       0., L,
                                       QUAD9);


  // Print information about the mesh to the screen.
  mesh.print_info();


  // Create an equation systems object.
  EquationSystems equation_systems (mesh);

  // Declare the system and its variables.
  // Create a system named "Elasticity"
  LinearImplicitSystem& system =
    equation_systems.add_system<LinearImplicitSystem> ("Elasticity");


  // Add two displacement variables, u and v, to the system
  unsigned int u_var = system.add_variable("u", SECOND, LAGRANGE);
  unsigned int v_var = system.add_variable("v", SECOND, LAGRANGE);


  system.attach_assemble_function (assemble_elasticity);

  // Construct a Dirichlet boundary condition object
  // We impose a "clamped" boundary condition on the
  // "lowear" and "upper" boundaries, i.e. bc_id = 0,2
  std::set<boundary_id_type> boundary_ids;
  boundary_ids.insert(0);
  boundary_ids.insert(2);

  // Create a vector storing the variable numbers which the BC applies to
  std::vector<unsigned int> variables(2);
  variables[0] = u_var; variables[1] = v_var;

  // Create a ZeroFunction to initialize dirichlet_bc
  ZeroFunction<> zf;

  DirichletBoundary dirichlet_bc(boundary_ids,
                                 variables,
                                 &zf);

  // We must add the Dirichlet boundary condition _before_
  // we call equation_systems.init()
  system.get_dof_map().add_dirichlet_boundary(dirichlet_bc);

  // Initialize the data structures for the equation system.
  equation_systems.init();

  // Print information about the system to the screen.
  equation_systems.print_info();

  // Solve the system
  system.solve();

  // Plot the solution
#ifdef LIBMESH_HAVE_EXODUS_API
  ExodusII_IO
(mesh).write_equation_systems("displacement.e",equation_systems);
#endif // #ifdef LIBMESH_HAVE_EXODUS_API

  // All done.
  return 0;
}


Real mu (const Real x){
    //steel inner and outer constants
    const Real E_pipe_mod = 2e11;
    const Real poisson_pipe_mod = 0.3;

    //mu pipe
    const Real mu_p = E_pipe_mod/(2*(1+poisson_pipe_mod));

    //insulation constants
    const Real E_ins_mod = 5e9;
    const Real poisson_ins_mod = 0.4;


    const Real mu_i = E_ins_mod/(2*(1+poisson_ins_mod));

    //overall internal and external radius
    const Real R_i = 0.12;
    const Real R_e = 0.30;

    //internal and external steel pipe thickness
    const Real ti = 0.020;
    const Real te = 0.018;

    //insulation thickness

    if (x >= R_i && x <= R_i+ti )
        return mu_p;

    else if (x > R_i + ti && x < R_e-te )
        return mu_i;

    else if (x >= R_e - te && x <= R_e )
        return mu_p;

    else{
        std::string s1("Function mu called for x out of domain bonds!");
        error(s1);

    }




}

Real lambda (const Real x){
    //steel inner and outer constants
    const Real E_pipe_mod = 2e11;
    const Real poisson_pipe_mod = 0.3;

    //mu pipe
    const Real lambda_p =
(E_pipe_mod*poisson_pipe_mod)/((1+poisson_pipe_mod)*(1-2*poisson_pipe_mod));

    //insulation constants
    const Real E_ins_mod = 5e9;
    const Real poisson_ins_mod = 0.4;


    const Real lambda_i =
(E_ins_mod*poisson_ins_mod)/((1+poisson_ins_mod)*(1-2*poisson_ins_mod));

    //overall internal and external radius
    const Real R_i = 0.12;
    const Real R_e = 0.30;

    //internal and external steel pipe thickness
    const Real ti = 0.020;
    const Real te = 0.018;

    //insulation thickness

    if (x >= R_i && x <= R_i+ti )
        return lambda_p;

    else if (x > R_i + ti && x < R_e-te )
        return lambda_i;

    else if (x >= R_e - te && x <= R_e )
        return lambda_p;

    else{
        std::string s1("Function lambda called for x out of domain bonds!");
        error(s1);

    }




}

Real rho (const Real x){
    //steel inner and outer constants
    const Real rho_pipe = 8e3;


    const Real rho_ins = 1.3e3;

    //overall internal and external radius
    const Real R_i = 0.12;
    const Real R_e = 0.30;

    //internal and external steel pipe thickness
    const Real ti = 0.020;
    const Real te = 0.018;

    //insulation thickness

    if (x >= R_i && x <= R_i+ti )
        return rho_pipe;

    else if (x > R_i + ti && x < R_e-te )
        return rho_ins;

    else if (x >= R_e - te && x <= R_e )
        return rho_pipe;

    else{
        std::string s1("Function rho called for x out of domain bonds!");
        error(s1);

    }




}


Real PressurexR (const Real x,const Real y = 0.){

    const Real R_i = 0.12;
    const Real R_e = 0.30;
    const Real L = 10;

    //linear change on external temperature with gradient equal to the max
    //verified in ocean conditions
    if (x == R_i)
        return R_i*(104e6 - 10000*y);

    else if (x == R_e)
        return R_e*(1.5e7 - 10500*y);

    else{
        std::cerr<<"x = "<<x<<"y = "<<y<<std::endl;
        std::string s1("Function PressurexR called for x out of domain
bonds!");
        error(s1);

    }



}
void assemble_elasticity(EquationSystems& es,
                         const std::string& system_name)
{
    //making sure we will assemble the right system
    libmesh_assert_equal_to (system_name, "Elasticity");

    //getting the mesh reference
    const MeshBase& mesh = es.get_mesh();

    //getting dimension of the system
    const unsigned int dim = mesh.mesh_dimension();


    LinearImplicitSystem& system =
es.get_system<LinearImplicitSystem>("Elasticity");

    //getting the variable numbers
    const unsigned int u_var = system.variable_number ("u");
    const unsigned int v_var = system.variable_number ("v");

    //getting dof map and the fe type (both variables have the same type
otherwise need to be changed)
    const DofMap& dof_map = system.get_dof_map();
    FEType fe_type = dof_map.variable_type(0);

    //having a "dynamic" pointer of the prescribed type, getting default
quadrature order
    AutoPtr<FEBase> fe (FEBase::build(dim, fe_type));
    QGauss qrule (dim, fe_type.default_quadrature_order());
    fe->attach_quadrature_rule (&qrule);

    //same for boundary elements
    AutoPtr<FEBase> fe_face (FEBase::build(dim, fe_type));
    QGauss qface(dim-1, fe_type.default_quadrature_order());
    fe_face->attach_quadrature_rule (&qface);


    //jacobian and quadrature weights for numeric integration (taken in the
quadrature points)
    const std::vector<Real>& JxW = fe->get_JxW();
    const std::vector<std::vector<Real> >& phi = fe->get_phi();
    const std::vector<std::vector<RealGradient> >& dphi = fe->get_dphi();

    const std::vector<Point>& q_point = fe->get_xyz();



    DenseMatrix<Number> Ke;
    DenseVector<Number> Fe;

    //Submatrix for handling
    DenseSubMatrix<Number>
    Kuu(Ke), Kuv(Ke),
    Kvu(Ke), Kvv(Ke);

    DenseSubVector<Number>
    Fu(Fe),
    Fv(Fe);

    std::vector<dof_id_type> dof_indices;
    std::vector<dof_id_type> dof_indices_u;
    std::vector<dof_id_type> dof_indices_v;

    MeshBase::const_element_iterator       el     =
mesh.active_local_elements_begin();
    const MeshBase::const_element_iterator end_el =
mesh.active_local_elements_end();

    for ( ; el != end_el; ++el)
    {
      const Elem* elem = *el;

      dof_map.dof_indices (elem, dof_indices);
      dof_map.dof_indices (elem, dof_indices_u, u_var);
      dof_map.dof_indices (elem, dof_indices_v, v_var);

      const unsigned int n_dofs   = dof_indices.size();
      const unsigned int n_u_dofs = dof_indices_u.size();
      const unsigned int n_v_dofs = dof_indices_v.size();

      fe->reinit (elem);

      Ke.resize (n_dofs, n_dofs);
      Fe.resize (n_dofs);

      Kuu.reposition (u_var*n_u_dofs, u_var*n_u_dofs, n_u_dofs, n_u_dofs);
      Kuv.reposition (u_var*n_u_dofs, v_var*n_u_dofs, n_u_dofs, n_v_dofs);

      Kvu.reposition (v_var*n_v_dofs, u_var*n_v_dofs, n_v_dofs, n_u_dofs);
      Kvv.reposition (v_var*n_v_dofs, v_var*n_v_dofs, n_v_dofs, n_v_dofs);

      Fu.reposition (u_var*n_u_dofs, n_u_dofs);
      Fv.reposition (v_var*n_u_dofs, n_v_dofs);

      for (unsigned int qp=0; qp<qrule.n_points(); qp++)
      {

          const Real x = q_point[qp](0);
          const Real y = q_point[qp](1);

          for (unsigned int i=0; i<n_u_dofs; i++){
            for (unsigned int j=0; j<n_u_dofs; j++)
            {


              //See the weak formulation

              Kuu(i,j) += JxW[qp]*2*mu(x)*x*dphi[j][qp](0)*dphi[i][qp](0);

              Kuu(i,j) += JxW[qp]*2*mu(x)*phi[j][qp]*phi[i][qp]/x;

              Kuu(i,j) += JxW[qp]*2*mu(x)*x*dphi[j][qp](1)*dphi[i][qp](1);

              Kuu(i,j) += JxW[qp]*lambda(x)*x*dphi[j][qp](0)*dphi[i][qp](0);

              Kuu(i,j) += JxW[qp]*lambda(x)*dphi[j][qp](0)*phi[i][qp];

              Kuu(i,j) += JxW[qp]*lambda(x)*phi[j][qp]*dphi[i][qp](0);

              Kuu(i,j) += JxW[qp]*lambda(x)*phi[j][qp]*phi[i][qp]/x;


            }
          }
          for (unsigned int i=0; i<n_u_dofs; i++)
            for (unsigned int j=0; j<n_v_dofs; j++)
            {

              Kuv(i,j) += JxW[qp]*2*mu(x)*x*dphi[j][qp](0)*dphi[i][qp](1);

              Kuv(i,j) += JxW[qp]*lambda(x)*x*dphi[j][qp](1)*dphi[i][qp](0);

              Kuv(i,j) +=  JxW[qp]*lambda(x)*dphi[j][qp](1)*phi[i][qp];

            }

          for (unsigned int i=0; i<n_v_dofs; i++)
            for (unsigned int j=0; j<n_u_dofs; j++)
            {

                Kvu(i,j) += JxW[qp]*2*mu(x)*x*dphi[j][qp](1)*dphi[i][qp](0);

                Kvu(i,j) +=
JxW[qp]*lambda(x)*x*dphi[j][qp](0)*dphi[i][qp](1);

                Kvu(i,j) +=  JxW[qp]*lambda(x)*phi[j][qp]*dphi[j][qp](1);
            }

          for (unsigned int i=0; i<n_v_dofs; i++)
            for (unsigned int j=0; j<n_v_dofs; j++)
            {

              Kvv(i,j) +=
JxW[qp]*(2*mu(x)+lambda(x))*x*dphi[j][qp](1)*dphi[j][qp](1);

              Kvv(i,j) += JxW[qp]*2*mu(x)*x*dphi[j][qp](0)*dphi[j][qp](0);
            }

          //body load
          for (unsigned int i=0; i<n_v_dofs; i++)
              Fv(i) += -JxW[qp]*10*x*(1000-rho(x))*phi[i][qp];


        }

        for (unsigned int side=0; side<elem->n_sides(); side++)
          if (elem->neighbor(side) == NULL)
            {
              const std::vector<std::vector<Real> >&  phi_face =
fe_face->get_phi();
              const std::vector<Real>& JxW_face = fe_face->get_JxW();
              const std::vector<Point>& q_point_face = fe_face->get_xyz();

              fe_face->reinit(elem, side);

              // Apply pressure on lateral sides (Newmann)
              if( !mesh.boundary_info->has_boundary_id (elem, side, 0) &&
!mesh.boundary_info->has_boundary_id (elem, side, 2) )
              {
                for (unsigned int qp=0; qp<qface.n_points(); qp++)
                {
                  const Real x = q_point_face[qp](0);
                  const Real y = q_point_face[qp](1);

                  for (unsigned int i=0; i<n_u_dofs; i++)
                  {
                      const Real R_i = 0.12;
                      const Real R_e = 0.30;

                      if (mesh.boundary_info->has_boundary_id (elem, side,
1) || mesh.boundary_info->has_boundary_id (elem, side, 3)){
                          std::cout<<"(x,y)=("<<x<<","<<y<<")"<<std::endl;

std::cout<<"PxR=("<<PressurexR(x,y)<<")"<<std::endl;
                          Fu(i) +=
-JxW_face[qp]*PressurexR(x,y)*phi_face[i][qp];

                      }

                  }
                }
              }
            }


      dof_map.constrain_element_matrix_and_vector (Ke, Fe, dof_indices);

      system.matrix->add_matrix (Ke, dof_indices);
      system.rhs->add_vector    (Fe, dof_indices);
    }


}
------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Libmesh-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libmesh-users

Reply via email to