Example #1
0
template<bool simple> static void add_gradient_helper(RawArray<const Vector<int,4>> bends, RawArray<const CubicHinges<TV3>::Info> info, const T scale, RawArray<const TV3> X, SolidMatrix<TV3>& matrix) {
  if (!scale) return;
  for (int b=0;b<bends.size();b++) {
    const auto& I = info[b];
    int i0,i1,i2,i3;bends[b].get(i0,i1,i2,i3);
    const T quad = -scale*I.dot;
    matrix.add_entry(i0,quad*sqr(I.c[0]));
    matrix.add_entry(i1,quad*sqr(I.c[1]));
    matrix.add_entry(i2,quad*sqr(I.c[2]));
    matrix.add_entry(i3,quad*sqr(I.c[3]));
    if (simple) {
      matrix.add_entry(i0,i1,quad*I.c[0]*I.c[1]);
      matrix.add_entry(i0,i2,quad*I.c[0]*I.c[2]);
      matrix.add_entry(i0,i3,quad*I.c[0]*I.c[3]);
      matrix.add_entry(i1,i2,quad*I.c[1]*I.c[2]);
      matrix.add_entry(i1,i3,quad*I.c[1]*I.c[3]);
      matrix.add_entry(i2,i3,quad*I.c[2]*I.c[3]);
    } else {
      const T cubic = -scale*I.det;
      const TV3 x0 = cubic*X[i0], x1 = cubic*X[i1], x2 = cubic*X[i2], x3 = cubic*X[i3];
      matrix.add_entry(i0,i1,quad*I.c[0]*I.c[1]+cross_product_matrix(x3-x2)); //  e3
      matrix.add_entry(i0,i2,quad*I.c[0]*I.c[2]+cross_product_matrix(x1-x3)); // -e1
      matrix.add_entry(i0,i3,quad*I.c[0]*I.c[3]+cross_product_matrix(x2-x1)); //  e0
      matrix.add_entry(i1,i2,quad*I.c[1]*I.c[2]+cross_product_matrix(x3-x0));
      matrix.add_entry(i1,i3,quad*I.c[1]*I.c[3]+cross_product_matrix(x0-x2)); //  e4
      matrix.add_entry(i2,i3,quad*I.c[2]*I.c[3]+cross_product_matrix(x1-x0)); // -e2
    }
  }
}
Example #2
0
template<bool definite> void SimpleShell::add_elastic_gradient_helper(SolidMatrix<TV>& matrix) const {
  const int m = 3, d = 2;
  Matrix<T,m> dGdD[d+1][d+1];
  for (const auto& I : info) {
    for (int i=0;i<d;i++)
      for (int j=0;j<m;j++) {
        Matrix<T,m,d> dDs;
        dDs(j,i) = 1;
        Matrix<T,m,d> dG = force_differential<definite>(I,dDs);
        for (int k=0;k<d;k++)
          dGdD[k+1][i+1].set_column(j,dG.column(k));
      }
    Matrix<T,m> sum;
    for (int i=0;i<d;i++) {
      Matrix<T,m> sum_i;
      for (int j=0;j<d;j++)
        sum_i -= dGdD[i+1][j+1];
      dGdD[i+1][0] = sum_i;
      sum -= sum_i;
    }
    dGdD[0][0] = sum;
    for (int j=0;j<d+1;j++)
      for (int i=j;i<d+1;i++)
        matrix.add_entry(I.nodes[i],I.nodes[j],dGdD[i][j]);
  }
}
Example #3
0
template<class TV> void CubicHinges<TV>::
add_elastic_gradient(SolidMatrix<TV>& matrix) const {
  GEODE_ASSERT(matrix.size()>=nodes_);
  if (simple_hessian)
    add_gradient_helper<true>(bends,info,stiffness,X,matrix);
  else
    add_gradient_helper<false>(bends,info,stiffness,X,matrix);
}
Example #4
0
template<bool simple> static void add_gradient_helper(RawArray<const Vector<int,3>> bends, RawArray<const CubicHinges<TV2>::Info> info, const T scale, RawArray<const TV2> X, SolidMatrix<TV2>& matrix) {
  if (!scale) return;
  for (int b=0;b<bends.size();b++) {
    const auto& I = info[b];
    int i0,i1,i2;bends[b].get(i0,i1,i2);
    const T quad = -scale*I.dot;
    matrix.add_entry(i0,quad*sqr(I.c[0]));
    matrix.add_entry(i1,quad*sqr(I.c[1]));
    matrix.add_entry(i2,quad*sqr(I.c[2]));
    if (simple) {
      matrix.add_entry(i0,i1,quad*I.c[0]*I.c[1]);
      matrix.add_entry(i0,i2,quad*I.c[0]*I.c[2]);
      matrix.add_entry(i1,i2,quad*I.c[1]*I.c[2]);
    } else {
      const T a = scale*I.det;
      const Matrix<T,2> anti(0,a,-a,0); // x'Ay = cross(x,y), scaled
      matrix.add_entry(i0,i1,quad*I.c[0]*I.c[1]-anti);
      matrix.add_entry(i0,i2,quad*I.c[0]*I.c[2]+anti);
      matrix.add_entry(i1,i2,quad*I.c[1]*I.c[2]-anti);
    }
  }
}
Example #5
0
template<class TV> void CubicHinges<TV>::
add_damping_gradient(SolidMatrix<TV>& matrix) const {
  GEODE_ASSERT(matrix.size()>=nodes_);
  add_gradient_helper<true>(bends,info,damping,X,matrix);
}
Example #6
0
void SurfacePins::add_damping_gradient(SolidMatrix<TV>& matrix) const {
  GEODE_ASSERT(matrix.size()==mass.size());
  GEODE_NOT_IMPLEMENTED();
}