Skip to content

Instantly share code, notes, and snippets.

@alecjacobson
Created October 26, 2024 17:51
Show Gist options
  • Save alecjacobson/72ebf7bb5d0eb25216c33546808c9daa to your computer and use it in GitHub Desktop.
Save alecjacobson/72ebf7bb5d0eb25216c33546808c9daa to your computer and use it in GitHub Desktop.
ElasticModuli class implementing the conversion table at https://en.wikipedia.org/wiki/Elastic_modulus . Setting any two input parameters will calculate the remaining four.
#include <optional>
#include <cmath>
//////////////////////////////////////////////////////////////////////////
/// ElasticModuli class implementing the conversion table at
/// https://en.wikipedia.org/wiki/Elastic_modulus
///
/// Setting any two input parameters will calculate the remaining four.
///
//////////////////////////////////////////////////////////////////////////
// Helper struct so we can pass parameters to the constructor of ElasticModuli
struct ElasticModuliParams {
std::optional<double> K; // Bulk modulus
std::optional<double> E; // Young's modulus
std::optional<double> nu; // Poisson's ratio
std::optional<double> G; // Shear modulus
std::optional<double> lambda; // Lame's first parameter
std::optional<double> M; // P-wave modulus
};
struct ElasticModuli
{
double K; // Bulk modulus
double E; // Young's modulus
double nu; // Poisson's ratio
double G; // Shear modulus
double lambda; // Lame's first parameter
double M; // P-wave modulus
ElasticModuli(const ElasticModuliParams& params)
: K(params.K.value_or(std::nan(""))),
E(params.E.value_or(std::nan(""))),
nu(params.nu.value_or(std::nan(""))),
G(params.G.value_or(std::nan(""))),
lambda(params.lambda.value_or(std::nan(""))),
M(params.M.value_or(std::nan("")))
{
int num_params = 0;
if (params.K) num_params++;
if (params.E) num_params++;
if (params.nu) num_params++;
if (params.G) num_params++;
if (params.lambda) num_params++;
if (params.M) num_params++;
if (num_params <= 1) { return; }
if (num_params > 2) { throw std::invalid_argument("Invalid number of parameters"); }
if (params.K && params.E) {
lambda = (3*K*(3*K-E))/(9*K-E);
G = (3*K*E)/(9*K-E);
nu = (3*K-E)/(6*K);
M = (3*K*(3*K+E))/(9*K-E);
}
if (params.K && params.lambda) {
E = (9*K*(K-lambda))/(3*K-lambda);
G = (3*(K-lambda))/(2);
nu = (lambda)/(3*K-lambda);
M = 3*K-2*lambda;
}
if (params.K && params.G) {
E = (9*K*G)/(3*K+G);
lambda = K- (2*G)/(3);
nu = (3*K-2*G)/(2*(3*K+G));
M = K+ (4*G)/(3);
}
if (params.K && params.nu) {
E = 3*K*(1-2*nu);
lambda = (3*K*nu)/(1+nu);
G = (3*K*(1-2*nu))/(2*(1+nu));
M = (3*K*(1-nu))/(1+nu);
}
if (params.K && params.M) {
E = (9*K*(M-K))/(3*K+M);
lambda = (3*K-M)/(2);
G = (3*(M-K))/(4);
nu = (3*K-M)/(3*K+M);
}
if (params.E && params.lambda) {
double R = sqrt(E*E+9*lambda*lambda + 2*E*lambda);
K = (E + 3*lambda + R)/(6);
G = (E-3*lambda+R)/(4);
nu = (2*lambda)/(E+lambda+R);
M = (E-lambda+R)/(2);
}
if (params.E && params.G) {
K = (E*G)/(3*(3*G-E));
lambda = (G*(E-2*G))/(3*G-E);
nu = (E)/(2*G)-1;
M = (G*(4*G-E))/(3*G-E);
}
if (params.E && params.nu) {
K = (E)/(3*(1-2*nu));
lambda = (E*nu)/((1+nu)*(1-2*nu));
G = (E)/(2*(1+nu));
M = (E*(1-nu))/((1+nu)*(1-2*nu));
}
if (params.E && params.M) {
double S = sqrt(E*E+9*M*M-10*E*M);
K = (3*M-E+S)/(6);
lambda = (M-E+S)/(4);
G = (3*M+E-S)/(8);
nu = (E-M+S)/(4*M);
}
if (params.lambda && params.G) {
K = lambda+ (2*G)/(3);
E = (G*(3*lambda + 2*G))/(lambda + G);
nu = (lambda)/(2*(lambda + G));
M = lambda+2*G;
}
if (params.lambda && params.nu) {
K = (lambda*(1+nu))/(3*nu);
E = (lambda*(1+nu)*(1-2*nu))/(nu);
G = (lambda*(1-2*nu))/(2*nu);
M = (lambda*(1-nu))/(nu);
}
if (params.lambda && params.M) {
K = (M + 2*lambda)/(3);
E = ((M-lambda)*(M+2*lambda))/(M+lambda);
G = (M-lambda)/(2);
nu = (lambda)/(M+lambda);
}
if (params.G && params.nu) {
K = (2*G*(1+nu))/(3*(1-2*nu));
E = 2*G*(1+nu);
lambda = (2*G*nu)/(1-2*nu);
M = (2*G*(1-nu))/(1-2*nu);
}
if (params.G && params.M) {
K = M - (4*G)/(3);
E = (G*(3*M-4*G))/(M-G);
lambda = M - 2*G;
nu = (M - 2*G)/(2*M - 2*G);
}
if (params.nu && params.M) {
K = (M*(1+nu))/(3*(1-nu));
E = (M*(1+nu)*(1-2*nu))/(1-nu);
lambda = (M*nu)/(1-nu);
G = (M*(1-2*nu))/(2*(1-nu));
}
}
};
//////////////////////////////////////////////////////////////////////////
/// Example usage
//////////////////////////////////////////////////////////////////////////
#include <cstdio>
void print(const ElasticModuli& em)
{
// Print in JSON format
std::printf("{ \"K\": %.2g, \"E\": %.2g, \"ν\": %.2g, \"G\": %.2g, \"λ\": %.2g, \"M\": %.2g }\n",
em.K, em.E, em.nu, em.G, em.lambda, em.M);
}
int main()
{
// Initializer lists emulating named parameters
print(ElasticModuli({.E = 2.0, .nu = 0.3}));
print(ElasticModuli({.K = 5.0, .G = 2.0}));
print(ElasticModuli({.E = 2.0, .G = 1.0}));
print(ElasticModuli({.E = 2e4, .nu = 0.49999}));
print(ElasticModuli({}));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment