6 #ifndef DIMENSIONALITY_H 
    7 #define DIMENSIONALITY_H 
   15 #define THREE_DIMENSIONAL 
   24 #ifdef ONE_DIMENSIONAL 
   25 const int Dimension = 1;
 
   26 const int TwoPowDim = 2;
 
   31   T& 
x() {
return P[0];};    
 
   34   operator T*() {
return P;}
 
   36   T 
sum()
 const {
return P[0];}
 
   37   double length()
 const {
return fabs(
P[0]);}
 
   43   T& operator[](
const int i) {
return P[i];}
 
   44   T operator[](
const int i)
 const {
return P[i];}
 
   56 template<
class T1, 
class T2>
 
   58 template<
class T1, 
class T2>
 
   68 template<
class T1, 
class T2>
 
   79 template<
class T1, 
class T2>
 
   80 bool operator<(const Position_<T1>& A, 
const Position_<T2>& B) {
return A.
P[0]<B.P[0];}
 
   81 template<
class T1, 
class T2>
 
   83 template<
class T1, 
class T2>
 
   86 std::ostream& operator<<(std::ostream &O, const Position_<T>& A) {
return O << A.P[0];}
 
   89 template<
class T1, 
class T2>
 
   92 void WeightOnGrid(G& g, 
const Position& p, 
double v) {
 
  104 #ifdef TWO_DIMENSIONAL 
  105 const int Dimension = 2;
 
  106 const int TwoPowDim = 4;
 
  113   T& 
x() {
return P[0];};
 
  115   T& 
y() {
return P[1];};
 
  117   const T& 
x()
 const {
return P[0];};
 
  119   const T& 
y()
 const {
return P[1];};
 
  127   operator T*() {
return P;}
 
  129   T 
volume()
 const {
return P[0]*
P[1];}          
 
  131   T 
sum()
 const {
return P[0]+
P[1];}             
 
  133   double length()
 const {
return sqrt(
P[0]*
P[0]+
P[1]*
P[1]);}             
 
  141     if (
P[0]>pos.
P[0]) 
P[0]=pos.
P[0];
 
  142     if (
P[1]>pos.
P[1]) 
P[1]=pos.
P[1];
 
  154   T& operator[](
const int i) {
return P[i];}
 
  155   T operator[](
const int i)
 const {
return P[i];}
 
  197 template<
class T1, 
class T2>
 
  200 template<
class T1, 
class T2>
 
  214 template<
class T1, 
class T2>
 
  221 template<
class T1, 
class T2>
 
  239 template<
class T1, 
class T2>
 
  240 bool operator<(const Position_<T1>& A, 
const Position_<T2>& B) {
return (A.P[0]<B.
P[0]) || (A.P[1]<B.
P[1]);}
 
  242 template<
class T1, 
class T2>
 
  245 template<
class T1, 
class T2>
 
  250 std::ostream& operator<<(std::ostream &O, const Position_<T>& A) {
return O << A.
P[0] << 
' ' << A.
P[1];}
 
  259 template<
class T1, 
class T2>
 
  261   if (A.
P[0]>=B.
P[0]) 
return 0;
 
  262   if (A.
P[1]>=B.
P[1]) 
return 1;
 
  270 void WeightOnGrid(G& g, 
const Position& p, 
double v) {
 
  275   g[gp] += diff[0]*diff[1]*v;
 
  277   g[gp] += Diff[0]*diff[1]*v;
 
  279   g[gp] += Diff[0]*Diff[1]*v;
 
  281   g[gp] += diff[0]*Diff[1]*v;
 
  294 #ifdef THREE_DIMENSIONAL 
  295 const int Dimension = 3;
 
  296 const int TwoPowDim = 8;
 
  304   T& 
x() {
return P[0];};
 
  306   T& 
y() {
return P[1];};
 
  308   T& 
z() {
return P[2];};
 
  310   const T& 
x()
 const {
return P[0];};
 
  312   const T& 
y()
 const {
return P[1];};
 
  314   const T& 
z()
 const {
return P[2];};
 
  322   operator T*() {
return P;}
 
  336     if (
P[0]>pos.
P[0]) 
P[0]=pos.
P[0];
 
  337     if (
P[1]>pos.
P[1]) 
P[1]=pos.
P[1];
 
  338     if (
P[2]>pos.
P[2]) 
P[2]=pos.
P[2];
 
  350   T& operator[](
const int i) {
return P[i];}
 
  393 template<
class T1, 
class T2>
 
  396 template<
class T1, 
class T2>
 
  412 template<
class T1, 
class T2>
 
  420 template<
class T1, 
class T2>
 
  439 template<
class T1, 
class T2>
 
  441   return (A.P[0]<B.
P[0]) || (A.P[1]<B.
P[1]) || (A.P[2]<B.
P[2]);
 
  444 template<
class T1, 
class T2>
 
  446   return (A.
P[0]>B.
P[0]) || (A.
P[1]>B.
P[1]) || (A.
P[2]>B.
P[2]);
 
  449 template<
class T1, 
class T2>
 
  451   return (A.
P[0]==B.
P[0]) && (A.
P[1]==B.
P[1]) && (A.
P[2]==B.
P[2]);
 
  456 std::ostream& operator<<(std::ostream &O, const Position_<T>& A) {
return O << A.P[0] << 
' ' << A.P[1] << 
' ' << A.P[2];}
 
  465 template<
class T1, 
class T2>
 
  467   if (A.
P[0]>=B.
P[0]) 
return 0;
 
  468   if (A.
P[1]>=B.
P[1]) 
return 1;
 
  469   if (A.
P[2]>=B.
P[2]) 
return 2;
 
  472 void WeightOnGrid(G& g, 
const Position& p, 
double v) {
 
  476   g[gp] += diff[0]*diff[1]*diff[2]*v;
 
  478   g[gp] += Diff[0]*diff[1]*diff[2]*v;
 
  480   g[gp] += Diff[0]*Diff[1]*diff[2]*v;
 
  482   g[gp] += diff[0]*Diff[1]*diff[2]*v;
 
  484   g[gp] += diff[0]*Diff[1]*Diff[2]*v;
 
  486   g[gp] += Diff[0]*Diff[1]*Diff[2]*v;
 
  488   g[gp] += Diff[0]*diff[1]*Diff[2]*v;
 
  490   g[gp] += diff[0]*diff[1]*Diff[2]*v;
 
  510   T& 
x() {
return P[0];};
 
  512   T& 
y() {
return P[1];};
 
  514   T& 
z() {
return P[2];};
 
  522   operator T*() {
return P;}
 
  536     if (
P[0]>pos.
P[0]) 
P[0]=pos.
P[0];
 
  537     if (
P[1]>pos.
P[1]) 
P[1]=pos.
P[1];
 
  538     if (
P[2]>pos.
P[2]) 
P[2]=pos.
P[2];
 
  605 template<
class T1, 
class T2>
 
  607   return A.
P[0]*B.
P[0] + A.
P[1]*B.
P[1] + A.
P[2]*B.
P[2];
 
  618 template<
class T1, 
class T2>
 
  634 template<
class T1, 
class T2>
 
  653 template<
class T1, 
class T2>
 
  655   return (A.P[0]<=B.
P[0]) || (A.P[1]<=B.
P[1]) || (A.P[2]<=B.
P[2]);
 
  658 template<
class T1, 
class T2>
 
  660   return (A.
P[0]>=B.
P[0]) || (A.
P[1]>=B.
P[1]) || (A.
P[2]>=B.
P[2]);
 
  668 template<
class T1, 
class T2>
 
  670   if (A.
P[0]>=B.
P[0]) 
return 0;
 
  671   if (A.
P[1]>=B.
P[1]) 
return 1;
 
  672   if (A.
P[2]>=B.
P[2]) 
return 2;
 
  676 std::ostream& operator<<(std::ostream &O, const Velocity_<T>& A) {
return O << A.P[0] << 
' ' << A.P[1] << 
' ' << A.P[2];}
 
  685 template<
class G, 
class T>
 
  687   T sum = g[p1]*wa.
P[0]*wa.
P[1]*wa.
P[2] + g[p2]*wb.
P[0]*wb.
P[1]*wb.
P[2];
 
  690   sum += g[p1]*wb.
P[0]*wa.
P[1]*wa.
P[2] + g[p2]*wa.
P[0]*wb.
P[1]*wb.
P[2];
 
  693   sum += g[p1]*wb.
P[0]*wb.
P[1]*wa.
P[2] + g[p2]*wa.
P[0]*wa.
P[1]*wb.
P[2];
 
  696   return sum + g[p1]*wa.
P[0]*wb.
P[1]*wa.
P[2] + g[p2]*wb.
P[0]*wa.
P[1]*wb.
P[2];
 
  699 const Velocity ZeroVelocity(0,0,0);