MooneyRivlinIsotropicMaterial::MooneyRivlinIsotropicMaterial(TetMesh * tetMesh, int enableCompressionResistance_, double compressionResistance_) : IsotropicMaterialWithCompressionResistance(enableCompressionResistance_), compressionResistance(compressionResistance_)
{
  int numElements = tetMesh->getNumElements();
  mu01_ = (double*) malloc (sizeof(double) * numElements);
  mu10_ = (double*) malloc (sizeof(double) * numElements);
  v1_ = (double*) malloc (sizeof(double) * numElements);

  if (enableCompressionResistance)
    EdivNuFactor = (double*) malloc (sizeof(double) * numElements);
  else
    EdivNuFactor = NULL;

  for(int el=0; el<numElements; el++)
  {
    VolumetricMesh::Material * material = tetMesh->getElementMaterial(el);
    VolumetricMesh::MooneyRivlinMaterial * mooneyRivlinMaterial = downcastMooneyRivlinMaterial(material);
    if (mooneyRivlinMaterial == NULL)
    {
      printf("Error: MooneyRivlinIsotropicMaterial: mesh does not consist of Mooney-Rivlin materials.\n");
      throw 1;
    }

    mu01_[el] = mooneyRivlinMaterial->getmu01();
    mu10_[el] = mooneyRivlinMaterial->getmu10();
    v1_[el] = mooneyRivlinMaterial->getv1();

    if (enableCompressionResistance)
    {
      // invert the following formulas to compute "pseudo" E and nu that correspond to this material
      //K = Ea / ( 3 * ( 1 - 2 * nua ) );
      //G = Ea / ( 2 * ( 1 + nua ) );
      //mu10 = G / ( 2 * ( 1 + mur ) );
      //mu01 = mur * mu10;
      //v1 = K / 2;

      double K = 2.0 * v1_[el];
      double muRatio = mu01_[el] / mu10_[el];
      double G = mu10_[el] * ( 2 * ( 1 + muRatio ) );

      double E = 9 * K * G / (3 * K + G);
      double nu = (3 * K - 2 * G) / (2 * (3 * K + G));

      EdivNuFactor[el] = compressionResistance * E / (1.0 - 2.0 * nu);
      //printf("Setting EdivNuFactor[%d]=%G\n", el, EdivNuFactor[el]);
    }
  }
}
MooneyRivlinIsotropicMaterial::MooneyRivlinIsotropicMaterial(TetMesh * tetMesh)
{
  int numElements = tetMesh->getNumElements();
  mu01_ = (double*) malloc (sizeof(double) * numElements);
  mu10_ = (double*) malloc (sizeof(double) * numElements);
  v1_ = (double*) malloc (sizeof(double) * numElements);

  for(int el=0; el<numElements; el++)
  {
    VolumetricMesh::Material * material = tetMesh->getElementMaterial(el);
    VolumetricMesh::MooneyRivlinMaterial * mooneyRivlinMaterial = downcastMooneyRivlinMaterial(material);
    if (mooneyRivlinMaterial == NULL)
    {
      printf("Error: mesh does not consist of Mooney-Rivlin materials.\n");
      throw 1;
    }

    mu01_[el] = mooneyRivlinMaterial->getmu01();
    mu10_[el] = mooneyRivlinMaterial->getmu10();
    v1_[el] = mooneyRivlinMaterial->getv1();
  }
}