feat(thermal): certify shell geometry and local heat operators
This commit is contained in:
@@ -13,21 +13,25 @@ struct ThermalTimeFrame {
|
||||
double delta;
|
||||
};
|
||||
|
||||
/// @brief Stores an O(1) fixed-increment grid with exact input-cell endpoint tests.
|
||||
/// @brief Stores an O(1) fixed-increment grid with exact input-cell endpoint
|
||||
/// tests.
|
||||
class ThermalTimeGrid final {
|
||||
public:
|
||||
/// @brief Checks finite positive controls and the uint32 INC bound before use.
|
||||
/// @brief Checks finite positive controls and the uint32 INC bound before
|
||||
/// use.
|
||||
static Result<ThermalTimeGrid> Create(double period, double increment,
|
||||
std::uint32_t maximum = 100U);
|
||||
std::uint32_t maximum = 100U);
|
||||
/// @brief Returns the number of completed increments, excluding initial time.
|
||||
std::uint32_t Count() const noexcept;
|
||||
/// @brief Returns fl(index * nominal increment), or the exact final input time.
|
||||
/// @brief Returns fl(index * nominal increment), or the exact final input
|
||||
/// time.
|
||||
/// @pre index is in [0, Count()].
|
||||
double Time(std::uint32_t index) const noexcept;
|
||||
/// @brief Returns the actual coefficient, never a difference of stored times.
|
||||
/// @pre index is in [1, Count()].
|
||||
double Delta(std::uint32_t index) const noexcept;
|
||||
/// @brief Checks index, finite values and strict increase for one frame in O(1).
|
||||
/// @brief Checks index, finite values and strict increase for one frame in
|
||||
/// O(1).
|
||||
Result<ThermalTimeFrame> Frame(std::uint32_t index) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -2,26 +2,71 @@
|
||||
#define FESA_ELEMENTS_THERMAL_SHELL_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
#include "fesa/core/source_identity.h"
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/math/matrix.h"
|
||||
#include "fesa/math/vector3.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Local Q4 times two-segment P2 transient-heat shell kernel.
|
||||
/// @brief Holds global heat flux at four CCW surface points times six traces.
|
||||
/// @note Trace order is -1+, -.5, 0-, 0+, .5, 1-. Frame columns are e1,e2,n.
|
||||
struct ThermalShellRecovery {
|
||||
std::array<Vector3, 24> global_flux;
|
||||
std::array<std::array<Vector3, 3>, 4> frames;
|
||||
};
|
||||
|
||||
/// @brief Owns checked local Q4 times two-segment P2 transient-heat operators.
|
||||
/// @note Twenty DOFs are node-major, five stations bottom to top per node.
|
||||
class ThermalShell final {
|
||||
public:
|
||||
ThermalShell(std::array<std::size_t, 4> node_indices,
|
||||
std::array<Vector3, 4> coordinates, double conductivity,
|
||||
double density, double specific_heat, double thickness);
|
||||
const std::array<std::size_t, 4>& NodeIndices() const noexcept;
|
||||
/// @brief Builds finite consistent capacity/conduction and flux operators.
|
||||
/// @param coordinates Original midsurface Cartesian coordinates, without
|
||||
/// projection.
|
||||
/// @return A complete kernel or a source-identified geometry/material
|
||||
/// failure.
|
||||
static Result<ThermalShell> Create(SourceEntityId source,
|
||||
std::array<EntityIndex, 4> node_indices,
|
||||
const std::array<Vector3, 4>& coordinates,
|
||||
double conductivity, double density,
|
||||
double specific_heat, double thickness,
|
||||
SourceLocation location = {});
|
||||
/// @brief Returns the original element identity.
|
||||
const SourceEntityId& SourceId() const noexcept;
|
||||
/// @brief Returns Domain node indices, not equation numbers.
|
||||
const std::array<EntityIndex, 4>& NodeIndices() const noexcept;
|
||||
/// @brief Returns the node-major conductivity matrix [power/temperature].
|
||||
const Matrix& Conductivity() const noexcept;
|
||||
/// @brief Returns the consistent capacity matrix [energy/temperature].
|
||||
const Matrix& Capacity() const noexcept;
|
||||
/// @brief Returns componentwise outward roundoff bounds, excluding quadrature
|
||||
/// error.
|
||||
const Matrix& ConductivityError() const noexcept;
|
||||
/// @brief Returns componentwise outward roundoff bounds, excluding quadrature
|
||||
/// error.
|
||||
const Matrix& CapacityError() const noexcept;
|
||||
/// @brief Evaluates q=-k*grad(T) without averaging the two midsurface traces.
|
||||
/// @return Finite global fluxes and right-handed frames or source-identified
|
||||
/// failure.
|
||||
Result<ThermalShellRecovery> Recover(
|
||||
const std::array<double, 20>& temperature) const;
|
||||
|
||||
private:
|
||||
std::array<std::size_t, 4> node_indices_;
|
||||
/// @brief Initializes an unpublished candidate whose operators are filled by
|
||||
/// Create.
|
||||
ThermalShell(SourceEntityId source, std::array<EntityIndex, 4> node_indices,
|
||||
SourceLocation location, double conductivity);
|
||||
SourceEntityId source_;
|
||||
std::array<EntityIndex, 4> node_indices_;
|
||||
SourceLocation location_;
|
||||
double conductivity_value_;
|
||||
Matrix conductivity_{20U, 20U};
|
||||
Matrix capacity_{20U, 20U};
|
||||
Matrix conductivity_error_{20U, 20U};
|
||||
Matrix capacity_error_{20U, 20U};
|
||||
std::array<std::array<Vector3, 20>, 24> gradients_{};
|
||||
std::array<std::array<Vector3, 3>, 4> frames_{};
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
Reference in New Issue
Block a user