![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsCUDA_DevFns_ModelElasticRod_Def.cu 00003 00004 CUDA Definition for ModelElasticRod (i.e., cpp file). 00005 00006 SUKITTI PUNAK (09/03/2009) 00007 UPDATE (09/24/2009) 00008 ******************************************************************************/ 00009 00010 #include "TAPsCUDA_DevFns_ModelElasticRod.cu" 00011 00012 BEGIN_NAMESPACE_TAPs__CUDA 00013 //============================================================================= 00014 // CUDA Device Functions 00015 //----------------------------------------------------------------------------- 00016 00017 // An explicit Euler integration for calculating new velocity 00018 __device__ 00019 float3 Device__EulerInt_NewVel_ModelElasticRod ( 00020 float3 Force, // force 00021 float3 Velocity, // velocity 00022 float mass, // mass 00023 float h // time step 00024 ) 00025 { 00026 // F = mA; A = F/m; V = A*h; P = V*h 00027 float scale = h / mass; 00028 float3 vel_chg = Mul( Force, scale ); 00029 return Add( Velocity, vel_chg ); 00030 } 00031 00032 00033 // An explicit Euler integration for calculating new position 00034 __device__ 00035 float3 Device__EulerInt_NewPos_ModelElasticRod ( 00036 float3 Velocity, // velocity 00037 float3 Position, // position 00038 float h // time step 00039 ) 00040 { 00041 return Add( Position, Mul( Velocity, h ) ); 00042 } 00043 00044 00045 // A semi explicit Euler integration for calculating new orientation 00046 __device__ 00047 float4 Device__EulerInt_NewOri_ModelElasticRod ( 00048 float k_mdr, // an constant value in proportion to material density and radius 00049 float l_rest, // orientation's rest length 00050 float4 Orientation, // orientation 00051 float4 Torque, // torque in 4-dimension 00052 float h // time step 00053 ) 00054 { 00055 // Compute the components of the inverse of the inertia tersor matrix 00056 // Only the diagonal components are non-zero, since the rod's material is assumed to be isotropic. 00057 float c = l_rest * k_mdr; 00058 float Jinv_0 = 4.0f / c; 00059 float Jinv_1 = Jinv_0; 00060 float Jinv_2 = 2.0f / k_mdr; 00061 00062 00063 // Compute the angular velocity from the 4d torque 00064 // 1/2 * Q_j^T * torque_in_4Dim 00065 // (Q_j^T * torque_in_4Dim) equals "the multiplication of conjugation_of_q_j with torque_in_4Dim" 00066 float4 torque_transformed = Mul( QuaternionMul( QuaternionConjugate( Orientation ), Torque ), 0.5f ); 00067 // Angular velocity := 1/2 * Jinv * torque_transformed_into_3Dim 00068 float4 angularVelocity = make_float4( 00069 0.0f, // deliberately set to zero 00070 0.5f * Jinv_0 * torque_transformed.y, 00071 0.5f * Jinv_1 * torque_transformed.z, 00072 0.5f * Jinv_2 * torque_transformed.w 00073 ); 00074 00075 // Compute the velocity of the orientation 00076 float4 q_velocity = Mul( QuaternionMul( Orientation, angularVelocity ), 0.5f ); 00077 00078 // Compute and return the next orientation 00079 return Add( Orientation, Mul( q_velocity, h ) ); 00080 } 00081 00082 00083 // Calculate the stretch force of centerline 00084 __device__ 00085 float3 Device__CalStretchForce_ModelElasticRod ( 00086 float Ps, // potential stretch constant 00087 float Lrest, // rest length 00088 float Lcurr, // current length 00089 float3 Fdir // difference of two position -- i.e. unpolished force 00090 ) 00091 { 00092 00093 #ifdef __DEVICE_EMULATION__ 00094 { 00095 float mag = (Lcurr/Lrest - 1.0f) * Ps; 00096 float3 Fs = make_float3( mag*Fdir.x/Lcurr, mag*Fdir.y/Lcurr, mag*Fdir.z/Lcurr ); 00097 printf( "Ps: %f\n", Ps ); 00098 printf( "Lrest: %f\n", Lrest ); 00099 printf( "Lcurr: %f\n", Lcurr ); 00100 printf( "Lcurr/Lrest: %f\n", Lcurr/Lrest ); 00101 printf( "Lcurr/Lrest - 1.0f: %f\n", Lcurr/Lrest-1.0f ); 00102 printf( "mag: %f\n", mag ); 00103 printf( "Fs: %f %f %f\n", Fs.x, Fs.y, Fs.z ); 00104 } 00105 #endif 00106 00107 float mag = (Lcurr/Lrest - 1.0f) * Ps; 00108 return make_float3( mag*Fdir.x/Lcurr, mag*Fdir.y/Lcurr, mag*Fdir.z/Lcurr ); 00109 } 00110 00111 00112 // Calculate the bend torque of orientation 00113 __device__ 00114 float4 Device__CalBendTorque_ModelElasticRod ( 00115 float4 O1, // orientation 1 00116 float4 O2, // orientation 2 00117 float3 Pb // potential bend constant -- xyz 00118 ) 00119 { 00120 //return make_float4( 0.0f, 0.0f, 0.0f, 0.0f ); 00121 00122 float4 OA = Add( O2, O1 ); // O2 + O1 00123 float4 OS = Sub( O2, O1 ); // O2 - O1 00124 00125 // B_k(q_{j+1}+q{j}) 00126 float4 B1 = make_float4( -OA.y, OA.x, OA.w, -OA.z ); 00127 float4 B2 = make_float4( -OA.z, -OA.w, OA.x, OA.y ); 00128 float4 B3 = make_float4( -OA.w, OA.z, -OA.y, OA.x ); 00129 00130 // 2 * K_k ( B_k(q_{j+1}+q{j}) inner_product_with (q_{j+1}-q{j}) ) 00131 float k1 = 2.0f * Pb.x * InnerProduct( B1, OS ); 00132 float k2 = 2.0f * Pb.y * InnerProduct( B2, OS ); 00133 float k3 = 2.0f * Pb.z * InnerProduct( B3, OS ); 00134 00135 // Differentiation of ( B_k(q_{j+1}+q{j}) inner_product_with (q_{j+1}-q{j}) ) by q_{j} 00136 float4 dB1 = make_float4( -O2.y, O2.x, O2.w, -O2.z ); 00137 float4 dB2 = make_float4( -O2.z, -O2.w, O2.x, O2.y ); 00138 float4 dB3 = make_float4( -O2.w, O2.z, -O2.y, O2.x ); 00139 00140 return Add( Mul( dB1, k1 ), Add( Mul( dB2, k2 ), Mul( dB3, k3 ) ) ); 00141 } 00142 00143 00144 // Calculate the constraint force applied to centerline 00145 // to align centerline's tangent with orientation's 3rd direction 00146 __device__ 00147 float3 Device__CalTheConstraintForce_ModelElasticRod ( 00148 float3 Cen21, // centerline2 - centerline1 00149 float l_Cen21, // length of (centerline2 - centerline1) 00150 float inv_l_Cen21, // the inverse length of (centerline2 - centerline1) 00151 float4 Ori, // orientation 00152 float l_rest, // rest length 00153 float Kc // Kconstraint for aligning centerline's tangent with orientation's 3rd direction 00154 ) 00155 { 00156 float l_Cen21_square = l_Cen21 * l_Cen21; 00157 00158 // the third director of orientation 00159 float3 Dir3 = make_float3( 00160 2.0f*( Ori.y*Ori.w + Ori.x*Ori.z ), 00161 2.0f*( Ori.z*Ori.w - Ori.x*Ori.y ), 00162 Ori.x*Ori.x - Ori.y*Ori.y - Ori.z*Ori.z + Ori.w*Ori.w 00163 ); 00164 00165 // rest_len * Kappa * ( (r_{i+1}-r_{i})/||r_{i+1}-r_{i}|| - d3(q_{i}) ) 00166 float3 Vc = Mul( Sub( Mul( Cen21, inv_l_Cen21 ), Dir3 ), l_rest * Kc ); 00167 00168 // Compute the constraint force for the centerline 00169 float3 Vcr = Mul( Vc, inv_l_Cen21 / l_Cen21_square ); 00170 float xd = Cen21.x, yd = Cen21.y, zd = Cen21.z; 00171 float xd_yd = xd*yd; 00172 float xd_zd = xd*zd; 00173 float yd_zd = yd*zd; 00174 return make_float3( 00175 InnerProduct( Vcr, make_float3( l_Cen21_square - xd*xd, xd_yd, xd_zd ) ), 00176 InnerProduct( Vcr, make_float3( xd_yd, l_Cen21_square - yd*yd, yd_zd ) ), 00177 InnerProduct( Vcr, make_float3( xd_zd, yd_zd, l_Cen21_square - zd*zd ) ) 00178 ); 00179 } 00180 00181 00182 // Calculate the constraint torque applied to orientation 00183 // to align centerline's tangent with orientation's 3rd direction 00184 __device__ 00185 float4 Device__CalTheConstraintTorque_ModelElasticRod ( 00186 float3 Cen21, // centerline2 - centerline1 00187 float l_Cen21, // length of (centerline2 - centerline1) 00188 float inv_l_Cen21, // the inverse length of (centerline2 - centerline1) 00189 float4 Ori, // orientation 00190 float l_rest, // rest length 00191 float Kc // Kconstraint for aligning centerline's tangent with orientation's 3rd direction 00192 ) 00193 { 00194 // the third director of orientation 00195 float3 Dir3 = make_float3( 00196 2.0f*( Ori.y*Ori.w + Ori.x*Ori.z ), 00197 2.0f*( Ori.z*Ori.w - Ori.x*Ori.y ), 00198 Ori.x*Ori.x - Ori.y*Ori.y - Ori.z*Ori.z + Ori.w*Ori.w 00199 ); 00200 00201 // rest_len * Kappa * ( (r_{i+1}-r_{i})/||r_{i+1}-r_{i}|| - d3(q_{i}) ) 00202 float3 Vc = Mul( Sub( Mul( Cen21, inv_l_Cen21 ), Dir3 ), l_rest * Kc ); 00203 00204 // Compute the constraint force (torque) for the orientation 00205 float3 Vcq = Mul( Vc, 2.0f ); 00206 return make_float4( 00207 InnerProduct( Vcq, make_float3( Ori.z, -Ori.y, Ori.x ) ), 00208 InnerProduct( Vcq, make_float3( Ori.w, -Ori.x, -Ori.y ) ), 00209 InnerProduct( Vcq, make_float3( Ori.x, Ori.w, -Ori.z ) ), 00210 InnerProduct( Vcq, make_float3( Ori.y, Ori.z, Ori.w ) ) 00211 ); 00212 } 00213 00214 00215 // Calculate the total force of the node at vertexNo 00216 __device__ 00217 float3 Device__CalForce_ModelElasticRod ( 00218 int vertexNo, // vertex number 00219 unsigned int numOfNodes, // number of vertices 00220 float4 Pos0, 00221 float4 Pos1, 00222 float4 Pos2, 00223 float4 Ori0, 00224 float4 Ori1, 00225 float radius, // radius 00226 float length, // rest length 00227 float mass, // point mass 00228 //float Kt, // kinetic translational constant 00229 //float3 Kr, // kinetic rotational constant -- xyz 00230 //float Dt, // translational constant 00231 //float3 Dr, // rotational dissipation constant -- xyz 00232 float Kconstraint_3rdDirAlignTangent, // Kconstraint for aligning centerline's tangent with orientation's 3rd direction 00233 float Kvdamping, // centerline's velocity damper 00234 float Ps, // potential stretch constant 00235 float3 Pb // potential bend constant -- xyz 00236 ) 00237 { 00238 //float4 Pos1 = tex1Dfetch( CudaTexVertexList, vertexNo ); // position 00239 float3 P1 = XYZ( Pos1 ); 00240 float3 total_force = make_float3( 0.0f, 0.0f, 0.0f ); 00241 00242 if ( vertexNo > 0 ) { // skip the first one 00243 // Cal the stretch force due to connection with the previous centerline 00244 //float4 Pos0 = tex1Dfetch( CudaTexVertexList, vertexNo-1 ); // position 00245 float3 P0 = XYZ( Pos0 ); 00246 float3 P0_P1 = Sub( P0, P1 ); 00247 00248 #ifdef __DEVICE_EMULATION__ 00249 printf( "P1: %f %f %f\n", P1.x, P1.y, P1.z ); 00250 printf( "P0: %f %f %f\n", P0.x, P0.y, P0.z ); 00251 #endif 00252 00253 float l_curr_01 = Length( P0_P1 ); 00254 float3 force = Device__CalStretchForce_ModelElasticRod( 00255 Ps, 00256 length, 00257 l_curr_01, 00258 P0_P1 00259 ); 00260 total_force.x += force.x; 00261 total_force.y += force.y; 00262 total_force.z += force.z; 00263 00264 #ifdef __DEVICE_EMULATION__ 00265 printf( "(#v>0) Fs[%i]: %f %f %f\n", vertexNo, force.x, force.y, force.z ); 00266 #endif//__DEVICE_EMULATION__ 00267 00268 if ( vertexNo < numOfNodes - 2 ) { // skip the last two 00269 // Cal the constraint force due to connection with the previous centerline and orientation 00270 //float4 Ori0 = tex1Dfetch( CudaTexOrientationList, vertexNo-1 ); // orientation 00271 float3 P10 = make_float3( -P0_P1.x, -P0_P1.y, -P0_P1.z ); 00272 force = Device__CalTheConstraintForce_ModelElasticRod ( 00273 P10, 00274 l_curr_01, 00275 1.0/l_curr_01, 00276 Ori0, 00277 length, 00278 Kconstraint_3rdDirAlignTangent 00279 ); 00280 total_force.x -= force.x; 00281 total_force.y -= force.y; 00282 total_force.z -= force.z; 00283 00284 #ifdef __DEVICE_EMULATION__ 00285 printf( "(#v>0) Fc[%i]: %f %f %f\n", vertexNo, force.x, force.y, force.z ); 00286 #endif//__DEVICE_EMULATION__ 00287 } 00288 } 00289 00290 if ( vertexNo < numOfNodes - 1 ) { // skip the last one 00291 // Cal the stretch force due to connection with the next centerline 00292 //float4 Pos2 = tex1Dfetch( CudaTexVertexList, vertexNo+1 ); // position 00293 float3 P2 = XYZ( Pos2 ); 00294 float3 P2_P1 = Sub( P2, P1 ); 00295 00296 #ifdef __DEVICE_EMULATION__ 00297 printf( "P1: %f %f %f\n", P1.x, P1.y, P1.z ); 00298 printf( "P2: %f %f %f\n", P2.x, P2.y, P2.z ); 00299 #endif 00300 00301 float l_curr_21 = Length( P2_P1 ); 00302 float3 force = Device__CalStretchForce_ModelElasticRod( 00303 Ps, 00304 length, 00305 l_curr_21, 00306 P2_P1 00307 ); 00308 total_force.x += force.x; 00309 total_force.y += force.y; 00310 total_force.z += force.z; 00311 00312 #ifdef __DEVICE_EMULATION__ 00313 printf( "(#v<#N-1) Fs[%i]: %f %f %f\n", vertexNo, force.x, force.y, force.z ); 00314 #endif//__DEVICE_EMULATION__ 00315 00316 if ( vertexNo < numOfNodes - 2 ) { // skip the last two 00317 // Cal the constraint force due to connection with the next centerline and orientation 00318 //float4 Ori1 = tex1Dfetch( CudaTexOrientationList, vertexNo ); // orientation 00319 force = Device__CalTheConstraintForce_ModelElasticRod ( 00320 P2_P1, 00321 l_curr_21, 00322 1.0/l_curr_21, 00323 Ori1, 00324 length, 00325 Kconstraint_3rdDirAlignTangent 00326 ); 00327 total_force.x += force.x; 00328 total_force.y += force.y; 00329 total_force.z += force.z; 00330 00331 #ifdef __DEVICE_EMULATION__ 00332 printf( "(#v<#N-1) Fc[%i]: %f %f %f\n", vertexNo, force.x, force.y, force.z ); 00333 #endif//__DEVICE_EMULATION__ 00334 } 00335 } 00336 00337 return total_force; 00338 } 00339 00340 00342 __device__ 00343 float4 Device__CalTorque_ModelElasticRod ( 00344 int vertexNo, 00345 unsigned int numOfNodes, 00346 float4 Pos1, 00347 float4 Pos2, 00348 float4 Ori0, 00349 float4 Ori1, 00350 float4 Ori2, 00351 float radius, 00352 float length, 00353 float mass, 00354 //float Kt, //!< kinetic translational constant 00355 //float3 Kr, //!< kinetic rotational constant -- xyz 00356 //float Dt, //!< translational constant 00357 //float3 Dr, //!< rotational dissipation constant -- xyz 00358 float Kconstraint_3rdDirAlignTangent, 00359 float Kvdamping, 00360 float Ps, 00361 float3 Pb 00362 ) 00363 { 00364 //float4 Ori1 = tex1Dfetch( CudaTexOrientationList, vertexNo ); // orientation 00365 float4 total_torque = make_float4( 0.0f, 0.0f, 0.0f, 0.0f ); 00366 00367 //if ( vertexNo >= 0 ) 00368 // return total_torque; 00369 00370 // Skip the last one 00371 if ( vertexNo < numOfNodes-1 ) 00372 { 00373 { 00374 // Cal the constraint torque due to connection with the before and after centerlines 00375 // --- centerline1 ---- orientation1 --- centerline2 --- 00376 //float4 Pos1 = tex1Dfetch( CudaTexVertexList, vertexNo ); // position 00377 float3 P1 = XYZ( Pos1 ); 00378 //float4 Pos2 = tex1Dfetch( CudaTexVertexList, vertexNo+1 ); // position 00379 float3 P2 = XYZ( Pos2 ); 00380 float3 P2_P1 = Sub( P2, P1 ); 00381 float l_curr_21 = Length( P2_P1 ); 00382 float4 torque = Device__CalTheConstraintTorque_ModelElasticRod ( 00383 P2_P1, 00384 l_curr_21, 00385 1.0/l_curr_21, 00386 Ori1, 00387 length, 00388 Kconstraint_3rdDirAlignTangent 00389 ); 00390 total_torque.x += torque.x; 00391 total_torque.y += torque.y; 00392 total_torque.z += torque.z; 00393 total_torque.w += torque.w; 00394 00395 #ifdef __DEVICE_EMULATION__ 00396 printf( "(#v>0) Ctorque[%i]: %f %f %f %f\n", vertexNo, torque.x, torque.y, torque.z, torque.w ); 00397 #endif//__DEVICE_EMULATION__ 00398 } 00399 00400 if ( vertexNo >= 0 ) // skip the first one 00401 { 00402 // Cal the bend torque due to connection with the previous orientation 00403 //float4 Ori0 = tex1Dfetch( CudaTexOrientationList, vertexNo-1 ); // orientation 00404 float4 torque = Device__CalBendTorque_ModelElasticRod( 00405 Ori1, 00406 Ori0, 00407 Pb 00408 ); 00409 total_torque.x += torque.x; 00410 total_torque.y += torque.y; 00411 total_torque.z += torque.z; 00412 total_torque.w += torque.w; 00413 00414 #ifdef __DEVICE_EMULATION__ 00415 printf( "(#v>0) Btorque[%i]: %f %f %f %f\n", vertexNo, torque.x, torque.y, torque.z, torque.w ); 00416 #endif//__DEVICE_EMULATION__ 00417 } 00418 00419 if ( vertexNo < numOfNodes - 2 ) // skip the last two 00420 { 00421 // Cal the bend torque due to connection with the next orientation 00422 //float4 Ori2 = tex1Dfetch( CudaTexOrientationList, vertexNo+1 ); // orientation 00423 float4 torque = Device__CalBendTorque_ModelElasticRod( 00424 Ori1, 00425 Ori2, 00426 Pb 00427 ); 00428 total_torque.z += torque.z; 00429 total_torque.x += torque.x; 00430 total_torque.w += torque.w; 00431 total_torque.y += torque.y; 00432 00433 #ifdef __DEVICE_EMULATION__ 00434 printf( "(#v<#N-2) Btorque[%i]: %f %f %f %f\n", vertexNo, torque.x, torque.y, torque.z, torque.w ); 00435 #endif//__DEVICE_EMULATION__ 00436 } 00437 } 00438 return total_torque; 00439 } 00440 //----------------------------------------------------------------------------- 00441 // CUDA Device Functions 00442 //============================================================================= 00443 END_NAMESPACE_TAPs__CUDA 00444 //----------------------------------------------------------------------------- 00445 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00446 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----