@@ -2992,53 +2992,51 @@ namespace OrthoTree
29922992 TEntityID EntityID;
29932993 MortonLocationID LocationID;
29942994 };
2995- auto pointLocations = std::vector<Location>(pointNo);
2995+ auto locations = std::vector<Location>(pointNo);
29962996 EXEC_POL_DEF (ept); // GCC 11.3
2997- std::transform (EXEC_POL_ADD (ept) points.begin (), points.end (), pointLocations .begin (), [&](auto const & point) {
2997+ std::transform (EXEC_POL_ADD (ept) points.begin (), points.end (), locations .begin (), [&](auto const & point) {
29982998 return Location{ detail::getKeyPart (points, point), tree.GetLocationID (detail::getValuePart (point)) };
29992999 });
30003000
30013001 if constexpr (IS_PARALLEL_EXEC)
30023002 {
30033003 EXEC_POL_DEF (eps); // GCC 11.3
3004- std::sort (EXEC_POL_ADD (eps) pointLocations.begin (), pointLocations.end (), [&](auto const & leftLocation, auto const & rightLocation) {
3005- return leftLocation.LocationID < rightLocation.LocationID ;
3006- });
3004+ std::sort (EXEC_POL_ADD (eps) locations.begin (), locations.end (), [&](auto const & l, auto const & r) { return l.LocationID < r.LocationID ; });
30073005 }
30083006
3009- // Build the tree in depth-first search order
3007+ // Build the tree in depth-first order
30103008
3011- struct NodeData
3009+ struct NodeStackData
30123010 {
30133011 std::pair<MortonNodeID, Node> NodeInstance;
3014- typename std::vector<Location>::iterator LocationEndIterator ;
3012+ typename std::vector<Location>::iterator EndLocationIt ;
30153013 };
3016- std::array<NodeData , SI::MAX_THEORETICAL_DEPTH> nodeStack;
3017- nodeStack[0 ] = NodeData { *tree.m_nodes .find (SI::GetRootKey ()), pointLocations .end () };
3014+ std::array<NodeStackData , SI::MAX_THEORETICAL_DEPTH> nodeStack;
3015+ nodeStack[0 ] = NodeStackData { *tree.m_nodes .find (SI::GetRootKey ()), locations .end () };
30183016 tree.m_nodes .clear (); // Root will be inserted again via the nodeStack, unspecified behavior
30193017
3020- auto locationBeginIterator = pointLocations .begin ();
3018+ auto beginLocationIt = locations .begin ();
30213019 for (int depthID = 0 ; depthID >= 0 ;)
30223020 {
3023- auto & [node, locationEndIterator ] = nodeStack[depthID];
3024- std::size_t const elementNo = std::distance (locationBeginIterator, locationEndIterator );
3021+ auto & [node, endLocationIt ] = nodeStack[depthID];
3022+ std::size_t const elementNo = std::distance (beginLocationIt, endLocationIt );
30253023 if (elementNo == 0 )
30263024 {
30273025 tree.m_nodes .emplace (std::move (node));
30283026 --depthID;
30293027 continue ;
30303028 }
30313029
3032- if ((( elementNo < tree.m_maxElementNo ) && !node.second .IsAnyChildExist ()) || depthID == maxDepthNo)
3030+ if ((elementNo < tree.m_maxElementNo && !node.second .IsAnyChildExist ()) || depthID == maxDepthNo)
30333031 {
30343032 auto & entityIDs = node.second .GetEntities ();
30353033 entityIDs.resize (elementNo);
30363034
30373035 LOOPIVDEP
30383036 for (std::size_t i = 0 ; i < elementNo; ++i)
30393037 {
3040- entityIDs[i] = locationBeginIterator ->EntityID ;
3041- ++locationBeginIterator ;
3038+ entityIDs[i] = beginLocationIt ->EntityID ;
3039+ ++beginLocationIt ;
30423040 }
30433041
30443042 tree.m_nodes .emplace (std::move (node));
@@ -3049,19 +3047,18 @@ namespace OrthoTree
30493047 ++depthID;
30503048 auto const examinedLevel = tree.GetDepthMax () - depthID;
30513049 auto const keyGenerator = typename SI::ChildKeyGenerator (node.first );
3052- auto const childChecker = typename SI::ChildCheckerFixedDepth (examinedLevel, locationBeginIterator ->LocationID );
3050+ auto const childChecker = typename SI::ChildCheckerFixedDepth (examinedLevel, beginLocationIt ->LocationID );
30533051 auto childKey = keyGenerator.GetChildNodeKey (childChecker.GetChildID (examinedLevel));
30543052 if constexpr (IS_PARALLEL_EXEC)
30553053 {
3056- nodeStack[depthID].LocationEndIterator = std::partition_point (locationBeginIterator, locationEndIterator, [&](auto const & location) {
3057- return childChecker.Test (location.LocationID );
3058- });
3054+ nodeStack[depthID].EndLocationIt =
3055+ std::partition_point (beginLocationIt, endLocationIt, [&](auto const & location) { return childChecker.Test (location.LocationID ); });
30593056 node.second .AddChild (childKey);
30603057 }
30613058 else
30623059 {
3063- nodeStack[depthID].LocationEndIterator =
3064- std::partition (locationBeginIterator, locationEndIterator , [&](auto const & location) { return childChecker.Test (location.LocationID ); });
3060+ nodeStack[depthID].EndLocationIt =
3061+ std::partition (beginLocationIt, endLocationIt , [&](auto const & location) { return childChecker.Test (location.LocationID ); });
30653062 node.second .AddChildInOrder (childKey);
30663063 }
30673064
@@ -3509,68 +3506,6 @@ namespace OrthoTree
35093506 using LocationContainer = std::vector<Location>;
35103507 using LocationIterator = typename LocationContainer::iterator;
35113508
3512- void CreateChildNodes (
3513- Node& parentNode,
3514- MortonNodeIDCR parentKey,
3515- LocationIterator& beginLocationIterator,
3516- LocationIterator const & endLocationIterator,
3517- depth_t remainingDepthNo) noexcept
3518- {
3519- std::size_t const elementNo = std::distance (beginLocationIterator, endLocationIterator);
3520- if (elementNo < this ->m_maxElementNo || remainingDepthNo == 0 )
3521- {
3522- auto & entityIDs = parentNode.GetEntities ();
3523- entityIDs.resize (elementNo);
3524-
3525- LOOPIVDEP
3526- for (std::size_t i = 0 ; i < elementNo; ++i)
3527- {
3528- entityIDs[i] = beginLocationIterator->EntityID ;
3529- ++beginLocationIterator;
3530- }
3531- return ;
3532- }
3533-
3534- depth_t currentDepthID = this ->m_maxDepthNo - remainingDepthNo;
3535- if (beginLocationIterator->DepthAndLocation .DepthID == currentDepthID)
3536- {
3537- auto stuckedEndLocationIterator = std::partition_point (beginLocationIterator, endLocationIterator, [&](auto const & location) {
3538- return location.DepthAndLocation .DepthID == beginLocationIterator->DepthAndLocation .DepthID ;
3539- });
3540-
3541- std::size_t const stuckedElementNo = std::distance (beginLocationIterator, stuckedEndLocationIterator);
3542-
3543- auto & entityIDs = parentNode.GetEntities ();
3544- entityIDs.resize (stuckedElementNo);
3545-
3546- LOOPIVDEP
3547- for (std::size_t i = 0 ; i < stuckedElementNo; ++i)
3548- {
3549- entityIDs[i] = beginLocationIterator->EntityID ;
3550- ++beginLocationIterator;
3551- }
3552- }
3553-
3554- ++currentDepthID;
3555- --remainingDepthNo;
3556-
3557- auto const keyGenerator = typename SI::ChildKeyGenerator (parentKey);
3558- while (beginLocationIterator != endLocationIterator)
3559- {
3560- auto const childChecker = typename SI::ChildCheckerFixedDepth (remainingDepthNo, beginLocationIterator->DepthAndLocation .LocID );
3561- auto const actualEndLocationIterator = std::partition_point (beginLocationIterator, endLocationIterator, [&](auto const & location) {
3562- return childChecker.Test (location.DepthAndLocation .LocID );
3563- });
3564-
3565- auto const childKey = keyGenerator.GetChildNodeKey (childChecker.GetChildID (remainingDepthNo));
3566-
3567- parentNode.AddChild (childKey);
3568- auto [childNode, _] = this ->m_nodes .emplace (childKey, this ->CreateChild (parentNode, childKey));
3569- this ->CreateChildNodes (childNode->second , childKey, beginLocationIterator, actualEndLocationIterator, remainingDepthNo);
3570- }
3571- }
3572-
3573-
35743509 void SplitEntityLocation (std::array<DimArray<GridID>, 2 > const & boxMinMaxGridID, Location& location, LocationContainer& additionalLocations) const noexcept
35753510 {
35763511 depth_t depthID = location.DepthAndLocation .DepthID + SPLIT_DEPTH_INCREASEMENT;
@@ -3716,11 +3651,105 @@ namespace OrthoTree
37163651 });
37173652 }
37183653
3719- EXEC_POL_DEF (eps); // GCC 11.3
3720- std::sort (EXEC_POL_ADD (eps) locations.begin (), locations.end ());
3654+ if constexpr (IS_PARALLEL_EXEC)
3655+ {
3656+ EXEC_POL_DEF (eps); // GCC 11.3
3657+ std::sort (EXEC_POL_ADD (eps) locations.begin (), locations.end ());
3658+ }
3659+
3660+ // Build the tree in depth-first order
3661+
3662+ struct NodeStackData
3663+ {
3664+ std::pair<MortonNodeID, Node> NodeInstance;
3665+ typename std::vector<Location>::iterator EndLocationIt;
3666+ };
3667+ std::array<NodeStackData, SI::MAX_THEORETICAL_DEPTH> nodeStack;
3668+ nodeStack[0 ] = NodeStackData{ *tree.m_nodes .find (SI::GetRootKey ()), locations.end () };
3669+ tree.m_nodes .clear (); // Root will be inserted again via the nodeStack, unspecified behavior
3670+
3671+ auto beginLocationIt = locations.begin ();
3672+ for (int depthID = 0 ; depthID >= 0 ;)
3673+ {
3674+ auto & [node, endLocationIt] = nodeStack[depthID];
3675+
3676+ std::size_t elementNo = std::distance (beginLocationIt, endLocationIt);
3677+
3678+ auto const hasNoChild = !node.second .IsAnyChildExist ();
3679+ if ((elementNo > 0 && elementNo < tree.m_maxElementNo && hasNoChild) || depthID == maxDepthNo)
3680+ {
3681+ auto & entityIDs = node.second .GetEntities ();
3682+ entityIDs.resize (elementNo);
3683+
3684+ LOOPIVDEP
3685+ for (std::size_t i = 0 ; i < elementNo; ++i)
3686+ {
3687+ entityIDs[i] = beginLocationIt->EntityID ;
3688+ ++beginLocationIt;
3689+ }
3690+
3691+ elementNo = 0 ;
3692+ }
3693+ else if (hasNoChild)
3694+ {
3695+ typename std::vector<Location>::iterator stuckedEndLocationIt;
3696+ if constexpr (IS_PARALLEL_EXEC)
3697+ {
3698+ stuckedEndLocationIt = std::partition_point (beginLocationIt, endLocationIt, [depthID](auto const & location) {
3699+ return location.DepthAndLocation .DepthID == depthID;
3700+ });
3701+ }
3702+ else
3703+ {
3704+ stuckedEndLocationIt =
3705+ std::partition (beginLocationIt, endLocationIt, [depthID](auto const & location) { return location.DepthAndLocation .DepthID == depthID; });
3706+ }
3707+
3708+ std::size_t const stuckedElementNo = std::distance (beginLocationIt, stuckedEndLocationIt);
3709+
3710+ auto & entityIDs = node.second .GetEntities ();
3711+ entityIDs.resize (stuckedElementNo);
3712+
3713+ LOOPIVDEP
3714+ for (std::size_t i = 0 ; i < stuckedElementNo; ++i)
3715+ {
3716+ entityIDs[i] = beginLocationIt->EntityID ;
3717+ ++beginLocationIt;
3718+ }
3719+
3720+ elementNo -= stuckedElementNo;
3721+ }
3722+
3723+ if (elementNo == 0 )
3724+ {
3725+ tree.m_nodes .emplace (std::move (node));
3726+ --depthID;
3727+ continue ;
3728+ }
3729+
3730+ ++depthID;
3731+ auto const examinedLevel = tree.GetDepthMax () - depthID;
3732+ auto const keyGenerator = typename SI::ChildKeyGenerator (node.first );
3733+ auto const childChecker = typename SI::ChildCheckerFixedDepth (examinedLevel, beginLocationIt->DepthAndLocation .LocID );
3734+ auto childKey = keyGenerator.GetChildNodeKey (childChecker.GetChildID (examinedLevel));
3735+ if constexpr (IS_PARALLEL_EXEC)
3736+ {
3737+ nodeStack[depthID].EndLocationIt = std::partition_point (beginLocationIt, endLocationIt, [&](auto const & location) {
3738+ return childChecker.Test (location.DepthAndLocation .LocID );
3739+ });
3740+ node.second .AddChild (childKey);
3741+ }
3742+ else
3743+ {
3744+ nodeStack[depthID].EndLocationIt =
3745+ std::partition (beginLocationIt, endLocationIt, [&](auto const & location) { return childChecker.Test (location.DepthAndLocation .LocID ); });
3746+ node.second .AddChildInOrder (childKey);
3747+ }
3748+
3749+ nodeStack[depthID].NodeInstance .first = std::move (childKey);
3750+ nodeStack[depthID].NodeInstance .second = tree.CreateChild (node.second , childKey);
3751+ }
37213752
3722- auto beginLocationIterator = locations.begin ();
3723- tree.CreateChildNodes (nodeRoot, rootKey, beginLocationIterator, locations.end (), maxDepthNo);
37243753 if constexpr (SPLIT_DEPTH_INCREASEMENT > 0 )
37253754 {
37263755 // Eliminate duplicates. Not all sub-nodes will be created due to the maxElementNoInNode, which cause duplicates in the parent nodes.
0 commit comments