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
......@@ -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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment