From 4ec94c97879aafef15f7663135745e4ba61e62cf Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 17 May 2021 00:15:33 +0200 Subject: Extract first public LiterateLB version --- tangle/LLBM/materials.h | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 tangle/LLBM/materials.h (limited to 'tangle/LLBM/materials.h') diff --git a/tangle/LLBM/materials.h b/tangle/LLBM/materials.h new file mode 100644 index 0000000..d782d8d --- /dev/null +++ b/tangle/LLBM/materials.h @@ -0,0 +1,108 @@ +#pragma once + +#include "memory.h" +#include "sdf.h" + +template +class CellMaterials : public SharedVector { +private: + const descriptor::Cuboid _cuboid; + int* const _materials; + +public: + CellMaterials(descriptor::Cuboid cuboid): + SharedVector(cuboid.volume), + _cuboid(cuboid), + _materials(this->host()) { } + + template + CellMaterials(descriptor::Cuboid cuboid, F f): + CellMaterials(cuboid) { + set(f); + } + + descriptor::Cuboid cuboid() const { + return _cuboid; + }; + + int get(std::size_t iCell) const { + return _materials[iCell]; + } + + void set(std::size_t iCell, int material) { + _materials[iCell] = material; + } + template + void set(F f) { + for (std::size_t iCell=0; iCell < _cuboid.volume; ++iCell) { + set(iCell, f(gidInverse(_cuboid, iCell))); + } + } + + template + void sdf(S distance, int material, float eps=1e-2) { + for (std::size_t iCell=0; iCell < _cuboid.volume; ++iCell) { + auto p = gidInverseSmooth(_cuboid, iCell); + if (distance(p) < eps) { + set(iCell, material); + } + } + } + + void clean(int material) { + for (std::size_t iCell=0; iCell < _cuboid.volume; ++iCell) { + if (get(iCell) == material) { + if (_cuboid.isInside(iCell)) { + bool surrounded = true; + for (unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) { + int m = get(descriptor::neighbor(_cuboid, iCell, iPop)); + surrounded &= m == material || m == 0; + } + if (surrounded) { + set(iCell, 0); + } + } + } + } + } + DeviceBuffer list_of_material(int material) { + std::vector cells; + for (std::size_t iCell=0; iCell < _cuboid.volume; ++iCell) { + if (_materials[iCell] == material) { + cells.emplace_back(iCell); + } + } + return DeviceBuffer(cells); + } + DeviceBuffer mask_of_material(int material) { + std::unique_ptr mask(new bool[_cuboid.volume]{}); + for (std::size_t iCell=0; iCell < _cuboid.volume; ++iCell) { + mask[iCell] = (_materials[iCell] == material); + } + return DeviceBuffer(mask.get(), _cuboid.volume); + } + std::size_t get_link_count(int bulk, int solid) { + std::size_t count = 0; + for (pop_index_t iPop=0; iPop < DESCRIPTOR::q; ++iPop) { + for (std::size_t iCell=0; iCell < _cuboid.volume; ++iCell) { + std::size_t jCell = descriptor::neighbor(_cuboid, iCell, iPop); + if (get(iCell) == bulk && get(jCell) == solid) { + count++; + } + } + } + return count; + } + + template + void for_links(int bulk, int solid, F f) { + for (pop_index_t iPop=0; iPop < DESCRIPTOR::q; ++iPop) { + for (std::size_t iCell=0; iCell < _cuboid.volume; ++iCell) { + std::size_t jCell = descriptor::neighbor(_cuboid, iCell, iPop); + if (get(iCell) == bulk && get(jCell) == solid) { + f(iCell, iPop); + } + } + } + } +}; -- cgit v1.2.3