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
00014
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
00027 };
00028
00029
00030
00031
00032
00033 template<class Scalar, int D, class ArrayType=FieldContainer<Scalar> >
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(ArrayType & cubPoints, ArrayType & cubWeights) const;
00040
00041 int size() const {return nodes.size();}
00042 };
00043
00044
00045
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
00115
00116
00117 template<class Scalar, int D, class ArrayType>
00118 bool SGNodes<Scalar,D,ArrayType>::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
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{
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
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 ArrayType>
00185 void SGNodes<Scalar,D,ArrayType>::copyToArrays(ArrayType & cubPoints, ArrayType & 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
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 }
00217 #endif