feat(mean_field): added dimensions, discritization, and start of eos
The full rewrite of mean_field into something maintainable is progressing. dimensions is mostly done, discritization (domain, blocks, and fields) is done, and eos is progressing quickly
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "serif/discretization/domain/concepts.hpp"
|
||||
#include "serif/discretization/domain/mesh/topology.hpp"
|
||||
#include "serif/discretization/domain/relation/relations.hpp"
|
||||
#include "serif/discretization/domain/relation/validation/runtime.hpp"
|
||||
#include "serif/discretization/domain/schema/concepts.hpp"
|
||||
#include "serif/discretization/domain/schema/validation/validator.hpp"
|
||||
|
||||
// Inscribed<InnerT, OuterT>: every face where the inner domain stops must have
|
||||
// the outer domain on the far side.
|
||||
namespace serif::discretization::domain::schema::validation {
|
||||
using relation::Inscribed;
|
||||
|
||||
using relation::validation::RelationValidationResult;
|
||||
using relation::validation::RelationValidationFailure;
|
||||
|
||||
template <IsDomainOrSet InnerT, IsDomainOrSet OuterT>
|
||||
struct RelationValidator<Inscribed<InnerT, OuterT>> {
|
||||
template <IsSchema SchemaT>
|
||||
[[nodiscard]] static RelationValidationResult validate(const mesh::MeshTopology &topology) {
|
||||
static_assert(
|
||||
SchemaT::template contains_domain<InnerT>(), "The inner domain of an Inscribed relation is not present in the supplied schema. Inscribed cannot be enforced"
|
||||
);
|
||||
|
||||
static_assert(
|
||||
SchemaT::template contains_domain<OuterT>(), "The outer domain of an Inscribed relation is not present in the supplied schema. Inscribed cannot be enforced"
|
||||
);
|
||||
|
||||
bool foundInnerElement = false;
|
||||
bool foundOuterElement = false;
|
||||
bool foundInnerBoundary = false;
|
||||
|
||||
for (int elementID = 0; elementID < topology.element_count(); ++elementID) {
|
||||
const int domainID = topology.element_domain_id(elementID);
|
||||
|
||||
foundInnerElement = foundInnerElement || SchemaT::template domain_id_belongs_to<InnerT>(domainID);
|
||||
foundOuterElement = foundOuterElement || SchemaT::template domain_id_belongs_to<OuterT>(domainID);
|
||||
}
|
||||
|
||||
if (!foundInnerElement) {
|
||||
return {.failure = RelationValidationFailure::InnerDomainAbsent};
|
||||
}
|
||||
|
||||
if (!foundOuterElement) {
|
||||
return {.failure = RelationValidationFailure::OuterDomainAbsent};
|
||||
}
|
||||
|
||||
for (int faceID = 0; faceID < topology.face_count(); ++faceID) {
|
||||
const mesh::FaceElements faceElements = topology.face_elements(faceID);
|
||||
|
||||
const int firstElementID = faceElements.firstElementID;
|
||||
const int secondElementID = faceElements.secondElementID;
|
||||
|
||||
const bool firstIsInner = firstElementID >= 0 &&
|
||||
SchemaT::template domain_id_belongs_to<InnerT>(topology.element_domain_id(firstElementID));
|
||||
const bool secondIsInner = secondElementID >= 0 &&
|
||||
SchemaT::template domain_id_belongs_to<InnerT>(topology.element_domain_id(secondElementID));
|
||||
|
||||
if (firstIsInner == secondIsInner) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foundInnerBoundary = true;
|
||||
|
||||
const int innerElementID = firstIsInner ? firstElementID : secondElementID;
|
||||
const int adjacentElementID = firstIsInner ? secondElementID : firstElementID;
|
||||
|
||||
if (adjacentElementID < 0) {
|
||||
return {
|
||||
.failure = RelationValidationFailure::InnerDomainTouchesMeshBoundary,
|
||||
.inscribedDiagnostics = std::make_optional<RelationValidationResult::InscribedDiagnostics>({
|
||||
.faceID = faceID,
|
||||
.innerElementID = innerElementID,
|
||||
})};
|
||||
}
|
||||
|
||||
const int adjacentDomainID = topology.element_domain_id(adjacentElementID);
|
||||
|
||||
if (!SchemaT::template domain_id_belongs_to<OuterT>(adjacentDomainID)) {
|
||||
return {
|
||||
.failure = RelationValidationFailure::InnerDomainTouchesUnexpectedDomain,
|
||||
.inscribedDiagnostics = std::make_optional<RelationValidationResult::InscribedDiagnostics>({
|
||||
.faceID = faceID,
|
||||
.innerElementID = innerElementID,
|
||||
.adjacentElementID = adjacentElementID,
|
||||
.adjacentDomainID = adjacentDomainID
|
||||
})};
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundInnerBoundary) {
|
||||
return {.failure = RelationValidationFailure::InnerDomainHasNoBoundary};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user