Intrepid
/usr/src/RPM/BUILD/trilinos10-10.6.4/packages/intrepid/src/Discretization/Integration/Intrepid_CubatureSparseHelper.hpp
00001 #ifndef INTREPID_CUBATURE_SPARSE_HELPER_HPP
00002 #define INTREPID_CUBATURE_SPARSE_HELPER_HPP
00003 
00004 #include "Intrepid_ConfigDefs.hpp"
00005 #include "Intrepid_Types.hpp"
00006 #include "Intrepid_FieldContainer.hpp"
00007 #include "Teuchos_TestForException.hpp"
00008 #include "Teuchos_Array.hpp"
00009 
00010 namespace Intrepid{
00011 
00012 /************************************************************************
00013 **  Class Definition for class SGPoint
00014 **  Function: Helper Class with cosntruction of Sparse Grid
00015 *************************************************************************/
00016 template<class Scalar, int D>
00017 class SGPoint{
00018 public:
00019   Scalar coords[D];
00020 
00021   SGPoint();
00022   SGPoint(Scalar p[D]);
00023   bool const operator==(const SGPoint<Scalar, D> & right);
00024   bool const operator<(const SGPoint<Scalar, D> & right);
00025   bool const operator>(const SGPoint<Scalar, D> & right);
00026   //friend ostream & operator<<(ostream & o, const SGPoint<D> & p);
00027 };
00028 
00029 /************************************************************************
00030 **  Class Definition for class SGNodes
00031 **  function: Helper Class with constrution of Sparse Grid
00032 ************************************************************************/
00033 template<class Scalar, int D, class ArrayPoint=FieldContainer<Scalar>, class ArrayWeight=ArrayPoint>
00034 class SGNodes{
00035 public:
00036   Teuchos::Array< SGPoint<Scalar, D> > nodes;
00037   Teuchos::Array< Scalar > weights;
00038   bool addNode(Scalar new_node[D], Scalar weight);
00039   void copyToArrays(ArrayPoint & cubPoints, ArrayWeight & cubWeights) const;
00040   //void copyToTeuchos(Teuchos::Array< Scalar* > & cubPoints, Teuchos::Array<Scalar> & cubWeights) const;
00041   int size() const {return nodes.size();}
00042 };
00043 
00044 /**************************************************************************
00045 **  Function Definitions for Class SGPoint
00046 ***************************************************************************/
00047 template<class Scalar, int D>
00048 SGPoint<Scalar,D>::SGPoint()
00049 {
00050   for(int i = 0; i < D; i++)
00051   {
00052     coords[i] = 0;
00053   }
00054 }
00055 
00056 template<class Scalar, int D>
00057 SGPoint<Scalar, D>::SGPoint(Scalar p[D])
00058 {
00059   for(int i = 0; i < D; i++)
00060   {
00061     coords[i] = p[i];
00062   }
00063 }
00064 
00065 template<class Scalar, int D>
00066 bool const SGPoint<Scalar, D>::operator==(const SGPoint<Scalar, D> & right)
00067 {
00068   bool equal = true;
00069 
00070   for(int i = 0; i < D; i++)
00071   {
00072     if(coords[i] != right.coords[i])
00073       return false;
00074   }
00075 
00076   return equal;
00077 }
00078 
00079 template<class Scalar, int D>
00080 bool const SGPoint<Scalar, D>::operator<(const SGPoint<Scalar, D> & right)
00081 {
00082   for(int i = 0; i < D; i++)
00083   {
00084     if(coords[i] < right.coords[i])
00085       return true;
00086     else if(coords[i] > right.coords[i])
00087       return false;
00088   }
00089   
00090   return false;
00091 }
00092 
00093 template<class Scalar, int D>
00094 bool const SGPoint<Scalar, D>::operator>(const SGPoint<Scalar, D> & right)
00095 {
00096   if(this < right || this == right)
00097     return false;
00098 
00099   return true;
00100 }
00101 
00102 template<class Scalar, int D>
00103 std::ostream & operator<<(std::ostream & o, SGPoint<Scalar, D> & p)
00104 {
00105   o << "(";
00106   for(int i = 0; i<D;i++)
00107     o<< p.coords[i] << " ";
00108   o << ")";
00109   return o;
00110 }
00111 
00112 
00113 /**************************************************************************
00114 **  Function Definitions for Class SGNodes
00115 ***************************************************************************/
00116 
00117 template<class Scalar, int D, class ArrayPoint, class ArrayWeight>
00118 bool SGNodes<Scalar,D,ArrayPoint,ArrayWeight>::addNode(Scalar new_node[D], Scalar weight)
00119 {
00120   SGPoint<Scalar, D> new_point(new_node);
00121   bool new_and_added = true;
00122 
00123   if(nodes.size() == 0)
00124   {
00125     nodes.push_back(new_point);
00126     weights.push_back(weight);
00127   }
00128   else
00129   {   
00130     int left = -1;
00131     int right = (int)nodes.size();
00132     int mid_node = (int)ceil(nodes.size()/2.0)-1;
00133 
00134     bool iterate_continue = true;
00135 
00136     while(iterate_continue)
00137     {
00138       if(new_point == nodes[mid_node]){
00139         weights[mid_node] += weight;
00140         iterate_continue = false;
00141         new_and_added = false;  
00142       }
00143       else if(new_point < nodes[mid_node]){
00144         if(right - left <= 2)
00145         {
00146           //insert the node into the vector to the left of mid_node
00147           nodes.insert(nodes.begin()+mid_node, new_point);
00148           weights.insert(weights.begin()+mid_node,weight);
00149           iterate_continue = false;
00150         }
00151         else 
00152         {
00153           right = mid_node;
00154           mid_node += (int)ceil((left-mid_node)/2.0);
00155         }
00156       }
00157       else{ //new_point > nodes[mid_node];
00158 
00159         if(mid_node == (int)nodes.size()-1)
00160         {
00161           nodes.push_back(new_point);
00162           weights.push_back(weight);
00163           iterate_continue = false;
00164         }
00165         else if(right - left <= 2)
00166         {
00167           //insert the node into the vector to the right of mid_node
00168           nodes.insert(nodes.begin()+mid_node+1, new_point);
00169           weights.insert(weights.begin()+mid_node+1,weight);
00170           iterate_continue = false;
00171         }
00172         else 
00173         {
00174           left = mid_node;
00175           mid_node += (int)ceil((right-mid_node)/2.0);
00176         }
00177       }
00178     }
00179   }
00180 
00181   return new_and_added;
00182 }
00183 
00184 template<class Scalar, int D, class ArrayPoint, class ArrayWeight>
00185 void SGNodes<Scalar,D,ArrayPoint,ArrayWeight>::copyToArrays(ArrayPoint & cubPoints, ArrayWeight & cubWeights) const
00186 {
00187   int numPoints = size();
00188 
00189   for(int i = 0; i < numPoints; i++)
00190   {
00191     for (int j=0; j<D; j++) {
00192       cubPoints(i,j) = nodes[i].coords[j];
00193     }
00194     cubWeights(i) = weights[i];
00195   }
00196 }
00197 
00198 /*
00199 template< class Scalar, int D>
00200 void SGNodes<Scalar,D>::copyToTeuchos(Teuchos::Array< Scalar* > & cubPoints, Teuchos::Array<Scalar> & cubWeights) const
00201 {
00202   int numPoints = size();
00203 
00204   Scalar tempPoint[D];
00205   cubPoints.assign(numPoints,tempPoint);
00206   cubWeights.assign(numPoints, 0.0);
00207 
00208   for(int i = 0; i < numPoints; i++)
00209   {
00210     cubPoints[i] = nodes[i].coords;
00211     cubWeights[i] = weights[i];
00212   }
00213 }
00214 */
00215 
00216 }
00217 #endif