#ifdef HAVE_CONFIG_H #include "config.h" #endif #include <dune/fufem/grid/hierarchic-approximation.hh> #include <dune/fufem/hdf5/singletonwriter.hh> #include "patchinfo-writer.hh" template <class LocalVector, class GridView> GridEvaluator<LocalVector, GridView>::GridEvaluator( ConvexPolyhedron<LocalVector> const &weakPatch, GridView const &gridView) { double const bufferWidth = 0.05 * MyGeometry::lengthScale; auto const xminmax = std::minmax_element( weakPatch.vertices.begin(), weakPatch.vertices.end(), [](LocalVector const &a, LocalVector const &b) { return a[0] < b[0]; }); double const xmin = (*xminmax.first)[0] - bufferWidth; double const xspan = (*xminmax.second)[0] + bufferWidth - xmin; double const zmin = -MyGeometry::depth / 2.0; double const zspan = MyGeometry::depth; double spatialResolution = 0.01 * MyGeometry::lengthScale; size_t const xsteps = std::round(xspan / spatialResolution); size_t const zsteps = std::round(zspan / spatialResolution); xCoordinates.resize(xsteps + 1); for (size_t xi = 0; xi <= xsteps; xi++) xCoordinates[xi] = xmin + xi * xspan / xsteps; zCoordinates.resize(zsteps + 1); for (size_t zi = 0; zi <= zsteps; zi++) zCoordinates[zi] = zmin + zi * zspan / zsteps; HierarchicApproximation<typename GridView::Grid, GridView> const hApproximation(gridView.grid(), gridView, 1e-6 * MyGeometry::lengthScale); LocalVector global(0); localInfo.resize(xsteps + 1); for (size_t xi = 0; xi < xCoordinates.size(); ++xi) { localInfo[xi].resize(zsteps + 1); for (size_t zi = 0; zi < zCoordinates.size(); ++zi) { global[0] = xCoordinates[xi]; global[2] = zCoordinates[zi]; auto const element = hApproximation.findEntity(global); localInfo[xi][zi] = std::make_pair(element, element.geometry().local(global)); } } } template <class LocalVector, class GridView> template <class Function> Dune::Matrix<typename Function::RangeType> GridEvaluator<LocalVector, GridView>::evaluate(Function const &f) const { Dune::Matrix<typename Function::RangeType> ret(xCoordinates.size(), zCoordinates.size()); for (size_t xi = 0; xi < localInfo.size(); ++xi) { auto const &localInfoX = localInfo[xi]; for (size_t zi = 0; zi < localInfoX.size(); ++zi) { auto const &localInfoXZ = localInfoX[zi]; f.evaluateLocal(localInfoXZ.first, localInfoXZ.second, ret[xi][zi]); } } return ret; } template <class ProgramState, class VertexBasis, class GridView> PatchInfoWriter<ProgramState, VertexBasis, GridView>::PatchInfoWriter( HDF5::Grouplike &file, VertexBasis const &vertexBasis, Patch const &frictionalBoundary, ConvexPolyhedron<LocalVector> const &weakPatch) : group_(file, "weakPatchGrid"), vertexBasis_(vertexBasis), gridEvaluator_(weakPatch, frictionalBoundary.gridView()), weakPatchGridVelocityWriter_( group_, "velocity", gridEvaluator_.xCoordinates.size(), gridEvaluator_.zCoordinates.size(), Vector::block_type::dimension) { HDF5::SingletonWriter<1> weakPatchGridXCoordinateWriter( group_, "xCoordinates", gridEvaluator_.xCoordinates.size()); setEntry(weakPatchGridXCoordinateWriter, gridEvaluator_.xCoordinates); HDF5::SingletonWriter<1> weakPatchGridZCoordinateWriter( group_, "zCoordinates", gridEvaluator_.zCoordinates.size()); setEntry(weakPatchGridZCoordinateWriter, gridEvaluator_.zCoordinates); } template <class ProgramState, class VertexBasis, class GridView> void PatchInfoWriter<ProgramState, VertexBasis, GridView>::write( ProgramState const &programState) { // TODO BasisGridFunction<VertexBasis, Vector> velocity(vertexBasis_, programState.v[0]); auto const gridVelocity = gridEvaluator_.evaluate(velocity); addEntry(weakPatchGridVelocityWriter_, programState.timeStep, gridVelocity); } #include "patchinfo-writer_tmpl.cc"