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