Hello, I think I'm having a similar problem to the OP. I searched a lot, 
but that's the closest that I could find. I'm trying to work with some 
meshes from gmsh, so I used the gridin functions to read them. 

  Triangulation<dim> triangulation;
  GridIn<dim> gridin;
  gridin.attach_triangulation(triangulation);
  std::ifstream f("plate4");
  gridin.read_msh(f);

The mesh was generated with the physical lines and physical surfaces as 
mentioned in step 49.

I even tested if it was actually reading by printing the number of active 
elements, and it is.

However, when I'm going to distribute the dofs, it gives this message

An error occurred in line <999> of file 
</home/erik/Downloads/dealii-9.0.1/source/dofs/dof_handler.cc> in function
    void dealii::DoFHandler<dim, spacedim>::distribute_dofs(const 
dealii::FiniteElement<dim, spacedim>&) [with int dim = 2; int spacedim = 2]
The violated condition was: 
    tria->n_levels() > 0
Additional information: 
    The Triangulation you are using is empty!


There's some problem that for some reason the information is lost in the 
next function when I call

  dof_handler.distribute_dofs (fe);

I double checked, and the DoF_handler is already associated with the 
triangulation

fe (FE_Q<dim>(order), dim),
  dof_handler (triangulation),

It is specially confusing to me, because if I generate a grid with the grid 
generator, it works perfectly fine. 

Respectfully
E.

Em sábado, 31 de agosto de 2013 07:16:10 UTC-3, Wolfgang Bangerth escreveu:
>
>
> > void CellProb::make_grid () 
> > { 
> >   Triangulation<2> tria1; 
> >   GridGenerator::hyper_cube_with_cylindrical_hole (tria1, 0.25, 1.0); 
> > 
> >          Triangulation<2> tria3; 
> >   GridGenerator::hyper_cube_with_cylindrical_hole (tria3, 0.25, 1.0); 
> >    GridTools::shift (Point<2>(0,-2), tria3); 
> >   Triangulation<2> triangulation2; 
> >   GridGenerator::merge_triangulations (tria1, tria3, triangulation2); 
> > 
> >   mesh_info(triangulation2, "grid-2.eps"); 
> >   std::cout << "Number of active cells: " 
> >              << triangulation.n_active_cells() 
> >              << std::endl; 
> >          std::cout << "Total number of cells: " 
> >              << triangulation.n_cells() 
> >              << std::endl; 
> > 
> > } 
> > but I get the following report: 
> > ============================ Remaking Makefile.dep 
> > ==============debug========= cell.cc  ->  cell.g.o 
> > ============================ Linking cell 
> > ============================ Running cell 
> > terminate called after throwing an instance of 
> > 'dealii::internal::Triangulation::ExcGridHasInvalidCell' 
> >    what():  -------------------------------------------------------- 
> > An error occurred in line <1672> of file 
> > </usr/local_rwth/sw/deal.II/deal.II-7.3.0/source/grid/tria.cc> in 
> function 
> >      static void 
> > 
> dealii::internal::Triangulation::Implementation::create_triangulation(const 
> > std::vector<dealii::Point<spacedim, double>, 
> > std::allocator<dealii::Point<spacedim, double>>> &, const 
> > std::vector<dealii::CellData<2>, std::allocator<dealii::CellData<2>>> &, 
> const 
> > dealii::SubCellData &, dealii::Triangulation<2, spacedim> &) [with 
> spacedim = 2] 
> > The violated condition was: 
> >      needed_lines.find(std::make_pair(line_vertices.second, 
> > line_vertices.first)) == needed_lines.end() 
> > The name and call sequence of the exception was: 
> >      ExcGridHasInvalidCell(cell) 
> > Additional Information: 
> > Something went wrong when making cell 9. Read the docs and the source 
> code for 
> > more information. 
> > -------------------------------------------------------- 
>
> I can reproduce this. Can you please open a bug report with the issue 
> tracker, 
> including your small testcase that shows the problem? 
>
>
> > My second question: 
> > I tried grid_2 (from tutorial 49) with the simple version of Poisson's 
> > equation and I get the following: 
> > ============================ Remaking Makefile.dep 
> > ==============debug========= cell.cc  ->  cell.g.o 
> > ============================ Linking cell 
> > ============================ Running cell 
> > Mesh info: 
> >   dimension: 2 
> >   no. of cells: 224 
> >   boundary indicators: 0(88 times) 
> >   written to grid-2.eps 
> > Number of active cells: 224 
> > Total number of cells: 294 
> > -------------------------------------------------------- 
> > An error occurred in line <230> of file 
> > 
> </usr/local_rwth/sw/deal.II/deal.II-7.3.0/source/dofs/dof_handler_policy.cc> 
>
> > in function 
> >      static unsigned int 
> > 
> dealii::internal::DoFHandler::Policy::Implementation::distribute_dofs(unsigned
>  
>
> > int, unsigned int, dealii::DoFHandler<dim, spacedim> &) [with dim = 2, 
> > spacedim = 2] 
> > The violated condition was: 
> >      tria.n_levels() > 0 
> > The name and call sequence of the exception was: 
> >      ExcMessage("Empty triangulation") 
> > Additional Information: 
> > Empty triangulation 
> > Stacktrace: 
> > ----------- 
> > #0  /usr/local_rwth/sw/deal.II/deal.II-7.3.0/lib/libdeal_II.g.so.7.3.0: 
> > unsigned int 
> > dealii::internal::DoFHandler::Policy::Implementation::distribute_dofs<2, 
> > 2>(unsigned int, unsigned int, dealii::DoFHandler<2, 2>&) 
> > #1  /usr/local_rwth/sw/deal.II/deal.II-7.3.0/lib/libdeal_II.g.so.7.3.0: 
> > dealii::internal::DoFHandler::Policy::Sequential<2, 
> > 2>::distribute_dofs(dealii::DoFHandler<2, 2>&) const 
> > #2  /usr/local_rwth/sw/deal.II/deal.II-7.3.0/lib/libdeal_II.g.so.7.3.0: 
> > dealii::DoFHandler<2, 2>::distribute_dofs(dealii::FiniteElement<2, 2> 
> const&) 
> > #3  ./cell: CellProb::setup_system() 
> > #4  ./cell: CellProb::run() 
> > #5  ./cell: main 
> > -------------------------------------------------------- 
> > make: *** [run] Aborted (core dumped) 
> > Why is the triangulation empty? 
> > I called "triangulation.refine_global (2)" because the documentation 
> says 
> > "since it will most likely be repopulated soon by the next refinement 
> > process", but it did not help. 
>
> Can you send us the code you used? This seems odd. Are you sure you have 
> associated the dof_handler object with the same triangulation for which 
> you 
> output the mesh info? 
>
> Best 
> W. 
>
> -- 
> ------------------------------------------------------------------------ 
> Wolfgang Bangerth               email:            bang...@math.tamu.edu 
> <javascript:> 
>                                  www: http://www.math.tamu.edu/~bangerth/ 
>
>

-- 
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see 
https://groups.google.com/d/forum/dealii?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to dealii+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/dealii/c55e8e0d-02f0-4647-b767-c37d3903a343%40googlegroups.com.
/*This is a template file for use with 3D finite elements (vector field).
  The portions of the code you need to fill in are marked with the comment "//EDIT".

  Do not change the name of any existing functions, but feel free
  to create additional functions, variables, and constants.
  It uses the deal.II FEM library.*/

//Include files
//Data structures and solvers
#include <deal.II/base/quadrature_lib.h>
#include <deal.II/base/function.h>
#include <deal.II/base/logstream.h>
#include <deal.II/base/tensor_function.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/sparse_direct.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/base/symmetric_tensor.h>
//Mesh related classes
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/grid/tria_boundary_lib.h>
#include <deal.II/grid/grid_tools.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/grid/grid_in.h>
#include <deal.II/grid/manifold_lib.h>
#include <deal.II/grid/grid_out.h>
//Finite element implementation classes
#include <deal.II/fe/fe_system.h>
#include <deal.II/fe/fe_values.h>
#include <deal.II/fe/fe_q.h>

#include <deal.II/lac/solver_cg.h>
#include <deal.II/lac/precondition.h>


//Standard C++ libraries
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <math.h>
using namespace dealii;

//Define the order of the basis functions (Lagrange polynomials)
//and the order of the quadrature rule globally
const unsigned int order = 1;
const unsigned int quadRule = 2;

template <int dim>
class FEM
{
 public:
  //Class functions
  FEM (); // Class constructor 
  ~FEM(); //Class destructor

  //Function to calculate components of the elasticity tensor
  double C(unsigned int i,unsigned int j,unsigned int k,unsigned int l);

  //Solution steps
  void generate_mesh(std::vector<unsigned int> numberOfElements);
  void define_boundary_conds();
  void setup_system();
  void assemble_system();
  void solve();
  void compute_stress();
  void output_results();



  //Class objects
  
  Triangulation<dim> triangulation; //mesh
  FESystem<dim>      fe;            //FE element
  DoFHandler<dim>    dof_handler;   //Connectivity matrices

  //NEW - deal.II quadrature
  QGauss<dim>   quadrature_formula;      //Quadrature
  QGauss<dim-1> face_quadrature_formula; //Face Quadrature

  //Data structures
  SparsityPattern      sparsity_pattern; //Sparse matrix pattern
  SparseMatrix<double> K;                //Global stiffness matrix - Sparse matrix - used in the solver
  Vector<double>       D, F;             //Global vectors - Solution vector (D) and Global force vector (F)

  Table<2,double>	        dofLocation;	 //Table of the coordinates of dofs by global dof number
  std::map<unsigned int,double> boundary_values; //Map of dirichlet boundary conditions

  //solution name array
  std::vector<std::string> nodal_solution_names;
  std::vector<DataComponentInterpretation::DataComponentInterpretation> nodal_data_component_interpretation;
};

// Class constructor for a vector field
template <int dim>
FEM<dim>::FEM ()
:
fe (FE_Q<dim>(order), dim),
  dof_handler (triangulation),
  quadrature_formula(quadRule),
  face_quadrature_formula(quadRule)
{	
	
  //Nodal Solution names - this is for writing the output file
  for (unsigned int i=0; i<dim; ++i){
    nodal_solution_names.push_back("u");
    nodal_data_component_interpretation.push_back(DataComponentInterpretation::component_is_part_of_vector);
  }
}

//Class destructor
template <int dim>
FEM<dim>::~FEM (){dof_handler.clear ();}

//Function to calculate the components of the 4th order elasticity tensor
template <int dim>
double FEM<dim>::C(unsigned int i,unsigned int j,unsigned int k,unsigned int l){

  double C11,C12,C13,C22,C23,C33,C44,C55,C66,lambda,mu;
  C11=8.75*pow(10,9);
  C12=1.5*pow(10,8);
  C13=0;
  C22=8.75*pow(10,9);
  C23=0;
  C33=0;
  C44=0;
  C55=0;
  C66=4.2*pow(10,9);
  lambda=3;
  mu=4.3333;
    
  if (i==0 && j==0 && k==0 && l==0)
    { 
      return (C11);
    }
  else if ((i==0 && j==0 && k==1 && l==1) || (i==1 && j==1 && k==0 && l==0))
    {
      return (C12);
    }
  else if ((i==0 && j==0 && k==2 && l==2) || (i==2 && j==2 && k==0 && l==0))
    {
      return (C13);
    }
  else if ((i==1 && j==1 && k==1 && l==1))
    {
      return (C22);
    }
  else if ((i==2 && j==2 && k==1 && l==1) || (i==1 && j==1 && k==2 && l==2))
    {
      return (C23);
    }
  else if ((i==2 && j==2 && k==2 && l==2))
    {
      return (C33);
    }
  else if ((i==1 && j==2 && k==1 && l==2) || (i==1 && j==2 && k==2 && l==1) || (i==2 && j==1 && k==1 && l==2) || (i==2 && j==1 && k==2 && l==1))
    {
      return (C44);
    }
  else if ((i==0 && j==2 && k==0 && l==2) || (i==0 && j==2 && k==2 && l==0) || (i==2 && j==0 && k==0 && l==2) || (i==2 && j==0 && k==2 && l==0))
    {
      return (C55);
    }
  else if ((i==0 && j==1 && k==0 && l==1) || (i==0 && j==1 && k==1 && l==0) || (i==1 && j==0 && k==0 && l==1) || (i==1 && j==0 && k==1 && l==0))
    {
      return (C66);
    }
  else
    {
      return 0;
    }

}

