cosmotool/src/octTree.hpp

164 lines
3.8 KiB
C++
Raw Normal View History

2009-11-01 18:20:50 +01:00
#ifndef __COSMOTOOL_AMR_HPP
#define __COSMOTOOL_AMR_HPP
#include "config.hpp"
namespace CosmoTool
{
typedef uint32_t octPtr;
typedef uint16_t octCoordType;
static const uint16_t octCoordTypeNorm = 0xffff;
static const uint16_t octCoordCenter = 0x8000;
// This is also the root cell, but this one
// is never referenced (really ??).
static const octPtr invalidOctCell = 0xffffffff;
static const octPtr emptyOctCell = 0;
static const octPtr octParticleMarker = 0x80000000;
static const octPtr octParticleMask = 0x7fffffff;
typedef octCoordType OctCoords[3];
struct OctCell
{
octPtr numberLeaves;
octPtr children[8];
};
class OctTree
{
public:
OctTree(const FCoordinates *particles, octPtr numParticles,
uint32_t maxTreeDepth, uint32_t maxAbsoluteDepth,
uint32_t threshold = 1);
~OctTree();
void buildTree(uint32_t maxAbsoluteDepth);
void insertParticle(octPtr node,
const OctCoords& icoord,
octCoordType halfNodeLength,
octPtr particleId,
uint32_t maxAbsoluteDepth);
octPtr getNumberLeaves() const {
return cells[0].numberLeaves;
}
static bool unconditioned(const FCoordinates&, octPtr, float, bool)
{
return true;
}
2009-11-01 18:20:50 +01:00
template<typename FunT>
void walkTree(FunT f)
2009-11-07 05:05:00 +01:00
{
walkTree(f, unconditioned);
}
template<typename FunT, typename CondT>
void walkTree(FunT f, CondT condition)
2009-11-01 18:20:50 +01:00
{
OctCoords rootCenter = { octCoordCenter, octCoordCenter, octCoordCenter };
2009-11-07 05:05:00 +01:00
walkTreeElements(f, condition, 0, rootCenter, octCoordCenter);
2009-11-01 18:20:50 +01:00
}
2009-12-07 15:46:59 +01:00
2009-11-01 18:20:50 +01:00
protected:
const FCoordinates *particles;
octPtr numParticles;
OctCell *cells;
float Lbox;
octPtr lastNode;
octPtr numCells;
2009-11-02 01:56:10 +01:00
float lenNorm;
float xMin[3];
2009-11-01 18:20:50 +01:00
2010-05-04 14:41:42 +02:00
<<<<<<< HEAD
2009-11-07 05:05:00 +01:00
static bool unconditioned()
{
return true;
}
template<typename FunT, typename CondT>
void walkTreeElements(FunT f, CondT condition,
octPtr node,
2010-05-04 14:41:42 +02:00
=======
template<typename FunT,typename CondT>
void walkTreeElements(FunT f, CondT condition, octPtr node,
2010-05-04 14:41:42 +02:00
>>>>>>> 37b41b5ac9b32213b865cbeddd63102f3fa0935a
2009-11-01 18:20:50 +01:00
const OctCoords& icoord,
octCoordType halfNodeLength)
{
OctCoords newCoord;
2009-11-02 01:56:10 +01:00
FCoordinates center, realCenter;
2009-11-01 18:20:50 +01:00
for (int j = 0; j < 3; j++)
2009-11-02 01:56:10 +01:00
{
center[j] = icoord[j]/(2.*octCoordCenter);
realCenter[j] = xMin[j] + center[j]*lenNorm;
2009-11-02 01:56:10 +01:00
}
f(realCenter, cells[node].numberLeaves, lenNorm*halfNodeLength/(float)octCoordCenter,
2009-11-01 18:20:50 +01:00
cells[node].children[0] == invalidOctCell, // True if this is a meta-node
false);
2010-05-04 14:41:42 +02:00
<<<<<<< HEAD
2009-11-07 05:05:00 +01:00
if (!condition(realCenter, cells[node].numberLeaves,
lenNorm*halfNodeLength/(float)octCoordCenter,
cells[node].children[0] == invalidOctCell))
return;
2009-11-01 18:20:50 +01:00
2010-05-04 14:41:42 +02:00
=======
if (!condition(realCenter, cells[node].numberLeaves,
lenNorm*halfNodeLength/(float)octCoordCenter,
cells[node].children[0] == invalidOctCell))
return;
2010-05-04 14:41:42 +02:00
>>>>>>> 37b41b5ac9b32213b865cbeddd63102f3fa0935a
2009-11-01 18:20:50 +01:00
for (int i = 0; i < 8; i++)
{
octPtr newNode = cells[node].children[i];
int ipos[3] = { (i&1), (i&2)>>1, (i&4)>>2 };
if (newNode == emptyOctCell || newNode == invalidOctCell)
continue;
for (int j = 0; j < 3; j++)
newCoord[j] = icoord[j]+(2*ipos[j]-1)*halfNodeLength/2;
if (newNode & octParticleMarker)
{
for (int j = 0; j < 3; j++)
2009-11-02 01:56:10 +01:00
{
center[j] = newCoord[j]/(2.*octCoordCenter);
realCenter[j] = xMin[j] + lenNorm*center[j];
}
2009-11-01 18:20:50 +01:00
f(realCenter,
1, lenNorm*halfNodeLength/(2.*octCoordCenter),
2009-11-01 18:20:50 +01:00
false, true);
continue;
}
2010-05-04 14:41:42 +02:00
<<<<<<< HEAD
2009-11-07 05:05:00 +01:00
walkTreeElements(f, condition,
cells[node].children[i], newCoord, halfNodeLength/2);
2010-05-04 14:41:42 +02:00
=======
walkTreeElements(f, condition, cells[node].children[i], newCoord, halfNodeLength/2);
2010-05-04 14:41:42 +02:00
>>>>>>> 37b41b5ac9b32213b865cbeddd63102f3fa0935a
2009-11-01 18:20:50 +01:00
}
}
};
};
#endif