00001 
00026 #ifndef COORDCONN_H_
00027 #define COORDCONN_H_
00028 
00029 #include "AuxDefs.h"
00030 #include "Element.h"
00031 #include "P12DElement.h"
00032 #include "P13DElement.h"
00033 #include "ElementGeometry.h"
00034 #include "Triangle.h"
00035 #include "Tetrahedron.h"
00036 #include "Femap.h"
00037 
00038 #include <cassert>
00039 
00040 #include <algorithm>
00041 #include <sstream>
00042 #include <iostream>
00043 #include <vector>
00044 #include <stdexcept>
00045 
00052 class CoordConn {
00053 
00054 
00055 public:
00056   CoordConn () {}
00057 
00058   virtual ~CoordConn () {}
00059 
00066   virtual const std::vector<GlobalNodalIndex>& getConnectivity () const = 0;
00067 
00074   virtual const std::vector<double>& getCoordinates () const = 0;
00075 
00076   virtual size_t getSpatialDim () const = 0;
00077 
00078   virtual size_t getNodesPerElem () const = 0;
00079 
00083   virtual size_t getTopology () const = 0;
00084 
00088   virtual void subdivide () = 0;
00089 
00090   virtual void initFromFileData (const FemapInput& neu) = 0;
00091 
00092   virtual size_t getNumNodes () const = 0;
00093 
00094   virtual size_t getNumElements () const = 0;
00095 
00104   virtual Element* makeElem (const size_t elemIndex) const = 0;
00105 
00106 protected:
00107 
00117   virtual void genElemConnectivity (size_t elemIndex, std::vector<GlobalNodalIndex>& elemConn) const = 0;
00118 
00119 
00120 };
00121 
00126 template <size_t SPD, size_t NODES_PER_ELEM, size_t TOPO>
00127 class AbstractCoordConn: public CoordConn {
00128 protected:
00129   std::vector<GlobalNodalIndex> connectivity;
00130   std::vector<double> coordinates;
00131 
00132 public:
00133   AbstractCoordConn (): CoordConn() {
00134 
00135   }
00136 
00137   AbstractCoordConn (const AbstractCoordConn& that):
00138     CoordConn(that), connectivity (that.connectivity), coordinates (that.coordinates) {
00139 
00140   }
00141 
00142   AbstractCoordConn& operator = (const AbstractCoordConn& that) {
00143     CoordConn::operator = (that);
00144     if (this != &that) {
00145       connectivity = that.connectivity;
00146       coordinates = that.coordinates;
00147     }
00148     return (*this);
00149   }
00150 
00151   virtual inline size_t getSpatialDim () const {
00152     return SPD;
00153   }
00154 
00155   virtual inline size_t getNodesPerElem () const {
00156     return NODES_PER_ELEM;
00157   }
00158 
00159   virtual inline size_t getTopology () const {
00160     return TOPO;
00161   }
00162 
00163   virtual const std::vector<GlobalNodalIndex>& getConnectivity () const {
00164     return connectivity;
00165   }
00166 
00167   virtual const std::vector<double>& getCoordinates () const {
00168     return coordinates;
00169   }
00170 
00171   virtual size_t getNumNodes () const {
00172     return getCoordinates ().size () / getSpatialDim ();
00173   }
00174 
00175   virtual size_t getNumElements () const {
00176     return getConnectivity ().size () / getNodesPerElem ();
00177   }
00178 
00179   virtual void initFromFileData (const FemapInput& neu) {
00180 
00181     size_t nodes = neu.getNumNodes ();
00182     size_t elements = neu.getNumElements (getTopology ());
00183 
00184     coordinates.clear ();
00185     coordinates.resize (nodes * getSpatialDim ());
00186 
00187     connectivity.clear ();
00188     connectivity.resize (elements * getNodesPerElem ());
00189 
00190     transferNodes (neu);
00191     transferElements (neu);
00192   }
00193 
00194 
00195 protected:
00196   virtual void genElemConnectivity (size_t elemIndex, std::vector<GlobalNodalIndex>& conn) const {
00197     const size_t npe = getNodesPerElem ();
00198     conn.clear();
00199 
00200     for (size_t i = 0; i < npe; ++i) {
00201       conn.push_back (connectivity[elemIndex * npe + i]);
00202     }
00203   }
00204 
00205 private:
00206   void transferNodes (const FemapInput& neu) {
00207 
00208     size_t n, d;
00209     for (n = 0; n < neu.getNumNodes (); n++) {
00210       const femapNode& nd = neu.getNode (n);
00211       for (d = 0; d < getSpatialDim (); d++) {
00212         coordinates[getSpatialDim () * n + d] = nd.x[d];
00213       }
00214     }
00215 
00216   }
00217 
00218 
00219   void transferElements (const FemapInput& neu) {
00220     size_t i, j;
00221     for (i = 0; i < neu.getNumElements (); i++) {
00222       const femapElement& e = neu.getElement (i);
00223       if (e.topology == getTopology ()) {
00224         for (j = 0; j < getNodesPerElem (); ++j) {
00225           
00226           
00227           connectivity[getNodesPerElem () * i + j] = neu.getNodeId (e.node[j]);
00228         }
00229 
00230       } else {
00231         std::ostringstream ss;
00232         ss << "Warning: topology of element " << neu.getElementId (e.id)
00233           << " is not supported for conversion to ADLIB.  Skipping. " << std::endl;
00234         throw std::runtime_error (ss.str ());
00235       }
00236     }
00237 
00238     return;
00239   }
00240 
00241 
00242 };
00243 
00244 
00245 
00249 struct edgestruct {
00250   size_t elemId;
00251   size_t edgeId;
00252   GlobalNodalIndex node0;
00253   GlobalNodalIndex node1;
00254 
00255   edgestruct(size_t ielem, size_t iedge, GlobalNodalIndex _node0, GlobalNodalIndex _node1) :
00256     elemId(ielem), edgeId(iedge) {
00257 
00258     
00259     
00260     if (_node1 < _node0) {
00261       std::swap (_node0, _node1);
00262     }
00263 
00264     
00265     
00266 
00267     node0 = _node0;
00268     node1 = _node1;
00269 
00270     assert (node0 <= node1);
00271 
00272   }
00273 
00274 
00280   bool operator < (const edgestruct &that) const {
00281     
00282     int result = compare (that);
00283     return result < 0;
00284   }
00285 
00294   inline int compare (const edgestruct& that) const {
00295     int result = this->node0 - that.node0;
00296     if (result == 0) {
00297       result = this->node1 - that.node1;
00298     }
00299     return result;
00300   }
00301 
00302 };
00303 
00304 #endif