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
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
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
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
00166
00167
00168
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 }
00183
00184 using namespace RegularTopology;
00185
00186 }
00187
00188 #endif
00189