TAPs 0.7.7.3
TAPsFEMMesh_withSparseSymmetricMatrix.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 SUKITTI PUNAK   (04/05/2010)
00003 UPDATE          (05/01/2010)
00004 ******************************************************************************/
00005 
00006 BEGIN_NAMESPACE_TAPs__FEM
00007 //=============================================================================
00008 // Simulation
00009 //-----------------------------------------------------------------------------
00010 template <typename T>
00011 void Mesh<T>::AdvanceSimulationStatic ()
00012 {
00013     // Without the update statement below, m_u is always zero.
00014     // m_u is used as an initial estimation for displacements.
00015     // m_u will not be modified (or affected) by the call of MPCGSolver function below.
00016     //UpdateDisplacementVector();
00017 
00018     Mstiff.MPCGSolver( Mstiff, m_u, m_Forces, m_u_out, m_Filters, m_Precond, m_iIterationLimit, m_tErrorThreshold );
00019     UpdateDeformedMeshNodes();
00020 }
00021 
00022 //-----------------------------------------------------------------------------
00023 #ifdef  TAPs_SIM_DYNAMIC_SYSTEM
00024 //-------------------------------------
00025 template <typename T>
00026 void Mesh<T>::AdvanceSimulationDynamic ()
00027 {
00028     UpdateDisplacementVector();
00029     UpdateAandB ( Mstiff );
00030 
00031     // Copy current velocities to m_u
00032     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00033         m_u[i] = m_vNodeVelocities[m_currVelIdx][i];
00034     }
00035 
00036     Mstiff.MPCGSolver( m_A, m_u, m_b, m_vNodeVelocities[m_nextVelIdx], m_Filters, m_Precond, m_iIterationLimit, m_tErrorThreshold );
00037 
00038     // Update new positions
00039     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00040         m_vDeformedMeshNodes[i][0] += m_vNodeVelocities[m_nextVelIdx][i][0]*m_tTimeStep*m_Filters[i][0];
00041         m_vDeformedMeshNodes[i][1] += m_vNodeVelocities[m_nextVelIdx][i][1]*m_tTimeStep*m_Filters[i][1];
00042         m_vDeformedMeshNodes[i][2] += m_vNodeVelocities[m_nextVelIdx][i][2]*m_tTimeStep*m_Filters[i][2];
00043     }
00044 
00045     // Swap indices for velocities
00046     unsigned char tmp = m_nextVelIdx;
00047     m_nextVelIdx = m_currVelIdx;
00048     m_currVelIdx = tmp;
00049 }
00050 //-------------------------------------
00051 #endif//TAPs_SIM_DYNAMIC_SYSTEM
00052 //-----------------------------------------------------------------------------
00053 
00054 
00055 
00056 template <typename T>
00057 void Mesh<T>::AdvanceSimulationStatic_wFixedDisplacementNodes ()
00058 {
00059     // Modify stiffness matrix for calculating forces generated by fixed displacement nodes
00060     // The rows associated with fixed nodes will be diagonalized to one.
00061     Mstiff_2 = Mstiff;
00062     // Set m_u for calculating forces generated by fixed displacement nodes
00063     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00064         if ( m_FixedNodes[i] ) {
00065             //Mstiff_2.DiagonalizeRow( i, 1 );  // diagonalize the row i (due to node i is fixed)
00066             m_u[i] = m_FixedDisplacements[i];   // adjust the displacement caused by the displacement of node i
00067         }
00068         else {
00069             m_u[i].Clear(); // the displacement for unfixed node is set to zero
00070         }
00071         m_b[i].Clear(); // clear m_b
00072     }
00073     // Calculating forces generated by fixed displacement nodes
00074     // The statements below is similar to MOD(Mstiff_2) * m_u = m_b 
00075     // where MOD(Mstiff2) diagonalizes rows of Mstiff2 (associated with fixed nodes) to 1.
00076     // REMARK: MOD(Mstiff2) is on longer a symmetric matrix.
00077     std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator it;
00078     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00079         if ( m_FixedNodes[i] ) {
00080             // skip fixed nodes
00081         }
00082         else {
00083             unsigned int r = 0;
00084             // row 0 to row (i-1)
00085             for ( r = 0; r < i; ++r ) {
00086                 it = Mstiff_2.DirectAccess(r)->RefToElements().begin();
00087                 // find symmetric element to row i
00088                 while ( it != Mstiff_2.DirectAccess(r)->RefToElements().end() && it->idx < i ) {
00089                     ++it;
00090                 }
00091                 if ( it != Mstiff_2.DirectAccess(r)->RefToElements().end() && it->idx == i ) {
00092                     m_b[i] += it->M * m_u[i];
00093                 }
00094             }
00095             // row i
00096             it = Mstiff_2.DirectAccess(r)->RefToElements().begin();
00097             while ( it != Mstiff_2.DirectAccess(r)->RefToElements().end() ) {
00098                 m_b[i] += it->M * m_u[it->idx];
00099                 ++it;
00100             }
00101         }
00102     }
00103     // Set force vector 
00104     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00105         if ( m_FixedNodes[i] == false ) {
00106             m_b[i] *= -1;
00107             m_b[i] += m_Forces[i];
00108         }
00109         else {
00110             m_b[i] = m_FixedDisplacements[i];
00111         }
00112         //std::cout << "FFFS m_b["<<i<<"]: " << m_b[i] << "\n";
00113     }
00114 
00115 
00116     // Modify stiffness matrix for before solving the system of equations
00117     // Diagonalize the rows and columns of fixed nodes to one
00118     Mstiff_2.DiagonalizeRowsCols( m_FixedNodes, 1 );
00119 
00120     //std::cout << Mstiff_2 << "TESTMMM\n";
00121 
00122     //Mstiff_2.MPCGSolverSpecificForFEM( m_FixedNodes, Mstiff_2, m_u, m_b, m_u_out, m_Filters, m_Precond, m_iIterationLimit, m_tErrorThreshold );
00123     Mstiff_2.MPCGSolver( Mstiff_2, m_u, m_b, m_u_out, m_Filters, m_Precond, m_iIterationLimit, m_tErrorThreshold );
00124     UpdateDeformedMeshNodes();
00125     //*/
00126 }
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 //-----------------------------------------------------------------------------
00138 #ifdef  TAPs_SIM_DYNAMIC_SYSTEM
00139 //-------------------------------------
00140 
00141 template <typename T>
00142 void Mesh<T>::AdvanceSimulationDynamic_wFixedDisplacementNodes ()
00143 {
00144 
00145     /*
00146     // TEST
00147     SparseMatrix_Matrix3x3<T> K;
00148     K = Mstiff;
00149     std::cout << Mstiff << "AAA\n";
00150     std::cout << K << "BBB\n";
00151     //*/
00152 
00153     // Modify stiffness matrix for calculating forces generated by fixed displacement nodes
00154     // The rows associated with fixed nodes will be diagonalized to one.
00155     Mstiff_2 = Mstiff;
00156     // Set m_u for calculating forces generated by fixed displacement nodes
00157     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00158         if ( m_FixedNodes[i] ) {
00159             //Mstiff_2.DiagonalizeRow( i, 1 );  // diagonalize the row i (due to node i is fixed)
00160             m_u[i] = m_FixedDisplacements[i];   // adjust the displacement caused by the displacement of node i
00161         }
00162         else {
00163             m_u[i].Clear(); // the displacement for unfixed node is set to zero
00164         }
00165         m_b[i].Clear(); // clear m_b
00166     }
00167     // Calculating forces generated by fixed displacement nodes
00168     // The statements below is similar to MOD(Mstiff_2) * m_u = m_b 
00169     // where MOD(Mstiff2) diagonalizes rows of Mstiff2 (associated with fixed nodes) to 1.
00170     // REMARK: MOD(Mstiff2) is on longer a symmetric matrix.
00171     std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator it;
00172     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00173         if ( m_FixedNodes[i] ) {
00174             // skip fixed nodes
00175         }
00176         else {
00177             unsigned int r = 0;
00178             // row 0 to row (i-1)
00179             for ( r = 0; r < i; ++r ) {
00180                 it = Mstiff_2.DirectAccess(r)->RefToElements().begin();
00181                 // find symmetric element to row i
00182                 while ( it != Mstiff_2.DirectAccess(r)->RefToElements().end() && it->idx < i ) {
00183                     ++it;
00184                 }
00185                 if ( it != Mstiff_2.DirectAccess(r)->RefToElements().end() && it->idx == i ) {
00186                     m_b[i] += it->M * m_u[i];
00187                 }
00188             }
00189             // row i
00190             it = Mstiff_2.DirectAccess(r)->RefToElements().begin();
00191             while ( it != Mstiff_2.DirectAccess(r)->RefToElements().end() ) {
00192                 m_b[i] += it->M * m_u[it->idx];
00193                 ++it;
00194             }
00195         }
00196     }
00197     // Set force vector 
00198     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00199         if ( m_FixedNodes[i] == false ) {
00200             m_b[i] *= -1;
00201             m_b[i] += m_Forces[i];
00202         }
00203         else {
00204             m_b[i] = m_FixedDisplacements[i];
00205         }
00206         //std::cout << "FFFS m_b["<<i<<"]: " << m_b[i] << "\n";
00207     }
00208 
00209     UpdateDisplacementVector_wFixedDisplacementNodes();
00210     UpdateAandB_wFixedDisplacementNodes( Mstiff_2 );
00211 
00212     // Modify stiffness matrix for before solving the system of equations
00213     // Diagonalize the rows and columns of fixed nodes to one
00214     Mstiff_2.DiagonalizeRowsCols( m_FixedNodes, 1 );
00215 
00216     // Copy current velocities to m_u
00217     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00218         if ( m_FixedNodes[i] == false ) {
00219             m_u[i] = m_vNodeVelocities[m_currVelIdx][i];
00220         }
00221         //else {
00222         //  m_vNodeVelocities[m_currVelIdx][i].Clear();
00223         //}
00224     }
00225 
00226     Mstiff_2.MPCGSolver( m_A, m_u, m_b, m_vNodeVelocities[m_nextVelIdx], m_Filters, m_Precond, m_iIterationLimit, m_tErrorThreshold );
00227 
00228     // Update new positions
00229     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00230 
00231         //std::cout << "m_vNodeVelocities[m_currVelIdx]["<<i<<"]: " << m_vNodeVelocities[m_currVelIdx][i] << "\n";
00232         //std::cout << "m_vNodeVelocities[m_nextVelIdx]["<<i<<"]: " << m_vNodeVelocities[m_nextVelIdx][i] << "\n";
00233         //std::cout << "m_tTimeStep: " << m_tTimeStep << "\n";
00234         //std::cout << "m_vDeformedMeshNodes[i]: (bef) " << m_vDeformedMeshNodes[i] << "\n";
00235 
00236         if ( m_FixedNodes[i] == false ) {
00237             m_vDeformedMeshNodes[i][0] += m_vNodeVelocities[m_nextVelIdx][i][0]*m_tTimeStep*m_Filters[i][0];
00238             m_vDeformedMeshNodes[i][1] += m_vNodeVelocities[m_nextVelIdx][i][1]*m_tTimeStep*m_Filters[i][1];
00239             m_vDeformedMeshNodes[i][2] += m_vNodeVelocities[m_nextVelIdx][i][2]*m_tTimeStep*m_Filters[i][2];
00240         }
00241         else {
00242             m_vDeformedMeshNodes[i] = m_u[i] + m_vUndeformedMeshNodes[i];
00243         }
00244 
00245         //std::cout << "m_vDeformedMeshNodes[i]: (aft) DF " << m_vDeformedMeshNodes[i] << "\n";
00246         //std::cout << i << " (aft) DF " << m_vDeformedMeshNodes[i] - m_vUndeformedMeshNodes[i] << "\n";
00247     }
00248 
00249     //UpdateDeformedMeshNodes();
00250 
00251     // Swap indices for velocities
00252     unsigned char tmp = m_nextVelIdx;
00253     m_nextVelIdx = m_currVelIdx;
00254     m_currVelIdx = tmp;
00255 
00256     //std::cout << "END: AdvanceSimulationDynamic\n\n";
00257     //*/
00258 }
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 //-------------------------------------
00272 template <typename T>
00273 void Mesh<T>::UpdateAandB ( SparseSymmetricMatrix_Matrix3x3<T> & Mstiff )
00274 {
00275     SparseVector_Matrix3x3<T> * K;
00276     SparseVector_Matrix3x3<T> * R;
00277     Matrix3x3<T> * diagR;
00278     std::list< SparseVector_Matrix3x3_ElementData<T> >::const_iterator itK;
00279     std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator itR;
00280 
00281     // since C = alpha*M + beta*K
00282     // and A := M + h*C + h*h*K 
00283     //        = M + h*alpha*M + h*beta*K + h*h*K
00284     //        = (1 + h*alpha)*M + h*(beta + h)*K
00285     T scaleB = (m_tNodeDamping_Beta + m_tTimeStep) * m_tTimeStep;
00286     T scaleA = 1 + m_tTimeStep*m_tNodeDamping_Alpha;
00287     // therefore, R  = h*(beta+h) * K  = K * scaleB
00288     //            R += (1+h*alpha) * M = M * scaleA
00289     for ( unsigned int i = 0; i < Mstiff.GetNumOfRows(); ++i ) {
00290         K = Mstiff.DirectAccess( i );
00291         R = m_A.DirectAccess( i );
00292         itK = K->RefToElements().begin();
00293         itR = R->RefToElements().begin();
00294 
00295         while ( itK != K->RefToElements().end() ) {
00296             // R  = K * scaleB
00297             itR->M = itK->M * scaleB;
00298             ++itK;
00299             ++itR;
00300         }
00301 
00302         // R += M * scaleA
00303         diagR= R->ReturnMatrix3x3( i );
00304         (*diagR)[0] += m_vNodeMass[i][0] * scaleA;
00305         (*diagR)[4] += m_vNodeMass[i][1] * scaleA;
00306         (*diagR)[8] += m_vNodeMass[i][2] * scaleA;
00307     }
00308 
00309     // b := M*v_curr - h*( K*(x_def - x_orig) - f )
00310     // after UpdateDisplacementVector(), m_u = x_def - x_orig
00311     // therefore, m_b  = K*m_u
00312     //            m_b -= f
00313     //            m_b *= -h
00314     //            m_b += M*v_curr
00315     Mstiff.MulWith( m_u, m_b );
00316     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00317         m_b[i] -= m_Forces[i];
00318         m_b[i] *= -m_tTimeStep;
00319         m_b[i][0] += m_vNodeMass[i][0] * m_vNodeVelocities[m_currVelIdx][i][0];
00320         m_b[i][1] += m_vNodeMass[i][1] * m_vNodeVelocities[m_currVelIdx][i][1];
00321         m_b[i][2] += m_vNodeMass[i][2] * m_vNodeVelocities[m_currVelIdx][i][2];
00322     }
00323 }
00324 
00325 //-------------------------------------
00326 template <typename T>
00327 void Mesh<T>::UpdateAandB_wFixedDisplacementNodes ( SparseSymmetricMatrix_Matrix3x3<T> & Mstiff )
00328 {
00329     SparseVector_Matrix3x3<T> * K;
00330     SparseVector_Matrix3x3<T> * R;
00331     Matrix3x3<T> * diagR;
00332     std::list< SparseVector_Matrix3x3_ElementData<T> >::const_iterator itK;
00333     std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator itR;
00334 
00335     // since C = alpha*M + beta*K
00336     // and A := M + h*C + h*h*K 
00337     //        = M + h*alpha*M + h*beta*K + h*h*K
00338     //        = (1 + h*alpha)*M + h*(beta + h)*K
00339     T scaleB = (m_tNodeDamping_Beta + m_tTimeStep) * m_tTimeStep;
00340     T scaleA = 1 + m_tTimeStep*m_tNodeDamping_Alpha;
00341     // therefore, R  = h*(beta+h) * K  = K * scaleB
00342     //            R += (1+h*alpha) * M = M * scaleA
00343     for ( unsigned int i = 0; i < Mstiff.GetNumOfRows(); ++i ) {
00344         K = Mstiff.DirectAccess( i );
00345         R = m_A.DirectAccess( i );
00346         itK = K->RefToElements().begin();
00347         itR = R->RefToElements().begin();
00348 
00349         while ( itK != K->RefToElements().end() ) {
00350             // R  = K * scaleB
00351             itR->M = itK->M * scaleB;
00352             ++itK;
00353             ++itR;
00354         }
00355 
00356         // R += M * scaleA
00357         diagR= R->ReturnMatrix3x3( i );
00358         (*diagR)[0] += m_vNodeMass[i][0] * scaleA;
00359         (*diagR)[4] += m_vNodeMass[i][1] * scaleA;
00360         (*diagR)[8] += m_vNodeMass[i][2] * scaleA;
00361     }
00362 
00363     // b := M*v_curr - h*( K*(x_def - x_orig) - f )
00364     // after UpdateDisplacementVector_wFixedDisplacementNodes(), m_u = x_def - x_orig
00365     // therefore, m_b  = K*m_u
00366     //            m_b -= f
00367     //            m_b *= -h
00368     //            m_b += M*v_curr
00369     Mstiff.MulWith( m_u, m_b );
00370     for ( unsigned int i = 0; i < GetNumOfNodes(); ++i ) {
00371         if ( m_FixedNodes[i] == false ) {
00372             m_b[i] -= m_Forces[i];
00373             m_b[i] *= -m_tTimeStep;
00374             m_b[i][0] += m_vNodeMass[i][0] * m_vNodeVelocities[m_currVelIdx][i][0];
00375             m_b[i][1] += m_vNodeMass[i][1] * m_vNodeVelocities[m_currVelIdx][i][1];
00376             m_b[i][2] += m_vNodeMass[i][2] * m_vNodeVelocities[m_currVelIdx][i][2];
00377         }
00378         else {
00379             m_b[i] = m_u[i];
00380         }
00381     }
00382 }
00383 
00384 
00385 //-------------------------------------
00386 #endif//TAPs_SIM_DYNAMIC_SYSTEM
00387 //-----------------------------------------------------------------------------
00388 //=============================================================================
00389 END_NAMESPACE_TAPs__FEM
00390 //34567890123456789012345678901234567890123456789012345678901234567890123456789
00391 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines