exasim-project / NeoFOAM

WIP Prototype of a modern CFD core
19 stars 1 forks source link

Strategy pattern to inject update logic into the boundary conditions #83

Closed HenningScheufler closed 2 weeks ago

HenningScheufler commented 3 weeks ago

This PR introduces the strategy pattern to implement the specific correctBoundaryConditions member functions.

Features for BC:

volumeBoundaryBase.hpp:

template<typename ValueType>
class VolumeBoundary : public BoundaryPatchMixin
{
public:

    VolumeBoundary(const UnstructuredMesh& mesh, const Dictionary dict, int patchID)
        : BoundaryPatchMixin(
            mesh.boundaryMesh().offset()[patchID],
            mesh.boundaryMesh().offset()[patchID + 1],
            patchID
        ),
          boundaryCorrectionStrategy_(
              NeoFOAM::finiteVolume::cellCentred::VolumeBoundaryFactory<ValueType>::create(
                  mesh, dict, patchID
              )
          )
    {}

    virtual void correctBoundaryConditions(DomainField<ValueType>& domainField)
    {
        boundaryCorrectionStrategy_->correctBoundaryCondition(domainField);
    }

private:

    // NOTE needs full namespace to be not ambiguous
    std::unique_ptr<NeoFOAM::finiteVolume::cellCentred::VolumeBoundaryFactory<ValueType>>
        boundaryCorrectionStrategy_;
};

}

VolumeBoundaryModel register the class and is explicit instantiated for scalar and vector

avoid code duplication with explicit template instantiation test_boundaryField.cpp:

template<typename ValueType>
class FixedValue : public fvcc::VolumeBoundaryFactory<ValueType>
{

public:

  using FixedValueType = fixedValue<ValueType>;
  ...
}

template class fixedValue<NeoFOAM::scalar>;
template class fixedValue<NeoFOAM::Vector>;
SECTION("FixedValue" + execName)
{
    NeoFOAM::DomainField<NeoFOAM::scalar> domainField(exec, 10, 10, 1);

    FixedValue<NeoFOAM::scalar> fixedValue(0, 10, 1, 1.0);
    fixedValue.correctBoundaryCondition(domainField);
    auto refValueHost = domainField.boundaryField().refValue().copyToHost().field();
    for (std::size_t i = 0; i < 10; i++)
    {
        REQUIRE(refValueHost[i] == 1.0);
    }
}

Limitations: