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