Skip to content

Commit

Permalink
Add support for simplex meshes (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
fdrmrc authored Sep 20, 2024
1 parent d9bf51d commit 9aa5396
Show file tree
Hide file tree
Showing 5 changed files with 303 additions and 30 deletions.
34 changes: 21 additions & 13 deletions examples/benchmarks_3D.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#include <deal.II/fe/fe_simplex_p.h>
#include <deal.II/fe/mapping_fe.h>

#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_in.h>
#include <deal.II/grid/grid_out.h>
Expand Down Expand Up @@ -47,7 +50,7 @@ class AgglomerationBenchmark
make_grid();

Triangulation<dim> tria;
MappingQ<dim> mapping;
MappingFE<dim> mapping;
std::unique_ptr<AgglomerationHandler<dim>> ah;

public:
Expand All @@ -74,7 +77,7 @@ AgglomerationBenchmark<dim>::AgglomerationBenchmark(
const PartitionerType &partitioner_type,
const unsigned int extraction_level,
const unsigned int n_subdomains)
: mapping(1)
: mapping(FE_SimplexDGP<dim>(1))
, grid_type(grid_type)
, partitioner_type(partitioner_type)
, extraction_level(extraction_level)
Expand Down Expand Up @@ -105,9 +108,11 @@ AgglomerationBenchmark<dim>::make_grid()
// }
grid_in.attach_triangulation(tria);
std::ifstream mesh_file(
"../../meshes/csf_brain_filled_centered_UCD.inp"); // piston mesh
grid_in.read_ucd(mesh_file);
tria.refine_global(1);
"../../meshes/gray_level_image1.vtk"); // liver mesh
grid_in.read_vtk(mesh_file);
// grid_in.read_ucd(mesh_file);
// "../../meshes/csf_brain_filled_centered_UCD.inp"); // brain mesh
// tria.refine_global(1);
}
}
else
Expand Down Expand Up @@ -158,8 +163,8 @@ AgglomerationBenchmark<dim>::make_grid()


// const auto tree = pack_rtree<bgi::rstar<max_elem_per_node>>(boxes);
auto start = std::chrono::system_clock::now();
const auto tree = pack_rtree<bgi::rstar<max_elem_per_node>>(boxes);
auto start = std::chrono::system_clock::now();
auto tree = pack_rtree<bgi::rstar<max_elem_per_node>>(boxes);
std::cout << "Total number of available levels: " << n_levels(tree)
<< std::endl;

Expand All @@ -169,9 +174,9 @@ AgglomerationBenchmark<dim>::make_grid()
ExcMessage("At least two levels are needed."));
#endif

const auto &csr_and_agglomerates =
PolyUtils::extract_children_of_level(tree, extraction_level);
const auto &agglomerates = csr_and_agglomerates.second; // vec<vec<>>
CellsAgglomerator<dim, decltype(tree)> agglomerator{tree,
extraction_level};
const auto agglomerates = agglomerator.extract_agglomerates();

std::size_t agglo_index = 0;
for (std::size_t i = 0; i < agglomerates.size(); ++i)
Expand Down Expand Up @@ -240,7 +245,7 @@ main()
std::cout << "Benchmarking with Rtree:" << std::endl;
// for (unsigned int i = 0; i < 10; ++i)
// {
for (const unsigned int extraction_level : {2, 3, 4, 5})
for (const unsigned int extraction_level : {2, 3, 4, 5, 6})
{
AgglomerationBenchmark<3> poisson_problem{GridType::unstructured,
PartitionerType::rtree,
Expand All @@ -255,12 +260,15 @@ main()
// // {
// // for (const unsigned int target_partitions : {12, 90, 715, 5715})
// //piston
for (const unsigned int target_partitions : {47, 372, 2976, 23804}) // brain
// for (const unsigned int target_partitions : {47, 372, 2976, 23804}) //
// brain
for (const unsigned int target_partitions :
{9, 70, 556, 4441, 29000}) // liver
{
AgglomerationBenchmark<3> poisson_problem{GridType::unstructured,
PartitionerType::metis,
0,
target_partitions}; // 16, 64
target_partitions};
poisson_problem.run();
}
}
232 changes: 232 additions & 0 deletions examples/repairing.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
#include <deal.II/fe/fe_simplex_p.h>
#include <deal.II/fe/mapping_fe.h>

