Advertisement
Guest User

Untitled

a guest
Jul 20th, 2017
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.67 KB | None | 0 0
  1. inline void computeGreenStrain (float deformation[9], float gstrain[6]) {
  2.     float ftf[9];
  3.     float deformation_t[9];
  4.  
  5.     transpose(deformation, deformation_t);
  6.  
  7.     multiplyMatrices(deformation_t, deformation, ftf);
  8.  
  9.     gstrain[S_00] = 0.5*ftf[I_00] - 0.5;
  10.     gstrain[S_11] = 0.5*ftf[I_11] - 0.5;
  11.     gstrain[S_22] = 0.5*ftf[I_22] - 0.5;
  12.     gstrain[S_01] = 0.5*ftf[I_01];
  13.     gstrain[S_02] = 0.5*ftf[I_02];
  14.     gstrain[S_12] = 0.5*ftf[I_12];
  15. }
  16. inline void computeSVKStress (float gstrain[6], float youngs_modulus, float poisson, float svk[6]) {
  17.     float lame_lambda = youngs_modulus*poisson/(1.0+poisson)/(1.0-2.0*poisson);
  18.     float lame_mu = youngs_modulus/2.0/(1.0+poisson);
  19.  
  20.     float firstterm = lame_lambda*(gstrain[0] + gstrain[1] + gstrain[2]);
  21.  
  22.     svk[S_00] = firstterm + 2.0*lame_mu*gstrain[S_00];
  23.     svk[S_11] = firstterm + 2.0*lame_mu*gstrain[S_11];
  24.     svk[S_22] = firstterm + 2.0*lame_mu*gstrain[S_22];
  25.     svk[S_01] = 2.0*lame_mu*gstrain[S_01];
  26.     svk[S_02] = 2.0*lame_mu*gstrain[S_02];
  27.     svk[S_12] = 2.0*lame_mu*gstrain[S_12];
  28. }
  29. inline void SVKToCauchy (float svk[6], float deformation[9], float cauchy[6]) {
  30.     float temp[9];
  31.  
  32.     for (uint d = 0; d < 9; ++d) temp[d] = 0;
  33.  
  34.     multiplyAS(deformation, svk, temp);
  35.  
  36.     float deformation_t[9];
  37.  
  38.     transpose(deformation, deformation_t);
  39.  
  40.     multiplyMatrices(temp, deformation_t, cauchy);
  41.  
  42.     multiplyMatrixScalar(determinant(deformation), cauchy, cauchy);
  43. }
  44.  
  45. kernel void compute_stresses (PSO_ARGS) {
  46.     USE_FIELD_FIRST_VALUE(n, uint)
  47.     USE_FIELD_FIRST_VALUE(youngs_modulus, float)
  48.     USE_FIELD_FIRST_VALUE(poisson,        float)
  49.  
  50.     USE_FIELD(deformation, float)
  51.     USE_FIELD(stress,      float)
  52.  
  53.     uint i = get_global_id(0);
  54.  
  55.     if (i >= n) return;
  56.  
  57.     global float * def = deformation + i*3*3;
  58.  
  59.     float strain[6];
  60.    
  61.     computeGreenStrain(def, strain);
  62.  
  63.     float svk[6];
  64.  
  65.     computeSVKStress(strain, youngs_modulus, poisson, svk);
  66.    
  67.     global float * cauchy = stress + i*6;
  68.  
  69.     SVKToCauchy(svk, def, cauchy);
  70. }
  71.  
  72. kernel void compute_deformations (PSO_ARGS) {
  73.     USE_GRID_PROPS
  74.  
  75.     USE_FIELD(deformation, float) USE_FIELD(position, float)
  76.     USE_FIELD(originalpos, float) USE_FIELD(density, float)
  77.  
  78.     USE_FIELD_FIRST_VALUE(smoothingradius, float)
  79.     USE_FIELD_FIRST_VALUE(mass, float)
  80.     USE_FIELD_FIRST_VALUE(n, uint)
  81.  
  82. #ifdef SYMMETRY
  83.     USE_FIELD(symmetry_planes, float)
  84.  
  85.     uint num_symmetry_planes = dimensions[dimensions_offsets[symmetry_planes_f] + num_dimensions[symmetry_planes_f] - 1];
  86. #endif
  87.  
  88.     uint i = get_global_id(0);
  89.  
  90.     if (i >= n) return;
  91.  
  92.     float3 ipos = vload3(i, position);
  93.     float3 ipos0 = vload3(i, originalpos);
  94.  
  95.     float apq[9];
  96.     float aqq[9];
  97.  
  98.     for (uint d = 0; d < 9; ++d) apq[d] = 0;
  99.     for (uint d = 0; d < 9; ++d) aqq[d] = 0;
  100.  
  101.     FOR_PARTICLES_IN_RANGE(i, j,
  102.         float3 jpos = vload3(j, position);
  103.         float3 jpos0 = vload3(j, originalpos);
  104.  
  105.         float3 p = jpos - ipos;
  106.         float3 q = jpos0 - ipos0;
  107.  
  108.         float kernelp = applyKernel(length(p), smoothingradius);
  109.  
  110.         if (j != i) {
  111.             contributeApq(p, q, kernelp, apq);
  112.             contributeAqq(q, kernelp, aqq);
  113.         }
  114.  
  115. #ifdef SYMMETRY
  116.         for (uint plane_bits = 1; plane_bits < (1 << num_symmetry_planes); ++plane_bits) {
  117.             float3 refpos = jpos;
  118.             float3 refpos0 = jpos0;
  119.  
  120.             bool skip_region = false;
  121.  
  122.             global float * symmetry_plane;
  123.             float3 point;
  124.             float3 normal;
  125.  
  126.             for (uint s = 0; s < num_symmetry_planes; ++s) {
  127.                 if ((plane_bits & (1 << s)) == 0) continue;
  128.  
  129.                 symmetry_plane = symmetry_planes + s*6;
  130.  
  131.                 point = vload3(0, symmetry_plane);
  132.                 normal = vload3(1, symmetry_plane);
  133.  
  134.                 float jplane_dist = fabs(dot(normal, jpos - point));
  135.                 if (fabs(dot(normal, ipos - point)) > smoothingradius || jplane_dist > smoothingradius || jplane_dist < 1.0e-5) {
  136.                     skip_region = true;
  137.                     break;
  138.                 }
  139.  
  140.                 refpos = refpos - 2 * normal * dot(normal, refpos - point);
  141.                 refpos0 = refpos0 - 2 * normal * dot(normal, refpos0 - point);
  142.             }
  143.  
  144.             if (skip_region) continue;
  145.  
  146.             p = refpos - ipos;
  147.             q = refpos0 - ipos0;
  148.  
  149.             float dist = length(p);
  150.  
  151.             if (dist < smoothingradius) {
  152.                 kernelp = applyKernel(dist, smoothingradius);
  153.                 contributeApq(p, q, kernelp, apq);
  154.                 contributeAqq(q, kernelp, aqq);
  155.             }
  156.         }
  157. #endif
  158.     )
  159.  
  160.     global float * def = deformation + i*3*3;
  161.  
  162.     jacobiInvert(aqq, aqq);
  163.  
  164.     multiplyAS(apq, aqq, def);
  165. }
  166.  
  167. #ifdef SYMMETRY
  168.     // For StrainTest, discard the symmetry forces acting from the negative side of the test axis to get an accurate force reading
  169.     #define TEST_AXIS_CUTOFF_FORCES
  170. #endif
  171.  
  172. kernel void compute_forces_solids (PSO_ARGS) {
  173.     USE_GRID_PROPS
  174.  
  175.     USE_FIELD_FIRST_VALUE(n, uint)
  176.  
  177.     USE_FIELD(originalpos, float) USE_FIELD_FIRST_VALUE(smoothingradius, float)
  178.     USE_FIELD(stress, float) USE_FIELD_FIRST_VALUE(mass, float) USE_FIELD(density0, float)
  179.     USE_FIELD(force, float) USE_FIELD(velocity, float)
  180.     USE_FIELD_FIRST_VALUE(viscosity, float) USE_FIELD(density, float) USE_FIELD(position, float)
  181.  
  182.     USE_FIELD(body_number, uint)
  183.     USE_FIELD(padding, uint)
  184.  
  185. #ifdef SYMMETRY
  186.     USE_FIELD(symmetry_planes, float)
  187.  
  188.     uint num_symmetry_planes = dimensions[dimensions_offsets[symmetry_planes_f] + num_dimensions[symmetry_planes_f] - 1];
  189. #endif
  190.  
  191. #ifdef TEST_AXIS_CUTOFF_FORCES
  192.     USE_FIELD(cutoff_force, float)
  193. #endif
  194.  
  195. #define EXPORT_COMPONENTS
  196.  
  197. #ifdef EXPORT_COMPONENTS
  198.     USE_FIELD(force_elastic, float)
  199.     USE_FIELD(force_viscous, float)
  200. #endif
  201.  
  202.     uint i = get_global_id(0);
  203.  
  204.     if (i >= n) return;
  205.  
  206.     float3 ipos = vload3(i, position);
  207.     float3 ivel = vload3(i, velocity);
  208.  
  209. #define INIT_SOLIDS_FORCE_COMPUTATION \
  210.     float3 ipos0 = vload3(i, originalpos);\
  211. \
  212.     global float * i_stress = stress + i*6;\
  213. \
  214.     float3 f_e = (float3)(0, 0, 0);\
  215.     float3 f_v = (float3)(0, 0, 0);
  216.  
  217.     INIT_SOLIDS_FORCE_COMPUTATION
  218. #ifdef TEST_AXIS_CUTOFF_FORCES
  219.     float3 f_ec = (float3)(0, 0, 0);
  220.     float3 f_vc = (float3)(0, 0, 0);
  221. #endif
  222.  
  223.     float3 jpos0, x, f_ji, f_ij, jpos, jvel;
  224.  
  225.     FOR_PARTICLES_IN_RANGE(i, j,
  226.         jpos0 = vload3(j, originalpos);
  227.         x = ipos0 - jpos0;
  228.         jpos = vload3(j, position);
  229.         jvel = vload3(j, velocity);
  230.  
  231.         float vivj = mass*mass/density0[i]/density0[j];
  232.  
  233.         global float * j_stress = stress + j*6;
  234.  
  235.         float3 fe = (float3)(0, 0, 0);
  236.         float3 fv = (float3)(0, 0, 0);
  237.  
  238. #define SOLIDS_FORCE_COMPUTATION \
  239.         f_ji = -vivj * multiplySymMatrixVector(i_stress, applyKernelGradient(x, smoothingradius));\
  240.         f_ij = body_number[j] > 0 ? -f_ji : -vivj * multiplySymMatrixVector(j_stress, applyKernelGradient(-x, smoothingradius));\
  241.         fe = -f_ji + f_ij;\
  242. \
  243.         fv = mass/density[j] * (jvel - ivel) * applyLapKernel(length(jpos - ipos), smoothingradius);\
  244. \
  245.         f_e += fe;\
  246.         f_v += fv;
  247.  
  248.         if (j != i) {
  249.             SOLIDS_FORCE_COMPUTATION
  250. #ifdef TEST_AXIS_CUTOFF_FORCES
  251.             f_ec += fe;
  252.             f_vc += fv;
  253. #endif
  254.         }
  255.  
  256. #ifdef SYMMETRY
  257.         // Go through every region created by the symmetry planes
  258.         for (uint plane_bits = 1; plane_bits < (1 << num_symmetry_planes); ++plane_bits) {
  259.             float3 refpos = jpos;
  260.             float3 refpos0 = jpos0;
  261.             float3 refipos0 = ipos0;
  262.  
  263.             bool skip_region = false;
  264.  
  265.             global float * symmetry_plane;
  266.             float3 point;
  267.             float3 normal;
  268.  
  269.             // Reflect by every "1" plane
  270.             for (uint s = 0; s < num_symmetry_planes; ++s) {
  271.                 if ((plane_bits & (1 << s)) == 0) continue;
  272.  
  273.                 symmetry_plane = symmetry_planes + s*6;
  274.  
  275.                 point = vload3(0, symmetry_plane);
  276.                 normal = vload3(1, symmetry_plane);
  277.  
  278.                 // Ignore this region if
  279.                 //  - i is too far away from the boundary
  280.                 //  - j is too far away from the boundary
  281.                 //  - j is close enough to be regarded as on the boundary - then unreflected j is all that's needed
  282.                 float jplane_dist = fabs(dot(normal, jpos - point));
  283.                 if (fabs(dot(normal, ipos - point)) > smoothingradius || jplane_dist > smoothingradius || jplane_dist < 1.0e-5) {
  284.                     skip_region = true;
  285.                     break;
  286.                 }
  287.  
  288.                 refpos = refpos - 2 * normal * dot(normal, refpos - point);
  289.                 refpos0 = refpos0 - 2 * normal * dot(normal, refpos0 - point);
  290.                 refipos0 = refipos0 - 2 * normal * dot(normal, refipos0 - point);
  291.             }
  292.  
  293.             if (skip_region) continue;
  294.  
  295.             float3 diff = refpos - ipos;
  296.  
  297.             float dist = length(diff);
  298.  
  299.             x = ipos0 - refpos0;
  300.             float3 refx = refipos0 - jpos0;
  301.  
  302.             f_ji = -vivj * multiplySymMatrixVector(i_stress, applyKernelGradient(x, smoothingradius));
  303.             f_ij = -vivj * multiplySymMatrixVector(j_stress, applyKernelGradient(-refx, smoothingradius));
  304.  
  305.             for (uint s = num_symmetry_planes; s > 0; --s) {
  306.                 if ((plane_bits & (1 << (s-1))) == 0) continue;
  307.  
  308.                 symmetry_plane = symmetry_planes + (s-1)*6;
  309.  
  310.                 normal = vload3(1, symmetry_plane);
  311.  
  312.                 f_ij = f_ij - 2 * normal * dot(normal, f_ij);
  313.             }
  314.  
  315.             fe = -f_ji + f_ij;
  316.             f_e += fe;
  317.  
  318.             float3 refvel = jvel - 2 * normal * dot(normal, jvel);
  319.            
  320.             fv = mass/density[j] * (refvel - ivel) * applyLapKernel(length(refpos - ipos), smoothingradius);
  321.             f_v += fv;
  322.  
  323. #ifdef TEST_AXIS_CUTOFF_FORCES
  324.             // Depends on test axis being zero
  325.             if ((plane_bits & (1 << 0)) == 0) { // Still count the forces from the other mirrored planes
  326.                 f_ec += fe;
  327.                 f_vc += fv;
  328.             }
  329. #endif
  330.         }
  331. #endif
  332.     )
  333.  
  334. #define FINALISE_SOLIDS_FORCE_COMPUTATION \
  335.     f_e *= 0.5f;\
  336.     f_v *= viscosity;
  337.  
  338.     FINALISE_SOLIDS_FORCE_COMPUTATION
  339.  
  340.     float3 f = f_e + f_v;
  341.  
  342.     //APPLY_CUBE_BOUNDS(ipos, f, -2.0f, 2.0f)
  343.  
  344.     vstore3(f, i, force);
  345.  
  346. #ifdef EXPORT_COMPONENTS
  347.     vstore3(f_e, i, force_elastic);
  348.     vstore3(f_v, i, force_viscous);
  349. #endif
  350.  
  351. #ifdef TEST_AXIS_CUTOFF_FORCES
  352.     f_ec *= 0.5f;
  353.     f_vc *= viscosity;
  354.  
  355.     vstore3(f_ec + f_vc, i, cutoff_force);
  356. #endif
  357. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement