Skip to content

Commit 4affaea

Browse files
authored
Merge pull request #236 from SCOREC/wrt/nosharing-count
More general entity-type counting, expose the NoSharing type through the API for external usage
2 parents 58278c6 + e6e8e02 commit 4affaea

File tree

7 files changed

+117
-23
lines changed

7 files changed

+117
-23
lines changed

apf/apf.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "apfNumberingClass.h"
2222
#include <cstdio>
2323
#include <cstdlib>
24+
#include <PCU.h>
2425
#include <pcu_util.h>
2526
#include <lionPrint.h>
2627

@@ -140,6 +141,46 @@ bool hasEntity(Field* f, MeshEntity* e)
140141
return f->getData()->hasEntity(e);
141142
}
142143

144+
int countLocalNodes(Field* f, Sharing* shr)
145+
{
146+
Mesh * msh = getMesh(f);
147+
FieldShape * shp = getShape(f);
148+
return countLocalNodes(msh,shp,shr);
149+
}
150+
151+
int countLocalNodes(Mesh* m, FieldShape * shp, Sharing * shr)
152+
{
153+
// if shr is NULL, the default behavior of
154+
// countEntitiesOfType is to count ALL
155+
// entities on the local part of type tp
156+
int nds = 0;
157+
for(int tp = Mesh::VERTEX; tp != Mesh::TYPES; ++tp)
158+
nds += countEntitiesOfType(m,tp,shr) * shp->countNodesOn(tp);
159+
return nds;
160+
}
161+
162+
int countGlobalNodes(Field* f, Sharing* shr)
163+
{
164+
Mesh * msh = getMesh(f);
165+
FieldShape * shp = getShape(f);
166+
return countGlobalNodes(msh,shp,shr);
167+
}
168+
169+
int countGlobalNodes(Mesh* m, FieldShape* shp, Sharing* shr)
170+
{
171+
bool del = false;
172+
if(shr == NULL)
173+
{
174+
shr = getSharing(m);
175+
del = true;
176+
}
177+
int lcl_nds = countLocalNodes(m,shp,shr);
178+
int gbl_nds = PCU_Add_Int(lcl_nds);
179+
if(del)
180+
delete shr;
181+
return gbl_nds;
182+
}
183+
143184
const char* getName(Field* f)
144185
{
145186
return f->getName();

apf/apf.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,24 @@ Mesh* getMesh(Field* f);
204204
*/
205205
bool hasEntity(Field* f, MeshEntity* e);
206206

207+
/** \brief Count all field nodes owned according to shr, on all mesh
208+
entities on the local part, default is all to count every node,
209+
even those on owned entities
210+
*/
211+
int countLocalNodes(Field* f, Sharing* shr = NULL);
212+
/** \brief same as countLocalNodes but you don't need to allocate a field
213+
*/
214+
int countLocalNodes(Mesh* m, FieldShape* shp, Sharing* shr = NULL);
215+
216+
/** \brief Count all field nodes owned according to shr, on all mesh
217+
entities on all parts in PCU_COMM_WORLD, default is to use the
218+
NormalSharing to define ownership.
219+
*/
220+
int countGlobalNodes(Field* f, Sharing* shr = NULL);
221+
/** \brief same as countGlobalNodes but you don't need to allocate a field
222+
*/
223+
int countGlobalNodes(Mesh* m, FieldShape* shp, Sharing* shr = NULL);
224+
207225
/** \brief Get the name of a Field.
208226
*
209227
* \details Both for use convenience and for technical reasons
@@ -682,7 +700,7 @@ void synchronize(Field* f, Sharing* shr = 0);
682700
*/
683701
void accumulate(Field* f, Sharing* shr = 0, bool delete_shr = false);
684702

685-
/** \brief Apply a reudction operator along partition boundaries
703+
/** \brief Apply a reduction operator along partition boundaries
686704
\details Using the copies described by an apf::Sharing object, applied
687705
the specified operation pairwise to the values of the field on each
688706
partition. No guarantee is made about hte order of the pairwise

apf/apfMesh.cc

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,13 +676,16 @@ MeshEntity* getEdgeVertOppositeVert(Mesh* m, MeshEntity* edge, MeshEntity* v)
676676
return ev[0];
677677
}
678678

679-
int countEntitiesOfType(Mesh* m, int type)
679+
680+
int countEntitiesOfType(Mesh* m, int type, Sharing * shr)
680681
{
682+
if(shr == NULL)
683+
shr = getNoSharing();
681684
MeshIterator* it = m->begin(Mesh::typeDimension[type]);
682685
MeshEntity* e;
683686
int count = 0;
684687
while ((e = m->iterate(it)))
685-
if (m->getType(e)==type)
688+
if (m->getType(e)==type && shr->isOwned(e))
686689
++count;
687690
m->end(it);
688691
return count;
@@ -996,6 +999,36 @@ bool MatchedSharing::isShared(MeshEntity* e) {
996999
return false;
9971000
}
9981001

1002+
// treat all entities as if they are not shared,
1003+
// used to count all local entities instead of
1004+
// all owned entities as the default
1005+
// The ONLY justification for this being a
1006+
// singleton is that it is essentially a functor
1007+
// at this point, as it retains no state, so there
1008+
// only ever needs to be a single instance of this
1009+
struct NoSharing : public Sharing
1010+
{
1011+
private:
1012+
static NoSharing * instance;
1013+
NoSharing() {}
1014+
~NoSharing() {}
1015+
public:
1016+
static NoSharing * Instance()
1017+
{
1018+
if(instance == NULL)
1019+
instance = new NoSharing;
1020+
return instance;
1021+
}
1022+
virtual int getOwner(MeshEntity*) { return PCU_Comm_Self(); }
1023+
virtual bool isOwned(MeshEntity*) { return true; }
1024+
virtual void getCopies(MeshEntity*,CopyArray&) { }
1025+
virtual bool isShared(MeshEntity*) { return false; }
1026+
};
1027+
NoSharing * NoSharing::instance = NULL;
1028+
1029+
// obfuscate the singleton just a bit
1030+
Sharing* getNoSharing() { return NoSharing::Instance(); }
1031+
9991032
Sharing* getSharing(Mesh* m)
10001033
{
10011034
if (m->hasMatching())

apf/apfMesh.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,6 @@ MeshEntity* getEdgeVertOppositeVert(Mesh* m, MeshEntity* edge, MeshEntity* v);
430430
void getBridgeAdjacent(Mesh* m, MeshEntity* origin,
431431
int bridgeDimension, int targetDimension, Adjacent& result);
432432

433-
/** \brief count all on-part entities of one topological type */
434-
int countEntitiesOfType(Mesh* m, int type);
435-
436433
/** \brief return true if the topological type is a simplex */
437434
bool isSimplex(int type);
438435

@@ -516,13 +513,21 @@ struct MatchedSharing : public Sharing
516513
std::map<int, size_t> countMap;
517514
};
518515

516+
Sharing* getNoSharing();
517+
519518
/** \brief create a default sharing object for this mesh
520519
\details for normal meshes, the sharing object just
521520
describes remote copies. For matched meshes, the
522521
sharing object describes matches for matched entities
523522
and remote copies for other entities */
524523
Sharing* getSharing(Mesh* m);
525524

525+
/** \brief count all on-part entities of one topological type,
526+
\details if a sharing is provided, only 'owned' entities of
527+
the specified type are counted, otherwise all on-part entities
528+
are counted */
529+
int countEntitiesOfType(Mesh* m, int type, Sharing * shr = NULL);
530+
526531
/** \brief map from triangle edge order to triangle vertex order */
527532
extern int const tri_edge_verts[3][2];
528533
/** \brief map from quad edge order to quad vertex order */

apf/apfNumbering.cc

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,6 @@ void synchronize(Numbering * n, Sharing* shr, bool delete_shr)
221221
synchronizeFieldData<int>(n->getData(), shr, delete_shr);
222222
}
223223

224-
struct NoSharing : public Sharing
225-
{
226-
int getOwner(MeshEntity*) {return PCU_Comm_Self();}
227-
bool isOwned(MeshEntity*) {return true;}
228-
virtual void getCopies(MeshEntity*, CopyArray&) {}
229-
bool isShared(MeshEntity*) {return false;}
230-
};
231-
232224
Numbering* numberNodes(
233225
Mesh* mesh,
234226
const char* name,
@@ -258,23 +250,22 @@ Numbering* numberNodes(
258250
return n;
259251
}
260252

261-
Numbering* numberOwnedDimension(Mesh* mesh, const char* name, int dim,
262-
Sharing* shr)
253+
Numbering* numberOwnedDimension(Mesh* mesh, const char* name, int dim, Sharing * shr)
263254
{
264-
bool delete_shr=false;
265-
if (!shr)
255+
bool delete_shr = false;
256+
if (!shr)
266257
{
267258
shr = getSharing(mesh);
268-
delete_shr=true;
259+
delete_shr = true;
269260
}
270261
return numberNodes(mesh, name, getConstant(dim), shr, delete_shr);
271262
}
272263

273264
Numbering* numberOverlapDimension(Mesh* mesh, const char* name, int dim)
274265
{
275266
FieldShape* s = getConstant(dim);
276-
Sharing* shr = new NoSharing();
277-
return numberNodes(mesh, name, s, shr, true);
267+
Sharing* shr = getNoSharing();
268+
return numberNodes(mesh, name, s, shr, false);
278269
}
279270

280271
Numbering* numberElements(Mesh* mesh, const char* name)
@@ -286,8 +277,7 @@ Numbering* numberOverlapNodes(Mesh* mesh, const char* name, FieldShape* s)
286277
{
287278
if (!s)
288279
s = mesh->getShape();
289-
Sharing* shr = new NoSharing();
290-
return numberNodes(mesh, name, s, shr, true);
280+
return numberNodes(mesh, name, s, getNoSharing(), false);
291281
}
292282

293283
Numbering* numberOwnedNodes(

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ test_exe_func(quality quality.cc)
2222
test_exe_func(writeVtxPtn writeVtxPtn.cc)
2323
test_exe_func(verify_2nd_order_shapes verify_2nd_order_shapes.cc)
2424
test_exe_func(verify_convert verify_convert.cc)
25+
test_exe_func(count_entities count_entities.cc)
2526

2627
# Geometric model utilities
2728
if(ENABLE_SIMMETRIX)

test/testing.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ mpi_test(qr_test 1 ./qr)
3535
mpi_test(base64 1 ./base64)
3636
mpi_test(tensor_test 1 ./tensor)
3737
mpi_test(verify_convert 1 ./verify_convert)
38+
mpi_test(count_serial 1
39+
./count_entities
40+
"${MESHES}/cube/pumi11/cube.smb")
41+
mpi_test(count_parallel 2
42+
./count_entities
43+
"${MESHES}/cube/pumi670/2/cube.smb")
3844
mpi_test(test_integrator 1
3945
./test_integrator
4046
"${MESHES}/cube/cube.dmg"

0 commit comments

Comments
 (0)