37 constexpr
int NUM_PTS = NX * NY;
41 void check(
bool ok,
const std::string& what,
int rank)
44 std::cerr <<
"FAILED [rank " << rank <<
"]: " << what <<
'\n';
52 void global_indices(
int rank, vector<SF_int>& gidx)
54 gidx.resize(rank == 0 ? NUM_PTS : 0);
55 for (
size_t i = 0; i < gidx.size(); i++) gidx[i] =
SF_int(i);
60 void build_mesh(
int rank, MPI_Comm comm,
mesh_t& mesh)
63 mesh.g_numpts = NUM_PTS;
67 for (
int y = 0; y + 1 < NY; y++) {
68 for (
int x = 0; x + 1 < NX; x++) {
70 mesh.con.push_back(n);
71 mesh.con.push_back(n + 1);
72 mesh.con.push_back(n + NX + 1);
73 mesh.con.push_back(n + NX);
79 mesh.l_numelem = cnt.size();
83 global_indices(rank, gidx);
84 mesh.pl.assign(gidx, comm);
85 mesh.l_numpts = mesh.pl.num_local_idx();
89 void run_case(
bool use_rcm, MPI_Comm comm,
int rank)
91 const std::string what = use_rcm ?
"renumbered" :
"ascending";
94 build_mesh(rank, comm, mesh);
96 const vector<SF_int>& alg_nod = mesh.pl.algebraic_nodes();
98 check(alg_nod.size() == NUM_PTS, what +
": rank 0 owns the whole grid", rank);
100 check(alg_nod.size() == 0, what +
": rank owns no algebraic node", rank);
105 const vector<SF_int>& petsc_idx = mesh.get_numbering(
SF::NBR_PETSC);
106 const vector<SF_int>& alg_dsp = mesh.pl.algebraic_layout();
107 const SF_int alg_start = alg_dsp[rank];
111 bool positional =
true;
112 for (
size_t i = 0; i < alg_nod.size(); i++)
113 if (petsc_idx[alg_nod[i]] != alg_start +
SF_int(i)) positional =
false;
114 check(positional, what +
": algebraic position matches the PETSc slot", rank);
117 std::vector<bool> seen(mesh.pl.num_local_idx(),
false);
118 bool set_intact =
true;
119 for (
size_t i = 0; i < alg_nod.size(); i++) {
120 const SF_int n = alg_nod[i];
121 if (n < 0 ||
size_t(n) >= seen.size() || seen[n]) set_intact =
false;
124 check(set_intact, what +
": algebraic node set is free of gaps and duplicates", rank);
129 int main(
int argc,
char** argv)
131 MPI_Init(&argc, &argv);
133 MPI_Comm comm = MPI_COMM_WORLD;
135 MPI_Comm_size(comm, &size);
136 MPI_Comm_rank(comm, &rank);
139 if (!rank) std::cerr <<
"FAILED: this test needs at least 2 ranks to leave one empty\n";
144 run_case(
false, comm, rank);
145 run_case(
true, comm, rank);
148 MPI_Allreduce(&failures, &total, 1, MPI_INT, MPI_SUM, comm);
151 return total ? 1 : 0;
opencarp::global_index_t SF_int
Global algebraic index type.
Basic utility structs and functions, mostly IO related.
The mesh storage class. It contains both element and vertex data.
Functor class generating a numbering optimized for PETSc.
A vector storing arbitrary data.
void dsp_from_cnt(const vector< T > &cnt, vector< T > &dsp)
Compute displacements from counts.
@ NBR_PETSC
PETSc numbering of nodes.
mesh_t
The enum identifying the different meshes we might want to load.
int main(int argc, char **argv)