TAPs 0.7.7.3
TAPsCUDA_DevFns_ModelElasticRod_Def.cu
Go to the documentation of this file.
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----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines