122 lines
4.3 KiB
C++
122 lines
4.3 KiB
C++
#pragma once
|
|
|
|
#include "fesa/Math/Vector.hpp"
|
|
#include "fesa/Util/Diagnostics.hpp"
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace fesa {
|
|
|
|
using MITC4StrainVector = std::array<Real, 6>;
|
|
using MITC4MaterialMatrix = std::array<std::array<Real, 6>, 6>;
|
|
|
|
enum class MITC4StrainComponent {
|
|
Eps11 = 0,
|
|
Eps22 = 1,
|
|
Eps33 = 2,
|
|
Gamma23 = 3,
|
|
Gamma13 = 4,
|
|
Gamma12 = 5
|
|
};
|
|
|
|
inline std::size_t strainComponentIndex(MITC4StrainComponent component) {
|
|
return static_cast<std::size_t>(component);
|
|
}
|
|
|
|
inline std::array<std::string, 6> mitc4StrainComponentLabels() {
|
|
return {"eps11", "eps22", "eps33", "gamma23", "gamma13", "gamma12"};
|
|
}
|
|
|
|
struct MITC4MaterialMatrixEvaluation {
|
|
MITC4MaterialMatrix matrix{};
|
|
std::vector<Diagnostic> diagnostics;
|
|
|
|
bool ok() const {
|
|
return !hasError(diagnostics);
|
|
}
|
|
};
|
|
|
|
inline Diagnostic mitc4MaterialDiagnostic(std::string code, std::string message) {
|
|
return makeDiagnostic(Severity::Error, std::move(code), std::move(message), "mitc4", "<element>", 0);
|
|
}
|
|
|
|
inline MITC4MaterialMatrixEvaluation mitc4PlaneStressMaterialMatrix(Real elastic_modulus, Real poisson_ratio,
|
|
Real shear_correction = 5.0 / 6.0,
|
|
Real tolerance = 1.0e-12) {
|
|
MITC4MaterialMatrixEvaluation result;
|
|
if (!isFinite(elastic_modulus) || elastic_modulus <= tolerance) {
|
|
result.diagnostics.push_back(
|
|
mitc4MaterialDiagnostic("FESA-MITC4-MATERIAL", "MITC4 elastic modulus must be positive and finite"));
|
|
}
|
|
if (!isFinite(poisson_ratio) || poisson_ratio <= -1.0 || poisson_ratio >= 0.5) {
|
|
result.diagnostics.push_back(
|
|
mitc4MaterialDiagnostic("FESA-MITC4-POISSON", "MITC4 isotropic Poisson ratio must satisfy -1 < nu < 0.5"));
|
|
}
|
|
if (!isFinite(shear_correction) || shear_correction <= tolerance) {
|
|
result.diagnostics.push_back(mitc4MaterialDiagnostic("FESA-MITC4-SHEAR-CORRECTION",
|
|
"MITC4 shear correction factor must be positive and finite"));
|
|
}
|
|
if (hasError(result.diagnostics)) {
|
|
return result;
|
|
}
|
|
|
|
const Real scale = elastic_modulus / (1.0 - poisson_ratio * poisson_ratio);
|
|
const Real shear_modulus = elastic_modulus / (2.0 * (1.0 + poisson_ratio));
|
|
const std::size_t eps11 = strainComponentIndex(MITC4StrainComponent::Eps11);
|
|
const std::size_t eps22 = strainComponentIndex(MITC4StrainComponent::Eps22);
|
|
const std::size_t gamma23 = strainComponentIndex(MITC4StrainComponent::Gamma23);
|
|
const std::size_t gamma13 = strainComponentIndex(MITC4StrainComponent::Gamma13);
|
|
const std::size_t gamma12 = strainComponentIndex(MITC4StrainComponent::Gamma12);
|
|
|
|
result.matrix[eps11][eps11] = scale;
|
|
result.matrix[eps11][eps22] = poisson_ratio * scale;
|
|
result.matrix[eps22][eps11] = poisson_ratio * scale;
|
|
result.matrix[eps22][eps22] = scale;
|
|
result.matrix[gamma23][gamma23] = shear_correction * shear_modulus;
|
|
result.matrix[gamma13][gamma13] = shear_correction * shear_modulus;
|
|
result.matrix[gamma12][gamma12] = shear_modulus;
|
|
return result;
|
|
}
|
|
|
|
inline MITC4StrainVector multiplyMITC4MaterialMatrix(const MITC4MaterialMatrix& matrix,
|
|
const MITC4StrainVector& vector) {
|
|
MITC4StrainVector result{};
|
|
for (std::size_t row = 0; row < 6; ++row) {
|
|
for (std::size_t col = 0; col < 6; ++col) {
|
|
result[row] += matrix[row][col] * vector[col];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
inline Real dotMITC4Vector(const MITC4StrainVector& a, const MITC4StrainVector& b) {
|
|
Real result = 0.0;
|
|
for (std::size_t i = 0; i < 6; ++i) {
|
|
result += a[i] * b[i];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
inline MITC4MaterialMatrix mitc4TransformMaterialMatrix(const MITC4MaterialMatrix& local_material,
|
|
const MITC4MaterialMatrix& covariant_to_local) {
|
|
MITC4MaterialMatrix result{};
|
|
for (std::size_t i = 0; i < 6; ++i) {
|
|
for (std::size_t j = 0; j < 6; ++j) {
|
|
Real value = 0.0;
|
|
for (std::size_t a = 0; a < 6; ++a) {
|
|
for (std::size_t b = 0; b < 6; ++b) {
|
|
value += covariant_to_local[a][i] * local_material[a][b] * covariant_to_local[b][j];
|
|
}
|
|
}
|
|
result[i][j] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
} // namespace fesa
|