Skip to content
Snippets Groups Projects
Commit fc808ccf authored by Matteo Cicuttin's avatar Matteo Cicuttin
Browse files

Entities are distributed.

parent 47cd04ea
No related branches found
No related tags found
No related merge requests found
...@@ -56,7 +56,7 @@ class entity ...@@ -56,7 +56,7 @@ class entity
void populate_normals(entity_data_cpu&) const; void populate_normals(entity_data_cpu&) const;
public: public:
entity() = delete; entity() {}// = delete;
entity(const entity&) = delete; entity(const entity&) = delete;
entity(entity&&) = default; entity(entity&&) = default;
entity& operator=(const entity&) = delete; entity& operator=(const entity&) = delete;
......
...@@ -36,7 +36,9 @@ enum class face_type : int ...@@ -36,7 +36,9 @@ enum class face_type : int
NONE = 0, NONE = 0,
INTERFACE, INTERFACE,
BOUNDARY, BOUNDARY,
#ifdef USE_MPI
INTERPROCESS_BOUNDARY INTERPROCESS_BOUNDARY
#endif
}; };
struct boundary_descriptor struct boundary_descriptor
...@@ -84,6 +86,9 @@ class model ...@@ -84,6 +86,9 @@ class model
/* Map from the partition number to the entities belonging to that partition */ /* Map from the partition number to the entities belonging to that partition */
std::map<int, std::vector<int>> partition_map; std::map<int, std::vector<int>> partition_map;
/* Map from 3D entity tag to partition */
std::map<int, int> partition_inverse_map;
std::vector<entity> entities; std::vector<entity> entities;
std::vector<boundary_descriptor> bnd_descriptors; std::vector<boundary_descriptor> bnd_descriptors;
element_connectivity<element_key> conn; element_connectivity<element_key> conn;
...@@ -92,13 +97,16 @@ class model ...@@ -92,13 +97,16 @@ class model
std::map<size_t, entofs_pair> etag_to_entity_offset; std::map<size_t, entofs_pair> etag_to_entity_offset;
void map_boundaries(void); void map_boundaries(void);
void import_gmsh_entities(void); void import_gmsh_entities_rank0(void);
void update_connectivity(const entity&, size_t); void update_connectivity(const entity&, size_t);
void populate_from_gmsh_rank0(void); void populate_from_gmsh_rank0(void);
#ifdef USE_MPI #ifdef USE_MPI
bool is_interprocess_boundary(int);
void populate_from_gmsh_rankN(void); void populate_from_gmsh_rankN(void);
void import_gmsh_entities_rankN(void);
int my_partition(void) const;
#endif #endif
void make_boundary_to_faces_map(void); void make_boundary_to_faces_map(void);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
assert(__rank == 0); \ assert(__rank == 0); \
} }
#else #else
#define ASSERT_MPI_RANK_0 (void) 0 #define ASSERT_MPI_RANK_0 ((void) 0)
#endif #endif
template<typename T> template<typename T>
......
...@@ -57,7 +57,9 @@ model::~model() ...@@ -57,7 +57,9 @@ model::~model()
void void
model::make_boundary_to_faces_map(void) model::make_boundary_to_faces_map(void)
{ {
#ifdef USE_MPI
ASSERT_MPI_RANK_0; ASSERT_MPI_RANK_0;
#endif /* USE_MPI */
gvp_t gmsh_entities; gvp_t gmsh_entities;
...@@ -105,7 +107,9 @@ model::make_boundary_to_faces_map(void) ...@@ -105,7 +107,9 @@ model::make_boundary_to_faces_map(void)
void void
model::make_partition_to_entities_map() model::make_partition_to_entities_map()
{ {
#ifdef USE_MPI
ASSERT_MPI_RANK_0; ASSERT_MPI_RANK_0;
#endif /* USE_MPI */
gvp_t gmsh_entities; gvp_t gmsh_entities;
...@@ -127,6 +131,7 @@ model::make_partition_to_entities_map() ...@@ -127,6 +131,7 @@ model::make_partition_to_entities_map()
assert(parts.size() == 1); assert(parts.size() == 1);
gm::getPartitions(dim, tag, parts); gm::getPartitions(dim, tag, parts);
partition_map[ parts[0] ].push_back(tag); partition_map[ parts[0] ].push_back(tag);
partition_inverse_map[tag] = parts[0];
} }
} }
...@@ -137,7 +142,9 @@ model::make_partition_to_entities_map() ...@@ -137,7 +142,9 @@ model::make_partition_to_entities_map()
void void
model::update_connectivity(const entity& e, size_t entity_index) model::update_connectivity(const entity& e, size_t entity_index)
{ {
#ifdef USE_MPI
ASSERT_MPI_RANK_0; ASSERT_MPI_RANK_0;
#endif /* USE_MPI */
for (size_t iT = 0; iT < e.num_cells(); iT++) for (size_t iT = 0; iT < e.num_cells(); iT++)
{ {
...@@ -151,9 +158,25 @@ model::update_connectivity(const entity& e, size_t entity_index) ...@@ -151,9 +158,25 @@ model::update_connectivity(const entity& e, size_t entity_index)
} }
} }
#ifdef USE_MPI
int
model::my_partition(void) const
{
/* Here we are assuming that GMSH enumerates mesh partitions
* sequentially and starting from 1. */
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
return rank+1;
}
#endif /* USE_MPI */
void void
model::import_gmsh_entities(void) model::import_gmsh_entities_rank0(void)
{ {
#ifdef USE_MPI
ASSERT_MPI_RANK_0;
#endif /* USE_MPI */
gvp_t gmsh_entities; gvp_t gmsh_entities;
gm::getEntities(gmsh_entities, DIMENSION(3)); gm::getEntities(gmsh_entities, DIMENSION(3));
...@@ -189,6 +212,24 @@ model::import_gmsh_entities(void) ...@@ -189,6 +212,24 @@ model::import_gmsh_entities(void)
e.sort_by_orientation(); e.sort_by_orientation();
#ifdef USE_MPI
if (num_partitions > 1)
{
auto mp = my_partition();
auto tag_partition = partition_inverse_map.at(tag);
bool entity_is_remote = ( tag_partition != mp );
if (entity_is_remote)
{
assert(tag_partition > 0);
int rank = tag_partition - 1;
e.mpi_send(rank, MPI_COMM_WORLD);
std::cout << "Sending entity " << tag << " to " << rank << std::endl;
continue;
}
}
std::cout << "Keeping entity " << tag << std::endl;
#endif /* USE_MPI */
for (size_t i = 0; i < e.num_cells(); i++) for (size_t i = 0; i < e.num_cells(); i++)
{ {
const auto& pe = e.cell(i); const auto& pe = e.cell(i);
...@@ -211,12 +252,65 @@ model::import_gmsh_entities(void) ...@@ -211,12 +252,65 @@ model::import_gmsh_entities(void)
entity_index++; entity_index++;
} }
} }
std::cout << dof_base << " " << flux_base << std::endl;
}
#ifdef USE_MPI
void
model::import_gmsh_entities_rankN(void)
{
int mp = my_partition();
size_t entity_index = 0;
size_t dof_base = 0;
size_t flux_base = 0;
size_t index_base = 0;
for (auto& rtag : partition_map.at(mp))
{
std::cout << "Receiving " << rtag << ", rank " << mp-1 << std::endl;
entity e;
e.mpi_recv(0, MPI_COMM_WORLD);
for (size_t i = 0; i < e.num_cells(); i++)
{
const auto& pe = e.cell(i);
auto eitor = etag_to_entity_offset.find( pe.element_tag() );
if ( eitor != etag_to_entity_offset.end() )
throw std::logic_error("Duplicate tag");
etag_to_entity_offset[ pe.element_tag() ] = std::make_pair(entity_index, i);
}
e.base(dof_base, flux_base, index_base);
e.number(entity_index);
dof_base += e.num_dofs();
flux_base += e.num_fluxes();
index_base += e.num_cells();
update_connectivity(e, entity_index);
entities.push_back( std::move(e) );
entity_index++;
}
std::cout << dof_base << " " << flux_base << std::endl;
} }
bool
model::is_interprocess_boundary(int tag)
{
return comm_map.at(tag).size() == 2;
}
#endif /* USE_MPI */
void void
model::map_boundaries(void) model::map_boundaries(void)
{ {
#ifdef USE_MPI
ASSERT_MPI_RANK_0; ASSERT_MPI_RANK_0;
#endif /* USE_MPI */
/* Make a vector mapping element_key to entity tag */ /* Make a vector mapping element_key to entity tag */
using bfk_t = std::pair<element_key, int>; using bfk_t = std::pair<element_key, int>;
...@@ -253,9 +347,18 @@ model::map_boundaries(void) ...@@ -253,9 +347,18 @@ model::map_boundaries(void)
boundary_descriptor bd; boundary_descriptor bd;
/* determine if it is an interface or a boundary */ /* determine if it is an interface or a boundary */
if (conn.num_neighbours(fk) == 1) if (conn.num_neighbours(fk) == 1)
bd.type = face_type::BOUNDARY; {
#ifdef USE_MPI
if ( is_interprocess_boundary( (*itor).second ) )
bd.type = face_type::INTERPROCESS_BOUNDARY;
else
#endif /* USE_MPI */
bd.type = face_type::BOUNDARY;
}
else else
{
bd.type = face_type::INTERFACE; bd.type = face_type::INTERFACE;
}
/* and store the gmsh tag in the descriptor. */ /* and store the gmsh tag in the descriptor. */
bd.gmsh_entity = (*itor).second; bd.gmsh_entity = (*itor).second;
...@@ -277,7 +380,9 @@ model::map_boundaries(void) ...@@ -277,7 +380,9 @@ model::map_boundaries(void)
case face_type::NONE: normal++; break; case face_type::NONE: normal++; break;
case face_type::INTERFACE: interface++; break; case face_type::INTERFACE: interface++; break;
case face_type::BOUNDARY: boundary++; break; case face_type::BOUNDARY: boundary++; break;
#ifdef USE_MPI
case face_type::INTERPROCESS_BOUNDARY: ipc_boundary++; break; case face_type::INTERPROCESS_BOUNDARY: ipc_boundary++; break;
#endif /* USE_MPI */
} }
} }
...@@ -288,7 +393,9 @@ model::map_boundaries(void) ...@@ -288,7 +393,9 @@ model::map_boundaries(void)
void void
model::populate_from_gmsh_rank0() model::populate_from_gmsh_rank0()
{ {
#ifdef USE_MPI
ASSERT_MPI_RANK_0; ASSERT_MPI_RANK_0;
#endif /* USE_MPI */
gmm::setOrder( geometric_order ); gmm::setOrder( geometric_order );
make_boundary_to_faces_map(); make_boundary_to_faces_map();
...@@ -321,7 +428,7 @@ model::populate_from_gmsh_rank0() ...@@ -321,7 +428,7 @@ model::populate_from_gmsh_rank0()
#endif /* USE_MPI */ #endif /* USE_MPI */
entities.clear(); entities.clear();
import_gmsh_entities(); import_gmsh_entities_rank0();
map_boundaries(); /* This must happen after import_gmsh_entities(). */ map_boundaries(); /* This must happen after import_gmsh_entities(). */
} }
...@@ -344,6 +451,10 @@ model::populate_from_gmsh_rankN() ...@@ -344,6 +451,10 @@ model::populate_from_gmsh_rankN()
std::cout << v << " "; std::cout << v << " ";
std::cout << std::endl; std::cout << std::endl;
} }
entities.clear();
import_gmsh_entities_rankN();
map_boundaries();
} }
#endif /* USE_MPI */ #endif /* USE_MPI */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment