Topology.hpp

00001 #ifndef __FIBER_GRID_TOPOLOGY_HPP
00002 #define __FIBER_GRID_TOPOLOGY_HPP
00003 
00004 #include "GridAPI.h"
00005 #include <vector/MultiIndex.hpp>
00006 
00007 
00008 namespace Fiber
00009 {
00010 
00011 //      GRID_API BaseSpace : public MemCore::ReferenceBase<BaseSpace> , public MemCore::Intercube
00012 
00016 namespace RegularTopology
00017 {
00018 
00023 template <int Dims>
00024 inline index_t NumberOfEdges(const MultiIndex<Dims>&NumberOfVertices) throw()
00025 {
00026 index_t Edges = 0; 
00027         for(int i=0; i<Dims; i++)
00028         {
00029                 Edges += ( NumberOfVertices - MultiIndex<Dims>::BitIndex(1<<i) ).size();
00030         }
00031 
00032         return Edges;
00033 }
00034 
00045 template <int Dims>
00046 inline int      EdgeOrientation(index_t EdgeIndex, const MultiIndex<Dims>&NumberOfVertices) throw(int)
00047 {
00048         for(int Orientation=0; Orientation<Dims; Orientation++)
00049         {
00050         index_t NumberOfOrientedEdges = (NumberOfVertices - MultiIndex<Dims>::Axis(Orientation )).size(); 
00051                 if (EdgeIndex < NumberOfOrientedEdges)
00052                 {
00053                         return Orientation;
00054                 } 
00055                 EdgeIndex -= NumberOfOrientedEdges;
00056         } 
00057         throw -1;
00058 }
00059 
00074 template <int Dims>
00075 void ComputeFirstEdgeVertex(MultiIndex<Dims>&FirstVertex, int&Orientation,
00076                             index_t EdgeIndex, const MultiIndex<Dims>&NumberOfVertices) throw(int)
00077 {
00078 //      assert( EdgeIndex < NumberOfEdges( NumberOfVertices ) ); 
00079 
00080         for(Orientation=0; Orientation<Dims; Orientation++)
00081         {
00082         MultiIndex<Dims> NumberOfOrientedEdges = NumberOfVertices - MultiIndex<Dims>::Axis(Orientation );
00083         index_t NumberOfOrientedEdgesCount = NumberOfOrientedEdges.size(); 
00084                 if (EdgeIndex < NumberOfOrientedEdgesCount)
00085                 {
00086                         FirstVertex = MultiIndex<Dims>(EdgeIndex, NumberOfOrientedEdges, CreateFromLinear() );
00087                         return;
00088                 } 
00089                 EdgeIndex -= NumberOfOrientedEdgesCount;
00090         } 
00091         throw -1;
00092 }
00093 
00105 template <int Dims>
00106 inline MultiIndex<Dims> ComputeSecondEdgeVertex(const MultiIndex<Dims>&Vertex, int Orientation) throw()
00107 {
00108         return Vertex + MultiIndex<Dims>::BitIndex( 1 << Orientation );
00109 }
00110 
00120 template <int Dims>
00121 inline std::pair<MultiIndex<Dims>, MultiIndex<Dims> >
00122 ComputeEdgeVertices( index_t EdgeIndex, const MultiIndex<Dims>&NumberOfVertices) throw(int)
00123 {
00124 //      assert( EdgeIndex < NumberOfEdges( NumberOfVertices) ); 
00125 
00126 MultiIndex<Dims> FirstVertex;
00127 int     Orientation;
00128         ComputeFirstEdgeVertex(FirstVertex, Orientation,
00129                                EdgeIndex, NumberOfVertices); 
00130 
00131         return std::pair<MultiIndex<Dims>, MultiIndex<Dims> >(FirstVertex,
00132                                                          ComputeSecondEdgeVertex(FirstVertex, Orientation)
00133                 );
00134 }
00135 
00151 template <int Dims>
00152 inline index_t ComputeEdgeIDfromVertexAndOrientation(const MultiIndex<Dims>&Vertex, int Orientation,
00153                                                      const MultiIndex<Dims>&NumberOfVertices) throw(int)
00154 {
00155         assert( Vertex < NumberOfVertices ); 
00156         assert( Orientation >= 0);
00157 
00158 index_t EdgeNumberBias = 0;
00159         for(int O=0; O<Orientation+1; O++)
00160         {
00161         MultiIndex<Dims> NumberOfOrientedEdges = NumberOfVertices - MultiIndex<Dims>::Axis(O);
00162         index_t NumberOfOrientedEdgesCount = NumberOfOrientedEdges.size(); 
00163 
00164 /*
00165                 cout << "      ComputeEdgeIDfromVertexAndOrientation("<<Vertex<<","<<Orientation<<","<<NumberOfVertices<<")" 
00166                      << "Oriention Axis: " << MultiIndex<3>::Axis(O)
00167                      << "  O="<<O<<" NumberOfOrientedEdges="<<NumberOfOrientedEdges<<"   NumberOfOrientedEdgesCount="<<NumberOfOrientedEdgesCount
00168                      << "  EdgeNumberBias="<<EdgeNumberBias<<endl;
00169 */
00170                 if (O<Orientation)
00171                 {
00172                         EdgeNumberBias += NumberOfOrientedEdgesCount;
00173                 }
00174                 else
00175                 {
00176                         return EdgeNumberBias + Vertex.linear(NumberOfOrientedEdges);
00177                 }
00178         }
00179         throw EdgeNumberBias;
00180 }
00181 
00182 } // namespace RegularTopology
00183 
00184 using namespace RegularTopology;
00185 
00186 } /* namespace Fiber */ 
00187 
00188 #endif /* __FIBER_GRID_TOPOLOGY_HPP */
00189