//Define the problem domain and generate the mesh
template <int dim>
void FEM<dim>::generate_mesh(std::vector<unsigned int> numberOfElements){

{

  Triangulation<dim> triangulation;
  GridIn<dim> gridin;
  gridin.attach_triangulation(triangulation);
  std::ifstream f("plate4");
  gridin.read_msh(f);
  triangulation.refine_global(1);
  std::cout << "   Number of active elems:       " << triangulation.n_active_cells() << std::endl;

}

}

//Specify the Dirichlet boundary conditions
template <int dim>
void FEM<dim>::define_boundary_conds(){

  //EDIT - Define the Dirichlet boundary conditions.
	
  /*Note: this will be very similiar to the define_boundary_conds function
    in the HW2 template. You will loop over all degrees of freedom and use "dofLocation"
    to check if the dof is on the boundary with a Dirichlet condition.

    (Aside: Since we	now have more than 1 dof per node, it is possible to apply a different Dirichlet
    condition on each of the 3 dofs on the same node. Note that this is NOT the case for the current 
    assignment. But if you wanted to do it, you would need to check
    the nodal dof (0, 1, or 2) as well as the location. For example, if you wanted to fix displacements
    only in the x-direction at x=0, you would have an condition such as this:
    (dofLocation[globalDOF][0] == 0 && nodalDOF == 0)
    Note that you can get the nodal dof from the global dof using the "modulo" operator,
    i.e nodalDOF = globalDOF%dim. Here "%" gives you the remainder when dividing globalDOF by dim.)

    Add the global dof number and the specified value (displacement in this problem)
    to the boundary values map, something like this:

    boundary_values[globalDOFIndex] = dirichletDisplacementValue

    Note that "dofLocation" is now a Table of degree of freedom locations, not just node locations,
    so, for example, dofs 0, 1, and 2 correspond to the same node, so that have the same coordinates.
    The row index is the global dof number; the column index refers to the x, y, or z component (0, 1, or 2 for 3D).
    e.g. dofLocation[7][2] is the z-coordinate of global dof 7*/

  const unsigned int totalDOFs = dof_handler.n_dofs(); //Total number of degrees of freedom

	  for(unsigned int globalDOF=0; globalDOF<totalDOFs; globalDOF++){
                unsigned int nodalDOF = globalDOF%dim;

		if(dofLocation[globalDOF][0]+1 == 0){
		  boundary_values[globalDOF] = 0;
		}

		if(dofLocation[globalDOF][1]+1 == 0 ){
		  boundary_values[globalDOF] = 0;
		}


//		if(dofLocation[globalDOF][0] == 1 && nodalDOF==0){ //Aplica deslocamento prescrito na direção x na face x = 1
	//	  boundary_values[globalDOF] = 1;
	//	}
	  }


}

//Setup data structures (sparse matrix, vectors)
template <int dim>
void FEM<dim>::setup_system(){


  std::cout << "   Number of  elems:       " << triangulation.n_cells() << std::endl; 

  std::cout << "   Number of active elems:       " << triangulation.n_active_cells() << std::endl;
  std::cout << "   Number of degrees of freedom: " << dof_handler.n_dofs() << std::endl;
  
  //Let deal.II organize degrees of freedom
  dof_handler.distribute_dofs (fe);

  //Get a vector of global degree-of-freedom x-coordinates
  MappingQ1<dim,dim> mapping;
  std::vector< Point<dim,double> > dof_coords(dof_handler.n_dofs());
  dofLocation.reinit(dof_handler.n_dofs(),dim);
  DoFTools::map_dofs_to_support_points<dim,dim>(mapping,dof_handler,dof_coords);
  for(unsigned int i=0; i<dof_coords.size(); i++){
    for(unsigned int j=0; j<dim; j++){
      dofLocation[i][j] = dof_coords[i][j];
    }
  }

  //Specify boundary condtions (call the function)
  define_boundary_conds();

  //Define the size of the global matrices and vectors
  sparsity_pattern.reinit (dof_handler.n_dofs(), 
			   dof_handler.n_dofs(),
			   dof_handler.max_couplings_between_dofs());
  DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
  sparsity_pattern.compress();
  K.reinit (sparsity_pattern);
  D.reinit(dof_handler.n_dofs());
  F.reinit(dof_handler.n_dofs());

  //Just some notes...
  std::cout << "   Number of active elems:       " << triangulation.n_active_cells() << std::endl;
  std::cout << "   Number of degrees of freedom: " << dof_handler.n_dofs() << std::endl;   
}

//Form elmental vectors and matrices and assemble to the global vector (F) and matrix (K)
template <int dim>
void FEM<dim>::assemble_system(){

  /*NEW - deal.II basis functions, etc. The third input values (after fe and quadrature_formula) 
    specify what information we	want to be updated. For fe_values, we need the basis function values,
    basis function gradients,	and det(Jacobian) times the quadrature weights (JxW). For fe_face_values,
    we need the basis function values, the value of x at the quadrature points, and JxW.*/

  //For volume integration/quadrature points


    FEValues<dim> fe_values(fe,
			  quadrature_formula,
			  update_values |
                          update_gradients | 
                          update_quadrature_points |
			  update_JxW_values);

  //For surface integration/quadrature points
  FEFaceValues<dim> fe_face_values (fe,
				    face_quadrature_formula, 
				    update_values | 
				    update_quadrature_points | 
				    update_JxW_values);

  K=0; F=0;

  const unsigned int dofs_per_elem = fe.dofs_per_cell;                      //This gives you dofs per element
  const unsigned int nodes_per_elem = fe.dofs_per_cell/dim;
  const unsigned int num_quad_pts = quadrature_formula.size();              //Total number of quad points in the element
  const unsigned int num_face_quad_pts = face_quadrature_formula.size();    //Total number of quad points in the face
  const unsigned int faces_per_elem = GeometryInfo<dim>::faces_per_cell;
  FullMatrix<double> Klocal (dofs_per_elem, dofs_per_elem);
  Vector<double>     Flocal (dofs_per_elem);

  std::vector<unsigned int> local_dof_indices (dofs_per_elem);              //This relates local dof numbering to global dof numbering

  //loop over elements  
  typename DoFHandler<dim>::active_cell_iterator elem = dof_handler.begin_active(),
    endc = dof_handler.end();
  for (;elem!=endc; ++elem){
    //Update fe_values for the current element
    fe_values.reinit(elem);

    //Retrieve the effective "connectivity matrix" for this element
    elem->get_dof_indices (local_dof_indices);
		
    /*Global Assembly - 
      Get the current Flocal and Klocal from the functions you wrote above 
      and populate F_assembly and K_assembly using local_dof_indices to relate local and global DOFs.*/
    Klocal = 0.;

    //Loop over local DOFs and quadrature points to populate Klocal
    //Note that all quadrature points are included in this single loop
    for (unsigned int q=0; q<num_quad_pts; ++q){
      //      double z = fe_values.quadrature_point(q)[2]; //y-coordinate at the current surface quad. point
      //      std::cout << "z " << z << std::endl;
      //evaluate elemental stiffness matrix, K^{AB}_{ik} = \integral N^A_{,j}*C_{ijkl}*N^B_{,l} dV 
      for (unsigned int A=0; A<nodes_per_elem; A++) { //Loop over nodes
	for(unsigned int i=0; i<dim; i++){ //Loop over nodal dofs
	  for (unsigned int B=0; B<nodes_per_elem; B++) {
	    for(unsigned int k=0; k<dim; k++){
	      for (unsigned int j = 0; j<dim; j++){
		for (unsigned int l = 0; l<dim; l++){
		  /*//EDIT - You need to define Klocal here. Note that the indices of Klocal are the element dof numbers (0 through 23),
		    which you can caluclate from the element node numbers (0 through 8) and the nodal dofs (0 through 2).
		    You'll need the following information:
		    basis gradient vector: fe_values.shape_grad(elementDOF,q), where elementDOF is dim*A+i or dim*B+k
		    NOTE: this is the gradient with respect to the real domain (not the bi-unit domain)
		    elasticity tensor: use the function C(i,j,k,l)
		    det(J) times the total quadrature weight: fe_values.JxW(q)*/
			Klocal[dim*A+i][dim*B+k]+=fe_values.shape_grad(dim*A+i,q)[j]*C(i,j,k,l)*
		         fe_values.shape_grad(dim*B+k,q)[l]*fe_values.JxW(q);
		}
	      }
	    }
	  }
	}
      }
    }
    
    Flocal = 0.;
    //Loop over faces (for Neumann BCs), local DOFs and quadrature points to populate Flocal.

    //If you had a forcing function, you would need to use FEValues here as well to integrate over the volume.

    //Add Neumann boundary conditions here in Flocal by integrating over the appropriate surface
    Vector<double> h(dim); h=0.;
    for (unsigned int f=0; f < faces_per_elem; f++){
      //Update fe_face_values from current element and face
      fe_face_values.reinit (elem, f);
 
      /*elem->face(f)->center() gives a position vector (in the real domain) of the center point on face f
	of the current element. We can use it to see if we are at the Neumann boundary, x_3 = 1.*/
      if(elem->face(f)->center()[0]+0.5 >= 1){
 //     if(elem->face(f)->center()[2] == 1){
	//To integrate over this face, loop over all face quadrature points with this single loop

	for (unsigned int q=0; q<num_face_quad_pts; ++q){


	  //EDIT - define the value of the traction vector, h
	  // h[2]=1.e9*x;
	  h[0]=pow(10,5);

	  //	  	  h[0]=1.;
	  for (unsigned int A=0; A<nodes_per_elem; A++){ //loop over all element nodes
	    for(unsigned int i=0; i<dim; i++){ //loop over nodal dofs
	      /*//EDIT - define Flocal. Again, the indices of Flocal are the element dof numbers (0 through 23).
		Evaluate the basis functions using the elementDOF: fe_face_values.shape_value(elementDOF,q)

		Note that we are looping over all element dofs, not just those on the Neumann face. However,
		the face quadrature points are only on the Neumann face, so we are indeed doing a surface integral.

		For det(J) times the total quadrature weight: fe_face_values.JxW(q)*/
               Flocal[dim*A+i]+=h[i]*fe_face_values.shape_value(dim*A+i,q)*fe_face_values.JxW(q);
      
	    }
	  }
	}
      }
      if(elem->face(f)->center()[0]+0.5 == 0){
 //     if(elem->face(f)->center()[2] == 1){
	//To integrate over this face, loop over all face quadrature points with this single loop

	for (unsigned int q=0; q<num_face_quad_pts; ++q){


	  //EDIT - define the value of the traction vector, h
         //   h[2]=1.e9*x;
	  h[0]=-pow(10,5);

	  //	  h[1]=1.;
	  for (unsigned int A=0; A<nodes_per_elem; A++){ //loop over all element nodes
	    for(unsigned int i=0; i<dim; i++){ //loop over nodal dofs
	      /*//EDIT - define Flocal. Again, the indices of Flocal are the element dof numbers (0 through 23).
		Evaluate the basis functions using the elementDOF: fe_face_values.shape_value(elementDOF,q)

		Note that we are looping over all element dofs, not just those on the Neumann face. However,
		the face quadrature points are only on the Neumann face, so we are indeed doing a surface integral.

		For det(J) times the total quadrature weight: fe_face_values.JxW(q)*/
               Flocal[dim*A+i]+=h[i]*fe_face_values.shape_value(dim*A+i,q)*fe_face_values.JxW(q);
      
	    }
	  }
	}
      }

            if(elem->face(f)->center()[1]+0.5 == 0){
 //     if(elem->face(f)->center()[2] == 1){
	//To integrate over this face, loop over all face quadrature points with this single loop

	for (unsigned int q=0; q<num_face_quad_pts; ++q){


	  //EDIT - define the value of the traction vector, h
         //   h[2]=1.e9*x;
	  h[1]=0.9*pow(10,5);

	  //	  h[1]=1.;
	  for (unsigned int A=0; A<nodes_per_elem; A++){ //loop over all element nodes
	    for(unsigned int i=0; i<dim; i++){ //loop over nodal dofs
	      /*//EDIT - define Flocal. Again, the indices of Flocal are the element dof numbers (0 through 23).
		Evaluate the basis functions using the elementDOF: fe_face_values.shape_value(elementDOF,q)

		Note that we are looping over all element dofs, not just those on the Neumann face. However,
		the face quadrature points are only on the Neumann face, so we are indeed doing a surface integral.

		For det(J) times the total quadrature weight: fe_face_values.JxW(q)*/
               Flocal[dim*A+i]+=h[i]*fe_face_values.shape_value(dim*A+i,q)*fe_face_values.JxW(q);
      
	    }
	  }
	}
      }

	    if(elem->face(f)->center()[1]+0.5 == 1){
	      //     if(elem->face(f)->center()[2] == 1){
	      //To integrate over this face, loop over all face quadrature points with this single loop

	      for (unsigned int q=0; q<num_face_quad_pts; ++q){


		//EDIT - define the value of the traction vector, h
		//   h[2]=1.e9*x;
		h[1]=-0.9*pow(10,5);

		//	  h[1]=1.;
		for (unsigned int A=0; A<nodes_per_elem; A++){ //loop over all element nodes
		  for(unsigned int i=0; i<dim; i++){ //loop over nodal dofs
		    /*//EDIT - define Flocal. Again, the indices of Flocal are the element dof numbers (0 through 23).
		      Evaluate the basis functions using the elementDOF: fe_face_values.shape_value(elementDOF,q)

		      Note that we are looping over all element dofs, not just those on the Neumann face. However,
		      the face quadrature points are only on the Neumann face, so we are indeed doing a surface integral.

		      For det(J) times the total quadrature weight: fe_face_values.JxW(q)*/
		    Flocal[dim*A+i]+=h[i]*fe_face_values.shape_value(dim*A+i,q)*fe_face_values.JxW(q);
      
		  }
		}
	      }
	    }


    }
    //Assemble local K and F into global K and F
    for(unsigned int i=0; i<dofs_per_elem; i++){
      //EDIT - Assemble F from Flocal (you can look at HW2)
      F[local_dof_indices[i]]+=Flocal[i];
      for(unsigned int j=0; j<dofs_per_elem; j++){
	//EDIT - Assemble K from Klocal (you can look at HW2)
        K.add(local_dof_indices[i],local_dof_indices[j],Klocal[i][j]);
      }
    }
  }
  //Let deal.II apply Dirichlet conditions WITHOUT modifying the size of K and F global
  MatrixTools::apply_boundary_values (boundary_values, K, D, F, false);
}

//Solve for D in KD=F
template <int dim>
void FEM<dim>::solve(){

  //Solve for D
  SolverControl solver_control(1000000, 1e-12);
  SolverCG<> solver(solver_control);
  solver.solve(K, D, F, PreconditionIdentity());
//  std::cout << "D " << D << std::endl;
}

template <int dim>
void FEM<dim>::compute_stress(){

  std::ofstream strain;
  strain.open ("strain.txt");

  //  QTrapez<dim>                vertex_quadrature;
  //  std::vector<Tensor<1, dim>> solution_gradients(vertex_quadrature.size());
  FEValues<dim> fe_values(fe,
			  quadrature_formula,
			  update_values |
                          update_gradients | 
                          update_quadrature_points |
			  update_JxW_values);
  //  fe_values.get_function_gradients(D, solution_gradients);

  const unsigned int 				dofs_per_elem = fe.dofs_per_cell; //This gives you dofs per element
  std::vector<unsigned int> local_dof_indices (dofs_per_elem);
  const unsigned int 				num_quad_pts = quadrature_formula.size(); //Total number of quad points in the element

  double  x, y,  strain1, strain2, strain3,E1,E2,G12,null12,null21;
  Vector<double> stress_vector(3);
  Vector<double> strain_vector(3);
  
  E1=14*pow(10,9),E2=3.5*pow(10,9),G12=4.2*pow(10,9),null21=null12*E2/E1;
  SymmetricTensor<2, 3> strain_stress;
  strain_stress[0][0] = E1/(1-null12*null21);
  strain_stress[1][1] = E2/(1-null12*null21);
  strain_stress[2][2] = G12;
  strain_stress[0][1] = null21*E1/(1-null21*null12);
  strain_stress[0][2] = 0;
  strain_stress[1][2] = 0;
  //  std::cout << "strain_stress " << strain_stress << std::endl;     
  

  //loop over elements  
  typename DoFHandler<dim>::active_cell_iterator elem = dof_handler.begin_active (), 
    endc = dof_handler.end();
  for (;elem!=endc; ++elem){
    fe_values.reinit(elem); 
    //Retrieve the effective "connectivity matrix" for this element
    elem->get_dof_indices (local_dof_indices);


    for(unsigned int q=0; q<num_quad_pts; q++){
      strain1=0;
      strain2=0;
      strain3=0;
      x = fe_values.quadrature_point(q)[0]+0.5; //x-coordinate at the current surface quad. point
      y = fe_values.quadrature_point(q)[1]+0.5; //y-coordinate at the current surface quad. point
      //      std::cout << "x " << x << std::endl;
      //      std::cout << "y " << y << std::endl;
      SymmetricTensor<2, dim> tmp;
      //Find the values of x and u_h (the finite element solution) at the quadrature points
      for(unsigned int B=0; B<dofs_per_elem; B++){
	for (unsigned int i = 0; i < dim; ++i)
	  tmp[i][i] = fe_values.shape_grad_component(B, q, i)[i];
	for (unsigned int i = 0; i < dim; ++i)
	  for (unsigned int j = i + 1; j < dim; ++j)
	    tmp[i][j] =
	      (fe_values.shape_grad_component(B, q, i)[j] +
	       fe_values.shape_grad_component(B, q, j)[i]) /
	      2;
		   
	if (B%2==0){
	  strain1 += D[local_dof_indices[B]]*tmp[0][0];
	  strain3 += D[local_dof_indices[B]]*tmp[0][1];
	}
	else{
	  strain2 += D[local_dof_indices[B]]*tmp[1][1];
	  strain3 += D[local_dof_indices[B]]*tmp[0][1];
	}}
      strain << x << "  ";
      strain << y << "  ";
      strain << strain1 << "  ";
      strain << strain2 << "  ";
      strain << strain3 << std::endl;
      
      strain_vector[0]=strain1;
      strain_vector[1]=strain2;
      strain_vector[2]=strain3;
      
      for (unsigned int i = 0; i < 3; ++i){
	for (unsigned int j = 0; j < 3; ++j){
	  stress_vector[i]+=strain_stress[i][j]*strain_vector[j];	 
	}
      }
      //      std::cout << "stress_vector " << stress_vector << std::endl;
      
      //      std::cout << "strain1 " << strain1 << std::endl;     
      //      std::cout << "strain2 " << strain2 << std::endl;
      //      std::cout << "strain3 " << strain3 << std::endl;     
    }
  }

  strain.close();
}

//Output results
template <int dim>
void FEM<dim>::output_results (){

  //Write results to VTK file
  std::ofstream output1 ("solution.vtk");
  DataOut<dim> data_out; data_out.attach_dof_handler (dof_handler);

  //Add nodal DOF data
  data_out.add_data_vector (D,
			    nodal_solution_names,
			    DataOut<dim>::type_dof_data,
			    nodal_data_component_interpretation);
  data_out.build_patches();
  data_out.write_vtk(output1);
  output1.close();
}



/*This is a skeleton code file for use with the Finite Element Method for Problems in Physics.
It uses the deal.II FEM library, dealii.org*/

//Include files
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>

#include "FEM3.h"
//#include "writeSolutions.h"

using namespace dealii;

//The main program, using the FEM class
int main (){
  try{
    deallog.depth_console (0);

		const int dimension = 2;

		//NOTE: This is where you define the number of elements in the mesh
		std::vector<unsigned int> num_of_elems(dimension);
		num_of_elems[0] = 5;
		num_of_elems[1] = 5;
		//		num_of_elems[2] = 10; //For example, a 10 x 10 x 10 element mesh

          FEM<dimension> problemObject;
	  problemObject.generate_mesh(num_of_elems);
	  problemObject.setup_system();
	  problemObject.assemble_system();
	  problemObject.solve();
	  problemObject.compute_stress();
	  problemObject.output_results();
    
    //write solutions to h5 file
  //  char tag[21];
 //   sprintf(tag, "CA3");
//    writeSolutionsToFileCA3(problemObject.D, tag);

  }
  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;
}

Attachment: plate4
Description: Binary data

Attachment: plate4.geo
Description: Binary data

Reply via email to