Skip to content

Added reflection functionality for ip data output

  • Tests covering your feature were added?

This MR adds code facilitating IP data output.

Currently, for this task we have to write the following

struct LocalAssemblerInterface
{
    ...

    std::vector<double> getSigma() const
    {
        constexpr int kelvin_vector_size =
            MathLib::KelvinVector::kelvin_vector_dimensions(DisplacementDim);

        return transposeInPlace<kelvin_vector_size>(
            [this](std::vector<double>& values)
            { return getIntPtSigma(0, {}, {}, values); });
    }

    std::vector<double> const& getIntPtSigma(
        const double /*t*/,
        std::vector<GlobalVector*> const& /*x*/,
        std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
        std::vector<double>& cache) const
    {
        return ProcessLib::getIntegrationPointKelvinVectorData<DisplacementDim>(
            current_states_, [](auto const& cs) -> auto const& {
                return cs.s_mech_data.sigma_eff;
            },
            cache);
    }

    // and so on for all IP data...
};

void SomeProcess::init()
{
    ...

    _integration_point_writer.emplace_back(
        std::make_unique<MeshLib::IntegrationPointWriter>(
            "sigma_ip",
            static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
            integration_order, _local_assemblers, &LocalAssemblerIF::getSigma));

    _integration_point_writer.emplace_back(
        std::make_unique<MeshLib::IntegrationPointWriter>(
            "epsilon_ip",
            static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
            integration_order, _local_assemblers,
            &LocalAssemblerIF::getEpsilon));
    }

    // and so on for all IP data ...

    ...

    add_secondary_variable("sigma",
                           MathLib::KelvinVector::KelvinVectorType<
                               DisplacementDim>::RowsAtCompileTime,
                           &LocalAssemblerIF::getIntPtSigma);

    add_secondary_variable("epsilon",
                           MathLib::KelvinVector::KelvinVectorType<
                               DisplacementDim>::RowsAtCompileTime,
                           &LocalAssemblerIF::getIntPtEpsilon);
    
    // and so on for all secondary variables ...
};

With this MR this is reduced to roughly:

template <int DisplacementDim>
struct StrainData
{
    KelvinVector<DisplacementDim> eps = KVzero<DisplacementDim>();

    static auto reflect()
    {
        using Self = StrainData<DisplacementDim>;

        // reflection data has to be provided for all variables we want to output
        return ProcessLib::Reflection::reflectWithName("epsilon", &Self::eps);
    }
};

struct LocalAssemblerInterface
{
    ...

    // only needed once
    static auto getReflectionDataForOutput()
    {
        using Self = LocalAssemblerInterface<DisplacementDim>;

        return ProcessLib::Reflection::reflectWithoutName(
            &Self::current_states_, &Self::output_data_);
    }
};

void SomeProcess::init()
{
    ...

    // only needed once
    ProcessLib::Reflection::addReflectedIntegrationPointWriters<
        DisplacementDim>(LocalAssemblerIF::getReflectionDataForOutput(),
                         _integration_point_writer, integration_order,
                         local_assemblers_);

    ...

    // only needed once
    ProcessLib::Reflection::addReflectedSecondaryVariables<DisplacementDim>(
        LocalAssemblerIF::getReflectionDataForOutput(), _secondary_variables,
        getExtrapolator(), local_assemblers_);
};
  • This MR saves ~200 lines of code in the TRM process, similar savings are possible for all other processes
  • Setting IP data from VTU files is also possible with the reflection data (subsequent MR)
  • The major/hard part of this MR are ~400 lines of implementation in ProcessLib/Reflection/ReflectionIPData.h and ~500 lines of unit test.
Edited by Christoph Lehmann

Merge request reports