LR-splines  0.5
Element.cpp
Go to the documentation of this file.
00001 
00002 #include "LRSpline/Element.h"
00003 #include "LRSpline/Meshline.h"
00004 #include "LRSpline/Basisfunction.h"
00005 
00006 namespace LR {
00007 
00008 /************************************************************************************************************************/
00011 Element::Element() {
00012         id_      = -1;
00013         overloadCount = 0;
00014 }
00015 
00016 /************************************************************************************************************************/
00020 Element::Element(int dim) {
00021         id_           = -1;
00022         overloadCount = 0;
00023         min.resize(dim);
00024         max.resize(dim);
00025 }
00026 
00027 /************************************************************************************************************************/
00034 Element::Element(double start_u, double start_v, double stop_u, double stop_v) {
00035         min.resize(2);
00036         max.resize(2);
00037 
00038         min[0] = start_u;
00039         min[1] = start_v;
00040         max[0] = stop_u ;
00041         max[1] = stop_v ;
00042         id_    = -1;
00043         overloadCount = 0;
00044 }
00045 
00046 /************************************************************************************************************************/
00050 void Element::removeSupportFunction(Basisfunction *f) {
00051         support_.erase(f);
00052 }
00053 
00054 /************************************************************************************************************************/
00058 void Element::addSupportFunction(Basisfunction *f) {
00059         support_.insert(f);
00060 }
00061 
00062 /************************************************************************************************************************/
00065 Element* Element::copy() {
00066         Element *returnvalue = new Element();
00067         
00068         returnvalue->id_          = this->id_;
00069         returnvalue->min          = this->min;    // it seems that the default vector operator= thing takes a deep copy 
00070         returnvalue->max          = this->max;
00071 
00072         for(Basisfunction* b : support_)
00073                 returnvalue->support_ids_.push_back(b->getId());
00074         
00075         return returnvalue;
00076 }
00077 
00078 
00079 /************************************************************************************************************************/
00085 Element* Element::split(int splitDim, double par_value) {
00086         Element *newElement = NULL;
00087         if(par_value >= max[splitDim] || par_value <= min[splitDim])
00088                 return NULL;
00089                 
00090         std::vector<double> newMin(min.begin(), min.end());
00091         std::vector<double> newMax(max.begin(), max.end());
00092 
00093         newMin[splitDim] = par_value; // new element should start at par_value
00094         max[splitDim]    = par_value; // old element should stop  at par_value
00095 
00096         newElement = new Element(min.size(), newMin.begin(), newMax.begin());
00097 
00098         for(Basisfunction *b : support_)
00099                 if(b->addSupport(newElement)) // tests for overlapping as well
00100                         newElement->addSupportFunction(b);
00101 
00102         bool someChange = true;
00103         while(someChange) {
00104                 someChange = false;
00105                 for(Basisfunction *b : support_) {
00106                         if(!b->overlaps(this)) {
00107                                 support_.erase(b);
00108                                 someChange = true;
00109                                 break;
00110                         }
00111                 }
00112         }
00113         return newElement;
00114 }
00115 
00116 /************************************************************************************************************************/
00120 void Element::updateBasisPointers(std::vector<Basisfunction*> &basis) {
00121         for(uint i=0; i<support_ids_.size(); i++) {
00122                 // add pointer from Element to Basisfunction
00123                 support_.insert(basis[support_ids_[i]]);
00124                 // add pointer from Basisfunction back to Element
00125                 basis[support_ids_[i]]->addSupport(this);
00126         }
00127 }
00128 
00129 /************************************************************************************************************************/
00133 // convenience macro for reading formated input
00134 #define ASSERT_NEXT_CHAR(c) {ws(is); nextChar = is.get(); if(nextChar!=c) { std::cerr << "Error parsing element\n"; exit(326); } ws(is); }
00135 void Element::read(std::istream &is) {
00136         char nextChar;
00137         int dim;
00138         is >> id_;
00139         ASSERT_NEXT_CHAR('[');
00140         is >> dim;
00141         ASSERT_NEXT_CHAR(']');
00142         ASSERT_NEXT_CHAR(':');
00143         min.resize(dim);
00144         max.resize(dim);
00145 
00146         ASSERT_NEXT_CHAR('(');
00147         is >> min[0];
00148         for(int i=1; i<dim; i++) {
00149                 ASSERT_NEXT_CHAR(',');
00150                 is >> min[i];
00151         }
00152         ASSERT_NEXT_CHAR(')');
00153         ASSERT_NEXT_CHAR('x');
00154         ASSERT_NEXT_CHAR('(');
00155         is >> max[0];
00156         for(int i=1; i<dim; i++) {
00157                 ASSERT_NEXT_CHAR(',');
00158                 is >> max[i];
00159         }
00160         ASSERT_NEXT_CHAR(')');
00161         ASSERT_NEXT_CHAR('{');
00162 
00163         // read id's of all supported basis functions
00164         int basis_id;
00165         is >> basis_id;
00166         support_ids_.push_back(basis_id);
00167         ws(is);
00168         nextChar = is.peek();
00169         while(nextChar == ',') {
00170                 is.get(); ws(is);
00171                 is >> basis_id;
00172                 support_ids_.push_back(basis_id);
00173                 nextChar = is.peek();
00174         }
00175         ASSERT_NEXT_CHAR('}');
00176 }
00177 #undef ASSERT_NEXT_CHAR
00178 
00179 /************************************************************************************************************************/
00183 void Element::write(std::ostream &os) const {
00184         os << id_ << " [" << min.size() << "] : ";
00185         os << "(" << min[0];
00186         for(uint i=1; i<min.size(); i++) 
00187                 os << ", " << min[i] ;
00188         os << ") x (" << max[0];
00189         for(uint i=1; i<max.size(); i++) 
00190                 os << ", " << max[i] ;
00191         os << ")";
00192         os << "    {";
00193         bool isFirst = true;
00194         for(Basisfunction *b : support_) {
00195                 if(!isFirst) os << ", ";
00196                 os << b->getId();
00197                 isFirst = false;
00198         }
00199         os << "}";
00200 }
00201 
00202 /************************************************************************************************************************/
00207 bool Element::isOverloaded()  const {
00208         int n = support_.size();
00209         Basisfunction *b = *support_.begin();
00210         if(n > 0) {
00211                 if(b->nVariate() == 2) { // surfaces
00212                         int p1 = (*support_.begin())->getOrder(0);
00213                         int p2 = (*support_.begin())->getOrder(1);
00214                         if(n > p1*p2)
00215                                 return true;
00216                 } else if(b->nVariate() == 3) { // volumes
00217                         int p1 = (*support_.begin())->getOrder(0);
00218                         int p2 = (*support_.begin())->getOrder(1);
00219                         int p3 = (*support_.begin())->getOrder(2);
00220                         if(n > p1*p2*p3)
00221                                 return true;
00222                 }
00223         }
00224         return false;
00225 }
00226 
00227 /*
00228 int Element::overloadedBasisCount() const {
00229         int ans = 0;
00230         for(uint i=0; i<support_.size(); i++)
00231                 if(support_[i]->isOverloaded())
00232                         ans++;
00233         return ans;
00234 }
00235 */
00236 
00237 } // end namespace LR