Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

patchkernel: add support for parallel surface skd-tree searches #78

Merged
merged 8 commits into from
Aug 3, 2020
519 changes: 415 additions & 104 deletions src/patchkernel/patch_skd_tree.cpp

Large diffs are not rendered by default.

96 changes: 79 additions & 17 deletions src/patchkernel/patch_skd_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,30 @@ friend class PatchSkdTree;

};

class SkdNode {
class SkdBox {

public:
SkdBox();
SkdBox(const std::array<double,3> &boxMin, const std::array<double,3> &boxMax);

const std::array<double, 3> & getBoxMin() const;
const std::array<double, 3> & getBoxMax() const;

double evalPointMinDistance(const std::array<double, 3> &point) const;
double evalPointMaxDistance(const std::array<double, 3> &point) const;

bool boxContainsPoint(const std::array<double,3> &point, double offset) const;
bool boxIntersectsSphere(const std::array<double,3> &center, double radius) const;

protected:
std::array<double, 3> m_boxMin;
std::array<double, 3> m_boxMax;

};

class SkdNode : public SkdBox {

friend class PatchSkdTree;
friend class SkdNodeAllocator;

public:
static const std::size_t NULL_ID;
Expand All @@ -85,23 +105,18 @@ friend class SkdNodeAllocator;
std::vector<long> getCells() const;
long getCell(std::size_t n) const;

const std::array<double, 3> & getBoxMin() const;
const std::array<double, 3> & getBoxMax() const ;
const SkdBox & getBoundingBox() const;

std::array<double,3> evalBoxWeightedMean() const;

bool isLeaf() const;
bool hasChild(ChildLocation child) const;
std::size_t getChildId(ChildLocation child) const;

bool boxContainsPoint(const std::array<double,3> &point, double offset) const;
bool boxIntersectsSphere(const std::array<double,3> &center, double radius) const;

double evalPointMinDistance(const std::array<double, 3> &point) const;
double evalPointMaxDistance(const std::array<double, 3> &point) const;
double evalPointDistance(const std::array<double, 3> &point) const;
double evalPointDistance(const std::array<double, 3> &point, bool ignoreGhosts) const;

void findPointClosestCell(const std::array<double, 3> &point, long *id, double *distance) const;
void updatePointClosestCell(const std::array<double, 3> &point, long *id, double *distance) const;
void findPointClosestCell(const std::array<double, 3> &point, bool ignoreGhosts, long *id, double *distance) const;
void updatePointClosestCell(const std::array<double, 3> &point, bool ignoreGhosts, long *id, double *distance) const;

protected:
struct Allocator : std::allocator<SkdNode>
Expand All @@ -125,9 +140,6 @@ friend class SkdNodeAllocator;
std::size_t m_cellRangeBegin;
std::size_t m_cellRangeEnd;

std::array<double,3> m_boxMin;
std::array<double,3> m_boxMax;

std::array<std::size_t, MAX_CHILDREN> m_children;

void initializeBoundingBox();
Expand All @@ -138,6 +150,34 @@ friend class SkdNodeAllocator;

};

#if BITPIT_ENABLE_MPI
struct SkdGlobalCellDistance {

public:
static MPI_Datatype getMPIDatatype();
static MPI_Op getMPIMinOperation();
static void executeMPIMinOperation(SkdGlobalCellDistance *in, SkdGlobalCellDistance *inout, int *len, MPI_Datatype *datatype);

int & getRank();
long & getId();
double & getDistance();

void exportData(int *rank, long *id, double *distance) const;

private:
static bool m_MPIDatatypeInitialized;
static MPI_Datatype m_MPIDatatype;

static bool m_MPIMinOperationInitialized;
static MPI_Op m_MPIMinOperation;

double m_distance;
long m_id;
int m_rank;

};
#endif

class PatchSkdTree {

public:
Expand All @@ -158,6 +198,10 @@ class PatchSkdTree {

std::size_t evalMaxDepth(std::size_t rootId = 0) const;

#if BITPIT_ENABLE_MPI
const SkdBox & getPartitionBox(int rank) const;
#endif

protected:
SkdPatchInfo m_patchInfo;
std::vector<std::size_t> m_cellRawIds;
Expand All @@ -168,16 +212,34 @@ class PatchSkdTree {

std::vector<SkdNode, SkdNode::Allocator> m_nodes;

bool m_includeGhosts;
bool m_interiorOnly;

#if BITPIT_ENABLE_MPI
int m_rank;
int m_nProcessors;
MPI_Comm m_communicator;
std::vector<SkdBox> m_partitionBoxes;
#endif

PatchSkdTree(const PatchKernel *patch, bool includeGhosts = true);
PatchSkdTree(const PatchKernel *patch, bool interiorOnly = false);

SkdNode & _getNode(std::size_t nodeId);

#if BITPIT_ENABLE_MPI
bool isCommunicatorSet() const;
const MPI_Comm & getCommunicator() const;
void setCommunicator(MPI_Comm communicator);
void freeCommunicator();
#endif

private:
void createChildren(std::size_t parentId, std::size_t leaftThreshold);
void createLeaf(std::size_t nodeId);

#if BITPIT_ENABLE_MPI
void buildPartitionBoxes();
#endif

};

}
Expand Down
Loading