Connect HHT field convergence to production acceptance and v2 logs

This commit is contained in:
KOKO\Mimi
2026-10-19 02:49:53 +09:00
parent 0e392a7364
commit dd54b0ae1e
9 changed files with 811 additions and 23 deletions
+34 -2
View File
@@ -191,8 +191,34 @@ Result<double> ReferenceLength(const Domain& domain) {
return Result<double>::Success(length);
}
Result<std::array<hht_field_convergence::FieldInput, 2>> MeasureEndpointFields(
const DofManager& dofs, const DynamicAcceptedFrameState& trial,
const DynamicAcceptedFrameState& accepted, const std::optional<Vector>& previous) {
using Fields = std::array<hht_field_convergence::FieldInput, 2>;
const auto count = dofs.FullDofCount();
if (trial.generalized_coordinates.Size() != count || trial.residual.Size() != count ||
accepted.generalized_coordinates.Size() != count || (previous && previous->Size() != count))
return Result<Fields>::Failure(Failure("Invalid full endpoint field inventory."));
Fields fields;
for (auto& field : fields) if (previous) field.correction = 0.0;
for (const auto full : dofs.FreeDofs()) {
auto& field = fields[full % 6U < 3U ? 0U : 1U];
const double residual = std::abs(trial.residual[full]);
const double increment = std::abs(trial.generalized_coordinates[full] - accepted.generalized_coordinates[full]);
const double correction = previous ? std::abs(trial.generalized_coordinates[full] - (*previous)[full]) : 0.0;
if (!std::isfinite(residual) || !std::isfinite(increment) || !std::isfinite(correction))
return Result<Fields>::Failure(Failure("Nonfinite full endpoint field arithmetic."));
field.active = true;
field.residual = (std::max)(field.residual, residual);
field.increment = (std::max)(field.increment, increment);
if (previous) field.correction = (std::max)(*field.correction, correction);
}
return Result<Fields>::Success(std::move(fields));
}
Result<std::array<Vector, 2>> AssembleLoads(const Domain& domain,
const DofManager& dofs) {
const DofManager& dofs,
std::array<std::vector<hht_field_convergence::FluxOccurrence>, 2>* field_flux) {
const auto index = SourceTargetIndex::FromDomain(domain);
const SourceTargetResolver resolver(index);
const LoadContext context{domain, dofs, resolver};
@@ -203,6 +229,9 @@ Result<std::array<Vector, 2>> AssembleLoads(const Domain& domain,
if (!contributions.HasValue())
return Result<std::array<Vector, 2>>::Failure(contributions.GetStatus());
for (const auto& entry : contributions.Value()) {
if (field_flux != nullptr)
(*field_flux)[entry.full_dof_index % 6U < 3U ? 0U : 1U].push_back(
{entry.value, 0.0});
result[0U][entry.full_dof_index] += entry.value;
result[1U][entry.full_dof_index] += std::abs(entry.value);
if (!std::isfinite(result[0U][entry.full_dof_index]) ||
@@ -489,6 +518,7 @@ Result<DynamicAssembly> EvaluateAssembly(
Vector third(count);
Vector third_scale(count);
std::array<std::vector<CooContribution>, 6> entries;
std::array<std::vector<hht_field_convergence::FluxOccurrence>, 2> field_flux;
for (auto& values : entries) values.reserve(shells.size() * 24U * 24U);
double momentum_scale = 0.0;
double angular_scale = 0.0;
@@ -546,6 +576,8 @@ Result<DynamicAssembly> EvaluateAssembly(
const Vector mass_action = EntryProducts(mass_values, acceleration_values);
for (std::size_t row = 0U; row < 24U; ++row) {
const auto global = shells[e].scatter[row];
field_flux[row % 6U < 3U ? 0U : 1U].push_back(
{f.internal_force[row], m.force[row]});
frame.internal_force[global] += f.internal_force[row];
frame.inertia_force[global] += m.force[row];
third[global] += f.force_directional_second[row];
@@ -708,7 +740,7 @@ Result<DynamicAssembly> EvaluateAssembly(
std::move(third), std::move(third_scale), std::move(rotations),
momentum_scale, angular_scale, std::move(hidden_second),
std::move(hidden_second_scale), std::move(hidden_gradient),
std::move(trial_constraints)});
std::move(trial_constraints), std::move(field_flux)});
}
Status CompleteEquilibrium(const Domain& domain, const DofManager& dofs,