TAPs 0.7.7.3
TAPsFEMMeshTetrahedraGen.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsFEMMeshTetrahedraGen.cpp
00003 ******************************************************************************/
00007 /******************************************************************************
00008 SUKITTI PUNAK   (12/15/2009)
00009 UPDATE          (04/16/2010)
00010 ******************************************************************************/
00011 #include "TAPsFEMMeshTetrahedraGen.hpp"
00012 // Using Inclusion Model (i.e. definitions are included in declarations)
00013 //                       (this name.cpp is included in name.hpp)
00014 // Each friend is defined directly inside its declaration.
00015 
00016 BEGIN_NAMESPACE_TAPs__FEM
00017 //=============================================================================
00018 //template <typename T> std::vector< Tetrahedron<T> > * MeshTetrahedraGen<T>::m_pListOfElements = NULL;
00019 //template <typename T> std::vector< Vector3<T> > * MeshTetrahedraGen<T>::m_pListOfDeformedMeshNodes = NULL;
00020 //template <typename T> std::vector< Vector3<T> > * MeshTetrahedraGen<T>::m_pListOfUndeformedMeshNodes = NULL;
00021 //-----------------------------------------------------------------------------
00022 
00024 //template <typename T>
00025 //void MeshTetrahedraGen<T>::SetAccessors ( MeshTetrahedra<T> & rTetFemMesh )
00026 //{
00027 //  m_pListOfElements               = &( rTetFemMesh.RetListOfElements() );
00028 //  m_pListOfDeformedMeshNodes      = &( rTetFemMesh.RetListOfDeformedMeshNodes() );
00029 //  m_pListOfUndeformedMeshNodes    = &( rTetFemMesh.RetListOfUndeformedMeshNodes() );
00030 //}
00032 //template <typename T>
00033 //void MeshTetrahedraGen<T>::ClearAccessors ()
00034 //{
00035 //  m_pListOfElements               = NULL;
00036 //  m_pListOfDeformedMeshNodes      = NULL;
00037 //  m_pListOfUndeformedMeshNodes    = NULL;
00038 //}
00039 
00040 //-----------------------------------------------------------------------------
00041 template <typename T, typename DATA>
00042 void MeshTetrahedraGen<T,DATA>::OneElementMesh ( MeshTetrahedra<T> & rTetFemMesh, T mass, T YoungsModulus, T PoissonsRatio )
00043 {
00044     std::vector< Tetrahedron<T> > & E = rTetFemMesh.RetListOfElements();
00045     std::vector< Vector3<T> > & Nd = rTetFemMesh.RetListOfDeformedMeshNodes();
00046     std::vector< Vector3<T> > & Nu = rTetFemMesh.RetListOfUndeformedMeshNodes();
00047 
00048     // Clear the mesh
00049     E.clear();
00050     Nd.clear();
00051     Nu.clear();
00052 
00053     /*
00054     // 4 deformed nodes
00055     Nd.push_back( Vector3<T>(0,0,1.0) );
00056     Nd.push_back( Vector3<T>(0,1.0,0) );
00057     Nd.push_back( Vector3<T>(1.0,0,0) );
00058     Nd.push_back( Vector3<T>(0,0,0.0) );
00059     // 4 undeformed nodes
00060     Nu.push_back( Vector3<T>(0,0,1) );
00061     Nu.push_back( Vector3<T>(0,1,0) );
00062     Nu.push_back( Vector3<T>(1,0,0) );
00063     Nu.push_back( Vector3<T>(0,0,0) );
00064     //*/
00065 
00066     //*
00067     // TEST DATA
00068     // 4 deformed nodes
00069     Nd.push_back( Vector3<T>(2,3,4) );
00070     Nd.push_back( Vector3<T>(6,3,2) );
00071     Nd.push_back( Vector3<T>(2,5,1) );
00072     Nd.push_back( Vector3<T>(4,3,6) );
00073     // 4 undeformed nodes
00074     Nu.push_back( Vector3<T>(2,3,4) );
00075     Nu.push_back( Vector3<T>(6,3,2) );
00076     Nu.push_back( Vector3<T>(2,5,1) );
00077     Nu.push_back( Vector3<T>(4,3,6) );
00078     //*/
00079 
00080     // 1st element
00081     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 0, 1, 2, 3 ) );
00082 
00083     rTetFemMesh.SetSizeOfStiffnessMatrix();
00084     rTetFemMesh.AssembleStiffnessMatrix();
00085 
00086     // Allocate data for simulation
00087     rTetFemMesh.AllocateDataForSimulation( mass );
00088 }
00089 
00090 //-----------------------------------------------------------------------------
00091 template <typename T, typename DATA>
00092 void MeshTetrahedraGen<T,DATA>::TwoElementMeshJoinByNode ( MeshTetrahedra<T> & rTetFemMesh, T mass, T YoungsModulus, T PoissonsRatio )
00093 {
00094     std::vector< Tetrahedron<T> > & E = rTetFemMesh.RetListOfElements();
00095     std::vector< Vector3<T> > & Nd = rTetFemMesh.RetListOfDeformedMeshNodes();
00096     std::vector< Vector3<T> > & Nu = rTetFemMesh.RetListOfUndeformedMeshNodes();
00097 
00098     // Clear the mesh
00099     E.clear();
00100     Nd.clear();
00101     Nu.clear();
00102 
00103     // 7 deformed nodes
00104     Nd.push_back( Vector3<T>(0,0,1) );
00105     Nd.push_back( Vector3<T>(0,1,0) );
00106     Nd.push_back( Vector3<T>(1,0,0) );
00107     Nd.push_back( Vector3<T>(0,0,0) );
00108     Nd.push_back( Vector3<T>(-1,0,0) );
00109     Nd.push_back( Vector3<T>(0,-1,0) );
00110     Nd.push_back( Vector3<T>(0,0,-1) );
00111     // 7 undeformed nodes
00112     Nu.push_back( Vector3<T>(0,0,1) );
00113     Nu.push_back( Vector3<T>(0,1,0) );
00114     Nu.push_back( Vector3<T>(1,0,0) );
00115     Nu.push_back( Vector3<T>(0,0,0) );
00116     Nu.push_back( Vector3<T>(-1,0,0) );
00117     Nu.push_back( Vector3<T>(0,-1,0) );
00118     Nu.push_back( Vector3<T>(0,0,-1) );
00119 
00120     // 1st element
00121     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 0, 1, 2, 3 ) );
00122     // 2st element
00123     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 4, 5, 6, 3 ) );
00124 
00125     rTetFemMesh.SetSizeOfStiffnessMatrix();
00126     rTetFemMesh.AssembleStiffnessMatrix();
00127 
00128     // Allocate data for simulation
00129     rTetFemMesh.AllocateDataForSimulation( mass );
00130 }
00131 
00132 //-----------------------------------------------------------------------------
00133 template <typename T, typename DATA>
00134 void MeshTetrahedraGen<T,DATA>::TwoElementMeshJoinByEdge ( MeshTetrahedra<T> & rTetFemMesh, T mass, T YoungsModulus, T PoissonsRatio )
00135 {
00136     std::vector< Tetrahedron<T> > & E = rTetFemMesh.RetListOfElements();
00137     std::vector< Vector3<T> > & Nd = rTetFemMesh.RetListOfDeformedMeshNodes();
00138     std::vector< Vector3<T> > & Nu = rTetFemMesh.RetListOfUndeformedMeshNodes();
00139 
00140     // Clear the mesh
00141     E.clear();
00142     Nd.clear();
00143     Nu.clear();
00144 
00145     // 6 deformed nodes
00146     Nd.push_back( Vector3<T>(0,0,1) );
00147     Nd.push_back( Vector3<T>(0,1,0) );
00148     Nd.push_back( Vector3<T>(1,0,0) );
00149     Nd.push_back( Vector3<T>(0,0,0) );
00150     Nd.push_back( Vector3<T>(-1,0,0) );
00151     Nd.push_back( Vector3<T>(0,-1,0) );
00152     // 6 undeformed nodes
00153     Nu.push_back( Vector3<T>(0,0,1) );
00154     Nu.push_back( Vector3<T>(0,1,0) );
00155     Nu.push_back( Vector3<T>(1,0,0) );
00156     Nu.push_back( Vector3<T>(0,0,0) );
00157     Nu.push_back( Vector3<T>(-1,0,0) );
00158     Nu.push_back( Vector3<T>(0,-1,0) );
00159 
00160     // 1st element
00161     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 0, 1, 2, 3 ) );
00162     // 2st element
00163     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 3, 0, 4, 5 ) );
00164 
00165     rTetFemMesh.SetSizeOfStiffnessMatrix();
00166     rTetFemMesh.AssembleStiffnessMatrix();
00167 
00168     // Allocate data for simulation
00169     rTetFemMesh.AllocateDataForSimulation( mass );
00170 }
00171 
00172 //-----------------------------------------------------------------------------
00173 template <typename T, typename DATA>
00174 void MeshTetrahedraGen<T,DATA>::TwoElementMeshJoinByFace ( MeshTetrahedra<T> & rTetFemMesh, T mass, T YoungsModulus, T PoissonsRatio )
00175 {
00176     std::vector< Tetrahedron<T> > & E = rTetFemMesh.RetListOfElements();
00177     std::vector< Vector3<T> > & Nd = rTetFemMesh.RetListOfDeformedMeshNodes();
00178     std::vector< Vector3<T> > & Nu = rTetFemMesh.RetListOfUndeformedMeshNodes();
00179 
00180     // Clear the mesh
00181     E.clear();
00182     Nd.clear();
00183     Nu.clear();
00184 
00185     // 5 deformed nodes
00186     Nd.push_back( Vector3<T>(-0.1,0.2,1) );
00187     Nd.push_back( Vector3<T>(0.15,1,-0.25) );
00188     Nd.push_back( Vector3<T>(1,-0.1,0.2) );
00189     Nd.push_back( Vector3<T>(-1.1,-1.1,-1.1) );
00190     Nd.push_back( Vector3<T>(-1,-0.1,0.2) );
00191     // 5 undeformed nodes
00192     Nu.push_back( Vector3<T>(-0.1,0.2,1) );
00193     Nu.push_back( Vector3<T>(0.15,1,-0.25) );
00194     Nu.push_back( Vector3<T>(1,-0.1,0.2) );
00195     Nu.push_back( Vector3<T>(-1.1,-1.1,-1.1) );
00196     Nu.push_back( Vector3<T>(-1,-0.1,0.2) );
00197 
00198     // 1st element
00199     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 0, 1, 2, 3 ) );
00200     // 2st element
00201     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 0, 1, 3, 4 ) );
00202 
00203     rTetFemMesh.SetSizeOfStiffnessMatrix();
00204     rTetFemMesh.AssembleStiffnessMatrix();
00205 
00206     // Allocate data for simulation
00207     rTetFemMesh.AllocateDataForSimulation( mass );
00208 }
00209 
00210 //-----------------------------------------------------------------------------
00211 template <typename T, typename DATA>
00212 void MeshTetrahedraGen<T,DATA>::SixTetrahedraSubFromHexahedron ( MeshTetrahedra<T> & rTetFemMesh, T mass, T YoungsModulus, T PoissonsRatio )
00213 {
00214     std::vector< Tetrahedron<T> > & E = rTetFemMesh.RetListOfElements();
00215     std::vector< Vector3<T> > & Nd = rTetFemMesh.RetListOfDeformedMeshNodes();
00216     std::vector< Vector3<T> > & Nu = rTetFemMesh.RetListOfUndeformedMeshNodes();
00217 
00218     // Clear the mesh
00219     E.clear();
00220     Nd.clear();
00221     Nu.clear();
00222 
00223     T s = T(0.5);
00224     // 8 undeformed nodes
00225     Nu.push_back( Vector3<T>(-s,-s,-s) );
00226     Nu.push_back( Vector3<T>(+s,-s,-s) );
00227     Nu.push_back( Vector3<T>(+s,+s,-s) );
00228     Nu.push_back( Vector3<T>(-s,+s,-s) );
00229     Nu.push_back( Vector3<T>(-s,-s,+s) );
00230     Nu.push_back( Vector3<T>(+s,-s,+s) );
00231     Nu.push_back( Vector3<T>(+s,+s,+s) );
00232     Nu.push_back( Vector3<T>(-s,+s,+s) );
00233 
00234     //s += T(0.05);
00235     // 8 deformed nodes
00236     Nd.push_back( Vector3<T>(-s,-s,-s) );
00237     Nd.push_back( Vector3<T>(+s,-s,-s) );
00238     Nd.push_back( Vector3<T>(+s,+s,-s) );
00239     Nd.push_back( Vector3<T>(-s,+s,-s) );
00240     Nd.push_back( Vector3<T>(-s,-s,+s) );
00241     Nd.push_back( Vector3<T>(+s,-s,+s) );
00242     Nd.push_back( Vector3<T>(+s,+s,+s) );
00243     Nd.push_back( Vector3<T>(-s,+s,+s) );
00244 
00245     // 6 tetrahedra
00246     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 0, 2, 3, 6 ) );
00247     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 0, 3, 7, 6 ) );
00248     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 0, 7, 4, 6 ) );
00249     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 0, 5, 6, 4 ) );
00250     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 1, 5, 6, 0 ) );
00251     E.push_back( Tetrahedron<T>( &Nd, &Nu, YoungsModulus, PoissonsRatio, 1, 6, 2, 0 ) );
00252 
00253     rTetFemMesh.SetSizeOfStiffnessMatrix();
00254     rTetFemMesh.AssembleStiffnessMatrix();
00255 
00256     // Allocate data for simulation
00257     rTetFemMesh.AllocateDataForSimulation( mass );
00258 }
00259 
00260 
00261 //-----------------------------------------------------------------------------
00262 template <typename T, typename DATA>
00263 bool MeshTetrahedraGen<T,DATA>::MeshFromGridGenerator (
00264         MeshTetrahedra<T> & rTetFemMesh,    
00265         GridGenerator<T,DATA> & rGridGen,   
00266         T   mass,                           
00267         T   YoungsModulus,                  
00268         T   PoissonsRatio                   
00269 )
00270 {
00271 
00272     if ( !rGridGen.IsGridGenerated() ) {
00273         return false;
00274     }
00275 
00276     // Grid layout (right-handed coordinates)
00277     //      ^ y
00278     //      |
00279     //      |
00280     //      0-----> x       x = column
00281     //     /                y = row
00282     //    /                 z = depth
00283     //   v z
00284     //
00285     //  Where X := #columns-1, Y := #rows-1, and Z := #slices-1.
00286     //
00287     //                   O-------O-------O---------------O-------O
00288     //                  /|      /|      /|      ...     /|      /|
00289     //                 / |(0,Y,0)|     / |      ...    / |(X,Y,0)|
00290     //                /  |    /  |    /  |      ...   /  |    /  |
00291     //               /   O---/---O---/---O-----------/---O---/---O
00292     //              /    |  /    |  /    |      ... /    |  /   /|
00293     //             /     | /     | /     |      .../     | /   / |
00294     //            /      |/      |/      |      ../      |/   /  |
00295     //           /       /-------/-------O-------/-------/---/---O
00296     //          /       /|      /               HIGHEST / POINT /|
00297     //         O-------O-------O---------------O-------@   /   / |
00298     //         |       |       |      ...      | .     |  /   /  |
00299     //         |(0,Y,Z)|       |      ...      |(X,Y,Z)| /   /   |
00300     //         |       |       |      ...      | .     |/   /    |
00301     //         O-------O-------O---------------O-------O   /     |
00302     //         |       |       |      ...      | .     |  /      |
00303     //         |       |       |      ...      | .     | /       |
00304     //         |       |       |      ...      | .     |/        |
00305     //         O-------O-------O---------------O-------O         |
00306     //         |         |             .         .     |         |
00307     //         |         O-------O-----.-O-------------|-O-------0
00308     //         |        /|       |     . |      ...    | |      /|
00309     //         |       / |(0,0,0)|     . |      ...    | |(X,0,0)|
00310     //         |      /  |       |     . |      ...    | |    /  |
00311     //         |     /   @-------O-----.-O-------------|-O---/---O
00312     //         | LOWEST / POINT /      ./              |/   /   /
00313     //         |   /   /       /       .               |   /   /
00314     //         |  /   /       /       /.              /|  /   /
00315     //         | /   /       /       / .             / | /   /
00316     //         |/   /       /       /  .            /  |/   /
00317     //         O-------O-------O---------------O-------O   /
00318     //         |  /    |  /    |  /   ...      |  /    |  /
00319     //         |(0,0,Z)| /     | /    ...      |(X,0,Z)| /
00320     //         |/      |/      |/     ...      |/      |/
00321     //         O-------O-------O---------------O-------O
00322     //
00323     //  where D := Z;  R := Y;  C := X;
00324     //
00325     //  The n-th Z-slice
00326     //
00327     //  (nRC+(R-1)+C+0)--(nRC+(R-1)+C+1)--(nRC+(R-1)+C+2)-- ... --(nRC+(R+1)C+C-1)
00328     //          |                |                |                       |
00329     //          |                |                |                       |
00330     //          |                |                |                       |
00331     //         ...              ...              ...        ...          ...
00332     //          |                |                |                       |
00333     //          |                |                |                       |
00334     //          |                |                |                       |
00335     //     (nRC+2C+0)-------(nRC+2C+1)-------(nRC+2C+2)---- ... -----(nRC+2C+C-1)
00336     //          |                |                |                       |
00337     //          |                |                |                       |
00338     //          |                |                |                       |
00339     //      (nRC+C+0)--------(nRC+C+1)--------(nRC+C+2)---- ... ------(nRC+C+C-1)
00340     //          |                |                |                       |
00341     //          |                |                |                       |
00342     //          |                |                |                       |
00343     //       (nRC+0)----------(nRC+1)----------(nRC+2)----- ... -------(nRC+C-1)
00344     //
00345     //
00346     //
00347     //                 @---------@      ^ y
00348     //                /|        /|      |
00349     //               / | SLICE /A|      |
00350     //              @---------@  |      |
00351     //             /|  @- - -/| -@      +------>x
00352     //            / | SLICE /B| /      /
00353     //           @---------@  |/      /
00354     //           |  @------|--@      v z
00355     //           | /SLICE C| /
00356     //           |/        |/
00357     //           @---------@
00358 
00359     //*
00360     std::vector< Tetrahedron<T> > & E = rTetFemMesh.RetListOfElements();
00361     std::vector< Vector3<T> > & Nd = rTetFemMesh.RetListOfDeformedMeshNodes();
00362     std::vector< Vector3<T> > & Nu = rTetFemMesh.RetListOfUndeformedMeshNodes();
00363 
00364     // Clear the mesh
00365     E.clear();
00366     Nd.clear();
00367     Nu.clear();
00368 
00369     // Z goes first follows by Y then X.
00370     // So the slice is in Z-plane with Y as rows and X as columns
00371     T **** const GridVertices = rGridGen.ReturnPtrToVertexPositionData();
00372     unsigned int z,y,x;
00373     unsigned int C = rGridGen.GetGridSizeX();
00374     unsigned int R = rGridGen.GetGridSizeY();
00375     unsigned int D = rGridGen.GetGridSizeZ();
00376 
00377     // Add FEM mesh vertices from the grid data
00378     for ( z = 0; z < D; ++z ) {
00379         for ( y = 0; y < R; ++y ) {
00380             for ( x = 0; x < C; ++x ) {
00381                 Vector3<T> V( GridVertices[x][y][z][0], GridVertices[x][y][z][1], GridVertices[x][y][z][2] );
00382                 Nd.push_back( V );
00383                 Nu.push_back( V );
00384             }
00385         }
00386     }
00387 
00388     // Add tetrahedra from the FEM mesh vertices
00389     unsigned int v[8];
00390     unsigned int RC  = R*C;
00391     unsigned int SLICE = 0;
00392     unsigned int ROW;
00393     for ( z = 0; z < D-1; ++z ) {
00394         ROW = 0;
00395         for ( y = 0; y < R-1; ++y ) {
00396             for ( x = 0; x < C-1; ++x ) {
00397                 // Pt 1 to 8
00398                 //
00399                 //         3---------2      ^ y
00400                 //        /|        /|      |
00401                 //       / |       / |      |
00402                 //      7---------6  |      |
00403                 //      |  0- - - | -1      +------>x
00404                 //      | /       | /      /
00405                 //      |/        |/      /
00406                 //      4---------5      v z
00407                 v[0] = SLICE + ROW + x;
00408                 v[3] = v[0] + C;
00409                 v[4] = v[0] + RC;
00410                 v[7] = v[4] + C;
00411                 v[1] = v[0]+1;
00412                 v[2] = v[3]+1;
00413                 v[5] = v[4]+1;
00414                 v[6] = v[7]+1;
00415                 // Subdivided into six tetrahedra
00416                 // 0-2-3-6
00417                 E.push_back( Tetrahedron<T>( 
00418                     &Nd,            // the 4 deformed nodes
00419                     &Nu,            // the 4 undeformed nodes
00420                     YoungsModulus,  // Young's modulus
00421                     PoissonsRatio,  // Poisson's ratio
00422                     v[0], v[2], v[3], v[6] )
00423                 );
00424                 // 0-3-7-6
00425                 E.push_back( Tetrahedron<T>( 
00426                     &Nd,            // the 4 deformed nodes
00427                     &Nu,            // the 4 undeformed nodes
00428                     YoungsModulus,  // Young's modulus
00429                     PoissonsRatio,  // Poisson's ratio
00430                     v[0], v[3], v[7], v[6] )
00431                 );
00432                 // 0-7-4-6
00433                 E.push_back( Tetrahedron<T>( 
00434                     &Nd,            // the 4 deformed nodes
00435                     &Nu,            // the 4 undeformed nodes
00436                     YoungsModulus,  // Young's modulus
00437                     PoissonsRatio,  // Poisson's ratio
00438                     v[0], v[7], v[4], v[6] )
00439                 );
00440                 // 0-5-6-4
00441                 E.push_back( Tetrahedron<T>( 
00442                     &Nd,            // the 4 deformed nodes
00443                     &Nu,            // the 4 undeformed nodes
00444                     YoungsModulus,  // Young's modulus
00445                     PoissonsRatio,  // Poisson's ratio
00446                     v[0], v[5], v[6], v[4] )
00447                 );
00448                 // 1-5-6-0
00449                 E.push_back( Tetrahedron<T>( 
00450                     &Nd,            // the 4 deformed nodes
00451                     &Nu,            // the 4 undeformed nodes
00452                     YoungsModulus,  // Young's modulus
00453                     PoissonsRatio,  // Poisson's ratio
00454                     v[1], v[5], v[6], v[0] )
00455                 );
00456                 // 1-6-2-0
00457                 E.push_back( Tetrahedron<T>( 
00458                     &Nd,            // the 4 deformed nodes
00459                     &Nu,            // the 4 undeformed nodes
00460                     YoungsModulus,  // Young's modulus
00461                     PoissonsRatio,  // Poisson's ratio
00462                     v[1], v[6], v[2], v[0] )
00463                 );
00464             }
00465             ROW += C;
00466         }
00467         SLICE += RC;
00468     }
00469 
00470     rTetFemMesh.SetSizeOfStiffnessMatrix();
00471     rTetFemMesh.AssembleStiffnessMatrix();
00472 
00473     // Allocate data for simulation
00474     rTetFemMesh.AllocateDataForSimulation( mass );
00475     //*/
00476 
00477     // DEBUG
00478     std::cout << "Generated Tetrahedral FEM mesh has " << rTetFemMesh.GetNumOfNodes() 
00479         << " nodes and " << rTetFemMesh.GetNumOfElements() << " elements.\n";
00480 
00481     return true;
00482 }
00483 
00484 
00485 //-----------------------------------------------------------------------------
00486 template <typename T, typename DATA>
00487 bool MeshTetrahedraGen<T,DATA>::MeshFromGridGenerator (
00488         MeshTetrahedra<T> & rTetFemMesh,    
00489         std::vector< TetBarycentricCoordsForVertexRef<T> > & rBaryCoords, 
00490         //std::vector< unsigned int > & r_ElementID,    //!< identify the element that the barycentric coordinates are embedded in
00491         GridGenerator<T,DATA> & rGridGen,   
00492         T   mass,                           
00493         T   YoungsModulus,                  
00494         T   PoissonsRatio,                  
00495         bool bGenElementsInsideVolume       
00496 )
00497 {
00498 
00499     if ( !rGridGen.IsGridGenerated() ) {
00500         return false;
00501     }
00502 
00503     // Grid layout (right-handed coordinates)
00504     //      ^ y
00505     //      |
00506     //      |
00507     //      0-----> x       x = column
00508     //     /                y = row
00509     //    /                 z = depth
00510     //   v z
00511     //
00512     //  Where X := #columns-1, Y := #rows-1, and Z := #slices-1.
00513     //
00514     //                   O-------O-------O---------------O-------O
00515     //                  /|      /|      /|      ...     /|      /|
00516     //                 / |(0,Y,0)|     / |      ...    / |(X,Y,0)|
00517     //                /  |    /  |    /  |      ...   /  |    /  |
00518     //               /   O---/---O---/---O-----------/---O---/---O
00519     //              /    |  /    |  /    |      ... /    |  /   /|
00520     //             /     | /     | /     |      .../     | /   / |
00521     //            /      |/      |/      |      ../      |/   /  |
00522     //           /       /-------/-------O-------/-------/---/---O
00523     //          /       /|      /               HIGHEST / POINT /|
00524     //         O-------O-------O---------------O-------@   /   / |
00525     //         |       |       |      ...      | .     |  /   /  |
00526     //         |(0,Y,Z)|       |      ...      |(X,Y,Z)| /   /   |
00527     //         |       |       |      ...      | .     |/   /    |
00528     //         O-------O-------O---------------O-------O   /     |
00529     //         |       |       |      ...      | .     |  /      |
00530     //         |       |       |      ...      | .     | /       |
00531     //         |       |       |      ...      | .     |/        |
00532     //         O-------O-------O---------------O-------O         |
00533     //         |         |             .         .     |         |
00534     //         |         O-------O-----.-O-------------|-O-------0
00535     //         |        /|       |     . |      ...    | |      /|
00536     //         |       / |(0,0,0)|     . |      ...    | |(X,0,0)|
00537     //         |      /  |       |     . |      ...    | |    /  |
00538     //         |     /   @-------O-----.-O-------------|-O---/---O
00539     //         | LOWEST / POINT /      ./              |/   /   /
00540     //         |   /   /       /       .               |   /   /
00541     //         |  /   /       /       /.              /|  /   /
00542     //         | /   /       /       / .             / | /   /
00543     //         |/   /       /       /  .            /  |/   /
00544     //         O-------O-------O---------------O-------O   /
00545     //         |  /    |  /    |  /   ...      |  /    |  /
00546     //         |(0,0,Z)| /     | /    ...      |(X,0,Z)| /
00547     //         |/      |/      |/     ...      |/      |/
00548     //         O-------O-------O---------------O-------O
00549     //
00550     //  where D := Z;  R := Y;  C := X;
00551     //
00552     //  The n-th Z-slice
00553     //
00554     //  (nRC+(R-1)+C+0)--(nRC+(R-1)+C+1)--(nRC+(R-1)+C+2)-- ... --(nRC+(R+1)C+C-1)
00555     //          |                |                |                       |
00556     //          |                |                |                       |
00557     //          |                |                |                       |
00558     //         ...              ...              ...        ...          ...
00559     //          |                |                |                       |
00560     //          |                |                |                       |
00561     //          |                |                |                       |
00562     //     (nRC+2C+0)-------(nRC+2C+1)-------(nRC+2C+2)---- ... -----(nRC+2C+C-1)
00563     //          |                |                |                       |
00564     //          |                |                |                       |
00565     //          |                |                |                       |
00566     //      (nRC+C+0)--------(nRC+C+1)--------(nRC+C+2)---- ... ------(nRC+C+C-1)
00567     //          |                |                |                       |
00568     //          |                |                |                       |
00569     //          |                |                |                       |
00570     //       (nRC+0)----------(nRC+1)----------(nRC+2)----- ... -------(nRC+C-1)
00571     //
00572     //
00573     //
00574     //                 @---------@      ^ y
00575     //                /|        /|      |
00576     //               / | SLICE /A|      |
00577     //              @---------@  |      |
00578     //             /|  @- - -/| -@      +------>x
00579     //            / | SLICE /B| /      /
00580     //           @---------@  |/      /
00581     //           |  @------|--@      v z
00582     //           | /SLICE C| /
00583     //           |/        |/
00584     //           @---------@
00585 
00586     //*
00587     std::vector< Tetrahedron<T> > & E = rTetFemMesh.RetListOfElements();
00588     std::vector< Vector3<T> > & Nd = rTetFemMesh.RetListOfDeformedMeshNodes();
00589     std::vector< Vector3<T> > & Nu = rTetFemMesh.RetListOfUndeformedMeshNodes();
00590 
00591     // Clear the mesh
00592     E.clear();
00593     Nd.clear();
00594     Nu.clear();
00595 
00596     // Create temp data
00597     unsigned int gridsize[3] = { rGridGen.GetGridSizeX()-1, rGridGen.GetGridSizeY()-1, rGridGen.GetGridSizeZ()-1 };
00598     unsigned int gx = gridsize[0];
00599     unsigned int gxgy = gridsize[0]*gridsize[1];
00600     bool **** pValidElements = new bool***[gridsize[2]];
00601     for ( unsigned int k = 0; k < gridsize[2]; ++k ) {
00602         pValidElements[k] = new bool**[gridsize[1]];
00603         for ( unsigned int j = 0; j < gridsize[1]; ++j ) {
00604             pValidElements[k][j] = new bool*[gridsize[0]];
00605             for ( unsigned int i = 0; i < gridsize[0]; ++i ) {
00606                 pValidElements[k][j][i] = new bool[6];
00607                 for ( unsigned int e = 0; e < 6; ++e ) {
00608                     pValidElements[k][j][i][e] = false;
00609                 }
00610             }
00611         }
00612     }
00613 
00614     // Find all barycentric coordinates and mark all valid elements
00615     //FindAllBaryCoordsAndTheirLocInTheGrids( rBaryCoords, r_ElementID, rGridGen, pValidElements );
00616     FindAllBaryCoordsAndTheirLocInTheGrids( rBaryCoords, rGridGen, pValidElements );
00617     // Now rBaryCoords contain the barycentric coordinates of all vertices 
00618     // but not yet have the correct pointer to tetrehedra since they are not yet created.
00619     // pValidElements now contain all valid elements
00620     // r_ElementID store the element IDs associated with rBaryCoords in the format of 6(z(R-1)(C-1)+y(C-1)+x).
00621     // These values (format) has to be changed to the element IDs stored in the FEM mesh.
00622 
00623     /*
00624     // DID NOT SEE THE BENEFIT OF THIS ONE -- SEPARATING OF RIGHT_OUTSIDE_BOUNDARY AND ON_BOUNDARY FROM RIGHT_INSIDE_BOUNDARY AND INSIDE_MODEL!
00625     // FEM MESH DATA FROM THE ADJACENT ELEMENTS ON THE BOUNDARY OF THE SURFACE MESH
00626     if ( true ) {
00627         // Mark the valid vertices (location) in temp data based on the grid vertex data stored in rGridGen
00628         GridGenerator<T,DATA>::VertexFlag *** const vertexFlag = rGridGen.ReturnPtrToVertexFlagData();
00629         // Mark the valid vertices (location) in temp data
00630         bool b[8];
00631         for ( unsigned int x = 0; x < gridsize[0]; ++x ) {
00632             for ( unsigned int y = 0; y < gridsize[1]; ++y ) {
00633                 for ( unsigned int z = 0; z < gridsize[2]; ++z ) {
00634                     // Find valid FEM mesh vertices
00635                     if (    vertexFlag[x][y][z] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00636                         ||  vertexFlag[x][y][z] == GridGenerator<T,DATA>::ON_BOUNDARY )
00637                     {b[0] = true;} else {b[0] = false;}
00638                     if (    vertexFlag[x+1][y][z] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00639                         ||  vertexFlag[x+1][y][z] == GridGenerator<T,DATA>::ON_BOUNDARY )
00640                     {b[1] = true;} else {b[1] = false;}
00641                     if (    vertexFlag[x+1][y+1][z] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00642                         ||  vertexFlag[x+1][y+1][z] == GridGenerator<T,DATA>::ON_BOUNDARY )
00643                     {b[2] = true;} else {b[2] = false;}
00644                     if (    vertexFlag[x][y+1][z] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00645                         ||  vertexFlag[x][y+1][z] == GridGenerator<T,DATA>::ON_BOUNDARY )
00646                     {b[3] = true;} else {b[3] = false;}
00647                     if (    vertexFlag[x][y][z+1] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00648                         ||  vertexFlag[x][y][z+1] == GridGenerator<T,DATA>::ON_BOUNDARY )
00649                     {b[4] = true;} else {b[4] = false;}
00650                     if (    vertexFlag[x+1][y][z+1] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00651                         ||  vertexFlag[x+1][y][z+1] == GridGenerator<T,DATA>::ON_BOUNDARY )
00652                     {b[5] = true;} else {b[5] = false;}
00653                     if (    vertexFlag[x+1][y+1][z+1] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00654                         ||  vertexFlag[x+1][y+1][z+1] == GridGenerator<T,DATA>::ON_BOUNDARY )
00655                     {b[6] = true;} else {b[6] = false;}
00656                     if (    vertexFlag[x][y+1][z+1] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00657                         ||  vertexFlag[x][y+1][z+1] == GridGenerator<T,DATA>::ON_BOUNDARY )
00658                     {b[7] = true;} else {b[7] = false;}
00659 
00660                     // Six tetrahedra subdivided from a brick
00661                     // 0-2-3-6 --> #0
00662                     // 0-3-7-6 --> #1
00663                     // 0-7-4-6 --> #2
00664                     // 0-5-6-4 --> #3
00665                     // 1-5-6-0 --> #4
00666                     // 1-6-2-0 --> #5
00667                     if ( b[0] && b[2] && b[3] && b[6] ) pValidElements[z][y][x][0] = true;
00668                     if ( b[0] && b[3] && b[7] && b[6] ) pValidElements[z][y][x][1] = true;
00669                     if ( b[0] && b[7] && b[4] && b[6] ) pValidElements[z][y][x][2] = true;
00670                     if ( b[0] && b[5] && b[6] && b[4] ) pValidElements[z][y][x][3] = true;
00671                     if ( b[1] && b[5] && b[6] && b[0] ) pValidElements[z][y][x][4] = true;
00672                     if ( b[1] && b[6] && b[2] && b[0] ) pValidElements[z][y][x][5] = true;
00673                 }
00674             }
00675         }
00676     }
00677     //*/
00678 
00679     // FEM MESH DATA FROM VOLUME INSIDE THE SURFACE MESH
00680     if ( bGenElementsInsideVolume ) {
00681         // Mark the valid vertices (location) in temp data based on the grid vertex data stored in rGridGen
00682         GridGenerator<T,DATA>::VertexFlag *** const vertexFlag = rGridGen.ReturnPtrToVertexFlagData();
00683         // Mark the valid vertices (location) in temp data
00684         bool b[8];
00685         for ( unsigned int x = 0; x < gridsize[0]; ++x ) {
00686             for ( unsigned int y = 0; y < gridsize[1]; ++y ) {
00687                 for ( unsigned int z = 0; z < gridsize[2]; ++z ) {
00688                     // Find valid FEM mesh vertices
00689                     if (    vertexFlag[x][y][z] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00690                         ||  vertexFlag[x][y][z] == GridGenerator<T,DATA>::ON_BOUNDARY
00691                         ||  vertexFlag[x][y][z] == GridGenerator<T,DATA>::RIGHT_INSIDE_BOUNDARY
00692                         ||  vertexFlag[x][y][z] == GridGenerator<T,DATA>::INSIDE_MODEL )
00693                     {b[0] = true;} else {b[0] = false;}
00694                     if (    vertexFlag[x+1][y][z] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00695                         ||  vertexFlag[x+1][y][z] == GridGenerator<T,DATA>::ON_BOUNDARY
00696                         ||  vertexFlag[x+1][y][z] == GridGenerator<T,DATA>::RIGHT_INSIDE_BOUNDARY
00697                         ||  vertexFlag[x+1][y][z] == GridGenerator<T,DATA>::INSIDE_MODEL )
00698                     {b[1] = true;} else {b[1] = false;}
00699                     if (    vertexFlag[x+1][y+1][z] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00700                         ||  vertexFlag[x+1][y+1][z] == GridGenerator<T,DATA>::ON_BOUNDARY
00701                         ||  vertexFlag[x+1][y+1][z] == GridGenerator<T,DATA>::RIGHT_INSIDE_BOUNDARY
00702                         ||  vertexFlag[x+1][y+1][z] == GridGenerator<T,DATA>::INSIDE_MODEL )
00703                     {b[2] = true;} else {b[2] = false;}
00704                     if (    vertexFlag[x][y+1][z] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00705                         ||  vertexFlag[x][y+1][z] == GridGenerator<T,DATA>::ON_BOUNDARY
00706                         ||  vertexFlag[x][y+1][z] == GridGenerator<T,DATA>::RIGHT_INSIDE_BOUNDARY
00707                         ||  vertexFlag[x][y+1][z] == GridGenerator<T,DATA>::INSIDE_MODEL )
00708                     {b[3] = true;} else {b[3] = false;}
00709                     if (    vertexFlag[x][y][z+1] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00710                         ||  vertexFlag[x][y][z+1] == GridGenerator<T,DATA>::ON_BOUNDARY
00711                         ||  vertexFlag[x][y][z+1] == GridGenerator<T,DATA>::RIGHT_INSIDE_BOUNDARY
00712                         ||  vertexFlag[x][y][z+1] == GridGenerator<T,DATA>::INSIDE_MODEL )
00713                     {b[4] = true;} else {b[4] = false;}
00714                     if (    vertexFlag[x+1][y][z+1] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00715                         ||  vertexFlag[x+1][y][z+1] == GridGenerator<T,DATA>::ON_BOUNDARY
00716                         ||  vertexFlag[x+1][y][z+1] == GridGenerator<T,DATA>::RIGHT_INSIDE_BOUNDARY
00717                         ||  vertexFlag[x+1][y][z+1] == GridGenerator<T,DATA>::INSIDE_MODEL )
00718                     {b[5] = true;} else {b[5] = false;}
00719                     if (    vertexFlag[x+1][y+1][z+1] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00720                         ||  vertexFlag[x+1][y+1][z+1] == GridGenerator<T,DATA>::ON_BOUNDARY
00721                         ||  vertexFlag[x+1][y+1][z+1] == GridGenerator<T,DATA>::RIGHT_INSIDE_BOUNDARY
00722                         ||  vertexFlag[x+1][y+1][z+1] == GridGenerator<T,DATA>::INSIDE_MODEL )
00723                     {b[6] = true;} else {b[6] = false;}
00724                     if (    vertexFlag[x][y+1][z+1] == GridGenerator<T,DATA>::RIGHT_OUTSIDE_BOUNDARY
00725                         ||  vertexFlag[x][y+1][z+1] == GridGenerator<T,DATA>::ON_BOUNDARY
00726                         ||  vertexFlag[x][y+1][z+1] == GridGenerator<T,DATA>::RIGHT_INSIDE_BOUNDARY
00727                         ||  vertexFlag[x][y+1][z+1] == GridGenerator<T,DATA>::INSIDE_MODEL )
00728                     {b[7] = true;} else {b[7] = false;}
00729 
00730                     // Six tetrahedra subdivided from a brick
00731                     // 0-2-3-6 --> #0
00732                     // 0-3-7-6 --> #1
00733                     // 0-7-4-6 --> #2
00734                     // 0-5-6-4 --> #3
00735                     // 1-5-6-0 --> #4
00736                     // 1-6-2-0 --> #5
00737                     if ( b[0] && b[2] && b[3] && b[6] ) pValidElements[z][y][x][0] = true;
00738                     if ( b[0] && b[3] && b[7] && b[6] ) pValidElements[z][y][x][1] = true;
00739                     if ( b[0] && b[7] && b[4] && b[6] ) pValidElements[z][y][x][2] = true;
00740                     if ( b[0] && b[5] && b[6] && b[4] ) pValidElements[z][y][x][3] = true;
00741                     if ( b[1] && b[5] && b[6] && b[0] ) pValidElements[z][y][x][4] = true;
00742                     if ( b[1] && b[6] && b[2] && b[0] ) pValidElements[z][y][x][5] = true;
00743                 }
00744             }
00745         }
00746     }
00747 
00748     // Z goes first follows by Y then X.
00749     // So the slice is in Z-plane with Y as rows and X as columns
00750     T **** const GridVertices = rGridGen.ReturnPtrToVertexPositionData();
00751     unsigned int C = rGridGen.GetGridSizeX();
00752     unsigned int R = rGridGen.GetGridSizeY();
00753     unsigned int D = rGridGen.GetGridSizeZ();
00754     unsigned int RC  = R*C;
00755     unsigned int DRC = D*RC;
00756     unsigned int SLICE = 0;
00757     unsigned int ROW;
00758 
00759     // Temp data for finding valid FEM mesh vertices
00760     unsigned int *** pVertexLocs = new unsigned int**[D];
00761     for ( unsigned int k = 0; k < D; ++k ) {
00762         pVertexLocs[k] = new unsigned int*[R];
00763         for ( unsigned int j = 0; j < R; ++j ) {
00764             pVertexLocs[k][j] = new unsigned int[C];
00765             for ( unsigned int i = 0; i < C; ++i ) {
00766                 pVertexLocs[k][j][i] = DRC;
00767             }
00768         }
00769     }
00770 
00771     // Temp data for storing element ID
00772     std::vector< unsigned int > elementIDs( gridsize[2]*gridsize[1]*gridsize[0]*6 );
00773 
00774     // Find valid FEM mesh vertices
00775     // Six tetrahedra subdivided from a brick
00776     // 0-2-3-6
00777     // 0-3-7-6
00778     // 0-7-4-6
00779     // 0-5-6-4
00780     // 1-5-6-0
00781     // 1-6-2-0
00782     //                 @---------@      ^ y
00783     //                /|        /|      |
00784     //               / | SLICE /A|      |
00785     //              3---------2  |      |
00786     //             /|  @- - -/| -@      +------>x
00787     //            / | SLICE /B| /      /
00788     //           7---------6  |/      /
00789     //           |  0------|--1      v z
00790     //           | /SLICE C| /
00791     //           |/        |/
00792     //           4---------5
00793     unsigned int countV = 0;
00794     for ( unsigned int k = 0; k < gridsize[2]; ++k ) {
00795         for ( unsigned int j = 0; j < gridsize[1]; ++j ) {
00796             for ( unsigned int i = 0; i < gridsize[0]; ++i ) {
00797 
00798                 //std::cout << "k,j,i: " << k << "," << j << "," << i << "\n";
00799                 //std::cout << pValidElements[k][j][i][0]
00800                 //      << " " <<   pValidElements[k][j][i][1]
00801                 //      << " " <<   pValidElements[k][j][i][2]
00802                 //      << " " <<   pValidElements[k][j][i][3]
00803                 //      << " " <<   pValidElements[k][j][i][4]
00804                 //      << " " <<   pValidElements[k][j][i][5] << "\n";
00805 
00806                 // v0
00807                 if ( pVertexLocs[k][j][i] == DRC ) {
00808                     if (    pValidElements[k][j][i][0]
00809                         ||  pValidElements[k][j][i][1]
00810                         ||  pValidElements[k][j][i][2]
00811                         ||  pValidElements[k][j][i][3]
00812                         ||  pValidElements[k][j][i][4]
00813                         ||  pValidElements[k][j][i][5] )
00814                     {
00815                         Vector3<T> V( GridVertices[i][j][k][0], GridVertices[i][j][k][1], GridVertices[i][j][k][2] );
00816                         Nd.push_back( V );
00817                         Nu.push_back( V );
00818                         pVertexLocs[k][j][i] = countV;
00819                         ++countV;
00820                     }
00821                 }
00822                 // v1
00823                 if ( pVertexLocs[k][j][i+1] == DRC ) {
00824                     if (    pValidElements[k][j][i][4]
00825                         ||  pValidElements[k][j][i][5] )
00826                     {
00827                         Vector3<T> V( GridVertices[i+1][j][k][0], GridVertices[i+1][j][k][1], GridVertices[i+1][j][k][2] );
00828                         Nd.push_back( V );
00829                         Nu.push_back( V );
00830                         pVertexLocs[k][j][i+1] = countV;
00831                         ++countV;
00832                     }
00833                 }
00834                 // v2
00835                 if ( pVertexLocs[k][j+1][i+1] == DRC ) {
00836                     if (    pValidElements[k][j][i][0]
00837                         ||  pValidElements[k][j][i][5] )
00838                     {
00839                         Vector3<T> V( GridVertices[i+1][j+1][k][0], GridVertices[i+1][j+1][k][1], GridVertices[i+1][j+1][k][2] );
00840                         Nd.push_back( V );
00841                         Nu.push_back( V );
00842                         pVertexLocs[k][j+1][i+1] = countV;
00843                         ++countV;
00844                     }
00845                 }
00846                 // v3
00847                 if ( pVertexLocs[k][j+1][i] == DRC ) {
00848                     if (    pValidElements[k][j][i][0]
00849                         ||  pValidElements[k][j][i][1] )
00850                     {
00851                         Vector3<T> V( GridVertices[i][j+1][k][0], GridVertices[i][j+1][k][1], GridVertices[i][j+1][k][2] );
00852                         Nd.push_back( V );
00853                         Nu.push_back( V );
00854                         pVertexLocs[k][j+1][i] = countV;
00855                         ++countV;
00856                     }
00857                 }
00858                 // v4
00859                 if ( pVertexLocs[k+1][j][i] == DRC ) {
00860                     if (    pValidElements[k][j][i][2]
00861                         ||  pValidElements[k][j][i][3] )
00862                     {
00863                         Vector3<T> V( GridVertices[i][j][k+1][0], GridVertices[i][j][k+1][1], GridVertices[i][j][k+1][2] );
00864                         Nd.push_back( V );
00865                         Nu.push_back( V );
00866                         pVertexLocs[k+1][j][i] = countV;
00867                         ++countV;
00868                     }
00869                 }
00870                 // v5
00871                 if ( pVertexLocs[k+1][j][i+1] == DRC ) {
00872                     if (    pValidElements[k][j][i][3]
00873                         ||  pValidElements[k][j][i][4] )
00874                     {
00875                         Vector3<T> V( GridVertices[i+1][j][k+1][0], GridVertices[i+1][j][k+1][1], GridVertices[i+1][j][k+1][2] );
00876                         Nd.push_back( V );
00877                         Nu.push_back( V );
00878                         pVertexLocs[k+1][j][i+1] = countV;
00879                         ++countV;
00880                     }
00881                 }
00882                 // v6
00883                 if ( pVertexLocs[k+1][j+1][i+1] == DRC ) {
00884                     if (    pValidElements[k][j][i][0]
00885                         ||  pValidElements[k][j][i][1]
00886                         ||  pValidElements[k][j][i][2]
00887                         ||  pValidElements[k][j][i][3]
00888                         ||  pValidElements[k][j][i][4]
00889                         ||  pValidElements[k][j][i][5] )
00890                     {
00891                         Vector3<T> V( GridVertices[i+1][j+1][k+1][0], GridVertices[i+1][j+1][k+1][1], GridVertices[i+1][j+1][k+1][2] );
00892                         Nd.push_back( V );
00893                         Nu.push_back( V );
00894                         pVertexLocs[k+1][j+1][i+1] = countV;
00895                         ++countV;
00896                     }
00897                 }
00898                 // v7
00899                 if ( pVertexLocs[k+1][j+1][i] == DRC ) {
00900                     if (    pValidElements[k][j][i][1]
00901                         ||  pValidElements[k][j][i][2] )
00902                     {
00903                         Vector3<T> V( GridVertices[i][j+1][k+1][0], GridVertices[i][j+1][k+1][1], GridVertices[i][j+1][k+1][2] );
00904                         Nd.push_back( V );
00905                         Nu.push_back( V );
00906                         pVertexLocs[k+1][j+1][i] = countV;
00907                         ++countV;
00908                     }
00909                 }
00910             }
00911         }
00912     }
00913 
00914     // Add tetrahedron elements from the valid FEM mesh vertices
00915     unsigned int countE = 0;
00916     for ( unsigned int k = 0; k < D-1; ++k ) {
00917         ROW = 0;
00918         for ( unsigned int j = 0; j < R-1; ++j ) {
00919             for ( unsigned int i = 0; i < C-1; ++i ) {
00920                 unsigned int elementID = (k*gxgy + j*gx + i) * 6;
00921                 // Pt 1 to 8
00922                 //
00923                 //         3---------2      ^ y
00924                 //        /|        /|      |
00925                 //       / |       / |      |
00926                 //      7---------6  |      |
00927                 //      |  0- - - | -1      +------>x
00928                 //      | /       | /      /
00929                 //      |/        |/      /
00930                 //      4---------5      v z
00931                 // Subdivided into six tetrahedra
00932                 // 0-2-3-6
00933                 if ( pValidElements[k][j][i][0] ) {
00934                     E.push_back( Tetrahedron<T>( 
00935                         &Nd,            // the 4 deformed nodes
00936                         &Nu,            // the 4 undeformed nodes
00937                         YoungsModulus,  // Young's modulus
00938                         PoissonsRatio,  // Poisson's ratio
00939                         pVertexLocs[k][j][i], pVertexLocs[k][j+1][i+1], pVertexLocs[k][j+1][i], pVertexLocs[k+1][j+1][i+1] )
00940                     );
00941                     elementIDs[elementID] = countE++;
00942                 }
00943                 // 0-3-7-6
00944                 if ( pValidElements[k][j][i][1] ) {
00945                     E.push_back( Tetrahedron<T>( 
00946                         &Nd,            // the 4 deformed nodes
00947                         &Nu,            // the 4 undeformed nodes
00948                         YoungsModulus,  // Young's modulus
00949                         PoissonsRatio,  // Poisson's ratio
00950                         pVertexLocs[k][j][i], pVertexLocs[k][j+1][i], pVertexLocs[k+1][j+1][i], pVertexLocs[k+1][j+1][i+1] )
00951                     );
00952                     elementIDs[elementID+1] = countE++;
00953                 }
00954                 // 0-7-4-6
00955                 if ( pValidElements[k][j][i][2] ) {
00956                     E.push_back( Tetrahedron<T>( 
00957                         &Nd,            // the 4 deformed nodes
00958                         &Nu,            // the 4 undeformed nodes
00959                         YoungsModulus,  // Young's modulus
00960                         PoissonsRatio,  // Poisson's ratio
00961                         pVertexLocs[k][j][i], pVertexLocs[k+1][j+1][i], pVertexLocs[k+1][j][i], pVertexLocs[k+1][j+1][i+1] )
00962                     );
00963                     elementIDs[elementID+2] = countE++;
00964                 }
00965                 // 0-5-6-4
00966                 if ( pValidElements[k][j][i][3] ) {
00967                     E.push_back( Tetrahedron<T>( 
00968                         &Nd,            // the 4 deformed nodes
00969                         &Nu,            // the 4 undeformed nodes
00970                         YoungsModulus,  // Young's modulus
00971                         PoissonsRatio,  // Poisson's ratio
00972                         pVertexLocs[k][j][i], pVertexLocs[k+1][j][i+1], pVertexLocs[k+1][j+1][i+1], pVertexLocs[k+1][j][i] )
00973                     );
00974                     elementIDs[elementID+3] = countE++;
00975                 }
00976                 // 1-5-6-0
00977                 if ( pValidElements[k][j][i][4] ) {
00978                     E.push_back( Tetrahedron<T>( 
00979                         &Nd,            // the 4 deformed nodes
00980                         &Nu,            // the 4 undeformed nodes
00981                         YoungsModulus,  // Young's modulus
00982                         PoissonsRatio,  // Poisson's ratio
00983                         pVertexLocs[k][j][i+1], pVertexLocs[k+1][j][i+1], pVertexLocs[k+1][j+1][i+1], pVertexLocs[k][j][i] )
00984                     );
00985                     elementIDs[elementID+4] = countE++;
00986                 }
00987                 // 1-6-2-0
00988                 if ( pValidElements[k][j][i][5] ) {
00989                     E.push_back( Tetrahedron<T>( 
00990                         &Nd,            // the 4 deformed nodes
00991                         &Nu,            // the 4 undeformed nodes
00992                         YoungsModulus,  // Young's modulus
00993                         PoissonsRatio,  // Poisson's ratio
00994                         pVertexLocs[k][j][i+1], pVertexLocs[k+1][j+1][i+1], pVertexLocs[k][j+1][i+1], pVertexLocs[k][j][i] )
00995                     );
00996                     elementIDs[elementID+5] = countE++;
00997                 }
00998             }
00999             ROW += C;
01000         }
01001         SLICE += RC;
01002     }
01003 
01004     // Associated barycentric coordinates with tetrahedra
01005     // MUST BE DONE AFTER ALL TETRAHEDRAL ELEMENTS ARE GENERATED!
01006     // OTHERWISE THE POINTERS WILL NOT BE VALID DUE TO
01007     // THE AUTOMATICAL RESIZING OF STD::VECTOR!
01008     for ( unsigned int i = 0; i < rBaryCoords.size(); ++i ) {
01009         rBaryCoords[i].SetElementID( elementIDs[ rBaryCoords[i].GetElementID() ] );
01010         //r_ElementID[i] = elementIDs[ r_ElementID[i] ];
01011         //rBaryCoords[i].SetPtrToTetrahedron( &(E[ r_ElementID[i] ]) );
01012         rBaryCoords[i].SetPtrToTetrahedron( &(E[ rBaryCoords[i].GetElementID() ]) );
01013     }
01014 
01015     // Delete temp data
01016     for ( unsigned int k = 0; k < gridsize[2]; ++k ) {
01017         for ( unsigned int j = 0; j < gridsize[1]; ++j ) {
01018             delete [] pVertexLocs[k][j];
01019         }
01020         delete [] pVertexLocs[k];
01021     }
01022     delete [] pVertexLocs;
01023 
01024     // Delete temp data
01025     for ( unsigned int k = 0; k < gridsize[2]; ++k ) {
01026         for ( unsigned int j = 0; j < gridsize[1]; ++j ) {
01027             for ( unsigned int i = 0; i < gridsize[0]; ++i ) {
01028                 delete [] pValidElements[k][j][i];
01029             }
01030             delete [] pValidElements[k][j];
01031         }
01032         delete [] pValidElements[k];
01033     }
01034     delete [] pValidElements;
01035 
01036     // Assemble the stiffness matrix
01037     rTetFemMesh.SetSizeOfStiffnessMatrix();
01038     rTetFemMesh.AssembleStiffnessMatrix();
01039 
01040     // Allocate data for simulation
01041     rTetFemMesh.AllocateDataForSimulation( mass );
01042 
01043     // DEBUG
01044     std::cout << "Generated Tetrahedral FEM mesh has " << rTetFemMesh.GetNumOfNodes() 
01045         << " nodes and " << rTetFemMesh.GetNumOfElements() << " elements.\n";
01046     std::cout << std::flush;
01047 
01048     return true;
01049 }
01050 
01051 
01052 //-----------------------------------------------------------------------------
01053 template <typename T, typename DATA>
01054 void MeshTetrahedraGen<T,DATA>::FindAllBaryCoordsAndTheirLocInTheGrids (
01055         std::vector< TetBarycentricCoordsForVertexRef<T> > & rBaryCoords, 
01056         //std::vector< unsigned int > & r_ElementID,    //!< identify the element that the barycentric coordinates are embedded in
01057         GridGenerator<T,DATA> & rGridGen,   
01058         bool **** pValidElements    
01059 )
01060 {
01061     // FOR HALFEDGE MESH MODEL ONLY
01062     TAPs::OpenGL::HalfEdgeModel<T> * pHEModel = dynamic_cast< TAPs::OpenGL::HalfEdgeModel<T> * >( rGridGen.GetModelUseToGenGrid() );
01063     if ( pHEModel == NULL ) {
01064         std::cout << "MeshTetrahedraGen<...> --> MeshModel is not HalfEdge!" << std::endl;
01065         exit(-1);
01066     }
01067     rBaryCoords.clear();
01068     //std::cout << "#vertices: " << pHEModel->GetNoVertices() << "\n";
01069     //std::cout << "#vertices: " << pHEModel->GetNumVertices() << "\n";
01070     //std::cout << "#vertices: " << pHEModel->GetVertexList()->Size() << "\n";
01071     HEVertex<T> * pVertex = pHEModel->GetVertexList()->Head();
01072     unsigned int i,j,k;
01073     //T u,v,w;
01074     //T sx = 1.0 / (m_atGridDimension[0]*m_atGridDimension[0]);
01075     //T sy = 1.0 / (m_atGridDimension[1]*m_atGridDimension[1]);
01076     //T sz = 1.0 / (m_atGridDimension[2]*m_atGridDimension[2]);
01077     unsigned int gx = rGridGen.GetGridSizeX()-1;    // width
01078     unsigned int gy = rGridGen.GetGridSizeY()-1;    // height
01079     unsigned int gz = rGridGen.GetGridSizeZ()-1;    // depth
01080     unsigned int gxgy = gx*gy;
01081     unsigned int numOfElements = gx*gy*gz*6;
01082 
01083     // checkedElements for marking that the computed inverted matrices of 6 tetrahedra forming a brick
01084     // has been computed and stored in storedMatrices
01085     // so that the computations do not have to be repeated.
01086     std::vector< unsigned int > checkedElements( numOfElements );
01087     unsigned int locateMatrices = 0;
01088     std::vector< Matrix3x3<T> > storedMatrices;
01089     for ( unsigned int i = 0; i < numOfElements; ++i ) {
01090         checkedElements[i] = numOfElements;
01091     }
01092 
01093     unsigned int count = 0;
01094     T **** VP = rGridGen.ReturnPtrToVertexPositionData();
01095     while ( pVertex != NULL ) {
01096 
01097         Vector3<T> P = pVertex->GetPosition();
01098         rGridGen.LocateHexGrid( P[0], P[1], P[2], i, j, k );
01099 
01100         Vector3<T> v0( VP[i  ][j  ][k  ][0], VP[i  ][j  ][k  ][1], VP[i  ][j  ][k  ][2] );
01101         Vector3<T> v1( VP[i+1][j  ][k  ][0], VP[i+1][j  ][k  ][1], VP[i+1][j  ][k  ][2] );
01102         Vector3<T> v2( VP[i+1][j+1][k  ][0], VP[i+1][j+1][k  ][1], VP[i+1][j+1][k  ][2] );
01103         Vector3<T> v3( VP[i  ][j+1][k  ][0], VP[i  ][j+1][k  ][1], VP[i  ][j+1][k  ][2] );
01104         Vector3<T> v4( VP[i  ][j  ][k+1][0], VP[i  ][j  ][k+1][1], VP[i  ][j  ][k+1][2] );
01105         Vector3<T> v5( VP[i+1][j  ][k+1][0], VP[i+1][j  ][k+1][1], VP[i+1][j  ][k+1][2] );
01106         Vector3<T> v6( VP[i+1][j+1][k+1][0], VP[i+1][j+1][k+1][1], VP[i+1][j+1][k+1][2] );
01107         Vector3<T> v7( VP[i  ][j+1][k+1][0], VP[i  ][j+1][k+1][1], VP[i  ][j+1][k+1][2] );
01108 
01109         // Test against six tetrahedra
01110         // 0-2-3-6
01111         // 0-3-7-6
01112         // 0-7-4-6
01113         // 0-5-6-4
01114         // 1-5-6-0
01115         // 1-6-2-0
01116 
01117         // Computed the inverted matrices of 6 tetrahedra
01118         unsigned int enumber = i + j*gx + k*gxgy;
01119         if ( checkedElements[enumber] == numOfElements ) {
01120             checkedElements[enumber] = locateMatrices++;
01121             // 0-2-3-6
01122             storedMatrices.push_back( Matrix3x3<T>( 
01123                 v2[0]-v0[0], v3[0]-v0[0], v6[0]-v0[0], 
01124                 v2[1]-v0[1], v3[1]-v0[1], v6[1]-v0[1], 
01125                 v2[2]-v0[2], v3[2]-v0[2], v6[2]-v0[2]
01126             ).Inversed() );
01127             // 0-3-7-6
01128             storedMatrices.push_back( Matrix3x3<T>( 
01129                 v3[0]-v0[0], v7[0]-v0[0], v6[0]-v0[0], 
01130                 v3[1]-v0[1], v7[1]-v0[1], v6[1]-v0[1], 
01131                 v3[2]-v0[2], v7[2]-v0[2], v6[2]-v0[2]
01132             ).Inversed() );
01133             // 0-7-4-6
01134             storedMatrices.push_back( Matrix3x3<T>( 
01135                 v7[0]-v0[0], v4[0]-v0[0], v6[0]-v0[0], 
01136                 v7[1]-v0[1], v4[1]-v0[1], v6[1]-v0[1], 
01137                 v7[2]-v0[2], v4[2]-v0[2], v6[2]-v0[2]
01138             ).Inversed() );
01139             // 0-5-6-4
01140             storedMatrices.push_back( Matrix3x3<T>( 
01141                 v5[0]-v0[0], v6[0]-v0[0], v4[0]-v0[0], 
01142                 v5[1]-v0[1], v6[1]-v0[1], v4[1]-v0[1], 
01143                 v5[2]-v0[2], v6[2]-v0[2], v4[2]-v0[2]
01144             ).Inversed() );
01145             // 1-5-6-0
01146             storedMatrices.push_back( Matrix3x3<T>( 
01147                 v5[0]-v1[0], v6[0]-v1[0], v0[0]-v1[0], 
01148                 v5[1]-v1[1], v6[1]-v1[1], v0[1]-v1[1], 
01149                 v5[2]-v1[2], v6[2]-v1[2], v0[2]-v1[2]
01150             ).Inversed() );
01151             // 1-6-2-0
01152             storedMatrices.push_back( Matrix3x3<T>( 
01153                 v6[0]-v1[0], v2[0]-v1[0], v0[0]-v1[0], 
01154                 v6[1]-v1[1], v2[1]-v1[1], v0[1]-v1[1], 
01155                 v6[2]-v1[2], v2[2]-v1[2], v0[2]-v1[2]
01156             ).Inversed() );
01157         }
01158 
01159         bool notFound = true;
01160         unsigned int elementID = enumber * 6;
01161         unsigned int matID = checkedElements[enumber] * 6;
01162 
01163         // 0-2-3-6
01164         if ( notFound ) {
01165             Vector3<T> baryCoords = storedMatrices[matID] * (P-v0);
01166             if (
01167                 0 <= baryCoords[0] && baryCoords[0] <= 1
01168             &&  0 <= baryCoords[1] && baryCoords[1] <= 1
01169             &&  0 <= baryCoords[2] && baryCoords[2] <= 1 )
01170             {
01171                 notFound = false;
01172                 rBaryCoords.push_back( 
01173                     TetBarycentricCoordsForVertexRef<T>( 
01174                         pVertex->RefToPosition(),
01175                         NULL,
01176                         baryCoords[0], baryCoords[1], baryCoords[2]
01177                     ) 
01178                 );
01179                 pValidElements[k][j][i][0] = true;
01180                 //r_ElementID.push_back( elementID );
01181                 rBaryCoords[count].SetElementID( elementID );
01182                 ++count;
01183                 //std::cout << "0 baryCoords: " << baryCoords << "\n";
01184             }
01185         }
01186         // 0-3-7-6
01187         if ( notFound ) {
01188             Vector3<T> baryCoords = storedMatrices[++matID] * (P-v0);
01189             if (
01190                 0 <= baryCoords[0] && baryCoords[0] <= 1
01191             &&  0 <= baryCoords[1] && baryCoords[1] <= 1
01192             &&  0 <= baryCoords[2] && baryCoords[2] <= 1 )
01193             {
01194                 notFound = false;
01195                 rBaryCoords.push_back( 
01196                     TetBarycentricCoordsForVertexRef<T>( 
01197                         pVertex->RefToPosition(),
01198                         NULL,
01199                         baryCoords[0], baryCoords[1], baryCoords[2]
01200                     ) 
01201                 );
01202                 pValidElements[k][j][i][1] = true;
01203                 //r_ElementID.push_back( elementID+1 );
01204                 rBaryCoords[count].SetElementID( elementID+1 );
01205                 ++count;
01206                 //std::cout << "1 baryCoords: " << baryCoords << "\n";
01207             }
01208         }
01209         // 0-7-4-6
01210         if ( notFound ) {
01211             Vector3<T> baryCoords = storedMatrices[++matID] * (P-v0);
01212             if (
01213                 0 <= baryCoords[0] && baryCoords[0] <= 1
01214             &&  0 <= baryCoords[1] && baryCoords[1] <= 1
01215             &&  0 <= baryCoords[2] && baryCoords[2] <= 1 )
01216             {
01217                 notFound = false;
01218                 rBaryCoords.push_back( 
01219                     TetBarycentricCoordsForVertexRef<T>( 
01220                         pVertex->RefToPosition(),
01221                         NULL,
01222                         baryCoords[0], baryCoords[1], baryCoords[2]
01223                     ) 
01224                 );
01225                 pValidElements[k][j][i][2] = true;
01226                 //r_ElementID.push_back( elementID+2 );
01227                 rBaryCoords[count].SetElementID( elementID+2 );
01228                 ++count;
01229                 //std::cout << "2 baryCoords: " << baryCoords << "\n";
01230             }
01231         }
01232         // 0-5-6-4
01233         if ( notFound ) {
01234             Vector3<T> baryCoords = storedMatrices[++matID] * (P-v0);
01235             if (
01236                 0 <= baryCoords[0] && baryCoords[0] <= 1
01237             &&  0 <= baryCoords[1] && baryCoords[1] <= 1
01238             &&  0 <= baryCoords[2] && baryCoords[2] <= 1 )
01239             {
01240                 notFound = false;
01241                 rBaryCoords.push_back( 
01242                     TetBarycentricCoordsForVertexRef<T>( 
01243                         pVertex->RefToPosition(),
01244                         NULL,
01245                         baryCoords[0], baryCoords[1], baryCoords[2]
01246                     ) 
01247                 );
01248                 pValidElements[k][j][i][3] = true;
01249                 //r_ElementID.push_back( elementID+3 );
01250                 rBaryCoords[count].SetElementID( elementID+3 );
01251                 ++count;
01252                 //std::cout << "3 baryCoords: " << baryCoords << "\n";
01253             }
01254         }
01255         // 1-5-6-0
01256         if ( notFound ) {
01257             Vector3<T> baryCoords = storedMatrices[++matID] * (P-v1);
01258             if (
01259                 0 <= baryCoords[0] && baryCoords[0] <= 1
01260             &&  0 <= baryCoords[1] && baryCoords[1] <= 1
01261             &&  0 <= baryCoords[2] && baryCoords[2] <= 1 )
01262             {
01263                 notFound = false;
01264                 rBaryCoords.push_back( 
01265                     TetBarycentricCoordsForVertexRef<T>( 
01266                         pVertex->RefToPosition(),
01267                         NULL,
01268                         baryCoords[0], baryCoords[1], baryCoords[2]
01269                     ) 
01270                 );
01271                 pValidElements[k][j][i][4] = true;
01272                 //r_ElementID.push_back( elementID+4 );
01273                 rBaryCoords[count].SetElementID( elementID+4 );
01274                 ++count;
01275                 //std::cout << "4 baryCoords: " << baryCoords << "\n";
01276             }
01277         }
01278         // 1-6-2-0
01279         if ( notFound ) {
01280             Vector3<T> baryCoords = storedMatrices[++matID] * (P-v1);
01281             if (
01282                 0 <= baryCoords[0] && baryCoords[0] <= 1
01283             &&  0 <= baryCoords[1] && baryCoords[1] <= 1
01284             &&  0 <= baryCoords[2] && baryCoords[2] <= 1 )
01285             {
01286                 notFound = false;
01287                 rBaryCoords.push_back( 
01288                     TetBarycentricCoordsForVertexRef<T>( 
01289                         pVertex->RefToPosition(),
01290                         NULL,
01291                         baryCoords[0], baryCoords[1], baryCoords[2]
01292                     ) 
01293                 );
01294                 pValidElements[k][j][i][5] = true;
01295                 //r_ElementID.push_back( elementID+5 );
01296                 rBaryCoords[count].SetElementID( elementID+5 );
01297                 ++count;
01298                 //std::cout << "5 baryCoords: " << baryCoords << "\n";
01299             }
01300         }
01301 
01302         pVertex = pVertex->Next();
01303     }
01304 
01305     // Set the barycentric pointer for each vertex
01306     // MUST BE DONE AFTER ALL BARY COORDS ARE GENERATED!
01307     // OTHERWISE THE POINTERS WILL NOT BE VALID DUE TO
01308     // THE AUTOMATICAL RESIZING OF STD::VECTOR!
01309     count = 0;
01310     pVertex = pHEModel->GetVertexList()->Head();
01311     while ( pVertex != NULL ) {
01312         pVertex->SetBarycentricPtr( &rBaryCoords[count] );
01313         //std::cout << count << "\tTet\t" << pVertex << "\t" << pVertex->GetBarycentricPtr() << "\t" << *(pVertex->GetBarycentricPtr()) << "\n";
01314         pVertex = pVertex->Next();
01315         ++count;
01316     }
01317 
01318     // DEBUG
01319     //std::cout << "Surface mesh with Tetrahedral FEM mesh - #surface mesh vertices: " << pHEModel->GetNumVertices() << "\n";
01320     //std::cout << "Surface mesh with Tetrahedral FEM mesh - #barycoords (must equal to # surface mesh vertices): " << count << "\n";
01321     //std::cout << "#ElementIDs: " << r_ElementID.size() << "\n";
01322     //for ( unsigned int i = 0; i < r_ElementID.size(); ++i ) {
01323     //  std::cout << "ElementID["<<i<<"]: " << r_ElementID[i] << "\n";
01324     //}
01325     //std::cout << "#BaryCoords: " << rBaryCoords.size() << "\n";
01326     //for ( unsigned int i = 0; i < rBaryCoords.size(); ++i ) {
01327     //  std::cout << "rBaryCoords["<<i<<"]: " << rBaryCoords[i] << "\n";
01328     //}
01329 }
01330 
01331 //=============================================================================
01332 END_NAMESPACE_TAPs__FEM
01333 //34567890123456789012345678901234567890123456789012345678901234567890123456789
01334 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines