feat(shell-surface-pressure-load): step 4 - integrate-linear-shell-pressure
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include "fesa/analysis/linear_static_procedure.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -8,6 +10,7 @@
|
||||
#include "fesa/assembly/load_assembler.h"
|
||||
#include "fesa/assembly/parallel_for.h"
|
||||
#include "fesa/assembly/sparse_assembler.h"
|
||||
#include "fesa/assembly/surface_pressure_assembler.h"
|
||||
#include "fesa/constraints/essential_constraint_policy.h"
|
||||
#include "fesa/elements/element.h"
|
||||
#include "fesa/elements/element_factory.h"
|
||||
@@ -67,12 +70,67 @@ Result<LinearStaticExecutionResult> LinearStaticProcedureExecutor::Execute(
|
||||
return Result<LinearStaticExecutionResult>::Failure(factorized);
|
||||
}
|
||||
|
||||
Result<Vector> external =
|
||||
Result<Vector> nodal_external =
|
||||
LoadAssembler::AssembleFullNodalLoad(model.Value(), dofs);
|
||||
if (!external.HasValue()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(external.GetStatus());
|
||||
if (!nodal_external.HasValue()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(
|
||||
nodal_external.GetStatus());
|
||||
}
|
||||
state.ExternalForce() = std::move(external.Value());
|
||||
Vector reference_coordinates{dofs.FullDofCount()};
|
||||
Result<SurfacePressureAssemblyCandidate> pressure_external =
|
||||
AssembleSurfacePressure(model.Value(), dofs, reference_coordinates, 1.0,
|
||||
SurfacePressureConfiguration::kReference,
|
||||
parallel_for_);
|
||||
if (!pressure_external.HasValue()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(
|
||||
pressure_external.GetStatus());
|
||||
}
|
||||
if (pressure_external.Value().full_external_force.Size() !=
|
||||
nodal_external.Value().Size() ||
|
||||
pressure_external.Value().full_external_tangent.Rows() !=
|
||||
dofs.FullDofCount() ||
|
||||
pressure_external.Value().full_external_tangent.Columns() !=
|
||||
dofs.FullDofCount()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(Status::Failure(
|
||||
FailureCategory::kModel,
|
||||
{{Severity::kError,
|
||||
"invalid-pressure-dimensions",
|
||||
{domain.SourcePath(), 0U},
|
||||
"DSLOAD",
|
||||
domain.SourceContentIdentity(),
|
||||
"Pressure assembly must return the stable full-DOF dimensions."}}));
|
||||
}
|
||||
for (const double value :
|
||||
pressure_external.Value().full_external_tangent.Values()) {
|
||||
if (value != 0.0) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(Status::Failure(
|
||||
FailureCategory::kModel,
|
||||
{{Severity::kError,
|
||||
"nonzero-linear-pressure-tangent",
|
||||
{domain.SourcePath(), 0U},
|
||||
"DSLOAD",
|
||||
domain.SourceContentIdentity(),
|
||||
"Reference-configuration linear pressure requires zero "
|
||||
"tangent."}}));
|
||||
}
|
||||
}
|
||||
for (std::size_t index = 0U; index < nodal_external.Value().Size(); ++index) {
|
||||
const double combined =
|
||||
nodal_external.Value()[index] +
|
||||
pressure_external.Value().full_external_force[index];
|
||||
if (!std::isfinite(combined)) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(Status::Failure(
|
||||
FailureCategory::kSolver,
|
||||
{{Severity::kError,
|
||||
"nonfinite-load-accumulation",
|
||||
{domain.SourcePath(), 0U},
|
||||
"DSLOAD",
|
||||
std::to_string(index),
|
||||
"Nodal and surface pressure load accumulation is nonfinite."}}));
|
||||
}
|
||||
nodal_external.Value()[index] = combined;
|
||||
}
|
||||
state.ExternalForce() = std::move(nodal_external.Value());
|
||||
|
||||
Result<Vector> rhs = LoadAssembler::EffectiveFreeRhs(
|
||||
state.ExternalForce(), partitions.Value().k_fc, dofs.PrescribedValues(),
|
||||
@@ -97,6 +155,9 @@ Result<LinearStaticExecutionResult> LinearStaticProcedureExecutor::Execute(
|
||||
}
|
||||
|
||||
std::vector<Diagnostic> diagnostics = domain.Warnings();
|
||||
diagnostics.insert(diagnostics.end(),
|
||||
pressure_external.Value().diagnostics.begin(),
|
||||
pressure_external.Value().diagnostics.end());
|
||||
SortDiagnostics(diagnostics);
|
||||
return Result<LinearStaticExecutionResult>::Success(
|
||||
{std::move(state), std::move(diagnostics)});
|
||||
|
||||
Reference in New Issue
Block a user