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