Created
October 26, 2024 17:51
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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