perf(hex8): defer optional paired tangent until a valid linear trial
This commit is contained in:
@@ -2,10 +2,12 @@
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
|
||||
#include "../math/high_low_arithmetic.h"
|
||||
#include "hex8_geometry.h"
|
||||
#include "hex8_linear_tangent_cache.h"
|
||||
#include "hex8_pair_arithmetic.h"
|
||||
|
||||
namespace fesa {
|
||||
@@ -53,7 +55,8 @@ std::array<double, 6> Pack(const Tensor& a) {
|
||||
} // namespace
|
||||
|
||||
Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
|
||||
const Vector& high, const Vector& low, bool nonlinear) const {
|
||||
const Vector& high, const Vector& low, bool nonlinear,
|
||||
bool prepare_linear_cache) const {
|
||||
using math_internal::IsNormalized;
|
||||
if (!math_internal::ArithmeticEnvironmentSupported())
|
||||
return Result<Hex8HighLowResponse>::Failure(Failure(
|
||||
@@ -85,6 +88,19 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
|
||||
message = "Hex8 full high+low Jacobian interval arithmetic is nonfinite.";
|
||||
return Result<Hex8HighLowResponse>::Failure(Failure(message));
|
||||
}
|
||||
if (!nonlinear && prepare_linear_cache) {
|
||||
// Trial guards above run before optional reference preparation. The nested
|
||||
// zero trial bypasses this once entry and uses the original paired graph.
|
||||
std::call_once(paired_linear_tangent_->preparation, [this] {
|
||||
const Vector zero{24U};
|
||||
const auto paired = EvaluateHighLow(zero, zero, false, false);
|
||||
if (paired.HasValue()) {
|
||||
paired_linear_tangent_->high = paired.Value().high.tangent;
|
||||
paired_linear_tangent_->low = paired.Value().tangent_low;
|
||||
paired_linear_tangent_->ready = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Hex8HighLowResponse response;
|
||||
std::array<HighLow, 24> force{};
|
||||
@@ -196,7 +212,7 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
|
||||
for (std::size_t i = 0; i < 3; ++i) {
|
||||
force[3U * a + i] += Dot(p[i], gradients[a]) * HighLow{point.weight};
|
||||
}
|
||||
if (!nonlinear && paired_linear_tangent_ready_) continue;
|
||||
if (!nonlinear && paired_linear_tangent_->ready) continue;
|
||||
std::array<Triple, 8> fg{};
|
||||
for (std::size_t a = 0; a < 8; ++a)
|
||||
for (std::size_t i = 0; i < 3; ++i)
|
||||
@@ -243,7 +259,7 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nonlinear || !paired_linear_tangent_ready_) {
|
||||
if (nonlinear || !paired_linear_tangent_->ready) {
|
||||
std::array<Triple, 8> bulk_fg{};
|
||||
for (std::size_t a = 0; a < 8; ++a)
|
||||
for (std::size_t i = 0; i < 3; ++i)
|
||||
@@ -260,10 +276,10 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
|
||||
Failure("Hex8 high+low energy is unsupported or nonfinite."));
|
||||
response.high.strain_energy = energy.high;
|
||||
response.strain_energy_low = energy.low;
|
||||
if (!nonlinear && paired_linear_tangent_ready_) {
|
||||
response.high.material_tangent = paired_linear_tangent_high_;
|
||||
response.high.tangent = paired_linear_tangent_high_;
|
||||
response.tangent_low = paired_linear_tangent_low_;
|
||||
if (!nonlinear && paired_linear_tangent_->ready) {
|
||||
response.high.material_tangent = paired_linear_tangent_->high;
|
||||
response.high.tangent = paired_linear_tangent_->high;
|
||||
response.tangent_low = paired_linear_tangent_->low;
|
||||
}
|
||||
for (std::size_t i = 0; i < 24; ++i) {
|
||||
if (!IsNormalized(force[i]))
|
||||
@@ -271,7 +287,7 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
|
||||
Failure("Hex8 high+low force is unsupported or nonfinite."));
|
||||
response.high.internal_force[i] = force[i].high;
|
||||
response.internal_force_low[i] = force[i].low;
|
||||
if (!nonlinear && paired_linear_tangent_ready_) continue;
|
||||
if (!nonlinear && paired_linear_tangent_->ready) continue;
|
||||
for (std::size_t j = 0; j < 24; ++j) {
|
||||
const auto tangent = material[i][j] + geometric[i][j];
|
||||
if (!IsNormalized(material[i][j]) || !IsNormalized(geometric[i][j]) ||
|
||||
|
||||
Reference in New Issue
Block a user