Exemplo n.º 1
0
int main(int argc, char **argv)
{
    typedef viennagrid::tetrahedral_3d_mesh             MeshType;
    typedef viennagrid::tetrahedral_3d_segmentation       SegmentationType;

    typedef viennagrid::result_of::vertex<MeshType>::type         VertexType;
    typedef viennagrid::result_of::cell<MeshType>::type           CellType;


    if (argc < 4)
    {
        std::cout << "Usage: mosfet_3d_viennamesh <input_file> <output_file> <interpolate_names ...>" << std::endl;
        return -1;
    }
    
    std::string input_file = argv[1];
    std::string output_file = argv[2];
    
    
    
    MeshType mesh;
    SegmentationType segmentation(mesh);
    
    std::map< std::string, std::deque<double> > cell_values;
    std::map< std::string, std::deque<double> > vertex_values;

    try
    {
        viennagrid::io::vtk_reader<MeshType> reader;
        
        for (int i = 3; i < argc; ++i)
          viennagrid::io::add_scalar_data_on_cells(reader, viennagrid::make_accessor<CellType>(cell_values[argv[i]]), argv[i] );

        reader(mesh, segmentation, input_file);
    }
    catch (...)
    {
        std::cerr << "File-Reader failed. Aborting program..." << std::endl;
        return EXIT_FAILURE;
    }
    
    viennagrid::io::vtk_writer<MeshType> vtk_writer;
    
    for ( std::map< std::string, std::deque<double> >::iterator it = cell_values.begin(); it != cell_values.end(); ++it )
    {
        std::string interpolate_value_name = it->first;
        std::cout << "Interpolating " << interpolate_value_name << std::endl;
        
        viennagrid::result_of::accessor<std::deque<double>, CellType>::type cell_accessor( it->second );
        viennagrid::result_of::accessor<std::deque<double>, VertexType>::type vertex_accessor( vertex_values[it->first] );
        
        interpolate<viennagrid::tetrahedron_tag, viennagrid::vertex_tag>( mesh, cell_accessor, vertex_accessor );
        
        viennagrid::io::add_scalar_data_on_cells(vtk_writer, cell_accessor, interpolate_value_name);
        viennagrid::io::add_scalar_data_on_vertices(vtk_writer, vertex_accessor, interpolate_value_name);
    }
    
    vtk_writer( mesh, segmentation, output_file);
    return 0;
}
    void RunTest(unsigned numStepsInEachDimension)
    {
        MeshEventHandler::Reset();
        unsigned nodes = SmallPow(numStepsInEachDimension+1, 3);
        if (PetscTools::AmMaster())
        {
            std::cout<<"Number steps per dimension = " << std::setw(12) << numStepsInEachDimension<<std::endl;
            std::cout<<"Number nodes               = " << std::setw(12) << nodes<<std::endl;
        }
        std::string file_name = "cuboid";
        std::stringstream directory_stream;
        directory_stream << "TestMeshWritersWeekly/steps_" << std::setw(12) << std::setfill('0')<< numStepsInEachDimension;
        std::string directory_name = directory_stream.str();

        DistributedTetrahedralMesh<3,3> cuboid_mesh;
        cuboid_mesh.ConstructCuboid(numStepsInEachDimension, numStepsInEachDimension, numStepsInEachDimension);
        TS_ASSERT_EQUALS(cuboid_mesh.GetNumNodes(), nodes);


        MeshEventHandler::BeginEvent(MeshEventHandler::TRIANGLES);
        {
            TrianglesMeshWriter<3,3> mesh_writer(directory_name,  file_name, false);
            mesh_writer.WriteFilesUsingMesh(cuboid_mesh);
        }
        MeshEventHandler::EndEvent(MeshEventHandler::TRIANGLES);

        MeshEventHandler::BeginEvent(MeshEventHandler::BINTRI);
        {
            TrianglesMeshWriter<3,3> bin_mesh_writer(directory_name,  file_name+"_bin", false);
            bin_mesh_writer.SetWriteFilesAsBinary();
            bin_mesh_writer.WriteFilesUsingMesh(cuboid_mesh);
        }
        MeshEventHandler::EndEvent(MeshEventHandler::BINTRI);


#ifdef CHASTE_VTK
        MeshEventHandler::BeginEvent(MeshEventHandler::VTK);
        {
            VtkMeshWriter<3,3> vtk_writer(directory_name, file_name, false);
            vtk_writer.WriteFilesUsingMesh(cuboid_mesh);
        }
        MeshEventHandler::EndEvent(MeshEventHandler::VTK);

        MeshEventHandler::BeginEvent(MeshEventHandler::PVTK);
        {
            VtkMeshWriter<3,3> parallel_vtk_writer(directory_name, file_name+"par",false);
            parallel_vtk_writer.SetParallelFiles(cuboid_mesh);
            std::vector<double> dummy_data(cuboid_mesh.GetNumLocalNodes(), PetscTools::GetMyRank());
            parallel_vtk_writer.AddPointData("Process", dummy_data);
            parallel_vtk_writer.WriteFilesUsingMesh(cuboid_mesh);
        }
        MeshEventHandler::EndEvent(MeshEventHandler::PVTK);
#endif //CHASTE_VTK
        MeshEventHandler::Headings();
        MeshEventHandler::Report();
    }
int main()
{
  // Typedefing the mesh type representing the 2D geometry; using PLCs
  typedef viennagrid::plc_3d_mesh GeometryMeshType;
  typedef viennagrid::result_of::point<GeometryMeshType>::type PointType;

  // Creating the geometry mesh object and loading a file
  GeometryMeshType geometry;

  // The container of hole points, either filled manually or automatically filled by tetgen_poly_reader
  std::vector<PointType> hole_points;
  // The container of seed points, either filled manually or automatically filled by tetgen_poly_reader
  std::vector< std::pair<PointType, int> > seed_points;

  // using tetgen_poly_reader to fill hole points and seed points
  viennagrid::io::tetgen_poly_reader reader;
//   reader(geometry, "../data/cube.poly", hole_points, seed_points);
  reader(geometry, "../data/two_cubes.poly", hole_points, seed_points);
//   reader(geometry, "../data/big_and_small_cube.poly", hole_points, seed_points);
//   reader(geometry, "../data/example.poly", hole_points, seed_points);
//   reader(geometry, "../data/cube_with_tunnel.poly", hole_points, seed_points);
//   reader(geometry, "../data/cube_with_cube_hole.poly", hole_points, seed_points);

  // creating a parameter set object
  viennamesh::ConstParameterSet settings;

  // setting the parameters
  settings.set("seed_points", seed_points);   // the seed points
  settings.set("hole_points", hole_points);   // the seed points
  settings.set("cell_size", 1.0);

  // creating a triangular mesh and segmentation
  viennagrid::tetrahedral_3d_mesh tet_mesh;
  viennagrid::tetrahedral_3d_segmentation tet_segmentation(tet_mesh);

  // starting the algorithm
  viennamesh::run_algo<viennamesh::tetgen_tetrahedron_tag>(
    geometry, viennamesh::NoSegmentation(),
    tet_mesh, tet_segmentation,
    settings);

  // writing the output to a VTK file
  viennagrid::io::vtk_writer<viennagrid::tetrahedral_3d_mesh> vtk_writer;
  vtk_writer(tet_mesh, tet_segmentation, "cube_meshed_tetgen");

}
int main()
{
    viennagrid::plc_3d_mesh plc_mesh;


    viennagrid::io::tetgen_poly_reader reader;
    reader(plc_mesh, "../data/big_and_small_cube.poly");



    viennagrid::triangular_3d_mesh triangulated_plc_mesh;
    viennamesh::ConstParameterSet plc_settings;

    viennamesh::run_algo< viennamesh::cgal_plc_3d_mesher_tag >( plc_mesh, triangulated_plc_mesh, plc_settings );

    {
        viennagrid::io::vtk_writer<viennagrid::triangular_3d_mesh> vtk_writer;
        vtk_writer(triangulated_plc_mesh, "meshed_plc_hull");
    }





    typedef viennagrid::result_of::point<viennagrid::triangular_3d_mesh>::type point_type;
    viennagrid::triangular_hull_3d_segmentation triangulated_plc_segmentation(triangulated_plc_mesh);

    std::vector< std::pair< int, point_type > > seed_points;
    seed_points.push_back( std::make_pair(0, point_type(0.0, 0.0, 0.0)) );
    seed_points.push_back( std::make_pair(1, point_type(0.0, 0.0, 20.0)) );

    viennagrid::mark_face_segments( triangulated_plc_mesh, triangulated_plc_segmentation, seed_points.begin(), seed_points.end() );




    viennagrid::triangular_3d_mesh oriented_adapted_hull_mesh;
    viennagrid::triangular_hull_3d_segmentation oriented_adapted_hull_segmentation(oriented_adapted_hull_mesh);

    viennamesh::ConstParameterSet vgm_settings;
    vgm_settings.set("cell_size", 3.0);

    viennamesh::run_algo< viennamesh::vgmodeler_hull_adaption_tag >( triangulated_plc_mesh, triangulated_plc_segmentation,
                                                                     oriented_adapted_hull_mesh, oriented_adapted_hull_segmentation,
                                                                     vgm_settings );


    {
        viennagrid::io::vtk_writer<viennagrid::triangular_3d_mesh> vtk_writer;
        vtk_writer(oriented_adapted_hull_mesh, "netgen_adapt_hull");
    }



    viennagrid::tetrahedral_3d_mesh tetrahedron_mesh;
    viennagrid::tetrahedral_3d_segmentation tetrahedron_segmentation(tetrahedron_mesh);

    viennamesh::ConstParameterSet netgen_settings;
    netgen_settings.set("cell_size", 3.0);

    viennamesh::run_algo< viennamesh::netgen_tetrahedron_tag >( oriented_adapted_hull_mesh, oriented_adapted_hull_segmentation,
                                                                tetrahedron_mesh, tetrahedron_segmentation,
                                                                netgen_settings );


    {
        viennagrid::io::vtk_writer<viennagrid::tetrahedral_3d_mesh> vtk_writer;
        vtk_writer(tetrahedron_mesh, tetrahedron_segmentation, "netgen_volume");
    }



}
Exemplo n.º 5
0
//---------------------------------------------------------------------------//
int main( int argc, char** argv )
{
    // Problem parameters.
    int xN = 201;
    int yN = 201;
    int problem_size = xN*yN;

    double x_min = 0.0;
    double x_max = 2.0;
    double y_min = 0.0;
    double y_max = 2.0;

    double ic_val = 0.0;
    double bc_val_xmin = 0.0;
    double bc_val_xmax = 0.0;
    double bc_val_ymin = 10.0;
    double bc_val_ymax = 10.0;

    int num_steps = 1;
    double T = 0.01;

    double dx = (x_max-x_min)/(xN-1);
    double dy = (y_max-y_min)/(yN-1);
    double dt = T / num_steps;

    double alpha = 0.01;

    int max_iters = 1000;
    double tolerance = 1.0e-8;
    int num_histories = 40000;
    double weight_cutoff = 1.0e-12;

    // Setup up a VTK mesh for output.
    HMCSA::VtkWriter vtk_writer( x_min, x_max, y_min, y_max,
				 dx, dy, xN, yN );

    // Build the Diffusion operator.
    HMCSA::DiffusionOperator diffusion_operator(
	5,
	HMCSA::HMCSA_DIRICHLET,
	HMCSA::HMCSA_DIRICHLET,
	HMCSA::HMCSA_DIRICHLET,
	HMCSA::HMCSA_DIRICHLET,
	bc_val_xmin, bc_val_xmax, bc_val_ymin, bc_val_ymax,
	xN, yN,
	dx, dy, dt, alpha );

    Teuchos::RCP<Epetra_CrsMatrix> A = diffusion_operator.getCrsMatrix();
    Epetra_Map map = A->RowMap();

    // Solution Vector.
    std::vector<double> x_vector( problem_size );
    Epetra_Vector x( View, map, &x_vector[0] );
    
    // Build source - set intial and Dirichlet boundary conditions.
    std::vector<double> b_vector( problem_size, ic_val );
    buildIC( b_vector, xN, yN,
	     bc_val_xmin, bc_val_xmax, bc_val_ymin, bc_val_ymax );
    Epetra_Vector b( View, map, &b_vector[0] );

    // Linear problem.
    Teuchos::RCP<Epetra_LinearProblem> linear_problem = Teuchos::rcp(
    	new Epetra_LinearProblem( A.getRawPtr(), &x, &b ) );

    // Time step.
    HMCSA::TimeIntegrator time_integrator( linear_problem, vtk_writer );
    time_integrator.integrate( true, num_steps, max_iters, 
			       tolerance, num_histories,
			       weight_cutoff );    

    return 0;
}
    /* In the first test we use INCOMPRESSIBLE nonlinear elasticity. For incompressible elasticity, there
     * is a constraint on the deformation, which results in a pressure field (a Lagrange multiplier)
     * which is solved for together with the deformation.
     *
     * All the mechanics solvers solve for the deformation using the finite element method with QUADRATIC
     * basis functions for the deformation. This necessitates the use of a `QuadraticMesh` - such meshes have
     * extra nodes that aren't vertices of elements, in this case midway along each edge. (The displacement
     * is solved for at ''each node'' in the mesh (including internal [non-vertex] nodes), whereas the pressure
     * is only solved for at each vertex - in FEM terms, quadratic interpolation for displacement, linear
     * interpolation for pressure, which is required for stability. The pressure at internal nodes is computed
     * by linear interpolation).
     *
     */
    void TestSimpleIncompressibleProblem() throw(Exception)
    {
        /* First, define the geometry. This should be specified using the `QuadraticMesh` class, which inherits from `TetrahedralMesh`
         * and has mostly the same interface. Here we define a 0.8 by 1 rectangle, with elements 0.1 wide.
         * (`QuadraticMesh`s can also be read in using `TrianglesMeshReader`; see next tutorial/rest of code base for examples of this).
         */
        QuadraticMesh<2> mesh;
        mesh.ConstructRegularSlabMesh(0.1 /*stepsize*/, 0.8 /*width*/, 1.0 /*height*/);

        /* We use a Mooney-Rivlin material law, which applies to isotropic materials and has two parameters.
         * Restricted to 2D however, it only has one parameter, which can be thought of as the total
         * stiffness. We declare a Mooney-Rivlin law, setting the parameter to 1.
         */
        MooneyRivlinMaterialLaw<2> law(1.0);

        /* Next, the body force density. In realistic problems this will either be
         * acceleration due to gravity (ie b=(0,-9.81)) or zero if the effect of gravity can be neglected.
         * In this problem we apply a gravity-like downward force.
         */
        c_vector<double,2> body_force;
        body_force(0) =  0.0;
        body_force(1) = -2.0;


        /* Two types of boundary condition are required: displacement and traction. As with the other PDE solvers,
         * the displacement (Dirichlet) boundary conditions are specified at nodes, whereas traction (Neumann) boundary
         * conditions are specified on boundary elements.
         *
         * In this test we apply displacement boundary conditions on one surface of the mesh, the upper (Y=1.0) surface.
         * We are going to specify zero-displacement at these nodes.
         * We do not specify any traction boundary conditions, which means that (effectively) zero-traction boundary
         * conditions (ie zero pressures) are applied on the three other surfaces.
         *
         * We need to get a `std::vector` of all the node indices that we want to fix. The `NonlinearElasticityTools`
         * has a static method for helping do this: the following gets all the nodes for which Y=1.0. The second
         * argument (the '1') indicates Y . (So, for example, `GetNodesByComponentValue(mesh, 0, 10)` would get the nodes on X=10).
         */
        std::vector<unsigned> fixed_nodes = NonlinearElasticityTools<2>::GetNodesByComponentValue(mesh, 1, 1.0);

        /*
         * Before creating the solver we create a `SolidMechanicsProblemDefinition` object,  which contains
         * everything that defines the problem: mesh, material law, body force,
         * the fixed nodes and their locations, any traction boundary conditions, and the density
         * (which multiplies the body force, otherwise isn't used).
         */
        SolidMechanicsProblemDefinition<2> problem_defn(mesh);

        /* Set the material problem on the problem definition object, saying that the problem, and
         * the material law, is incompressible. All material law files can be found in
         * `continuum_mechanics/src/problem/material_laws`. */
        problem_defn.SetMaterialLaw(INCOMPRESSIBLE,&law);

        /* Set the fixed nodes, choosing zero displacement for these nodes (see later for how
         * to provide locations for the fixed nodes). */
        problem_defn.SetZeroDisplacementNodes(fixed_nodes);
        /* Set the body force and the density. (Note that the second line isn't technically
         * needed, as internally the density is initialised to 1)
         */
        problem_defn.SetBodyForce(body_force);
        problem_defn.SetDensity(1.0);

        /* Now we create the (incompressible) solver, passing in the mesh, problem definition
         * and output directory
         */
        IncompressibleNonlinearElasticitySolver<2> solver(mesh,
                                                          problem_defn,
                                                          "SimpleIncompressibleElasticityTutorial");

        /* .. and to compute the solution, just call `Solve()` */
        solver.Solve();


        /* '''Visualisation'''. Go to the folder `SimpleIncompressibleElasticityTutorial` in your test-output directory.
         * There should be 2 files, initial.nodes and solution.nodes. These are the original nodal positions and the deformed
         * positions. Each file has two columns, the x and y locations of each node. To visualise the solution in say
         * Matlab or Octave, you could do: `x=load('solution.nodes'); plot(x(:,1),x(:,2),'k*')`. For Cmgui output, see below.
         *
         * To get the actual solution from the solver, use these two methods. Note that the first
         * gets the deformed position (ie the new location, not the displacement). They are both of size
         * num_total_nodes.
         */
        std::vector<c_vector<double,2> >& r_deformed_positions = solver.rGetDeformedPosition();
        std::vector<double>& r_pressures = solver.rGetPressures();
        /* Let us obtain the values of the new position, and the pressure, at the bottom right corner node. */
        unsigned node_index = 8;
        assert( fabs(mesh.GetNode(node_index)->rGetLocation()[0] - 0.8) < 1e-6); // check that X=0.8, ie that we have the correct node,
        assert( fabs(mesh.GetNode(node_index)->rGetLocation()[1] - 0.0) < 1e-6); // check that Y=0.0, ie that we have the correct node,
        std::cout << "New position: " << r_deformed_positions[node_index](0) << " " << r_deformed_positions[node_index](1) << "\n";
        std::cout << "Pressure: " << r_pressures[node_index] << "\n";

        /* HOW_TO_TAG Continuum mechanics
         * Visualise nonlinear elasticity problems solutions, including visualisng strains
         */

        /* One visualiser is Cmgui. This method can be used to convert all the output files to Cmgui format.
         * They are placed in `[OUTPUT_DIRECTORY]/cmgui`. A script is created to easily load the data: in a
         * terminal cd to this directory and call `cmgui LoadSolutions.com`. (In this directory, the initial position is given by
         * solution_0.exnode, the deformed by solution_1.exnode).
         */
        solver.CreateCmguiOutput();

        /* The recommended visualiser is Paraview, for which Chaste must be installed with VTK. With paraview, strains (and in the future
         * stresses) can be visualised on the undeformed/deformed geometry). We can create VTK output using
         * the `VtkNonlinearElasticitySolutionWriter` class. The undeformed geometry, solution displacement, and pressure (if incompressible
         * problem) are written to file, and below we also choose to write the deformation tensor C for each element.
         */
        VtkNonlinearElasticitySolutionWriter<2> vtk_writer(solver);
        vtk_writer.SetWriteElementWiseStrains(DEFORMATION_TENSOR_C); // other options are DEFORMATION_GRADIENT_F and LAGRANGE_STRAIN_E
        vtk_writer.Write();


        /* These are just to check that nothing has been accidentally changed in this test.
         * Newton's method (with damping) was used to solve the nonlinear problem, and we check that
         * 4 iterations were needed to converge.
         */
        TS_ASSERT_DELTA(r_deformed_positions[node_index](0),  0.7980, 1e-3);
        TS_ASSERT_DELTA(r_deformed_positions[node_index](1), -0.1129, 1e-3);
        TS_ASSERT_EQUALS(solver.GetNumNewtonIterations(), 4u);
    }
Exemplo n.º 7
0
// Similar to above but uses a compressible material
unsigned SolvePressureOnUndersideCompressible(QuadraticMesh<3>& rMesh, std::string outputDirectory,
                                              std::vector<double>& rSolution,
                                              bool useSolutionAsGuess,
                                              double scaleFactor = 1.0)
{
    CompressibleExponentialLaw<3> law;
    std::vector<unsigned> fixed_nodes = NonlinearElasticityTools<3>::GetNodesByComponentValue(rMesh, 0, 0.0);

    std::vector<BoundaryElement<2,3>*> boundary_elems;

    double pressure = 0.001;

    for (TetrahedralMesh<3,3>::BoundaryElementIterator iter
           = rMesh.GetBoundaryElementIteratorBegin();
         iter != rMesh.GetBoundaryElementIteratorEnd();
         ++iter)
    {
        BoundaryElement<2,3>* p_element = *iter;
        double Z = p_element->CalculateCentroid()[2];
        if(fabs(Z)<1e-6)
        {
            boundary_elems.push_back(p_element);
        }
    }

    SolidMechanicsProblemDefinition<3> problem_defn(rMesh);
    problem_defn.SetMaterialLaw(COMPRESSIBLE,&law);
    problem_defn.SetZeroDisplacementNodes(fixed_nodes);

    problem_defn.SetApplyNormalPressureOnDeformedSurface(boundary_elems, pressure*scaleFactor);


    problem_defn.SetVerboseDuringSolve();

    CompressibleNonlinearElasticitySolver<3> solver(rMesh,problem_defn,outputDirectory);
    solver.SetWriteOutputEachNewtonIteration();

    // cover the SetTakeFullFirstNewtonStep() method, and the SetUsePetscDirectSolve() method
    solver.SetTakeFullFirstNewtonStep();
    solver.SetUsePetscDirectSolve();

    if(useSolutionAsGuess)
    {
        if(solver.rGetCurrentSolution().size()!=rSolution.size())
        {
            EXCEPTION("Badly-sized input");
        }
        for(unsigned i=0; i<rSolution.size(); i++)
        {
            solver.rGetCurrentSolution()[i] = rSolution[i];
        }
    }

    if(scaleFactor < 1.0)
    {
        try
        {
            solver.Solve();
        }
        catch (Exception& e)
        {
            // not final Solve, so don't quit
            WARNING(e.GetMessage());
        }
    }
    else
    {
        solver.Solve();
        solver.CreateCmguiOutput();
        
        VtkNonlinearElasticitySolutionWriter<3> vtk_writer(solver);
        vtk_writer.SetWriteElementWiseStrains(DEFORMATION_TENSOR_C);
        vtk_writer.Write();        
    }

    rSolution.clear();
    rSolution.resize(solver.rGetCurrentSolution().size());
    for(unsigned i=0; i<rSolution.size(); i++)
    {
        rSolution[i] = solver.rGetCurrentSolution()[i];
    }

    return solver.GetNumNewtonIterations();
}
int main()
{
  // Typedefing the mesh type representing the 2D geometry; using just lines, segments are represented using seed points
  typedef viennagrid::line_2d_mesh GeometryMeshType;

  // Typedefing vertex handle and point type for geometry creation
  typedef viennagrid::result_of::point<GeometryMeshType>::type PointType;
  typedef viennagrid::result_of::vertex_handle<GeometryMeshType>::type GeometryVertexHandle;

  // Creating the geometry mesh object
  GeometryMeshType geomerty;

  // creating the geometry
  double s = 10.0;
  GeometryVertexHandle vtx[6];

  vtx[0] = viennagrid::make_vertex( geomerty, PointType(0, 0) );
  vtx[1] = viennagrid::make_vertex( geomerty, PointType(0, s) );
  vtx[2] = viennagrid::make_vertex( geomerty, PointType(s, 0) );
  vtx[3] = viennagrid::make_vertex( geomerty, PointType(s, s) );
  vtx[4] = viennagrid::make_vertex( geomerty, PointType(2*s, 0) );
  vtx[5] = viennagrid::make_vertex( geomerty, PointType(2*s, s) );


  viennagrid::make_line( geomerty, vtx[0], vtx[1] );

  viennagrid::make_line( geomerty, vtx[0], vtx[2] );
  viennagrid::make_line( geomerty, vtx[1], vtx[3] );

  viennagrid::make_line( geomerty, vtx[2], vtx[3] );

  viennagrid::make_line( geomerty, vtx[2], vtx[4] );
  viennagrid::make_line( geomerty, vtx[3], vtx[5] );

  viennagrid::make_line( geomerty, vtx[4], vtx[5] );


  // creating a parameter set object
  viennamesh::ConstParameterSet settings;

  // creating the seed points
  // seed point constructor: seed_point_2d(x_coordinate_of_seed_point, y_coordinate_of_seed_point, segment_id)
  viennamesh::seed_point_2d_container seed_points;
  seed_points.push_back( std::make_pair(PointType(s/2, s/2), 0) );
  seed_points.push_back( std::make_pair(PointType(s+s/2, s/2), 1) );

  // setting the parameters
  settings.set("seed_points", seed_points);   // the seed points
  settings.set("cell_size", 1.0);             // maximum cell size is set to 1
  settings.set("min_angle", 30.0);            // minimum angle is set to 30

  // creating a triangular mesh and segmentation
  viennagrid::triangular_2d_mesh tri_mesh;
  viennagrid::triangular_2d_segmentation tri_segmentation(tri_mesh);

  // starting the algorithm
  viennamesh::run_algo<viennamesh::triangle_tag>(
    geomerty, viennamesh::NoSegmentation(),
    tri_mesh, tri_segmentation,
    settings);

  // writing the output to a VTK file
  viennagrid::io::vtk_writer<viennagrid::triangular_2d_mesh> vtk_writer;
  vtk_writer(tri_mesh, tri_segmentation, "meshed_triangles");
}
int main()
{
    typedef viennagrid::plc_2d_mesh mesh_type;
    mesh_type mesh;
    
    typedef viennagrid::result_of::point<mesh_type>::type point_type;
     
    typedef viennagrid::result_of::element<mesh_type, viennagrid::vertex_tag>::type vertex_type;
    typedef viennagrid::result_of::handle<mesh_type, viennagrid::vertex_tag>::type vertex_handle_type;
    
    typedef viennagrid::result_of::element<mesh_type, viennagrid::line_tag>::type line_type;
    typedef viennagrid::result_of::handle<mesh_type, viennagrid::line_tag>::type line_handle_type;
    
    typedef viennagrid::result_of::element<mesh_type, viennagrid::plc_tag>::type plc_type;
    typedef viennagrid::result_of::handle<mesh_type, viennagrid::plc_tag>::type plc_handle_type;
    
    plc_handle_type plc_handle;
    
    {
        std::vector<vertex_handle_type> v;
        
        v.push_back( viennagrid::make_vertex( mesh, point_type(0, 0) ) );
        v.push_back( viennagrid::make_vertex( mesh, point_type(10, 0) ) );
        v.push_back( viennagrid::make_vertex( mesh, point_type(20, 10) ) );
        v.push_back( viennagrid::make_vertex( mesh, point_type(20, 20) ) );
        v.push_back( viennagrid::make_vertex( mesh, point_type(10, 20) ) );
        v.push_back( viennagrid::make_vertex( mesh, point_type(0, 10) ) );
        v.push_back( viennagrid::make_vertex( mesh, point_type(5, 5) ) );
        
        v.push_back( viennagrid::make_vertex( mesh, point_type(10, 10) ) );
        v.push_back( viennagrid::make_vertex( mesh, point_type(12, 10) ) );
        v.push_back( viennagrid::make_vertex( mesh, point_type(10, 12) ) );
        
        v.push_back( viennagrid::make_vertex( mesh, point_type(8, 10) ) );
        
        v.push_back( viennagrid::make_vertex( mesh, point_type(15, 15) ) );
        
        
        std::vector<line_handle_type> lines;
        
        {
            std::vector<vertex_handle_type>::iterator start = v.begin();
            std::vector<vertex_handle_type>::iterator end = v.begin() + 7;
            
            std::vector<vertex_handle_type>::iterator it1 = start;
            std::vector<vertex_handle_type>::iterator it2 = it1; ++it2;
            for (; it2 != end; ++it1, ++it2)
                lines.push_back( viennagrid::make_line(mesh, *it1, *it2) );
            lines.push_back( viennagrid::make_line(mesh, *it1, *start) );
        }
        
        
        {
            std::vector<vertex_handle_type>::iterator start = v.begin() + 7;
            std::vector<vertex_handle_type>::iterator end = v.begin() + 10;
            
            std::vector<vertex_handle_type>::iterator it1 = start;
            std::vector<vertex_handle_type>::iterator it2 = it1; ++it2;
            for (; it2 != end; ++it1, ++it2)
                lines.push_back( viennagrid::make_line(mesh, *it1, *it2) );
            lines.push_back( viennagrid::make_line(mesh, *it1, *start) );
        }
        
        lines.push_back( viennagrid::make_element<line_type>( mesh, v.begin() + 9, v.begin() + 11 ) );
        
        vertex_handle_type point = v[11];

        
        std::vector<point_type> hole_points;
        hole_points.push_back( point_type(10.5, 10.5) );

        plc_handle  = viennagrid::make_plc(  mesh,
                                                                        lines.begin(), lines.end(),
                                                                        &point, &point + 1,
                                                                        hole_points.begin(), hole_points.end()
                                                                    );
    }
    
    plc_type & plc = viennagrid::dereference_handle(mesh, plc_handle);
    
    
    
    
    
    typedef viennagrid::result_of::element_range<plc_type, viennagrid::vertex_tag>::type vertex_range_type;
    typedef viennagrid::result_of::iterator<vertex_range_type>::type vertex_range_iterator;
    
    typedef viennagrid::result_of::element_range<plc_type, viennagrid::line_tag>::type line_range_type;
    typedef viennagrid::result_of::iterator<line_range_type>::type line_range_iterator;
    
    
    
    typedef CGAL::Exact_predicates_inexact_constructions_kernel     Kernel;
    
    typedef CGAL::Triangulation_vertex_base_2<Kernel>               VertexBase;
    typedef CGAL::Delaunay_mesh_face_base_2<Kernel>                 FaceBase;
    typedef CGAL::Triangulation_data_structure_2<VertexBase, FaceBase> Triangulation_structure;
    
    typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, Triangulation_structure> CDT;
    
    typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria;
    
    typedef CDT::Vertex_handle Vertex_handle;
    typedef CDT::Point Point;
    
    CDT cdt;
    
    std::map<vertex_handle_type, Vertex_handle> vertex_handle_map;
    
    vertex_range_type vertices = viennagrid::elements<viennagrid::vertex_tag>(plc);
    for (vertex_range_iterator it = vertices.begin(); it != vertices.end(); ++it)
    {
        vertex_handle_type const & vtx_handle = it.handle();
        vertex_type const & vtx = *it;
        point_type const & vgrid_point = viennagrid::point( mesh, vtx );
        
        Vertex_handle handle = cdt.insert( Point(vgrid_point[0], vgrid_point[1]) );
        
        vertex_handle_map[vtx_handle] = handle;
    }

    
    line_range_type lines = viennagrid::elements<viennagrid::line_tag>(plc);
    for (line_range_iterator it = lines.begin(); it != lines.end(); ++it)
    {
        line_type & line = *it;
        
        vertex_handle_type vgrid_v0 = viennagrid::elements<viennagrid::vertex_tag>(line).handle_at(0);
        vertex_handle_type vgrid_v1 = viennagrid::elements<viennagrid::vertex_tag>(line).handle_at(1);
        
        Vertex_handle cgal_v0 = vertex_handle_map[vgrid_v0];
        Vertex_handle cgal_v1 = vertex_handle_map[vgrid_v1];
        
        cdt.insert_constraint(cgal_v0, cgal_v1);
    }
    
    std::vector<point_type> & vgrid_list_of_holes = viennagrid::hole_points(plc);
    std::list<Point> cgal_list_of_holes;
    
    for (std::vector<point_type>::iterator it = vgrid_list_of_holes.begin(); it != vgrid_list_of_holes.end(); ++it)
        cgal_list_of_holes.push_back( Point( (*it)[0], (*it)[1] ) );
    
    CGAL::refine_Delaunay_mesh_2(cdt, cgal_list_of_holes.begin(), cgal_list_of_holes.end(), Criteria());
    
    std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;
    std::cout << "Number of finite faces: " << cdt.number_of_faces() << std::endl;
    
    
    
    
    
    typedef viennagrid::triangular_2d_mesh triangle_mesh_type;
    triangle_mesh_type triangle_mesh;
    
    typedef viennagrid::result_of::point<triangle_mesh_type>::type triangle_point_type;
     
    typedef viennagrid::result_of::element<triangle_mesh_type, viennagrid::vertex_tag>::type triangle_vertex_type;
    typedef viennagrid::result_of::handle<triangle_mesh_type, viennagrid::vertex_tag>::type triangle_vertex_handle_type;
    
    typedef viennagrid::result_of::element<triangle_mesh_type, viennagrid::line_tag>::type triangle_line_type;
    typedef viennagrid::result_of::handle<triangle_mesh_type, viennagrid::line_tag>::type triangle_line_handle_type;
    
    typedef viennagrid::result_of::element<triangle_mesh_type, viennagrid::triangle_tag>::type triangle_triangle_type;
    typedef viennagrid::result_of::handle<triangle_mesh_type, viennagrid::triangle_tag>::type triangle_triangle__handle_type;
    
    
    std::map<Point, triangle_vertex_handle_type> points;
    
    int mesh_faces_counter = 0;
    for(CDT::Finite_faces_iterator fit = cdt.finite_faces_begin(); fit != cdt.finite_faces_end(); ++fit) 
    {
        if(fit->is_in_domain())
        {
            typedef CDT::Triangle Triangle;
            Triangle tri = cdt.triangle(fit);
            
            triangle_vertex_handle_type vgrid_vtx[3];
            
            for (int i = 0; i < 3; ++i)
            {
                std::map<Point, triangle_vertex_handle_type>::iterator pit = points.find( tri[i] );
                if (pit == points.end())
                {
                    vgrid_vtx[i] = viennagrid::make_vertex( triangle_mesh, triangle_point_type(tri[i].x(), tri[i].y()) );
                    points[ tri[i] ] = vgrid_vtx[i];
                }
                else
                    vgrid_vtx[i] = pit->second;
            }
            
            viennagrid::make_element<triangle_triangle_type>( triangle_mesh, vgrid_vtx, vgrid_vtx+3 );
                
            
            std::cout << tri << std::endl;
            ++mesh_faces_counter;
        }
    }
    std::cout << "Number of faces in the mesh mesh: " << mesh_faces_counter << std::endl;
    

    
    std::copy( viennagrid::elements<triangle_triangle_type>(triangle_mesh).begin(), viennagrid::elements<triangle_triangle_type>(triangle_mesh).end(), std::ostream_iterator<triangle_triangle_type>(std::cout, "\n") );
    

    viennagrid::io::vtk_writer<triangle_mesh_type> vtk_writer;
    vtk_writer(triangle_mesh, "test");
    
}