feat(cpp-object-oriented-modular-refactoring): step 9 - result-io-vector3
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "fesa/elements/euler_beam_3d.h"
|
||||
#include "fesa/elements/mitc4_shell.h"
|
||||
#include "fesa/math/vector3.h"
|
||||
|
||||
namespace fesa {
|
||||
namespace {
|
||||
@@ -389,27 +390,12 @@ Result<std::vector<EntityIndex>> ResolveLoadTarget(const Domain& domain,
|
||||
"A station-eligibility load target must resolve to a node or node set.");
|
||||
}
|
||||
|
||||
std::array<double, 3> Cross(const std::array<double, 3>& left,
|
||||
const std::array<double, 3>& right) {
|
||||
return {left[1U] * right[2U] - left[2U] * right[1U],
|
||||
left[2U] * right[0U] - left[0U] * right[2U],
|
||||
left[0U] * right[1U] - left[1U] * right[0U]};
|
||||
}
|
||||
|
||||
double Dot(const std::array<double, 3>& left,
|
||||
const std::array<double, 3>& right) {
|
||||
return left[0U] * right[0U] + left[1U] * right[1U] + left[2U] * right[2U];
|
||||
}
|
||||
|
||||
double Norm(const std::array<double, 3>& value) {
|
||||
return std::hypot(value[0U], value[1U], value[2U]);
|
||||
}
|
||||
|
||||
bool AccumulateVectorAndScale(std::array<double, 3>& total, double& scale,
|
||||
const std::array<double, 3>& contribution) {
|
||||
const double magnitude = Norm(contribution);
|
||||
const Vector3 contribution_vector{contribution};
|
||||
const double magnitude = contribution_vector.Norm();
|
||||
const double accumulated_scale = scale + magnitude;
|
||||
if (!IsFinite(contribution) || !std::isfinite(magnitude) ||
|
||||
if (!contribution_vector.IsFinite() || !std::isfinite(magnitude) ||
|
||||
!std::isfinite(accumulated_scale)) {
|
||||
return false;
|
||||
}
|
||||
@@ -427,7 +413,7 @@ bool AccumulateVectorAndScale(std::array<double, 3>& total, double& scale,
|
||||
|
||||
double NormalizedBalance(const std::array<double, 3>& balance,
|
||||
const double scale) {
|
||||
const double balance_norm = Norm(balance);
|
||||
const double balance_norm = Vector3{balance}.Norm();
|
||||
if (!std::isfinite(balance_norm) || !std::isfinite(scale)) {
|
||||
return (std::numeric_limits<double>::infinity)();
|
||||
}
|
||||
@@ -474,10 +460,11 @@ Status PopulateShellGlobalEvidence(const Domain& domain, const DofManager& dofs,
|
||||
}
|
||||
}
|
||||
|
||||
const auto applied_force_moment =
|
||||
Cross(domain.Nodes()[node].coordinates, nodal_applied_force);
|
||||
const auto reaction_force_moment =
|
||||
Cross(domain.Nodes()[node].coordinates, nodal_reaction_force);
|
||||
const Vector3 position{domain.Nodes()[node].coordinates};
|
||||
const Vector3 applied_force_moment =
|
||||
position.Cross(Vector3{nodal_applied_force});
|
||||
const Vector3 reaction_force_moment =
|
||||
position.Cross(Vector3{nodal_reaction_force});
|
||||
for (std::size_t component = 0U; component < 3U; ++component) {
|
||||
nodal_applied_moment[component] += applied_force_moment[component];
|
||||
nodal_reaction_moment[component] += reaction_force_moment[component];
|
||||
@@ -498,24 +485,24 @@ Status PopulateShellGlobalEvidence(const Domain& domain, const DofManager& dofs,
|
||||
}
|
||||
}
|
||||
|
||||
std::array<double, 3> force_balance{};
|
||||
std::array<double, 3> moment_balance{};
|
||||
const Vector3 force_balance =
|
||||
Vector3{applied_force} + Vector3{reaction_force};
|
||||
const Vector3 moment_balance =
|
||||
Vector3{applied_moment} + Vector3{reaction_moment};
|
||||
for (std::size_t component = 0U; component < 3U; ++component) {
|
||||
force_balance[component] =
|
||||
applied_force[component] + reaction_force[component];
|
||||
moment_balance[component] =
|
||||
applied_moment[component] + reaction_moment[component];
|
||||
candidate.equilibrium[component] = force_balance[component];
|
||||
candidate.equilibrium[3U + component] = moment_balance[component];
|
||||
}
|
||||
const double force_metric = NormalizedBalance(
|
||||
force_balance, (std::max)(applied_force_scale, reaction_force_scale));
|
||||
const double force_metric =
|
||||
NormalizedBalance(force_balance.Components(),
|
||||
(std::max)(applied_force_scale, reaction_force_scale));
|
||||
const double moment_metric = NormalizedBalance(
|
||||
moment_balance, (std::max)(applied_moment_scale, reaction_moment_scale));
|
||||
moment_balance.Components(),
|
||||
(std::max)(applied_moment_scale, reaction_moment_scale));
|
||||
candidate.verification_metrics = {normalized_residual, force_metric,
|
||||
moment_metric};
|
||||
if (!IsFinite(candidate.equilibrium) ||
|
||||
!IsFinite(candidate.verification_metrics)) {
|
||||
!Vector3{candidate.verification_metrics}.IsFinite()) {
|
||||
return RecoveryFailure("nonfinite-recovery-value",
|
||||
{domain.SourcePath(), 0U}, "global-equilibrium",
|
||||
"Global equilibrium values and their physical "
|
||||
@@ -535,32 +522,25 @@ std::optional<AxisSet> LocalAxes(const Domain& domain,
|
||||
const EulerBeam3DDefinition& element) {
|
||||
const auto& first = domain.Nodes()[element.node_indices[0U]].coordinates;
|
||||
const auto& second = domain.Nodes()[element.node_indices[1U]].coordinates;
|
||||
const std::array<double, 3> delta = {
|
||||
second[0U] - first[0U], second[1U] - first[1U], second[2U] - first[2U]};
|
||||
const double length = Norm(delta);
|
||||
const Vector3 delta = Vector3{second} - Vector3{first};
|
||||
const double length = delta.Norm();
|
||||
if (!std::isfinite(length) || !(length > 0.0)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const std::array<double, 3> ex = {delta[0U] / length, delta[1U] / length,
|
||||
delta[2U] / length};
|
||||
const auto& guide = domain.Sections()[element.section_index].first_axis;
|
||||
const double projection = Dot(guide, ex);
|
||||
const std::array<double, 3> ey_trial = {guide[0U] - projection * ex[0U],
|
||||
guide[1U] - projection * ex[1U],
|
||||
guide[2U] - projection * ex[2U]};
|
||||
const double ey_norm = Norm(ey_trial);
|
||||
const Vector3 ex = delta / length;
|
||||
const Vector3 guide{domain.Sections()[element.section_index].first_axis};
|
||||
const double projection = guide.Dot(ex);
|
||||
const Vector3 ey_trial = guide - projection * ex;
|
||||
const double ey_norm = ey_trial.Norm();
|
||||
if (!std::isfinite(ey_norm) || !(ey_norm > 0.0)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const std::array<double, 3> ey = {
|
||||
ey_trial[0U] / ey_norm, ey_trial[1U] / ey_norm, ey_trial[2U] / ey_norm};
|
||||
const std::array<double, 3> ez = Cross(ex, ey);
|
||||
const AxisSet axes = {ex, ey, ez};
|
||||
const Vector3 ey = ey_trial / ey_norm;
|
||||
const Vector3 ez = ex.Cross(ey);
|
||||
const AxisSet axes = {ex.Components(), ey.Components(), ez.Components()};
|
||||
for (const auto& axis : axes) {
|
||||
for (const double component : axis) {
|
||||
if (!std::isfinite(component)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!Vector3{axis}.IsFinite()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
return axes;
|
||||
|
||||
Reference in New Issue
Block a user