feat(cpp-object-oriented-modular-refactoring): step 8 - element-geometry-vector3
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/math/vector3.h"
|
||||
|
||||
namespace fesa {
|
||||
namespace {
|
||||
|
||||
@@ -17,26 +19,6 @@ constexpr std::size_t kGeneralizedComponentCount = 4U;
|
||||
constexpr double kGeometryTolerance = 1.0e-12;
|
||||
constexpr double kStiffnessInvariantTolerance = 1.0e-12;
|
||||
|
||||
using Vector3 = std::array<double, 3>;
|
||||
|
||||
double Norm(const Vector3& value) {
|
||||
return std::hypot(value[0], value[1], value[2]);
|
||||
}
|
||||
|
||||
double Dot(const Vector3& lhs, const Vector3& rhs) {
|
||||
return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];
|
||||
}
|
||||
|
||||
Vector3 Cross(const Vector3& lhs, const Vector3& rhs) {
|
||||
return {lhs[1] * rhs[2] - lhs[2] * rhs[1], lhs[2] * rhs[0] - lhs[0] * rhs[2],
|
||||
lhs[0] * rhs[1] - lhs[1] * rhs[0]};
|
||||
}
|
||||
|
||||
bool IsFinite(const Vector3& value) {
|
||||
return std::isfinite(value[0]) && std::isfinite(value[1]) &&
|
||||
std::isfinite(value[2]);
|
||||
}
|
||||
|
||||
std::string ElementIdentity(const Node& first_node, const Node& second_node) {
|
||||
return first_node.source_id.instance_name + ":" +
|
||||
first_node.source_id.source_label_text + "-" +
|
||||
@@ -233,13 +215,13 @@ Result<EulerBeam3D> EulerBeam3D::Create(const Node& first_node,
|
||||
const GeneralBeamSection& section,
|
||||
const LinearElasticMaterial& material) {
|
||||
const std::string identity = ElementIdentity(first_node, second_node);
|
||||
const Vector3& first = first_node.coordinates;
|
||||
const Vector3& second = second_node.coordinates;
|
||||
const Vector3 delta = {second[0] - first[0], second[1] - first[1],
|
||||
second[2] - first[2]};
|
||||
const double length = Norm(delta);
|
||||
const double coordinate_scale = (std::max)({1.0, Norm(first), Norm(second)});
|
||||
if (!IsFinite(first) || !IsFinite(second) || !IsFinite(delta) ||
|
||||
const Vector3 first{first_node.coordinates};
|
||||
const Vector3 second{second_node.coordinates};
|
||||
const Vector3 delta = second - first;
|
||||
const double length = delta.Norm();
|
||||
const double coordinate_scale =
|
||||
(std::max)({1.0, first.Norm(), second.Norm()});
|
||||
if (!first.IsFinite() || !second.IsFinite() || !delta.IsFinite() ||
|
||||
!std::isfinite(length) || !std::isfinite(coordinate_scale) ||
|
||||
!(length > kGeometryTolerance * coordinate_scale)) {
|
||||
return ModelFailure(
|
||||
@@ -247,15 +229,13 @@ Result<EulerBeam3D> EulerBeam3D::Create(const Node& first_node,
|
||||
"Beam length must exceed the scale-aware geometry threshold.");
|
||||
}
|
||||
|
||||
const Vector3 ex = {delta[0] / length, delta[1] / length, delta[2] / length};
|
||||
const Vector3& guide = section.first_axis;
|
||||
const double guide_norm = Norm(guide);
|
||||
const double guide_projection = Dot(guide, ex);
|
||||
const Vector3 ey_trial = {guide[0] - guide_projection * ex[0],
|
||||
guide[1] - guide_projection * ex[1],
|
||||
guide[2] - guide_projection * ex[2]};
|
||||
const double ey_trial_norm = Norm(ey_trial);
|
||||
if (!IsFinite(guide) || !std::isfinite(guide_norm) || !IsFinite(ey_trial) ||
|
||||
const Vector3 ex = delta / length;
|
||||
const Vector3 guide{section.first_axis};
|
||||
const double guide_norm = guide.Norm();
|
||||
const double guide_projection = guide.Dot(ex);
|
||||
const Vector3 ey_trial = guide - guide_projection * ex;
|
||||
const double ey_trial_norm = ey_trial.Norm();
|
||||
if (!guide.IsFinite() || !std::isfinite(guide_norm) || !ey_trial.IsFinite() ||
|
||||
!std::isfinite(ey_trial_norm) ||
|
||||
!(ey_trial_norm > kGeometryTolerance * (std::max)(1.0, guide_norm))) {
|
||||
return ModelFailure(
|
||||
@@ -323,9 +303,8 @@ Result<EulerBeam3D> EulerBeam3D::Create(const Node& first_node,
|
||||
"Derived beam stiffness coefficients must be finite and positive.");
|
||||
}
|
||||
|
||||
const Vector3 ey = {ey_trial[0] / ey_trial_norm, ey_trial[1] / ey_trial_norm,
|
||||
ey_trial[2] / ey_trial_norm};
|
||||
const Vector3 ez = Cross(ex, ey);
|
||||
const Vector3 ey = ey_trial / ey_trial_norm;
|
||||
const Vector3 ez = ex.Cross(ey);
|
||||
// Rows map global vectors to the approved right-handed local (ex,ey,ez)
|
||||
// basis.
|
||||
const std::array<double, 9> rotation = {ex[0], ex[1], ex[2], ey[0], ey[1],
|
||||
|
||||
Reference in New Issue
Block a user