From e0147442149a1bdf77ec82e43b4f922f8c342b4c Mon Sep 17 00:00:00 2001 From: Karsten Rink <karsten.rink@ufz.de> Date: Fri, 10 Aug 2012 10:16:05 +0200 Subject: [PATCH] added first version to find and store neighbours of all elements during mesh initialisation (work in progress) --- GeoLib/Station.cpp | 2 +- GeoLib/Station.h | 2 +- MeshLib/Elements/Element.cpp | 32 ++++++++++++++++++++++ MeshLib/Elements/Element.h | 7 +++++ MeshLib/Elements/Face.cpp | 4 +-- MeshLib/Elements/Face.h | 2 +- MeshLib/Mesh.cpp | 43 ++++++++++++++++++++++-------- MeshLib/Node.h | 6 ++--- SimpleTests/MeshTests/MeshRead.cpp | 11 ++++++++ 9 files changed, 89 insertions(+), 20 deletions(-) diff --git a/GeoLib/Station.cpp b/GeoLib/Station.cpp index 6a04446937c..fa8205bccf7 100644 --- a/GeoLib/Station.cpp +++ b/GeoLib/Station.cpp @@ -243,7 +243,7 @@ int StationBorehole::addLayer(std::list<std::string> fields, StationBorehole* bo return 1; } -int StationBorehole::addStratigraphy(const std::vector<Point*> &profile, const std::vector<std::string> soil_names) +int StationBorehole::addStratigraphy(const std::vector<Point*> &profile, const std::vector<std::string> &soil_names) { if (((profile.size()-1) == soil_names.size()) && (soil_names.size()>0)) { diff --git a/GeoLib/Station.h b/GeoLib/Station.h index 0005b310a8a..4333eaf814d 100644 --- a/GeoLib/Station.h +++ b/GeoLib/Station.h @@ -221,7 +221,7 @@ public: std::string date = ""); /// Adds a stratigraphy to a borehole given a vector of points of length "n" and a vector of soil names of length "n-1". - int addStratigraphy(const std::vector<Point*> &profile, const std::vector<std::string> soil_names); + int addStratigraphy(const std::vector<Point*> &profile, const std::vector<std::string> &soil_names); /// Reads the stratigraphy for a specified station from a file static int addStratigraphy(const std::string &path, StationBorehole* borehole); diff --git a/MeshLib/Elements/Element.cpp b/MeshLib/Elements/Element.cpp index b952c3fe319..7341c11e565 100644 --- a/MeshLib/Elements/Element.cpp +++ b/MeshLib/Elements/Element.cpp @@ -33,6 +33,38 @@ Element::~Element() delete[] this->_nodes; } +bool Element::addNeighbor(Element* e) +{ + unsigned n(0); + unsigned nNeighbors (this->getNNeighbors()); + for (n=0; n<nNeighbors; n++) + { + if (this->_neighbors[n] == e) + return false; + if (this->_neighbors[n] == NULL) + break; + } + + if (n<nNeighbors) + { + const unsigned nNodes (this->getNNodes()); + const unsigned eNodes (e->getNNodes()); + const Node* const* e_nodes = e->getNodes(); + unsigned count(0); + for (unsigned i(0); i<nNodes; i++) + for (unsigned j(0); j<eNodes; j++) + if (_nodes[i] == e_nodes[j]) + //std::cout << _nodes[i]->getID() << " == " << e_nodes[j]->getID() << std::endl; + // increment shared nodes counter and check if enough nodes are similar to be sure e is a neighbour of this + if ((++count)>=this->getDimension()) + { + _neighbors[n]=e; + return true; + } + } + return false; +} + const Element* Element::getEdge(unsigned i) const { if (i < getNEdges()) diff --git a/MeshLib/Elements/Element.h b/MeshLib/Elements/Element.h index fe665baf358..2ff19bc4114 100644 --- a/MeshLib/Elements/Element.h +++ b/MeshLib/Elements/Element.h @@ -35,6 +35,13 @@ public: /// Compute the minimum and maximum squared edge length for this element virtual void computeSqrEdgeLengthRange(double &min, double &max) const; + /** + * \brief Tries to add an element e as neighbour to this element. + * If the elements really are neighbours, the element is added to the + * neighbour-ist and true is returned. Otherwise false is returned. + */ + bool addNeighbor(Element* e); + /// Returns the length, area or volume of a 1D, 2D or 3D element virtual double getContent() const = 0; diff --git a/MeshLib/Elements/Face.cpp b/MeshLib/Elements/Face.cpp index d3d097fe2fd..eb9d58c362d 100644 --- a/MeshLib/Elements/Face.cpp +++ b/MeshLib/Elements/Face.cpp @@ -34,7 +34,7 @@ Face::~Face() delete[] this->_neighbors; } -const double* Face::getSurfaceNormal() const +void Face::getSurfaceNormal(double normal[3]) const { const double edge1[3] = { (*this->_nodes[0])[0]-(*this->_nodes[1])[0], (*this->_nodes[0])[1]-(*this->_nodes[1])[1], @@ -42,9 +42,7 @@ const double* Face::getSurfaceNormal() const const double edge2[3] = { (*this->_nodes[1])[0]-(*this->_nodes[2])[0], (*this->_nodes[1])[1]-(*this->_nodes[2])[1], (*this->_nodes[1])[2]-(*this->_nodes[2])[2] }; - double normal[3]; MathLib::crossProd(edge1, edge2, normal); - return normal; } } diff --git a/MeshLib/Elements/Face.h b/MeshLib/Elements/Face.h index 1aa9e38f739..5da618a501e 100644 --- a/MeshLib/Elements/Face.h +++ b/MeshLib/Elements/Face.h @@ -43,7 +43,7 @@ public: unsigned getNFaces() const { return 0; }; /// Returns the surface normal of a 2D element. - const double* getSurfaceNormal() const; + void getSurfaceNormal(double normal[3]) const; /// Destructor virtual ~Face(); diff --git a/MeshLib/Mesh.cpp b/MeshLib/Mesh.cpp index 98573cab59f..b92bf46f9b6 100644 --- a/MeshLib/Mesh.cpp +++ b/MeshLib/Mesh.cpp @@ -35,6 +35,8 @@ Mesh::Mesh(const std::string &name, const std::vector<Node*> &nodes, const std:: Mesh::Mesh(const Mesh &mesh) : _name(mesh.getName()), _nodes(mesh.getNodes()), _elements(mesh.getElements()) { + this->setElementInformationForNodes(); + this->setNeighborInformationForElements(); } Mesh::~Mesh() @@ -105,21 +107,40 @@ void Mesh::setEdgeLengthRange(const double &min_length, const double &max_length void Mesh::setNeighborInformationForElements() { - /* TODO - const size_t nElements(_elements.size()); - std::vector<std::vector<char>> nb (nElements, std::vector<char>(nElements)); - - for (unsigned i=0; i<nElements; i++) + const size_t nElements = _elements.size(); + for (unsigned m(0); m<nElements; m++) { - Element* elem = _elements[i]; - const size_t nNodes (elem->getNNodes()); - for (unsigned j=0; j<nNodes; j++) + // create vector with all elements connected to current element (includes lots of doubles!) + std::vector<Element*> neighbors; + const size_t nNodes (_elements[m]->getNNodes()); + for (unsigned n(0); n<nNodes; n++) { - const Node* node = elem->getNode(j); - + const std::vector<Element*> conn_elems (_elements[m]->getNode(n)->getElements()); + neighbors.insert(neighbors.end(), conn_elems.begin(), conn_elems.end()); } + + const unsigned nNeighbors ( neighbors.size() ); + /*std::vector<bool> done (nNeighbors, false); + // mark off the element itself + for (unsigned j(0); j<nNeighbors; j++) + if (neighbors[j] == _elements[m]) + done[j] = true; + */ + // check if connected element is indeed a neighbour and mark all doubles of that element as 'done' + for (unsigned i(0); i<nNeighbors; i++) + //if (!done[i]) + { + if (_elements[m]->addNeighbor(neighbors[i])) + { + neighbors[i]->addNeighbor(_elements[m]); + }/* + for (unsigned j(0); j<nNeighbors; j++) + if (!done[j] && (neighbors[j] == neighbors[i])) + done[j] = true; + */ + + } } - */ } } diff --git a/MeshLib/Node.h b/MeshLib/Node.h index aa59cc0230d..0514b963d87 100644 --- a/MeshLib/Node.h +++ b/MeshLib/Node.h @@ -48,7 +48,7 @@ public: const Element* getElement(unsigned idx) const { return _elements[idx]; }; /// Get all elements the node is part of. - const std::vector<const Element*> getElements() const { return _elements; }; + const std::vector<Element*> getElements() const { return _elements; }; /// Get number of elements the node is part of. size_t getNElements() const { return _elements.size(); }; @@ -61,9 +61,9 @@ protected: * Add an element the node is part of. * This method is called by Mesh::addElement(Element*), see friend definition. */ - void addElement(const Element* elem) { _elements.push_back(elem); }; + void addElement(Element* elem) { _elements.push_back(elem); }; - std::vector<const Element*> _elements; + std::vector<Element*> _elements; }; /* class */ diff --git a/SimpleTests/MeshTests/MeshRead.cpp b/SimpleTests/MeshTests/MeshRead.cpp index 0dadf05f8bb..49b513f9f3f 100644 --- a/SimpleTests/MeshTests/MeshRead.cpp +++ b/SimpleTests/MeshTests/MeshRead.cpp @@ -55,6 +55,17 @@ int main(int argc, char *argv[]) // std::cout << "time for reading: " << run_time.elapsed() << " s" << std::endl; INFO ("time for reading: %f s", run_time.elapsed()); #endif +/* + unsigned elem_id = 1; + const MeshLib::Element* e = mesh->getElement(elem_id); + const size_t nElems = mesh->getNElements(); + for (unsigned i=0; i< e->getNNeighbors(); i++) + { + for (unsigned j=0; j< nElems; j++) + if (mesh->getElement(j) == e->getNeighbor(i)) + std::cout << "neighbour of " << elem_id << " : " << j << std::endl; + } +*/ delete mesh; delete logogCout; LOGOG_SHUTDOWN(); -- GitLab