double StVKInternalForces::ComputeEnergyContribution(double * vertexDisplacements, int elementLow, int elementHigh, double * buffer)
{
  if (buffer == NULL)
    buffer = this->buffer;

  int numVertices = volumetricMesh->getNumVertices();
  double energy = 0;

  // ---- linear
  ResetVector(buffer);
  AddLinearTermsContribution(vertexDisplacements, buffer, elementLow, elementHigh);
  for (int i=0; i< 3 * numVertices; i++)
    energy += 0.5 * buffer[i] * vertexDisplacements[i];

  // ---- quadratic
  ResetVector(buffer);
  AddQuadraticTermsContribution(vertexDisplacements, buffer, elementLow, elementHigh);
  double oneThird = 1.0 / 3;
  for (int i=0; i< 3 * numVertices; i++)
    energy += oneThird * buffer[i] * vertexDisplacements[i];

  // ---- cubic
  ResetVector(buffer);
  AddCubicTermsContribution(vertexDisplacements, buffer, elementLow, elementHigh);
  double oneQuarter = 1.0 / 4;
  for (int i=0; i< 3 * numVertices; i++)
    energy += oneQuarter * buffer[i] * vertexDisplacements[i];

  return energy;
}
// the master function
void StVKStiffnessMatrix::ComputeStiffnessMatrix(double * vertexDisplacements, SparseMatrix * sparseMatrix)
{
  //PerformanceCounter stiffnessCounter;
  sparseMatrix->ResetToZero();

  AddLinearTermsContribution(vertexDisplacements, sparseMatrix);
  AddQuadraticTermsContribution(vertexDisplacements, sparseMatrix);
  AddCubicTermsContribution(vertexDisplacements, sparseMatrix);

  //stiffnessCounter.StopCounter();
  //printf("Stiffness matrix: %G\n", stiffnessCounter.GetElapsedTime());
}
void StVKInternalForces::ComputeForces(double * vertexDisplacements, double * forces)
{
  //PerformanceCounter forceCounter;

  ResetVector(forces);
  AddLinearTermsContribution(vertexDisplacements, forces);
  AddQuadraticTermsContribution(vertexDisplacements, forces);
  AddCubicTermsContribution(vertexDisplacements, forces);

  if (addGravity)
  {
    int n = volumetricMesh->getNumVertices();
    for(int i=0; i<3*n; i++)
      forces[i] -= gravityForce[i];
  }

  //forceCounter.StopCounter();
  //printf("Internal forces: %G\n", forceCounter.GetElapsedTime());
}
void StVKHessianTensor::ComputeStiffnessMatrixCorrection(double * u, double * du, SparseMatrix * dK)
{
  dK->ResetToZero();
  AddQuadraticTermsContribution(u, du, dK);
  AddCubicTermsContribution(u, du, dK);
}