Skip to content
Snippets Groups Projects
hdf5-writer.hh 4.35 KiB
Newer Older
podlesny's avatar
podlesny committed
#ifndef SRC_HDF5_WRITER_HH
#define SRC_HDF5_WRITER_HH

podlesny's avatar
podlesny committed
#include <vector>
podlesny's avatar
podlesny committed

#include "hdf5/iteration-writer.hh"
#include "hdf5/time-writer.hh"
#include "hdf5-bodywriter.hh"

podlesny's avatar
podlesny committed
#include <dune/fufem/hdf5/file.hh>

podlesny's avatar
podlesny committed
template <class ProgramState, class VertexBasis, class GridView>
class HDF5Writer {
public:
    using HDF5BodyWriter = HDF5BodyWriter<ProgramState, VertexBasis, GridView>;
    using VertexCoordinates = std::vector<typename HDF5BodyWriter::VertexCoordinates>;
    using VertexBases = std::vector<const VertexBasis*>;
    using FrictionPatches = std::vector<const typename HDF5BodyWriter::Patch*>;
    using ScalarVector = typename ProgramState::ScalarVector;
podlesny's avatar
podlesny committed
    //using WeakPatches = std::vector<typename HDF5BodyWriter::WeakPatches>;
podlesny's avatar
podlesny committed

    //friend class HDF5NetworkWriter<ProgramState, VertexBasis, GridView>;

    HDF5Writer(HDF5::File& file,
             const VertexCoordinates& vertexCoordinates,
             const VertexBases& vertexBases,
podlesny's avatar
podlesny committed
             const FrictionPatches& frictionPatches)
             //const WeakPatches& weakPatches)
podlesny's avatar
podlesny committed
      : file_(file),
podlesny's avatar
podlesny committed
        iterationWriter_(file_),
podlesny's avatar
podlesny committed

        for (size_t i=0; i<vertexCoordinates.size(); i++) {
podlesny's avatar
podlesny committed
            if (frictionPatches_[i]->numVertices() > 0)
podlesny's avatar
podlesny committed
                bodyWriters_.push_back(std::make_unique<HDF5BodyWriter>(file_, i, vertexCoordinates[i], *vertexBases[i], *frictionPatches_[i])); //, weakPatches[i]));
podlesny's avatar
podlesny committed
        }
    }

    template <class ContactNetwork, class Friction>
podlesny's avatar
podlesny committed
    void reportSolution(const ProgramState& programState, const ContactNetwork& contactNetwork, const Friction& friction) {
podlesny's avatar
podlesny committed

        timeWriter_.write(programState);

        friction.updateAlpha(programState.alpha);
podlesny's avatar
podlesny committed

        // extract relative velocities
        using Vector = typename ProgramState::Vector;
        Vector mortarV;
        contactNetwork.nBodyAssembler().nodalToTransformed(programState.v, mortarV);

        std::vector<Vector> v_rel;
        split(mortarV, v_rel);

        using ScalarVector = typename ProgramState::ScalarVector;
        const auto frictionCoeff = friction.coefficientOfFriction(mortarV);

podlesny's avatar
podlesny committed
        const auto& bodyNodes = *frictionPatches_[0]->getVertices();
        for (size_t i=bodyNodes.size(); i<frictionCoeff.size(); i++) {
            norm += frictionCoeff[i].two_norm();
        } */
        //std::cout << std::setprecision(10) << "friction coefficients norm: " << norm << std::endl;
podlesny's avatar
podlesny committed

        std::vector<ScalarVector> splitCoeff;
        split(frictionCoeff, splitCoeff);

        /*if (std::isnan(norm) or std::isinf(norm)) {
            print(programState.alpha, "alpha");
            print(frictionCoeff, "frictionCoeff");
            print(splitCoeff, "splitCoeff");
            print(v_rel, "v_rel: ");
            DUNE_THROW(Dune::Exception, "invalid state");
        }*/
podlesny's avatar
podlesny committed

        for (size_t i=0; i<bodyWriters_.size(); i++) {
            auto bodyID = bodyWriters_[i]->id();
            bodyWriters_[i]->reportSolution(programState, v_rel[bodyID], splitCoeff[bodyID]);
        }
    }

    void reportIterations(const ProgramState& programState, const IterationRegister& iterationCount) {
        iterationWriter_.write(programState.timeStep, iterationCount);
    }


    void reportWeightedNormalStress(const ProgramState& programState) {
        for (size_t i=0; i<bodyWriters_.size(); i++) {
            auto bodyID = bodyWriters_[i]->id();
            bodyWriters_[i]->reportWeightedNormalStress(programState);
        }
    }

podlesny's avatar
podlesny committed
    template <class VectorType>
    void split(const VectorType& v, std::vector<VectorType>& splitV) const {
        const auto nBodies = frictionPatches_.size();
podlesny's avatar
podlesny committed

        size_t globalIdx = 0;
        splitV.resize(nBodies);
podlesny's avatar
podlesny committed
        for (size_t bodyIdx=0; bodyIdx<nBodies; bodyIdx++) {
            const auto& bodyNodes = *frictionPatches_[bodyIdx]->getVertices();

            auto& splitV_ = splitV[bodyIdx];
            splitV_.resize(bodyNodes.size());

            for (size_t i=0; i<splitV_.size(); i++) {
                if (toBool(bodyNodes[i])) {
                    splitV_[i] = v[globalIdx];
                }
                globalIdx++;
            }
        }
    }

private:
  HDF5::File& file_;
  const FrictionPatches& frictionPatches_;
podlesny's avatar
podlesny committed

  IterationWriter iterationWriter_;
  TimeWriter<ProgramState> timeWriter_;

  std::vector<std::unique_ptr<HDF5BodyWriter>> bodyWriters_;
};
#endif