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
102 lines
4.5 KiB
C++
102 lines
4.5 KiB
C++
#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 {};
|
|
}
|
|
};
|
|
}
|