80 lines
2.6 KiB
C++
80 lines
2.6 KiB
C++
#ifndef FESA_ELEMENTS_SHELL_KERNEL_VALUES_H_
|
|
#define FESA_ELEMENTS_SHELL_KERNEL_VALUES_H_
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "fesa/elements/mitc4_shell.h"
|
|
#include "fesa/math/matrix.h"
|
|
#include "fesa/math/vector3.h"
|
|
#include "fesa/model/model_types.h"
|
|
|
|
namespace fesa::shell_kernel_internal {
|
|
|
|
/// @brief Constructs the shared model-category shell-kernel failure envelope.
|
|
template <class T>
|
|
Result<T> Failure(const std::string& code, const SourceLocation& location,
|
|
const std::string& identity, std::string message) {
|
|
return Result<T>::Failure(Status::Failure(
|
|
FailureCategory::kModel, {{Severity::kError, code, location, "*ELEMENT",
|
|
identity, std::move(message)}}));
|
|
}
|
|
|
|
/// @brief Preserves raw source labels and the existing null-skip diagnostic identity.
|
|
inline std::string ElementIdentity(const std::array<const Node*, 4>& nodes) {
|
|
std::string identity;
|
|
for (const Node* node : nodes) {
|
|
if (node == nullptr) {
|
|
continue;
|
|
}
|
|
if (!identity.empty()) {
|
|
identity += "-";
|
|
}
|
|
identity += node->source_id.source_label_text;
|
|
}
|
|
return identity;
|
|
}
|
|
|
|
/// @brief Copies the initial semantic frame into its three ordered columns.
|
|
inline Matrix FrameMatrix(const ShellNodeInitialFrame& frame) {
|
|
Matrix result{3U, 3U};
|
|
for (std::size_t row = 0U; row < 3U; ++row) {
|
|
result(row, 0U) = frame.tangent_a[row];
|
|
result(row, 1U) = frame.tangent_b[row];
|
|
result(row, 2U) = frame.director[row];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// @brief Contracts one ordinary tensor component in the original row/column order.
|
|
inline double FrameComponent(
|
|
const Vector3& left, const std::array<std::array<double, 3>, 3>& tensor,
|
|
const Vector3& right) {
|
|
double value = 0.0;
|
|
for (std::size_t row = 0U; row < 3U; ++row) {
|
|
for (std::size_t column = 0U; column < 3U; ++column) {
|
|
value += left[row] * tensor[row][column] * right[column];
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/// @brief Projects fixed-reference tensor strain to the five engineering components.
|
|
inline std::array<double, 5> LocalEngineeringComponents(
|
|
const std::array<std::array<double, 3>, 3>& tensor,
|
|
const Mitc4LocalFrame& frame) {
|
|
const Vector3 e1{frame.e1};
|
|
const Vector3 e2{frame.e2};
|
|
const Vector3 e3{frame.e3};
|
|
return {FrameComponent(e1, tensor, e1), FrameComponent(e2, tensor, e2),
|
|
2.0 * FrameComponent(e1, tensor, e2),
|
|
2.0 * FrameComponent(e1, tensor, e3),
|
|
2.0 * FrameComponent(e2, tensor, e3)};
|
|
}
|
|
|
|
} // namespace fesa::shell_kernel_internal
|
|
|
|
#endif // FESA_ELEMENTS_SHELL_KERNEL_VALUES_H_
|