Chaste Release::3.1
|
00001 /* 00002 00003 Copyright (c) 2005-2012, University of Oxford. 00004 All rights reserved. 00005 00006 University of Oxford means the Chancellor, Masters and Scholars of the 00007 University of Oxford, having an administrative office at Wellington 00008 Square, Oxford OX1 2JD, UK. 00009 00010 This file is part of Chaste. 00011 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 * Redistributions of source code must retain the above copyright notice, 00015 this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright notice, 00017 this list of conditions and the following disclaimer in the documentation 00018 and/or other materials provided with the distribution. 00019 * Neither the name of the University of Oxford nor the names of its 00020 contributors may be used to endorse or promote products derived from this 00021 software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 */ 00035 00036 #ifndef _NODE_HPP_ 00037 #define _NODE_HPP_ 00038 00039 #include "UblasVectorInclude.hpp" 00040 00041 #include <set> 00042 #include <vector> 00043 00044 #include "ChasteSerialization.hpp" 00045 #include "ChastePoint.hpp" 00046 00047 //#include <boost/serialization/vector.hpp> 00048 //#include <boost/serialization/set.hpp> 00049 00050 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00051 class AbstractTetrahedralMesh; 00052 00056 template<unsigned SPACE_DIM> 00057 class Node 00058 { 00059 private: 00060 00062 unsigned mIndex; 00063 00065 unsigned mRegion; 00066 00068 c_vector<double, SPACE_DIM> mLocation; 00069 00071 bool mIsBoundaryNode; 00072 00074 bool mIsInternal; 00075 00080 bool mIsDeleted; 00081 00083 std::set<unsigned> mElementIndices; 00084 00086 std::set<unsigned> mBoundaryElementIndices; 00087 00089 std::vector<double> mNodeAttributes; 00090 00092 friend class boost::serialization::access; 00099 template<class Archive> 00100 void serialize(Archive & archive, const unsigned int version) 00101 { 00102 //archive & mLocation; //earlier versions of boost are unable to do this. See #1709 00103 // archive & mIndex; 00104 archive & mRegion; 00105 // archive & mIsBoundaryNode; 00106 // archive & mIsInternal; 00107 // archive & mIsDeleted; 00108 // archive & mElementIndices; 00109 // archive & mBoundaryElementIndices; 00110 // archive & mNodeAttributes; 00111 } 00112 00119 void CommonConstructor(unsigned index, bool isBoundaryNode); 00120 00121 public: 00122 00135 Node(unsigned index, ChastePoint<SPACE_DIM> point, bool isBoundaryNode=false); 00136 00144 Node(unsigned index, std::vector<double> coords, bool isBoundaryNode=false); 00145 00153 Node(unsigned index, c_vector<double, SPACE_DIM> location, bool isBoundaryNode=false); 00154 00164 Node(unsigned index, bool isBoundaryNode=false, double v1=0, double v2=0, double v3=0); 00165 00174 Node(unsigned index, double *location, bool isBoundaryNode=false); 00175 00184 void SetPoint(ChastePoint<SPACE_DIM> point); 00185 00191 void SetIndex(unsigned index); 00192 00198 void AddNodeAttribute(double attribute); 00199 00205 void SetAsBoundaryNode(bool value=true); 00206 00210 ChastePoint<SPACE_DIM> GetPoint() const; 00211 00218 const c_vector<double, SPACE_DIM>& rGetLocation() const; 00219 00228 c_vector<double, SPACE_DIM>& rGetModifiableLocation(); 00229 00233 unsigned GetIndex() const; 00234 00238 bool IsBoundaryNode() const; 00239 00245 void AddElement(unsigned index); 00246 00252 void RemoveElement(unsigned index); 00253 00259 void RemoveBoundaryElement(unsigned index); 00260 00266 void AddBoundaryElement(unsigned index); 00267 00271 std::set<unsigned>& rGetContainingElementIndices(); 00272 00276 std::vector<double>& rGetNodeAttributes(); 00277 00281 std::set<unsigned>& rGetContainingBoundaryElementIndices(); 00282 00286 unsigned GetNumContainingElements() const; 00287 00291 unsigned GetNumBoundaryElements() const; 00292 00296 void MarkAsDeleted(); 00297 00301 bool IsDeleted() const; 00302 00306 void MarkAsInternal(); 00307 00311 bool IsInternal() const; 00312 00318 template <unsigned ELEMENT_DIM> 00319 bool IsFlagged(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh) 00320 { 00321 bool in_flagged_element = false; 00322 for (ContainingElementIterator it = ContainingElementsBegin(); 00323 it != ContainingElementsEnd(); 00324 ++it) 00325 { 00326 if (rMesh.GetElement(*it)->IsFlagged()) 00327 { 00328 in_flagged_element = true; 00329 break; 00330 } 00331 } 00332 return in_flagged_element; 00333 } 00334 00340 void SetRegion(unsigned region); 00341 00345 unsigned GetRegion() const; 00346 00350 class ContainingElementIterator 00351 { 00352 public: 00358 ContainingElementIterator(std::set<unsigned>::const_iterator indexIterator) 00359 : mIndexIterator(indexIterator) 00360 {} 00364 const unsigned& operator*() const 00365 { 00366 return *mIndexIterator; 00367 } 00373 bool operator!=(const ContainingElementIterator& rOther) const 00374 { 00375 return mIndexIterator != rOther.mIndexIterator; 00376 } 00382 bool operator==(const ContainingElementIterator& rOther) const 00383 { 00384 return !operator!=(rOther); 00385 } 00389 ContainingElementIterator& operator++() 00390 { 00391 ++mIndexIterator; 00392 return *this; 00393 } 00394 private: 00395 std::set<unsigned>::const_iterator mIndexIterator; 00396 }; 00397 00401 ContainingElementIterator ContainingElementsBegin() const 00402 { 00403 return ContainingElementIterator(mElementIndices.begin()); 00404 } 00405 00409 ContainingElementIterator ContainingElementsEnd() const 00410 { 00411 return ContainingElementIterator(mElementIndices.end()); 00412 } 00413 00417 class ContainingBoundaryElementIterator 00418 { 00419 public: 00425 ContainingBoundaryElementIterator(std::set<unsigned>::const_iterator indexIterator) 00426 : mIndexIterator(indexIterator) 00427 {} 00431 const unsigned& operator*() const 00432 { 00433 return *mIndexIterator; 00434 } 00440 bool operator!=(const ContainingBoundaryElementIterator& rOther) const 00441 { 00442 return mIndexIterator != rOther.mIndexIterator; 00443 } 00449 bool operator==(const ContainingBoundaryElementIterator& rOther) const 00450 { 00451 return !operator!=(rOther); 00452 } 00456 ContainingBoundaryElementIterator& operator++() 00457 { 00458 ++mIndexIterator; 00459 return *this; 00460 } 00461 private: 00462 std::set<unsigned>::const_iterator mIndexIterator; 00463 }; 00464 00468 ContainingBoundaryElementIterator ContainingBoundaryElementsBegin() const 00469 { 00470 return ContainingBoundaryElementIterator(mBoundaryElementIndices.begin()); 00471 } 00472 00476 ContainingBoundaryElementIterator ContainingBoundaryElementsEnd() const 00477 { 00478 return ContainingBoundaryElementIterator(mBoundaryElementIndices.end()); 00479 } 00480 }; 00481 00482 #include "SerializationExportWrapper.hpp" 00483 // Declare identifier for the serializer 00484 EXPORT_TEMPLATE_CLASS_SAME_DIMS(Node) 00485 00486 namespace boost 00487 { 00488 namespace serialization 00489 { 00493 template<class Archive, unsigned SPACE_DIM> 00494 inline void save_construct_data( 00495 Archive & ar, const Node<SPACE_DIM> * t, const BOOST_PFTO unsigned int file_version) 00496 { 00497 00498 // Save data required to construct instance 00499 for (unsigned i = 0; i < SPACE_DIM; i++) 00500 { 00501 //we archive coordinates of mLocation one by one 00502 //this is because earlier version of boost (<1.40, I think) cannot archive c_vectors 00503 double coord = t->rGetLocation()[i]; 00504 ar & coord; 00505 } 00506 unsigned index = t->GetIndex(); 00507 ar << index; 00508 00509 bool is_boundary = t->IsBoundaryNode(); 00510 ar << is_boundary; 00511 } 00515 template<class Archive, unsigned SPACE_DIM> 00516 inline void load_construct_data( 00517 Archive & ar, Node<SPACE_DIM> * t, const unsigned int file_version) 00518 { 00519 // Retrieve data from archive required to construct new instance of Node 00520 c_vector<double,SPACE_DIM> location; 00521 for (unsigned i=0; i<SPACE_DIM; i++) 00522 { 00523 double coordinate; 00524 ar & coordinate;//resume coordinates one by one 00525 location[i] = coordinate; 00526 } 00527 00528 unsigned index; 00529 ar >> index; 00530 00531 bool is_boundary; 00532 ar >> is_boundary; 00533 00534 // Invoke inplace constructor to initialise instance 00535 ::new(t)Node<SPACE_DIM>(index, location, is_boundary); 00536 } 00537 } 00538 } // namespace ... 00539 00540 #endif //_NODE_HPP_