Ejemplo n.º 1
0
void StVKHessianTensor::AddCubicTermsContribution(double * u, double * du, SparseMatrix * dK, int elementLow, int elementHigh)
{
  if (elementLow < 0)
    elementLow = 0;
  if (elementHigh < 0)
    elementHigh = volumetricMesh->getNumElements();

  int ** row_, ** column_;
  stVKStiffnessMatrix->GetMatrixAccelerationIndices(&row_, &column_);

  int * vertices = (int*) malloc (sizeof(int) * numElementVertices);

  void * elIter;
  precomputedIntegrals->AllocateElementIterator(&elIter);

  double ** dataHandle = dK->GetDataHandle();

  for(int el=elementLow; el < elementHigh; el++)
  {
    precomputedIntegrals->PrepareElement(el, elIter);
    int * row = row_[el];
    int * column = column_[el];

    for(int ver=0; ver<numElementVertices ;ver++)
      vertices[ver] = volumetricMesh->getVertexIndex(el, ver);

    double lambda = lambdaLame[el]; 
    double mu = muLame[el];

    for (int c=0; c<numElementVertices; c++) // over all vertices of the voxel
    {
      int rowc = 3*row[c];
      int c8 = numElementVertices*c;
      for (int e=0; e<numElementVertices; e++) // compute contribution to block (c,e) of dK
      {
        double matrix[9];
        memset(matrix, 0, sizeof(double) * 9);
        for(int f=0; f<numElementVertices; f++)
        {
          double qf[3] = { du[3*vertices[f]+0], du[3*vertices[f]+1], du[3*vertices[f]+2] };
          for(int a=0; a<numElementVertices; a++)
          {
            double qa[3] = { u[3*vertices[a]+0], u[3*vertices[a]+1], u[3*vertices[a]+2] };

            // qa tensor qf
            double qaqf[9];
            qaqf[0] = qa[0] * qf[0]; qaqf[1] = qa[0] * qf[1]; qaqf[2] = qa[0] * qf[2];
            qaqf[3] = qa[1] * qf[0]; qaqf[4] = qa[1] * qf[1]; qaqf[5] = qa[1] * qf[2];
            qaqf[6] = qa[2] * qf[0]; qaqf[7] = qa[2] * qf[1]; qaqf[8] = qa[2] * qf[2];

            double D0 = lambda * precomputedIntegrals->D(elIter,f,c,a,e) + mu * (precomputedIntegrals->D(elIter,f,e,a,c) + precomputedIntegrals->D(elIter,f,a,c,e));

            matrix[0] += D0 * qaqf[0]; matrix[1] += D0 * qaqf[3]; matrix[2] += D0 * qaqf[6];
            matrix[3] += D0 * qaqf[1]; matrix[4] += D0 * qaqf[4]; matrix[5] += D0 * qaqf[7];
            matrix[6] += D0 * qaqf[2]; matrix[7] += D0 * qaqf[5]; matrix[8] += D0 * qaqf[8];

            double D1 = lambda * precomputedIntegrals->D(elIter,a,c,f,e) + mu * (precomputedIntegrals->D(elIter,a,e,f,c) + precomputedIntegrals->D(elIter,a,f,c,e));

            matrix[0] += D1 * qaqf[0]; matrix[1] += D1 * qaqf[1]; matrix[2] += D1 * qaqf[2];
            matrix[3] += D1 * qaqf[3]; matrix[4] += D1 * qaqf[4]; matrix[5] += D1 * qaqf[5];
            matrix[6] += D1 * qaqf[6]; matrix[7] += D1 * qaqf[7]; matrix[8] += D1 * qaqf[8];

            double D2 = lambda * precomputedIntegrals->D(elIter,f,a,c,e) + mu * (precomputedIntegrals->D(elIter,f,c,a,e) + precomputedIntegrals->D(elIter,a,c,f,e));

            // qf dot qa
            double dotp = D2 * (qf[0]*qa[0] + qf[1]*qa[1] + qf[2]*qa[2]);
            matrix[0] += dotp;
            matrix[4] += dotp;
            matrix[8] += dotp;
          }
        }
        int k,l;
        ADD_MATRIX_BLOCK(e);
      }
    }
  }

  free(vertices);

  precomputedIntegrals->ReleaseElementIterator(elIter);
}
void StVKStiffnessMatrix::AddCubicTermsContribution(double * vertexDisplacements, SparseMatrix * sparseMatrix, int elementLow, int elementHigh)
{
  if (elementLow < 0)
    elementLow = 0;
  if (elementHigh < 0)
    elementHigh = volumetricMesh->getNumElements();

  int * vertices = (int*) malloc (sizeof(int) * numElementVertices);

  void * elIter;
  precomputedIntegrals->AllocateElementIterator(&elIter);

  double ** dataHandle = sparseMatrix->GetDataHandle();

  for(int el=elementLow; el < elementHigh; el++)
  {
    precomputedIntegrals->PrepareElement(el, elIter);
    int * row = row_[el];
    int * column = column_[el];

    for(int ver=0; ver<numElementVertices; ver++)
      vertices[ver] = volumetricMesh->getVertexIndex(el, ver);

    double lambda = lambdaLame[el]; 
    double mu = muLame[el];

    for (int c=0; c<numElementVertices; c++) // over all vertices of the voxel, computing derivative on force on vertex c
    {
      int rowc = 3*row[c];
      int c8 = numElementVertices*c;
      // cubic terms
      for (int e=0; e<numElementVertices; e++) // compute contribution to block (c,e) of the stiffness matrix
      {
        double matrix[9];
        memset(matrix, 0, sizeof(double) * 9);
        for(int a=0; a<numElementVertices; a++)
        {
          int va = vertices[a];
          double * qa = &(vertexDisplacements[3*va]);
          for(int b=0; b<numElementVertices; b++)
          {
            int vb = vertices[b];

            double * qb = &(vertexDisplacements[3*vb]);

            double D0 = lambda * precomputedIntegrals->D(elIter,a,c,b,e) +
                        mu * ( precomputedIntegrals->D(elIter,a,e,b,c) + precomputedIntegrals->D(elIter,a,b,c,e) );

            matrix[0] += D0 * qa[0] * qb[0]; matrix[1] += D0 * qa[0] * qb[1]; matrix[2] += D0 * qa[0] * qb[2];
            matrix[3] += D0 * qa[1] * qb[0]; matrix[4] += D0 * qa[1] * qb[1]; matrix[5] += D0 * qa[1] * qb[2];
            matrix[6] += D0 * qa[2] * qb[0]; matrix[7] += D0 * qa[2] * qb[1]; matrix[8] += D0 * qa[2] * qb[2];

            double D1 = 0.5 * lambda * precomputedIntegrals->D(elIter,a,b,c,e) +
                        mu * precomputedIntegrals->D(elIter,a,c,b,e);

            double dotpD = D1 * (qa[0] * qb[0] + qa[1] * qb[1] + qa[2] * qb[2]);

            matrix[0] += dotpD; 
            matrix[4] += dotpD; 
            matrix[8] += dotpD; 
          }
        }
        int k,l;
        ADD_MATRIX_BLOCK(e);
      }
    }
  }

  free(vertices);

  precomputedIntegrals->ReleaseElementIterator(elIter);
}
Ejemplo n.º 3
0
void StVKHessianTensor::AddQuadraticTermsContribution(double * u, double * du, SparseMatrix * dK, int elementLow, int elementHigh) 
{
  if (elementLow < 0)
    elementLow = 0;
  if (elementHigh < 0)
    elementHigh = volumetricMesh->getNumElements();

  int ** row_, ** column_;
  stVKStiffnessMatrix->GetMatrixAccelerationIndices(&row_, &column_);

  int * vertices = (int*) malloc (sizeof(int) * numElementVertices);

  void * elIter;
  precomputedIntegrals->AllocateElementIterator(&elIter);

  double ** dataHandle = dK->GetDataHandle();

  for(int el=elementLow; el < elementHigh; el++)
  {
    precomputedIntegrals->PrepareElement(el, elIter);
    int * row = row_[el];
    int * column = column_[el];

    for(int ver=0; ver<numElementVertices ;ver++)
      vertices[ver] = volumetricMesh->getVertexIndex(el, ver);

    double lambda = lambdaLame[el]; 
    double mu = muLame[el];

    for (int c=0; c<numElementVertices; c++) // over all vertices of the voxel
    {
      int rowc = 3*row[c];
      int c8 = numElementVertices*c;
      for (int e=0; e<numElementVertices; e++) // compute contribution to block (c,e) of dK
      {
        double matrix[9];
        memset(matrix, 0, sizeof(double) * 9);
        for(int f=0; f<numElementVertices; f++)
        {
          double qf[3] = { du[3*vertices[f]+0], du[3*vertices[f]+1], du[3*vertices[f]+2] };
          
          Vec3d C0v = lambda * precomputedIntegrals->C(elIter,c,f,e) + mu * (precomputedIntegrals->C(elIter,e,f,c) + precomputedIntegrals->C(elIter,f,e,c));
          double C0[3] = {C0v[0], C0v[1], C0v[2]};

          // C0 tensor qf
          matrix[0] += C0[0] * qf[0]; matrix[1] += C0[0] * qf[1]; matrix[2] += C0[0] * qf[2];
          matrix[3] += C0[1] * qf[0]; matrix[4] += C0[1] * qf[1]; matrix[5] += C0[1] * qf[2];
          matrix[6] += C0[2] * qf[0]; matrix[7] += C0[2] * qf[1]; matrix[8] += C0[2] * qf[2];

          Vec3d C1v = lambda * precomputedIntegrals->C(elIter,e,f,c) + mu * (precomputedIntegrals->C(elIter,c,e,f) + precomputedIntegrals->C(elIter,f,e,c));
          double C1[3] = {C1v[0], C1v[1], C1v[2]};

          // qf tensor C1
          matrix[0] += qf[0] * C1[0]; matrix[1] += qf[0] * C1[1]; matrix[2] += qf[0] * C1[2];
          matrix[3] += qf[1] * C1[0]; matrix[4] += qf[1] * C1[1]; matrix[5] += qf[1] * C1[2];
          matrix[6] += qf[2] * C1[0]; matrix[7] += qf[2] * C1[1]; matrix[8] += qf[2] * C1[2];

          Vec3d C2v = lambda * precomputedIntegrals->C(elIter,f,e,c) + mu * (precomputedIntegrals->C(elIter,c,f,e) + precomputedIntegrals->C(elIter,e,f,c));
          double C2[3] = {C2v[0], C2v[1], C2v[2]};

          // qf dot C2
          double dotp = qf[0]*C2[0] + qf[1]*C2[1] + qf[2]*C2[2];
          matrix[0] += dotp;
          matrix[4] += dotp;
          matrix[8] += dotp;
        }
        int k,l;
        ADD_MATRIX_BLOCK(e);
      }
    }
  }

  precomputedIntegrals->ReleaseElementIterator(elIter);

  free(vertices);
}
void StVKStiffnessMatrix::AddQuadraticTermsContribution(double * vertexDisplacements, SparseMatrix * sparseMatrix, int elementLow, int elementHigh)
{
  if (elementLow < 0)
    elementLow = 0;
  if (elementHigh < 0)
    elementHigh = volumetricMesh->getNumElements();

  int * vertices = (int*) malloc (sizeof(int) * numElementVertices);

  void * elIter;
  precomputedIntegrals->AllocateElementIterator(&elIter);

  double ** dataHandle = sparseMatrix->GetDataHandle();

  for(int el=elementLow; el < elementHigh; el++)
  {
    precomputedIntegrals->PrepareElement(el, elIter);
    int * row = row_[el];
    int * column = column_[el];

    for(int ver=0; ver<numElementVertices; ver++)
      vertices[ver] = volumetricMesh->getVertexIndex(el, ver);

    double lambda = lambdaLame[el]; 
    double mu = muLame[el];

    for (int c=0; c<numElementVertices; c++) // over all vertices of the voxel, computing row of vertex c
    {
      int rowc = 3*row[c];
      int c8 = numElementVertices*c;
      // quadratic terms
      for (int e=0; e<numElementVertices; e++) // compute contribution to block (c,e) of the stiffness matrix
      {
        double matrix[9];
        memset(matrix, 0, sizeof(double) * 9);
        for(int a=0; a<numElementVertices; a++)
        {
          double qa[3] = { vertexDisplacements[3*vertices[a]+0], vertexDisplacements[3*vertices[a]+1], vertexDisplacements[3*vertices[a]+2] };

          Vec3d C0v = lambda * precomputedIntegrals->C(elIter,c,a,e) + mu * (precomputedIntegrals->C(elIter,e,a,c) + precomputedIntegrals->C(elIter,a,e,c));
          double C0[3] = {C0v[0], C0v[1], C0v[2]};

          // C0 tensor qa
          matrix[0] += C0[0] * qa[0]; matrix[1] += C0[0] * qa[1]; matrix[2] += C0[0] * qa[2];
          matrix[3] += C0[1] * qa[0]; matrix[4] += C0[1] * qa[1]; matrix[5] += C0[1] * qa[2];
          matrix[6] += C0[2] * qa[0]; matrix[7] += C0[2] * qa[1]; matrix[8] += C0[2] * qa[2];

          Vec3d C1v = lambda * precomputedIntegrals->C(elIter,e,a,c) + mu * (precomputedIntegrals->C(elIter,c,e,a) + precomputedIntegrals->C(elIter,a,e,c));
          double C1[3] = {C1v[0], C1v[1], C1v[2]};

          // qa tensor C1
          matrix[0] += qa[0] * C1[0]; matrix[1] += qa[0] * C1[1]; matrix[2] += qa[0] * C1[2];
          matrix[3] += qa[1] * C1[0]; matrix[4] += qa[1] * C1[1]; matrix[5] += qa[1] * C1[2];
          matrix[6] += qa[2] * C1[0]; matrix[7] += qa[2] * C1[1]; matrix[8] += qa[2] * C1[2];

          Vec3d C2v = lambda * precomputedIntegrals->C(elIter,a,e,c) + mu * (precomputedIntegrals->C(elIter,c,a,e) + precomputedIntegrals->C(elIter,e,a,c));
          double C2[3] = {C2v[0], C2v[1], C2v[2]};

          // qa dot C2
          double dotp = qa[0]*C2[0] + qa[1]*C2[1] + qa[2]*C2[2];
          matrix[0] += dotp; 
          matrix[4] += dotp; 
          matrix[8] += dotp; 

        }
        int k,l;
        ADD_MATRIX_BLOCK(e);
      }
    }
  }

  free(vertices);

  precomputedIntegrals->ReleaseElementIterator(elIter);
}