#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_in.h>
#include <deal.II/grid/grid_out.h>
#include <deal.II/grid/grid_tools.h>

#include <deal.II/numerics/data_out.h>

#include <agglomeration_handler.h>
#include <poly_utils.h>


// Check that the R-tree based agglomeration works also in 3D.


enum class GridType
{
grid_generator,
unstructured
};

enum class PartitionerType
{
metis,
rtree
};


template <int dim>
class Test
{
private:
void
make_grid();
void
setup_agglomeration();

Triangulation<dim> tria;
MappingFE<dim> mapping;
FE_DGQ<dim> dg_fe;
std::unique_ptr<AgglomerationHandler<dim>> ah;
// no hanging node in DG discretization, we define an AffineConstraints object
// so we can use the distribute_local_to_global() directly.
AffineConstraints<double> constraints;
Vector<double> system_rhs;
std::unique_ptr<GridTools::Cache<dim>> cached_tria;
std::unique_ptr<const Function<dim>> rhs_function;

public:
Test(const GridType &grid_type = GridType::grid_generator,
const PartitionerType &partitioner_type = PartitionerType::rtree,
const unsigned int = 0,
const unsigned int = 0,
const unsigned int fe_degree = 1);
void
run();

double penalty_constant = 10.;
GridType grid_type;
PartitionerType partitioner_type;
unsigned int extraction_level;
unsigned int n_subdomains;
};



template <int dim>
Test<dim>::Test(const GridType &grid_type,
const PartitionerType &partitioner_type,
const unsigned int extraction_level,
const unsigned int n_subdomains,
const unsigned int fe_degree)
: mapping(FE_SimplexDGP<dim>(fe_degree))
, dg_fe(fe_degree)
, grid_type(grid_type)
, partitioner_type(partitioner_type)
, extraction_level(extraction_level)
, n_subdomains(n_subdomains)
{}

template <int dim>
void
Test<dim>::make_grid()
{
GridIn<dim> grid_in;
if (grid_type == GridType::unstructured)
{
grid_in.attach_triangulation(tria);
std::cout << "########### Reading mesh file... ###########" << std::endl;
std::ifstream filename("../../meshes/ernie.msh"); // liver or brain domain
grid_in.read_msh(filename);
std::cout << "########### Done ###########" << std::endl;
}
else
{
GridGenerator::hyper_cube(tria, 0, 1);
tria.refine_global(2);
GridTools::distort_random(0.25, tria);
}
std::cout << "Size of tria: " << tria.n_active_cells() << std::endl;
cached_tria = std::make_unique<GridTools::Cache<dim>>(tria, mapping);
}

template <int dim>
void
Test<dim>::setup_agglomeration()

{
ah = std::make_unique<AgglomerationHandler<dim>>(*cached_tria);

std::vector<types::global_cell_index> idxs_to_be_agglomerated = {0, 1, 2, 7};

std::vector<typename Triangulation<2>::active_cell_iterator>
cells_to_be_agglomerated;
PolyUtils::collect_cells_for_agglomeration(tria,
idxs_to_be_agglomerated,
cells_to_be_agglomerated);

std::vector<types::global_cell_index> idxs_to_be_agglomerated2 = {4, 5, 9};

std::vector<typename Triangulation<2>::active_cell_iterator>
cells_to_be_agglomerated2;
PolyUtils::collect_cells_for_agglomeration(tria,
idxs_to_be_agglomerated2,
cells_to_be_agglomerated2);

std::vector<types::global_cell_index> idxs_to_be_agglomerated3 = {3, 6};

std::vector<typename Triangulation<2>::active_cell_iterator>
cells_to_be_agglomerated3;
PolyUtils::collect_cells_for_agglomeration(tria,
idxs_to_be_agglomerated3,
cells_to_be_agglomerated3);

std::vector<types::global_cell_index> idxs_to_be_agglomerated4 = {8,
9,
10,
15};

std::vector<typename Triangulation<2>::active_cell_iterator>
cells_to_be_agglomerated4;
PolyUtils::collect_cells_for_agglomeration(tria,
idxs_to_be_agglomerated4,
cells_to_be_agglomerated4);

std::vector<types::global_cell_index> idxs_to_be_agglomerated5 = {11,
12,
13,
14};

std::vector<typename Triangulation<2>::active_cell_iterator>
cells_to_be_agglomerated5;
PolyUtils::collect_cells_for_agglomeration(tria,
idxs_to_be_agglomerated5,
cells_to_be_agglomerated5);

// Agglomerate the cells just stored
ah->define_agglomerate_with_check(cells_to_be_agglomerated);
ah->define_agglomerate_with_check(cells_to_be_agglomerated2);
ah->define_agglomerate_with_check(cells_to_be_agglomerated3);
ah->define_agglomerate_with_check(cells_to_be_agglomerated4);
ah->define_agglomerate_with_check(cells_to_be_agglomerated5);

std::cout << "Number of generated agglomerates: " << ah->n_agglomerates()
<< std::endl;

// std::cout << "########### Repairing the grid... ###########" <<
// std::endl; ah->repair_grid();
std::cout << "Defined all agglomerates" << std::endl;

// Check local bboxes
for (const auto &box : ah->get_local_bboxes())
{
std::cout << "p0: " << box.get_boundary_points().first << std::endl;
std::cout << "p1: " << box.get_boundary_points().second << std::endl;
std::cout << std::endl;
}

std::cout << "########### Create output for visualization... ###########"
<< std::endl;
{
const std::string &partitioner =
(partitioner_type == PartitionerType::metis) ? "metis" : "rtree";

const std::string filename = "square_repaired" + partitioner + ".vtu";
std::ofstream output(filename);

DataOut<dim> data_out;
data_out.attach_dof_handler(ah->agglo_dh);
// data_out.attach_dof_handler(ah->output_dh);

Vector<float> agglo_idx(tria.n_active_cells());
for (const auto &polytope : ah->polytope_iterators())
{
const types::global_cell_index polytopal_idx = polytope->index();
const auto &deal_cells = polytope->get_agglomerate();
for (const auto &cell : deal_cells)
agglo_idx[cell->active_cell_index()] = polytopal_idx;
}
data_out.add_data_vector(agglo_idx,
"agglomerated_idx",
DataOut<dim>::type_cell_data);
data_out.build_patches(mapping);
data_out.write_vtu(output);
}
std::cout << "########### Done ###########" << std::endl;
}

template <int dim>
void
Test<dim>::run()
{
make_grid();
setup_agglomeration();
}

int
main()
{
{
Test<2> test{GridType::grid_generator,
PartitionerType::rtree,
4 /*extraction_level*/};
test.run();
}



return 0;
}
20 changes: 17 additions & 3 deletions include/agglomeration_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <deal.II/fe/fe_dgp.h>
#include <deal.II/fe/fe_dgq.h>
#include <deal.II/fe/fe_nothing.h>
#include <deal.II/fe/fe_simplex_p.h>
#include <deal.II/fe/fe_system.h>
#include <deal.II/fe/fe_values.h>
#include <deal.II/fe/mapping_fe_field.h>
Expand Down Expand Up @@ -56,9 +57,6 @@
using namespace dealii;

// Forward declarations
template <int dim>
class FinitElement;

template <int dim, int spacedim>
class AgglomerationHandler;

Expand Down Expand Up @@ -298,6 +296,9 @@ class AgglomerationHandler : public Subscriptor
inline const FiniteElement<dim, spacedim> &
get_fe() const;

inline const Mapping<dim> &
get_mapping() const;

inline const std::vector<BoundingBox<dim>> &
get_local_bboxes() const;

Expand Down Expand Up @@ -831,6 +832,10 @@ class AgglomerationHandler : public Subscriptor
// Map the master cell index with the polytope index
std::map<types::global_cell_index, types::global_cell_index> master2polygon;


std::vector<typename Triangulation<dim>::active_cell_iterator>
master_disconnected;

// Dummy FiniteElement objects needed only to generate quadratures

/**
Expand Down Expand Up @@ -883,6 +888,15 @@ AgglomerationHandler<dim, spacedim>::get_fe() const



template <int dim, int spacedim>
inline const Mapping<dim> &
AgglomerationHandler<dim, spacedim>::get_mapping() const
{
return *mapping;
}



template <int dim, int spacedim>
inline const Triangulation<dim, spacedim> &
AgglomerationHandler<dim, spacedim>::get_triangulation() const
Expand Down
Loading

0 comments on commit 9aa5396

Please sign in to comment.