Skip to content
Snippets Groups Projects
Commit 13a644a5 authored by Sandro Christian Wenzel's avatar Sandro Christian Wenzel
Browse files

Introduce a new API to LevelLocator for G4 integration

An API resembling what Geant4 needs.

Cleanup of some old uncommented code.
parent b274b1b9
Branches
No related tags found
No related merge requests found
......@@ -75,84 +75,60 @@ private:
return false;
}
public:
// virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, VPlacedVolume const
// *&pvol,
// Vector3D<Precision> &transformedPoint) const override
// {
// int halfvectorsize, numberOfNodes;
// auto boxes_v = fAccelerationStructure.GetABBoxes_v(lvol, halfvectorsize, numberOfNodes);
// std::vector<int> *nodeToDaughters = fAccelerationStructure.GetNodeToDaughters(lvol);
// constexpr auto kVS = vecCore::VectorSize<HybridManager2::Float_v>();
// for (int index = 0, nodeindex = 0; index < halfvectorsize * 2; index += 2 * (kVS + 1), nodeindex += kVS) {
// using Bool_v = vecCore::Mask_v<HybridManager2::Float_v>;
// Bool_v inChildNodes;
// ABBoxImplementation::ABBoxContainsKernel(boxes_v[index], boxes_v[index + 1], localpoint, inChildNodes);
// if (!vecCore::MaskEmpty(inChildNodes)) {
// for (size_t i = 0 /*inChildNodes.firstOne()*/; i < kVS; ++i) {
// if (vecCore::MaskLaneAt(inChildNodes, i)) {
// Bool_v inDaughterBox;
// ABBoxImplementation::ABBoxContainsKernel(boxes_v[index + 2 * i + 2], boxes_v[index + 2 * i + 3],
// localpoint,
// inDaughterBox);
// if (!vecCore::MaskEmpty(inDaughterBox)) {
// for (size_t j = 0 /*inDaughterBox.firstOne()*/; j < kVS; ++j) { // leaf node
// if (vecCore::MaskLaneAt(inDaughterBox, j) &&
// lvol->GetDaughters()[nodeToDaughters[nodeindex + i][j]]->Contains(localpoint, transformedPoint))
// {
// pvol = lvol->GetDaughters()[nodeToDaughters[nodeindex + i][j]];
// return true;
// }
// }
// }
// }
// }
// }
// }
// return false;
// }
// virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
// Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
// Vector3D<Precision> &transformedPoint) const override
// {
// int halfvectorsize, numberOfNodes;
// auto boxes_v = fAccelerationStructure.GetABBoxes_v(lvol, halfvectorsize, numberOfNodes);
// std::vector<int> *nodeToDaughters = fAccelerationStructure.GetNodeToDaughters(lvol);
// constexpr auto kVS = vecCore::VectorSize<HybridManager2::Float_v>();
// for (int index = 0, nodeindex = 0; index < halfvectorsize * 2; index += 2 * (kVS + 1), nodeindex += kVS) {
// using Bool_v = vecCore::Mask_v<HybridManager2::Float_v>;
// Bool_v inChildNodes;
// ABBoxImplementation::ABBoxContainsKernel(boxes_v[index], boxes_v[index + 1], localpoint, inChildNodes);
// if (!vecCore::MaskEmpty(inChildNodes)) {
// for (size_t i = 0 /*inChildNodes.firstOne()*/; i < kVS; ++i) {
// if (vecCore::MaskLaneAt(inChildNodes, i)) {
// Bool_v inDaughterBox;
// ABBoxImplementation::ABBoxContainsKernel(boxes_v[index + 2 * i + 2], boxes_v[index + 2 * i + 3],
// localpoint,
// inDaughterBox);
// if (!vecCore::MaskEmpty(inDaughterBox)) {
// for (size_t j = 0 /*inDaughterBox.firstOne()*/; j < kVS; ++j) { // leaf node
// if (vecCore::MaskLaneAt(inDaughterBox, j)) {
// auto daughter = lvol->GetDaughters()[nodeToDaughters[nodeindex + i][j]];
// if (daughter == exclvol) continue;
// if (daughter->Contains(localpoint, transformedPoint)) {
// pvol = daughter;
// return true;
// }
// }
// }
// }
// }
// }
// }
// }
// return false;
// }
// the actual implementation kernel
// the template "ifs" should be optimized away
// arguments are pointers to allow for nullptr
template <bool ExclV, bool ModifyState>
__attribute__((always_inline)) bool LevelLocateKernelWithDirection(LogicalVolume const *lvol,
VPlacedVolume const *exclvol,
Vector3D<Precision> const &localpoint,
Vector3D<Precision> const &localdir,
NavigationState *state, VPlacedVolume const *&pvol,
Vector3D<Precision> &daughterlocalpoint) const
{
auto accstructure = fAccelerationStructure.GetAccStructure(lvol);
int halfvectorsize, numberOfNodes;
auto boxes_v = fAccelerationStructure.GetABBoxes_v(*accstructure, halfvectorsize, numberOfNodes);
auto const *nodeToDaughters = accstructure->fNodeToDaughters;
constexpr auto kVS = vecCore::VectorSize<HybridManager2::Float_v>();
for (int index = 0, nodeindex = 0; index < halfvectorsize * 2; index += 2 * (kVS + 1), nodeindex += kVS) {
using Bool_v = vecCore::Mask_v<HybridManager2::Float_v>;
Bool_v inChildNodes;
ABBoxImplementation::ABBoxContainsKernel(boxes_v[index], boxes_v[index + 1], localpoint, inChildNodes);
if (!vecCore::MaskEmpty(inChildNodes)) {
for (size_t i = 0 /*inChildNodes.firstOne()*/; i < kVS; ++i) {
if (vecCore::MaskLaneAt(inChildNodes, i)) {
Bool_v inDaughterBox;
ABBoxImplementation::ABBoxContainsKernel(boxes_v[index + 2 * i + 2], boxes_v[index + 2 * i + 3], localpoint,
inDaughterBox);
if (!vecCore::MaskEmpty(inDaughterBox)) {
for (size_t j = 0 /*inDaughterBox.firstOne()*/; j < kVS; ++j) { // leaf node
if (vecCore::MaskLaneAt(inDaughterBox, j)) {
// final candidate check
VPlacedVolume const *candidate = lvol->GetDaughters()[nodeToDaughters[nodeindex + i][j]];
if (ExclV) {
if (candidate == exclvol) {
continue;
}
}
if (CheckCandidateVolWithDirection<IsAssemblyAware, ModifyState>(candidate, localpoint, localdir,
state, pvol, daughterlocalpoint)) {
return true;
}
}
}
}
}
}
}
}
return false;
}
public:
static std::string GetClassName() { return "HybridLevelLocator"; }
virtual std::string GetName() const override { return GetClassName(); }
......@@ -176,6 +152,14 @@ public:
return LevelLocateKernel<true, false>(lvol, exclvol, localpoint, nullptr, pvol, daughterlocalpoint);
}
virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdir,
VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint) const override
{
return LevelLocateKernelWithDirection<true, false>(lvol, exclvol, localpoint, localdir, nullptr, pvol,
daughterlocalpoint);
}
static VLevelLocator const *GetInstance()
{
static THybridLevelLocator instance;
......@@ -189,7 +173,7 @@ inline std::string THybridLevelLocator<true>::GetClassName()
{
return "AssemblyAwareHybridLevelLocator";
}
}
} // end namespace
} // namespace VECGEOM_IMPL_NAMESPACE
} // namespace vecgeom
#endif /* NAVIGATION_HYBRIDLEVELLOCATOR_H_ */
......@@ -71,40 +71,54 @@ private:
return false;
}
template <bool ExclV, bool ModifyState>
__attribute__((always_inline)) bool LevelLocateKernelWithDirection(LogicalVolume const *lvol,
VPlacedVolume const *exclvol,
Vector3D<Precision> const &localpoint,
Vector3D<Precision> const &localdir,
NavigationState *state, VPlacedVolume const *&pvol,
Vector3D<Precision> &daughterlocalpoint) const
{
int size;
ABBoxManager::ABBoxContainer_v alignedbboxes = fAccelerationStructure.GetABBoxes_v(lvol, size);
auto daughters = lvol->GetDaughtersp();
// here the loop is over groups of bounding boxes
// it is basically linear but vectorizable search
for (int boxgroupid = 0; boxgroupid < size; ++boxgroupid) {
using Bool_v = vecCore::Mask_v<ABBoxManager::Float_v>;
Bool_v inBox;
ABBoxImplementation::ABBoxContainsKernel(alignedbboxes[2 * boxgroupid], alignedbboxes[2 * boxgroupid + 1],
localpoint, inBox);
if (!vecCore::MaskEmpty(inBox)) {
constexpr auto kVS = vecCore::VectorSize<ABBoxManager::Float_v>();
// TODO: could start directly at first 1 in inBox
for (size_t ii = 0; ii < kVS; ++ii) {
auto daughterid = boxgroupid * kVS + ii;
if (daughterid < daughters->size() && vecCore::MaskLaneAt(inBox, ii)) {
VPlacedVolume const *nextvolume = (*daughters)[daughterid];
if (ExclV) {
if (exclvol == nextvolume) continue;
}
if (CheckCandidateVolWithDirection<IsAssemblyAware, ModifyState>(nextvolume, localpoint, localdir, state,
pvol, daughterlocalpoint)) {
return true;
}
}
}
}
}
return false;
}
public:
VECCORE_ATT_HOST_DEVICE
virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
Vector3D<Precision> &daughterlocalpoint) const override
{
return LevelLocateKernel<false, false>(lvol, nullptr, localpoint, nullptr, pvol, daughterlocalpoint);
// int size;
// ABBoxManager::ABBoxContainer_v alignedbboxes = fAccelerationStructure.GetABBoxes_v(lvol, size);
// auto daughters = lvol->GetDaughtersp();
// // here the loop is over groups of bounding boxes
// // it is basically linear but vectorizable search
// for (int boxgroupid = 0; boxgroupid < size; ++boxgroupid) {
// using Bool_v = vecCore::Mask_v<ABBoxManager::Float_v>;
// Bool_v inBox;
// ABBoxImplementation::ABBoxContainsKernel(alignedbboxes[2 * boxgroupid], alignedbboxes[2 * boxgroupid + 1],
// localpoint, inBox);
// if (!vecCore::MaskEmpty(inBox)) {
// constexpr auto kVS = vecCore::VectorSize<ABBoxManager::Float_v>();
// // TODO: could start directly at first 1 in inBox
// for (size_t ii = 0; ii < kVS; ++ii) {
// auto daughterid = boxgroupid * kVS + ii;
// if (daughterid < daughters->size() && vecCore::MaskLaneAt(inBox, ii)) {
// VPlacedVolume const *daughter = (*daughters)[daughterid];
// if (daughter->Contains(localpoint, daughterlocalpoint)) {
// pvol = daughter;
// // careful here: we also want to break on external loop
// return true;
// }
// }
// }
// }
// }
// return false;
} // end function
// version that directly modifies the navigation state
......@@ -114,34 +128,6 @@ public:
{
VPlacedVolume const *pvol;
return LevelLocateKernel<false, true>(lvol, nullptr, localpoint, &outstate, pvol, daughterlocalpoint);
// int size;
// ABBoxManager::ABBoxContainer_v alignedbboxes = fAccelerationStructure.GetABBoxes_v(lvol, size);
// auto daughters = lvol->GetDaughtersp();
// // here the loop is over groups of bounding boxes
// // it is basically linear but vectorizable search
// for (int boxgroupid = 0; boxgroupid < size; ++boxgroupid) {
// using Bool_v = vecCore::Mask_v<ABBoxManager::Float_v>;
// Bool_v inBox;
// ABBoxImplementation::ABBoxContainsKernel(alignedbboxes[2 * boxgroupid], alignedbboxes[2 * boxgroupid + 1],
// localpoint, inBox);
// if (!vecCore::MaskEmpty(inBox)) {
// constexpr auto kVS = vecCore::VectorSize<ABBoxManager::Float_v>();
// // TODO: could start directly at first 1 in inBox
// for (size_t ii = 0; ii < kVS; ++ii) {
// auto daughterid = boxgroupid * kVS + ii;
// if (daughterid < daughters->size() && vecCore::MaskLaneAt(inBox, ii)) {
// VPlacedVolume const *daughter = (*daughters)[daughterid];
// if (daughter->Contains(localpoint, daughterlocalpoint)) {
// outstate.Push(daughter);
// // careful here: we also want to break on external loop
// return true;
// }
// }
// }
// }
// }
// return false;
}
VECCORE_ATT_HOST_DEVICE
......@@ -150,37 +136,17 @@ public:
Vector3D<Precision> &daughterlocalpoint) const override
{
return LevelLocateKernel<true, false>(lvol, exclvol, localpoint, nullptr, pvol, daughterlocalpoint);
// int size;
// ABBoxManager::ABBoxContainer_v alignedbboxes = fAccelerationStructure.GetABBoxes_v(lvol, size);
// auto daughters = lvol->GetDaughtersp();
// // here the loop is over groups of bounding boxes
// // it is basically linear but vectorizable search
// for (int boxgroupid = 0; boxgroupid < size; ++boxgroupid) {
// using Bool_v = vecCore::Mask_v<ABBoxManager::Float_v>;
// Bool_v inBox;
// ABBoxImplementation::ABBoxContainsKernel(alignedbboxes[2 * boxgroupid], alignedbboxes[2 * boxgroupid + 1],
// localpoint, inBox);
// if (!vecCore::MaskEmpty(inBox)) {
// constexpr auto kVS = vecCore::VectorSize<ABBoxManager::Float_v>();
// // TODO: could start directly at first 1 in inBox
// for (size_t ii = 0; ii < kVS; ++ii) {
// auto daughterid = boxgroupid * kVS + ii;
// if (daughterid < daughters->size() && vecCore::MaskLaneAt(inBox, ii)) {
// VPlacedVolume const *daughter = (*daughters)[daughterid];
// if (daughter == exclvol) continue;
// if (daughter->Contains(localpoint, daughterlocalpoint)) {
// pvol = daughter;
// // careful here: we also want to break on external loop
// return true;
// }
// }
// }
// }
// }
// return false;
} // end function
VECCORE_ATT_HOST_DEVICE
virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdir,
VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint) const override
{
return LevelLocateKernelWithDirection<true, false>(lvol, exclvol, localpoint, localdir, nullptr, pvol,
daughterlocalpoint);
}
static std::string GetClassName() { return "SimpleABBoxLevelLocator"; }
virtual std::string GetName() const override { return GetClassName(); }
......@@ -237,7 +203,7 @@ inline std::string TSimpleABBoxLevelLocator<true>::GetClassName()
{
return "SimpleAssemblyAwareABBoxLevelLocator";
}
}
} // end namespace
} // namespace VECGEOM_IMPL_NAMESPACE
} // namespace vecgeom
#endif /* NAVIGATION_SIMPLEABBOXLEVELLOCATOR_H_ */
......@@ -51,6 +51,60 @@ __attribute__((always_inline)) inline static bool CheckCandidateVol(VPlacedVolum
return false;
}
// shared kernel for many locators
// treats the actual final check (depending on which interface to serve)
template <bool IsAssemblyAware, bool ModifyState>
__attribute__((always_inline)) inline static bool CheckCandidateVolWithDirection(
VPlacedVolume const *nextvolume, Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdirection,
NavigationState *state, VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint)
{
if (IsAssemblyAware && ModifyState) {
/* if (nextvolume->GetUnplacedVolume()->IsAssembly()) { */
/* // in this case we call a special version of Contains */
/* // offered by the assembly */
/* assert(ModifyState == true); */
/* if (((PlacedAssembly *)nextvolume)->Inside(localpoint, daughterlocalpoint, *state)) { */
/* return true; */
/* } */
/* } else { */
/* if (nextvolume->Inside(localpoint, daughterlocalpoint)) { */
/* state->Push(nextvolume); */
/* return true; */
/* } */
/* } */
assert(false && "not implemented yet");
} else {
//
const auto transf = nextvolume->GetTransformation();
const auto testdaughterlocal = transf->Transform(localpoint);
const auto inside = nextvolume->GetUnplacedVolume()->Inside(testdaughterlocal);
auto CheckEntering = [&transf, &testdaughterlocal, &localdirection, &nextvolume]() {
const auto unpl = nextvolume->GetUnplacedVolume();
Vector3D<Precision> normal;
unpl->Normal(testdaughterlocal, normal);
const auto directiondaughterlocal = transf->TransformDirection(localdirection);
const auto dot = normal.Dot(directiondaughterlocal);
if (dot >= 0) {
return false;
}
return true;
};
if (inside == kInside || ((inside == kSurface) && CheckEntering())) {
if (ModifyState) {
state->Push(nextvolume);
daughterlocalpoint = testdaughterlocal;
} else {
pvol = nextvolume;
daughterlocalpoint = testdaughterlocal;
}
return true;
}
}
return false;
}
// a simple version of a LevelLocator offering a generic brute force algorithm
template <bool IsAssemblyAware = false>
class TSimpleLevelLocator : public VLevelLocator {
......@@ -73,33 +127,34 @@ private:
if (ExclV) {
if (exclvol == nextvolume) continue;
}
if (CheckCandidateVol<IsAssemblyAware, ModifyState>(nextvolume, localpoint, state, pvol, daughterlocalpoint))
if (CheckCandidateVol<IsAssemblyAware, ModifyState>(nextvolume, localpoint, state, pvol, daughterlocalpoint)) {
return true;
}
}
return false;
}
// if (IsAssemblyAware) {
// if (nextvolume->GetUnplacedVolume()->IsAssembly()) {
// // in this case we call a special version of Contains
// // offered by the assembly
// assert(ModifyState == true);
// if (((PlacedAssembly *)nextvolume)->Contains(localpoint, daughterlocalpoint, *state)) {
// return true;
// }
// } else {
// if (nextvolume->Contains(localpoint, daughterlocalpoint)) {
// state->Push(nextvolume);
// return true;
// }
// }
// } else {
// if (nextvolume->Contains(localpoint, daughterlocalpoint)) {
// if (ModifyState) {
// state->Push(nextvolume);
// } else {
// pvol = nextvolume;
// }
// return true;
// }
// }
// the actual implementation kernel
// the template "ifs" should be optimized away
// arguments are pointers to allow for nullptr
template <bool ExclV, bool ModifyState>
__attribute__((always_inline)) bool LevelLocateKernelWithDirection(LogicalVolume const *lvol,
VPlacedVolume const *exclvol,
Vector3D<Precision> const &localpoint,
Vector3D<Precision> const &localdir,
NavigationState *state, VPlacedVolume const *&pvol,
Vector3D<Precision> &daughterlocalpoint) const
{
auto daughters = lvol->GetDaughtersp();
for (size_t i = 0; i < daughters->size(); ++i) {
VPlacedVolume const *nextvolume = (*daughters)[i];
if (ExclV) {
if (exclvol == nextvolume) continue;
}
if (CheckCandidateVolWithDirection<IsAssemblyAware, ModifyState>(nextvolume, localpoint, localdir, state, pvol,
daughterlocalpoint)) {
return true;
}
}
return false;
}
......@@ -128,6 +183,15 @@ public:
return LevelLocateKernel<true, false>(lvol, exclvol, localpoint, nullptr, pvol, daughterlocalpoint);
}
VECCORE_ATT_HOST_DEVICE
virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdirection,
VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint) const override
{
return LevelLocateKernelWithDirection<true, false>(lvol, exclvol, localpoint, localdirection, nullptr, pvol,
daughterlocalpoint);
}
static std::string GetClassName() { return "SimpleLevelLocator"; }
virtual std::string GetName() const override { return GetClassName(); }
......@@ -147,7 +211,7 @@ inline std::string TSimpleLevelLocator<true>::GetClassName()
return "SimpleAssemblyLevelLocator";
}
using SimpleAssemblyLevelLocator = TSimpleLevelLocator<true>;
}
} // end namespace
} // namespace VECGEOM_IMPL_NAMESPACE
} // namespace vecgeom
#endif /* NAVIGATION_SIMPLELEVELLOCATOR_H_ */
......@@ -52,26 +52,45 @@ public:
NavigationState & /*outstate*/, Vector3D<Precision> & /*daughterlocalpoint*/) const = 0;
/**
* Function which takes a logical volume and a local point in the reference frame of the logical volume
* and which determines in which daughter ( or the logical volume ) itself the given point is located
*
*
* @param lvol is a logical volume
* @param pvol a physical volume to be excluded
* @param localpoint is a point in the coordinate frame of the logical volume and should be contained within it
* @param daughterpvol is the placed volume in which the localpoint is contained (result of the computation)
* @param daughterlocalpoint is the local point in the next pvol (result of the computation)
* @return true of point is in a daughter; false otherwise
*/
* Function which takes a logical volume and a local point in the reference frame of the logical volume
* and which determines in which daughter ( or the logical volume ) itself the given point is located
*
*
* @param lvol is a logical volume
* @param pvol a physical volume to be excluded
* @param localpoint is a point in the coordinate frame of the logical volume and should be contained within it
* @param daughterpvol is the placed volume in which the localpoint is contained (result of the computation)
* @param daughterlocalpoint is the local point in the next pvol (result of the computation)
* @return true of point is in a daughter; false otherwise
*/
VECCORE_ATT_HOST_DEVICE
virtual bool LevelLocateExclVol(LogicalVolume const * /*lvol*/, VPlacedVolume const * /*pvol excl*/,
Vector3D<Precision> const & /*localpoint*/, VPlacedVolume const *& /*pvol*/,
Vector3D<Precision> & /*daughterlocalpoint*/) const = 0;
/**
* Function which takes a logical volume and a ray (local point + local direction) in the reference frame of the
* logical volume and which determines in which daughter ( or the logical volume ) itself the given point is located.
* This version resembles the logic done in Geant4.
*
* @param lvol is a logical volume
* @param pvol a physical volume to be excluded
* @param localpoint is a point in the coordinate frame of the logical volume and should be contained within it
* @param localdir is a direction in the coordinate frame of the logical volume
* @param daughterpvol is the placed volume in which the localpoint is contained (result of the computation)
* @param daughterlocalpoint is the local point in the next pvol (result of the computation)
* @return true if point is in a daughter; false otherwise
*/
VECCORE_ATT_HOST_DEVICE
virtual bool LevelLocateExclVol(LogicalVolume const * /*lvol*/, VPlacedVolume const * /*pvol excl*/,
Vector3D<Precision> const & /*localpoint*/, Vector3D<Precision> const & /*localdir*/,
VPlacedVolume const *& /*pvol*/,
Vector3D<Precision> & /*daughterlocalpoint*/) const = 0;
virtual std::string GetName() const = 0;
virtual ~VLevelLocator() {}
}; // end class declaration
}
} // end namespaces
} // namespace VECGEOM_IMPL_NAMESPACE
} // namespace vecgeom
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment