![]() |
TAPs 0.7.7.3
|
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----+----