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"); } }
//---------------------------------------------------------------------------// 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); }
// 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"); }