diff --git a/.gitignore b/.gitignore index 7f95e654bce310ad42218975fdddb1d60a2aefc8..57b3e576630ff40e47d7ec4c417424b093515df3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ # along with ae108. If not, see <https://www.gnu.org/licenses/>. build -*.pyc \ No newline at end of file +*.pyc +.vscode diff --git a/CMakeLists.txt b/CMakeLists.txt index 391692f32a083f01e758a1e15dc80d780d437e58..1c45e3c233cb7e240f3714e224cebfa8a53ade16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ include(cmake/ae108_install_library.cmake) include(cmake/ae108_add_cppptest.cmake) add_subdirectory(cppptest) -foreach(AE108_LIBRARY elements cpppetsc cppslepc assembly solve cmdline) +foreach(AE108_LIBRARY elements cpppetsc cppslepc assembly solve cmdline meshing) add_subdirectory(${AE108_LIBRARY}) endforeach() add_subdirectory(examples) @@ -50,6 +50,8 @@ install(FILES cmake/modules/FindAE108_PETSc.cmake cmake/modules/FindAE108_SLEPc.cmake cmake/modules/AE108_PETSc.cc + cmake/modules/FindVoro++.cmake + cmake/modules/FindGmsh.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/modules" ) @@ -65,7 +67,7 @@ set(CPACK_GENERATOR "DEB") set(CPACK_PACKAGE_NAME "libae108-${AE108_PETSC_SCALAR_TYPE}-dev") set(CPACK_DEBIAN_PACKAGE_SECTION "science") set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") -set(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-program-options-dev,libeigen3-dev,librange-v3-dev,libxrender1,libvtk9-dev,libpetsc-${AE108_PETSC_SCALAR_TYPE}-dev,libslepc-${AE108_PETSC_SCALAR_TYPE}3.15-dev") +set(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-program-options-dev,libeigen3-dev,librange-v3-dev,libxrender1,libvtk9-dev,libpetsc-${AE108_PETSC_SCALAR_TYPE}-dev,libslepc-${AE108_PETSC_SCALAR_TYPE}3.15-dev,libgmsh-dev,voro++-dev") set(CPACK_PACKAGE_DESCRIPTION "C++ foundation for computational solid mechanics simulations using a variational framework, primarily focusing on the Finite Element Method (FEM)") set(CPACK_PACKAGE_CONTACT "Mechanics & Materials Lab at ETH Zurich <gerhard.braeunlich@id.ethz.ch>") diff --git a/cmake/modules/FindGmsh.cmake b/cmake/modules/FindGmsh.cmake new file mode 100644 index 0000000000000000000000000000000000000000..ae912235c8918b099aabff1a7b2f70bac44b99da --- /dev/null +++ b/cmake/modules/FindGmsh.cmake @@ -0,0 +1,35 @@ +# © 2021 ETH Zurich, Mechanics and Materials Lab +# +# Licensed under the GNU General Public License (GPL), Version 2.0 (the +# "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https:#www.gnu.org/licenses/old-licenses/gpl-2.0.html +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if (NOT TARGET external::gmsh) + include(FindPackageHandleStandardArgs) + + if (NOT DEFINED ENV{GMSH_LIBRARIES} OR NOT DEFINED ENV{GMSH_INCLUDE_DIRS}) + find_library(Gmsh_LIBRARIES NAMES gmsh) + find_path(Gmsh_INCLUDE_DIRS gmsh.h) + else() + find_library(Gmsh_LIBRARIES NAMES gmsh PATHS $ENV{GMSH_LIBRARIES} NO_DEFAULT_PATH) + find_path(Gmsh_INCLUDE_DIRS gmsh.h PATHS $ENV{GMSH_INCLUDE_DIRS} NO_DEFAULT_PATH) + endif() + + find_package_handle_standard_args(Gmsh Gmsh_LIBRARIES Gmsh_INCLUDE_DIRS) + + if (Gmsh_FOUND) + add_library(external::gmsh UNKNOWN IMPORTED) + set_property(TARGET external::gmsh PROPERTY IMPORTED_LOCATION ${Gmsh_LIBRARIES}) + set_property(TARGET external::gmsh PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Gmsh_INCLUDE_DIRS}) + endif() +endif() + + diff --git a/cmake/modules/FindVoro++.cmake b/cmake/modules/FindVoro++.cmake new file mode 100644 index 0000000000000000000000000000000000000000..fa2cfdcc4aefd3401a0161109acad1b69d6c1521 --- /dev/null +++ b/cmake/modules/FindVoro++.cmake @@ -0,0 +1,35 @@ +# © 2021 ETH Zurich, Mechanics and Materials Lab +# +# This file is part of ae108. +# +# ae108 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or any +# later version. +# +# ae108 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ae108. If not, see <https://www.gnu.org/licenses/>. + +if (NOT TARGET external::voro++) + include(FindPackageHandleStandardArgs) + if (NOT DEFINED ENV{Voro++_LIBRARIES} OR NOT DEFINED ENV{Voro++_INCLUDE_DIRS}) + find_library(Voro++_LIBRARIES NAMES voro++ PATHS $ENV{VOROPP_DIR}/lib) + find_path(Voro++_INCLUDE_DIRS voro++.hh PATH_SUFFIXES voro++ PATHS $ENV{VOROPP_DIR}/include/voro++) + else() + find_library(Voro++_LIBRARIES NAMES voro++ PATHS $ENV{Voro++_LIBRARIES} NO_DEFAULT_PATH) + find_path(Voro++_INCLUDE_DIRS voro++.hh PATH_SUFFIXES voro++ PATHS $ENV{Voro++_INCLUDE_DIRS} NO_DEFAULT_PATH) + endif() + + find_package_handle_standard_args(Voro++ DEFAULT_MSG Voro++_LIBRARIES Voro++_INCLUDE_DIRS) + + if (Voro++_FOUND) + add_library(external::voro++ UNKNOWN IMPORTED) + set_property(TARGET external::voro++ PROPERTY IMPORTED_LOCATION ${Voro++_LIBRARIES}) + set_property(TARGET external::voro++ PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Voro++_INCLUDE_DIRS}) + endif() +endif() diff --git a/docker-compose.yml b/docker-compose.yml index 2911fc9a326ed2234b2d54b3f130f3142cb540ef..1317d71b81262c3d9baa14479d8ae1d1fb6bae66 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,7 +24,7 @@ services: context: ./docker dockerfile: Dockerfile volumes: - - .:/mnt/io + - .:/mnt/io tty: true shm_size: '1gb' working_dir: /mnt/io @@ -35,7 +35,7 @@ services: context: ./docker dockerfile: Dockerfile volumes: - - .:/mnt/io + - .:/mnt/io working_dir: /mnt/io tty: true shm_size: '1gb' @@ -44,6 +44,6 @@ services: context: ./docker dockerfile: Dockerfile_docu volumes: - - .:/mnt/io + - .:/mnt/io working_dir: /mnt/io - tty: true \ No newline at end of file + tty: true diff --git a/docker/Dockerfile b/docker/Dockerfile index a7c772f6a686e884f96298ce041920e189e67e9c..6bf11cea735348e0bb025e7aa6e7b05eedebb9d8 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -38,7 +38,14 @@ RUN apt-get update && \ libxrender1 \ ninja-build \ python3 python3-pip \ - python3-scipy + python3-scipy + +RUN apt-get update && \ + DEBIAN_FRONTEND="noninteractive" \ + TZ="Europe/Zurich" \ + apt-get install -y \ + libgmsh-dev \ + voro++-dev RUN pip3 install \ mypy==0.931 \ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 66a9d562b722fb4855d2a6784efd2716662b6eb3..49ba96946fed9c3d060bd0bb33d90e82a7ea25c0 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -156,3 +156,5 @@ if (NOT ${AE108_PETSC_COMPLEX}) PRIVATE ae108::elements ) endif() + +add_subdirectory(meshing) \ No newline at end of file diff --git a/examples/meshing/CMakeLists.txt b/examples/meshing/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e7b99ee36c43e94d7c1625632f4a1d8c6c3222a4 --- /dev/null +++ b/examples/meshing/CMakeLists.txt @@ -0,0 +1,48 @@ +# © 2020 ETH Zurich, Mechanics and Materials Lab +# +# This file is part of ae108. +# +# ae108 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or any +# later version. +# +# ae108 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ae108. If not, see <https://www.gnu.org/licenses/>. + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +project(ae108-examples LANGUAGES C CXX) + +if (NOT TARGET ae108::meshing) + find_package(ae108 REQUIRED) +endif() + +add_executable(${PROJECT_NAME}-SegmentMesh SegmentMesh.cc) +target_link_libraries(${PROJECT_NAME}-SegmentMesh + PRIVATE ae108::meshing +) + +add_executable(${PROJECT_NAME}-PeriodicRVEMesh PeriodicRVEMesh.cc) +target_link_libraries(${PROJECT_NAME}-PeriodicRVEMesh + PRIVATE ae108::meshing +) + +add_executable(${PROJECT_NAME}-TwoPhaseCube TwoPhaseCube.cc) +target_link_libraries(${PROJECT_NAME}-TwoPhaseCube + PRIVATE ae108::meshing +) + +add_executable(${PROJECT_NAME}-PhysicalGroups PhysicalGroups.cc) +target_link_libraries(${PROJECT_NAME}-PhysicalGroups + PRIVATE ae108::meshing +) +add_executable(${PROJECT_NAME}-GradedLattice GradedLattice.cc) +target_link_libraries(${PROJECT_NAME}-GradedLattice + PRIVATE ae108::meshing +) diff --git a/examples/meshing/GradedLattice.cc b/examples/meshing/GradedLattice.cc new file mode 100644 index 0000000000000000000000000000000000000000..e00f9cf4a88d0e8bcd894cb087a8069b41fddfe1 --- /dev/null +++ b/examples/meshing/GradedLattice.cc @@ -0,0 +1,98 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/construct_rectilinear_grid.h" +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/extract_mesh.h" +#include "ae108/meshing/cppgmsh/extrude_surface.h" +#include "ae108/meshing/cppgmsh/fuse_entities.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/remove_entities.h" +#include "ae108/meshing/cppgmsh/rotate_entities.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include "ae108/meshing/cppgmsh/translate_entities.h" +#include "ae108/meshing/cppgmsh/write_file.h" + +#include <gmsh.h> +#include <iostream> +#include <numeric> + +using namespace ae108::meshing; + +constexpr std::size_t dimension = 3; +using Point = std::array<double, dimension>; + +int main(int argc, char **argv) { + + const auto gmshContext = cppgmsh::Context(argc, argv, true, false); + + const double gamma_start = 5.; + const double gamma_end = 10.; + const double length = 466.75; + + const auto xcoords = [] { + std::vector<double> range(80); + std::iota(range.begin(), range.end(), -40); + std::transform(range.begin(), range.end(), range.begin(), + [](auto &N) { return N * 5; }); + return range; + }(); + + const auto ycoords = [&] { + std::vector<double> range(59); + std::iota(range.begin(), range.end(), -29); + std::transform(range.begin(), range.end(), range.begin(), [&](auto &N) { + return N * length * gamma_start / + (length - fabs(N) * gamma_end + fabs(N) * gamma_start); + }); + return range; + }(); + + const auto crosssection = + cppgmsh::construct_rectangle({-.25, -.5, 0}, {.5, 1.}); + cppgmsh::rotate_entities({crosssection}, {0, 0, 0}, {1, 0, 0}, M_PI_2); + + std::vector<std::pair<int, int>> entities; + for (const auto &xcoord : xcoords) + entities.push_back(cppgmsh::extrude_surface( + crosssection.second, {xcoord, -200, 0}, {xcoord, 200, 0}, {0, 1, 0})); + for (const auto &ycoord : ycoords) + entities.push_back(cppgmsh::extrude_surface( + crosssection.second, {-200, ycoord, 0}, {200, ycoord, 0}, {0, 1, 0})); + + entities.push_back(cppgmsh::construct_box({-225, -225, -.5}, {450, 25, 1})); + entities.push_back(cppgmsh::construct_box({-225, -225, -.5}, {25, 450, 1})); + entities.push_back(cppgmsh::construct_box({-225, 200, -.5}, {450, 25, 1})); + entities.push_back(cppgmsh::construct_box({200, -225, -.5}, {25, 450, 1})); + + cppgmsh::remove_entities({crosssection}, true); + + cppgmsh::fuse_entities(entities); + + cppgmsh::synchronize(); + cppgmsh::write_file("gradedLattice.step"); + + cppgmsh::generate_mesh(); + cppgmsh::write_file("gradedLattice.vtk"); + + const auto [positions, connectivity, _, __] = + cppgmsh::extract_mesh<dimension>(); + + std::cout << "# points: " << positions.size() << std::endl + << "# elements: " << connectivity.size() << std::endl; +} \ No newline at end of file diff --git a/examples/meshing/PeriodicRVEMesh.cc b/examples/meshing/PeriodicRVEMesh.cc new file mode 100644 index 0000000000000000000000000000000000000000..5d0b3bb77b9b29332e9e6c3bcb46e5f3b80f589f --- /dev/null +++ b/examples/meshing/PeriodicRVEMesh.cc @@ -0,0 +1,129 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/bounding_box_of.h" +#include "ae108/meshing/construct_periodic_point_cloud.h" +#include "ae108/meshing/construct_voronoi_cell.h" +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_cylinders.h" +#include "ae108/meshing/cppgmsh/construct_polyhedron.h" +#include "ae108/meshing/cppgmsh/extract_mesh.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_entities_in.h" +#include "ae108/meshing/cppgmsh/get_periodic_nodes_of.h" +#include "ae108/meshing/cppgmsh/intersect_entities.h" +#include "ae108/meshing/cppgmsh/set_domain_entities_periodic.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include "ae108/meshing/cppgmsh/write_file.h" + +#include <iostream> + +using namespace ae108::meshing; + +// In this example we will generate a periodic mesh of a representative volume +// element as it is often required for homogenization or Bloch wave analysis of +// a periodic medium. + +constexpr std::size_t dimension = 3; +using Point = std::array<double, dimension>; + +// A 3D periodic medium with translational symmetry is commonly described as a +// Bravais lattice by three translation vectors. Three well-known lattices are +// the simple cubic (sc), the body centered cubic (bcc), and the face centered +// cubic (fcc) lattice. https://en.wikipedia.org/wiki/Bravais_lattice + +constexpr auto lattice_vectors = + std::array<std::array<double, dimension>, dimension>{ + {{0.5, 0.5, 0.5}, {0.5, -0.5, 0.5}, {0.5, 0.5, -0.5}}}; // bcc +// {{1., 1., 0.}, {0., 1., 1.}, {1., 0., 1.}}}; //fcc +// {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}}; //sc + +int main(int argc, char **argv) { + + // In a first step, we need to initialize the meshing engine "cppgmsh" + + const auto gmshContext = cppgmsh::Context(argc, argv); + + // Let us now define the domain of our representative volume element (rve). + // For a perodic medium, like above Bravais lattice, the smallest possible + // unit cell is a primitive unit cell: Two frequent choices are the + // parallelpiped or the Wigner-Seitz (a type of Voronoi cell) primitive cell. + // https://en.wikipedia.org/wiki/Unit_cell + + std::vector<std::pair<std::size_t, std::size_t>> periodic_faces; + const auto domain = construct_voronoi_cell( + construct_periodic_point_cloud(lattice_vectors, {0, 0, 0}), + &periodic_faces); + const auto domain_entity = cppgmsh::construct_polyhedron(domain); + + // Next, we define the solid within the primitive unit cell. We choose to + // place cylinders on the edges of the domain. The solid may also span several + // unit cells like in a finite lattice. + + const auto solid_entity = cppgmsh::construct_cylinders( + domain.vertices, domain.edges, + std::vector<double>(domain.edges.size(), 0.05), true); + + // Finally, we construct the rve by cropping all solid outside of the + // domain of the primitive unit cell. + + const auto rve_entity = + cppgmsh::intersect_entities({solid_entity}, {domain_entity}); + + // We sync the constructive solid geometry engine and write a CAD file. + + cppgmsh::synchronize(); + // cppgmsh::write_file("periodic.step"); + + // To obtain a periodic mesh (e.g. for homogenization or Bloch wave analysis), + // we define the periodic domain faces. + + for (const auto &face_pair : periodic_faces) + cppgmsh::set_domain_entities_periodic( + bounding_box_of(domain.vertices_of_face(face_pair.first)), + bounding_box_of(domain.vertices_of_face(face_pair.second)), 2); + + // Finally, we generate the periodic FE mesh. + + cppgmsh::set_granularity(1. / 10); + cppgmsh::generate_mesh(); + + // We save the mesh directly as "periodic.vtk". Other formats are available. + + cppgmsh::write_file("periodic.vtk"); + + // To use the mesh in an ae108 FE application, we extract the positions and + // connectivities of the mesh elements. + + const auto [positions, connectivity, nodeTagToIndex, elementTagToIndex] = + cppgmsh::extract_mesh<dimension>(); + + for (const auto &face_pair : periodic_faces) { + std::pair<int, int> numper_of_nodes; + for (const auto &target_surface : cppgmsh::get_entities_in( + bounding_box_of(domain.vertices_of_face(face_pair.second)), 2)) { + const auto nodes = cppgmsh::get_periodic_nodes_of(target_surface); + assert(nodes.first.size() == nodes.second.size()); + numper_of_nodes.first += nodes.first.size(); + numper_of_nodes.second += nodes.second.size(); + } + std::cout << "# target face (" << face_pair.second + << ") nodes: " << numper_of_nodes.second << std::endl + << "# source face (" << face_pair.first + << ") nodes: " << numper_of_nodes.first << std::endl + << std::endl; + } +} diff --git a/examples/meshing/PhysicalGroups.cc b/examples/meshing/PhysicalGroups.cc new file mode 100644 index 0000000000000000000000000000000000000000..574c559ae79187567bdb4c6bda664c7b993dea45 --- /dev/null +++ b/examples/meshing/PhysicalGroups.cc @@ -0,0 +1,143 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/extract_mesh.h" +#include "ae108/meshing/cppgmsh/fragment_entities.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_elements_in.h" +#include "ae108/meshing/cppgmsh/get_entities_in.h" +#include "ae108/meshing/cppgmsh/get_nodes_of.h" +#include "ae108/meshing/cppgmsh/get_physical_groups.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/set_physical_group_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" + +#include <array> +#include <iostream> + +using namespace ae108::meshing; + +/* +In this example we will construct and mesh a cube with unit side lengths, which +consists of three layers (z < 0.3 -> layer 1, 0.3 < z < 0.7 -> layer 2, z > 0.7 +-> layer 3). Layers 1 and 3 are of one material, layer 2 of another. In order to +account for this, physical groups are defined. + + ________________ _ + | | | + | Material 1 | | 0.3 + |________________| |_ + | | | + | Material 2 | | 0.4 + | | | + |________________| |_ + | | | + | Material 1 | | 0.3 + |________________| |_ + ________________ + | 1.0 | + + z + ^ + | + --> x,y + +*/ + +int main(int argc, char **argv) { + + // Initialize the gmsh context: + const auto gmshContext = cppgmsh::Context(argc, argv, true, false); + + // Construct three boxes: + const auto boxes = std::vector<std::pair<int, int>>{ + cppgmsh::construct_box({0., 0., 0.}, {1., 1., 0.3}), + cppgmsh::construct_box({0., 0., .3}, {1., 1., 0.4}), + cppgmsh::construct_box({0., 0., .7}, {1., 1., 0.3})}; + + std::cout << "Box 1: dim = " << boxes[0].first + << ", tag = " << boxes[0].second << std::endl + << "Box 2: dim = " << boxes[1].first + << ", tag = " << boxes[1].second << std::endl + << "Box 3: dim = " << boxes[2].first + << ", tag = " << boxes[2].second << std::endl; + + // Fuse boxes, while keeping track of the original entities: + std::vector<std::pair<int, int>> fused_entitites = + cppgmsh::fragment_entities(boxes); + cppgmsh::synchronize(); + + // Define physical groups: + cppgmsh::set_physical_group_of({boxes[0], boxes[2]}); + cppgmsh::set_physical_group_of({boxes[1]}); + + // Show that the physical groups have been defined as desired: + auto groups = cppgmsh::get_physical_groups(); + std::cout << "Groups (dim, tag): "; + for (const auto &group : groups) + std::cout << "(" << group.first << "," << group.second << ") "; + std::cout << std::endl; + + // Get the tags of the entities attributed two both groups: + for (const auto &group : groups) { + std::cout << "Group " << group.second << ", dim: " << group.first + << ", entities: "; + const auto entities = cppgmsh::get_entities_in(group); + for (const auto &entity : entities) + std::cout << entity.second << " "; + std::cout << std::endl; + } + + // Create mesh: + cppgmsh::set_granularity(2.); + cppgmsh::generate_mesh(3, 1, 6); + + const auto [positions, connectivity, nodeTagToIndex, elementTagToIndex] = + cppgmsh::extract_mesh<3>(); + + // Print element tags and indides, as well as node indides for the two groups: + for (const auto &group : groups) { + std::cout << "Elements in group " << group.second << ":\n"; + std::cout << "\ttag\tindex\tnode indides\n"; + const auto entities = cppgmsh::get_entities_in(group); + for (const auto &entity : entities) { + const auto elements = cppgmsh::get_elements_in(entity); + for (const auto &element : elements) { + const auto index = elementTagToIndex.at(element.second); + std::cout << "\t" << element.second << "\t" << index << "\t"; + for (const auto &node : connectivity[index]) + std::cout << node << "\t"; + std::cout << std::endl; + } + } + } + + // Print node tags, indides and coordinates for the two boxes: + for (const auto &group : groups) { + std::cout << "Nodes in group " << group.second << ":\n"; + std::cout << "\ttag\tindex\tx\ty\tz\n"; + const auto entities = cppgmsh::get_entities_in(group); + for (const auto &entity : entities) { + const auto nodes = cppgmsh::get_nodes_of<3>(entity); + for (const auto &node : nodes) { + std::cout << "\t" << node.id << "\t" << nodeTagToIndex.at(node.id) + << "\t" << node.position[0] << "\t" << node.position[1] + << "\t" << node.position[2] << std::endl; + } + } + } +} \ No newline at end of file diff --git a/examples/meshing/SegmentMesh.cc b/examples/meshing/SegmentMesh.cc new file mode 100644 index 0000000000000000000000000000000000000000..428150f075835a1a2136f515db53db034b76b71c --- /dev/null +++ b/examples/meshing/SegmentMesh.cc @@ -0,0 +1,73 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/construct_rectilinear_grid.h" +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/extract_mesh.h" +#include "ae108/meshing/cppgmsh/extrude_surface.h" +#include "ae108/meshing/cppgmsh/fuse_entities.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/remove_entities.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include "ae108/meshing/cppgmsh/write_file.h" + +#include <gmsh.h> +#include <iostream> + +using namespace ae108::meshing; + +constexpr std::size_t dimension = 3; +using Point = std::array<double, dimension>; + +int main(int argc, char **argv) { + + const auto gmshContext = cppgmsh::Context(argc, argv, true, false); + + // construct a regular grid + // *--* + // | | + // *--* + + const auto coordinates = + std::array<std::vector<double>, dimension>{{{0, 1}, {0, 1}, {0}}}; + auto [nodes, segments] = construct_rectilinear_grid(coordinates); + + const auto crosssection = + cppgmsh::construct_rectangle({-.05, -.05, 0}, {.1, .1}); + + std::vector<std::pair<int, int>> beams; + for (const auto &segment : segments) + beams.push_back(cppgmsh::extrude_surface( + crosssection.second, nodes[segment[0]], nodes[segment[1]])); + + cppgmsh::remove_entities({crosssection}, true); + + cppgmsh::fuse_entities(beams); + + cppgmsh::synchronize(); + // cppgmsh::write_file("segmentMesh.step"); + + cppgmsh::set_granularity(0.25); + cppgmsh::generate_mesh(); + cppgmsh::write_file("segmentMesh.vtk"); + + const auto [positions, connectivity, _, __] = + cppgmsh::extract_mesh<dimension>(); + + std::cout << "# points: " << positions.size() << std::endl + << "# elements: " << connectivity.size() << std::endl; +} \ No newline at end of file diff --git a/examples/meshing/TwoPhaseCube.cc b/examples/meshing/TwoPhaseCube.cc new file mode 100644 index 0000000000000000000000000000000000000000..eafa734de62e996659b679e62e4232396b6c60c7 --- /dev/null +++ b/examples/meshing/TwoPhaseCube.cc @@ -0,0 +1,102 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/extract_mesh.h" +#include "ae108/meshing/cppgmsh/fragment_entities.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_elements_in.h" +#include "ae108/meshing/cppgmsh/get_nodes_of.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/synchronize.h" + +#include <array> +#include <iostream> + +using namespace ae108::meshing; + +/* +In this example we will construct and mesh a cube with unit side lengths, which +consists of two different phases (z < 0.5 -> phase 1,z > 0.5 -> phase 2). + ________________ _ + | | | + | Phase 2 | | 0.5 + |________________| |_ + | | | + | Phase 1 | | 0.5 + |________________| |_ + ________________ + | 1.0 | + z + ^ + | + --> x,y + +*/ + +int main(int argc, char **argv) { + + // Initialize the gmsh context: + const auto gmshContext = cppgmsh::Context(argc, argv, true, false); + + // Construct two boxes: + const auto boxes = std::vector<std::pair<int, int>>{ + cppgmsh::construct_box({0., 0., 0.}, {1., 1., 0.5}), + cppgmsh::construct_box({0., 0., .5}, {1., 1., 0.5})}; + + std::cout << "Box 1: dim = " << boxes[0].first + << ", tag = " << boxes[0].second << std::endl + << "Box 2: dim = " << boxes[1].first + << ", tag = " << boxes[1].second << std::endl; + + // Fuse boxes, while keeping track of the original entities: + const auto fused_entitites = cppgmsh::fragment_entities(boxes); + cppgmsh::synchronize(); + + // Create mesh: + cppgmsh::set_granularity(2.); + cppgmsh::generate_mesh(3, 1, 6); + + const auto [positions, connectivity, nodeTagToIndex, elementTagToIndex] = + cppgmsh::extract_mesh<3>(); + + // Print element tags and indides, as well as node indides for the two boxes: + for (const auto &box : boxes) { + std::cout << "Elements in box " << box.second << ":\n" + << "\ttag\tindex\tnode indices\n"; + + const auto elements = cppgmsh::get_elements_in(box); + for (const auto &element : elements) { + const auto index = elementTagToIndex.at(element.second); + std::cout << "\t" << element.second << "\t" << index << "\t"; + for (const auto &node : connectivity[index]) + std::cout << node << "\t"; + std::cout << std::endl; + } + } + + // Print node tags, indides and coordinates for the two boxes: + for (const auto &box : boxes) { + std::cout << "Nodes in box " << box.second << ":\n" + << "\ttag\tindex\tx\ty\tz\n"; + + const auto nodes = cppgmsh::get_nodes_of<3>(box); + for (const auto &node : nodes) + std::cout << "\t" << node.id << "\t" << nodeTagToIndex.at(node.id) << "\t" + << node.position[0] << "\t" << node.position[1] << "\t" + << node.position[2] << std::endl; + } +} \ No newline at end of file diff --git a/meshing/CMakeLists.txt b/meshing/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..78211faef4d5c5131ee513c51d74369bca107b9a --- /dev/null +++ b/meshing/CMakeLists.txt @@ -0,0 +1,21 @@ +# © 2021 ETH Zurich, Mechanics and Materials Lab +# +# This file is part of ae108. +# +# ae108 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or any +# later version. +# +# ae108 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ae108. If not, see <https://www.gnu.org/licenses/>. + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/meshing/src/BoundaryRepresentation.cc b/meshing/src/BoundaryRepresentation.cc new file mode 100644 index 0000000000000000000000000000000000000000..004a2bb42004706e4a365ad165e4285e628a370c --- /dev/null +++ b/meshing/src/BoundaryRepresentation.cc @@ -0,0 +1,16 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/BoundaryRepresentation.h" \ No newline at end of file diff --git a/meshing/src/BoundingBox.cc b/meshing/src/BoundingBox.cc new file mode 100644 index 0000000000000000000000000000000000000000..cdbf14129093859b6b9a1ba8adb846ab228a6477 --- /dev/null +++ b/meshing/src/BoundingBox.cc @@ -0,0 +1,16 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/BoundingBox.h" \ No newline at end of file diff --git a/meshing/src/CMakeLists.txt b/meshing/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..876ecb62745ca7baa709c3ce3296986f0b826b0e --- /dev/null +++ b/meshing/src/CMakeLists.txt @@ -0,0 +1,89 @@ +# © 2021 ETH Zurich, Mechanics and Materials Lab +# +# This file is part of ae108. +# +# ae108 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or any +# later version. +# +# ae108 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ae108. If not, see <https://www.gnu.org/licenses/>. + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +add_library(${PROJECT_NAME}-meshing + cppgmsh/Context.cc + cppgmsh/Node.cc + cppgmsh/as_affine_transform.cc + cppgmsh/construct_box.cc + cppgmsh/construct_cylinders.cc + cppgmsh/construct_polyhedron.cc + cppgmsh/construct_rectangle.cc + cppgmsh/copy_entities.cc + cppgmsh/extrude_entities.cc + cppgmsh/extrude_surface.cc + cppgmsh/fuse_entities.cc + cppgmsh/fragment_entities.cc + cppgmsh/intersect_entities.cc + cppgmsh/remove_entities.cc + cppgmsh/rotate_entities.cc + cppgmsh/translate_entities.cc + cppgmsh/get_boundary_of.cc + cppgmsh/get_centroid_of.cc + cppgmsh/get_coords_of.cc + cppgmsh/get_elements_in.cc + cppgmsh/get_entities_in.cc + cppgmsh/get_entities_of.cc + cppgmsh/get_nodes_of.cc + cppgmsh/get_normal_of.cc + cppgmsh/get_periodic_nodes_of.cc + cppgmsh/get_physical_groups.cc + cppgmsh/get_points_of.cc + cppgmsh/set_domain_entities_periodic.cc + cppgmsh/set_expert_mode.cc + cppgmsh/set_granularity.cc + cppgmsh/set_periodic.cc + cppgmsh/set_physical_group_of.cc + cppgmsh/heal_periodic_surfaces.cc + cppgmsh/heal_periodic_domains.cc + cppgmsh/import_shapes.cc + cppgmsh/read_file.cc + cppgmsh/write_file.cc + cppgmsh/extract_mesh.cc + cppgmsh/generate_mesh.cc + cppgmsh/synchronize.cc + BoundaryRepresentation.cc + BoundingBox.cc + bounding_box_of.cc + construct_rectilinear_grid.cc + construct_periodic_point_cloud.cc + construct_voronoi_cell.cc +) + +target_include_directories(${PROJECT_NAME}-meshing PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> +) + +target_compile_features(${PROJECT_NAME}-meshing + PUBLIC cxx_std_11 +) + +find_package(Gmsh 4.8.4 REQUIRED MODULE) +find_package(Voro++ REQUIRED MODULE) +find_package(Eigen3 3.3 CONFIG REQUIRED) +find_package(range-v3 0.11.0 CONFIG REQUIRED) +target_link_libraries(${PROJECT_NAME}-meshing + PUBLIC external::gmsh + PUBLIC external::voro++ + PUBLIC Eigen3::Eigen + PUBLIC range-v3::range-v3) + +add_library(${PROJECT_NAME}::meshing ALIAS ${PROJECT_NAME}-meshing) + +ae108_install_library(meshing) \ No newline at end of file diff --git a/meshing/src/bounding_box_of.cc b/meshing/src/bounding_box_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..0f2c92175441fa303275ad2d3dc5a9cf7acf2d32 --- /dev/null +++ b/meshing/src/bounding_box_of.cc @@ -0,0 +1,16 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/bounding_box_of.h" \ No newline at end of file diff --git a/meshing/src/construct_periodic_point_cloud.cc b/meshing/src/construct_periodic_point_cloud.cc new file mode 100644 index 0000000000000000000000000000000000000000..cea48c8fdccae854f78cb64590f673db451771c3 --- /dev/null +++ b/meshing/src/construct_periodic_point_cloud.cc @@ -0,0 +1,75 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/construct_periodic_point_cloud.h" +#include <Eigen/Dense> +#include <range/v3/view/cartesian_product.hpp> +#include <range/v3/view/zip.hpp> + +namespace ae108 { +namespace meshing { + +constexpr auto get_array = [](auto &&...x) { + return std::array{std::forward<decltype(x)>(x)...}; +}; + +template <std::size_t Dimension> +const auto construct_point_cloud = + [](const std::array<std::array<double, Dimension>, Dimension> &translations, + const std::array<double, Dimension> &origin, const auto &permutations) { + std::vector<std::array<double, Dimension>> pointCloud( + permutations.size()); + for (auto &&[point, tuple] : + ranges::views::zip(pointCloud, permutations)) { + const auto permutation = std::apply(get_array, tuple); + Eigen::Map<Eigen::Matrix<double, Dimension, 1>>(point.data()) = + Eigen::Map<const Eigen::Matrix<double, Dimension, 1>>( + origin.data()) + + (Eigen::Map<const Eigen::Matrix<double, Dimension, Dimension, + Eigen::ColMajor>>( + translations.front().data()) * + Eigen::Map<const Eigen::Matrix<double, Dimension, 1>>( + permutation.data())); + } + return pointCloud; + }; + +template <> +std::vector<std::array<double, 3>> construct_periodic_point_cloud( + const std::array<std::array<double, 3>, 3> &translations, + std::array<double, 3> origin, std::vector<double> set) noexcept { + return construct_point_cloud<3>( + translations, origin, ranges::views::cartesian_product(set, set, set)); +} + +template <> +std::vector<std::array<double, 2>> construct_periodic_point_cloud( + const std::array<std::array<double, 2>, 2> &translations, + std::array<double, 2> origin, std::vector<double> set) noexcept { + + return construct_point_cloud<2>(translations, origin, + ranges::views::cartesian_product(set, set)); +} + +template <> +std::vector<std::array<double, 1>> construct_periodic_point_cloud( + const std::array<std::array<double, 1>, 1> &translations, + std::array<double, 1> origin, std::vector<double> set) noexcept { + return construct_point_cloud<1>(translations, origin, + ranges::views::cartesian_product(set)); +} + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/construct_rectilinear_grid.cc b/meshing/src/construct_rectilinear_grid.cc new file mode 100644 index 0000000000000000000000000000000000000000..7eb8b5c134a939de2e2a8945153dabeccec7b6b1 --- /dev/null +++ b/meshing/src/construct_rectilinear_grid.cc @@ -0,0 +1,166 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/construct_rectilinear_grid.h" +#include <Eigen/Dense> + +namespace ae108 { +namespace meshing { + +template <> +std::tuple<std::vector<std::array<double, 1>>, + std::vector<std::array<std::size_t, 2>>> +construct_rectilinear_grid( + const std::array<std::vector<double>, 1> &instances) noexcept { + + const auto generate_points = [&]() { + std::vector<std::array<double, 1>> points; + points.reserve(instances[0].size()); + + for (const auto &x : instances[0]) + points.push_back({{x}}); + + return points; + }; + + const auto step_to_index = [&](const std::size_t step_x) { return step_x; }; + + const auto generate_edges = [&]() { + std::vector<std::array<std::size_t, 2>> edges; + edges.reserve(instances[0].size() - 1); + std::array<std::size_t, 1> step = {{0}}; + + // edges in x + for (step[0] = 0; step[0] < instances[0].size() - 1; ++step[0]) + edges.push_back({{step_to_index(step[0]), step_to_index(step[0] + 1)}}); + + return edges; + }; + + return {generate_points(), generate_edges()}; +} + +template <> +std::tuple<std::vector<std::array<double, 2>>, + std::vector<std::array<std::size_t, 2>>> +construct_rectilinear_grid( + const std::array<std::vector<double>, 2> &instances) noexcept { + + const auto generate_points = [&]() { + std::vector<std::array<double, 2>> points; + points.reserve(instances[0].size() * instances[1].size()); + + for (const auto &x : instances[0]) + for (const auto &y : instances[1]) + points.push_back({{x, y}}); + + return points; + }; + + const auto step_to_index = [&](const std::size_t step_x, + const std::size_t step_y) { + return step_x * instances[1].size() + step_y; + }; + + const auto generate_edges = [&]() { + std::vector<std::array<std::size_t, 2>> edges; + edges.reserve((instances[0].size() - 1) * instances[1].size() + + instances[0].size() * (instances[1].size() - 1)); + + std::array<std::size_t, 2> step = {{0, 0}}; + + // edges in y + for (step[0] = 0; step[0] < instances[0].size(); ++step[0]) + for (step[1] = 0; step[1] < instances[1].size() - 1; ++step[1]) + edges.push_back({{step_to_index(step[0], step[1]), + step_to_index(step[0], step[1] + 1)}}); + + // edges in x + for (step[0] = 0; step[0] < instances[0].size() - 1; ++step[0]) + for (step[1] = 0; step[1] < instances[1].size(); ++step[1]) + edges.push_back({{step_to_index(step[0], step[1]), + step_to_index(step[0] + 1, step[1])}}); + return edges; + }; + + return {generate_points(), generate_edges()}; +} + +template <> +std::tuple<std::vector<std::array<double, 3>>, + std::vector<std::array<std::size_t, 2>>> +construct_rectilinear_grid( + const std::array<std::vector<double>, 3> &instances) noexcept { + + const auto generate_points = [&]() { + std::vector<std::array<double, 3>> points; + points.reserve(instances[0].size() * instances[1].size() * + instances[2].size()); + + for (const auto &x : instances[0]) + for (const auto &y : instances[1]) + for (const auto &z : instances[2]) + points.push_back({{x, y, z}}); + + return points; + }; + + const auto step_to_index = [&](const std::size_t step_x, + const std::size_t step_y, + const std::size_t step_z) { + return step_x * instances[1].size() * instances[2].size() + + step_y * instances[2].size() + step_z; + }; + + const auto generate_edges = [&]() { + std::vector<std::array<std::size_t, 2>> edges; + edges.reserve((instances[0].size() - 1) * (instances[1].size() - 1) * + instances[2].size() + + instances[0].size() * (instances[1].size() - 1) * + (instances[2].size() - 1) + + (instances[0].size() - 1) * instances[1].size() * + (instances[2].size() - 1)); + + std::array<std::size_t, 3> step = {{0, 0, 0}}; + + // edges in z + for (step[0] = 0; step[0] < instances[0].size(); ++step[0]) + for (step[1] = 0; step[1] < instances[1].size(); ++step[1]) + for (step[2] = 0; step[2] < instances[2].size() - 1; ++step[2]) + edges.push_back({{step_to_index(step[0], step[1], step[2]), + step_to_index(step[0], step[1], step[2] + 1)}}); + + // edges in y + for (step[0] = 0; step[0] < instances[0].size(); ++step[0]) + for (step[1] = 0; step[1] < instances[1].size() - 1; ++step[1]) + for (step[2] = 0; step[2] < instances[2].size(); ++step[2]) + edges.push_back({{step_to_index(step[0], step[1], step[2]), + step_to_index(step[0], step[1] + 1, step[2])}}); + + // edges in x + for (step[0] = 0; step[0] < instances[0].size() - 1; ++step[0]) + for (step[1] = 0; step[1] < instances[1].size(); ++step[1]) + for (step[2] = 0; step[2] < instances[2].size(); ++step[2]) + edges.push_back({{step_to_index(step[0], step[1], step[2]), + step_to_index(step[0] + 1, step[1], step[2])}}); + + return edges; + }; + + return {generate_points(), generate_edges()}; +} + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/construct_voronoi_cell.cc b/meshing/src/construct_voronoi_cell.cc new file mode 100644 index 0000000000000000000000000000000000000000..076005440bf306b4983e2257b4efa5b4c1279ec6 --- /dev/null +++ b/meshing/src/construct_voronoi_cell.cc @@ -0,0 +1,112 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/construct_voronoi_cell.h" +#include <Eigen/Dense> +#include <range/v3/action/sort.hpp> +#include <range/v3/algorithm/copy.hpp> +#include <range/v3/view/chunk.hpp> +#include <range/v3/view/enumerate.hpp> +#include <voro++.hh> + +namespace ae108 { +namespace meshing { + +template <> +BoundaryRepresentation<std::size_t, double, 3> +construct_voronoi_cell<std::size_t, double, 3>( + const std::vector<std::array<double, 3>> &point_cloud, + std::vector<std::pair<std::size_t, std::size_t>> *periodic_faces) noexcept { + + assert(point_cloud.size()); + + voro::voronoicell voronoi_cell; + const auto bound = 1e3; + voronoi_cell.init(-bound, bound, -bound, bound, -bound, bound); + for (auto &point : point_cloud) + voronoi_cell.plane(point[0], point[1], point[2]); + + const auto vertices = [](voro::voronoicell &voronoi_cell) { + std::vector<double> vertices; + voronoi_cell.vertices(vertices); + return vertices; + }(voronoi_cell); + + const auto faces = [](voro::voronoicell &voronoi_cell) { + std::vector<std::vector<std::array<std::size_t, 2>>> faces; + std::vector<int> temp; + voronoi_cell.face_vertices(temp); + for (int i = 0; i < (int)temp.size(); i = i + temp[i] + 1) { + std::vector<std::array<std::size_t, 2>> edges; + for (int j = 1; j < temp[i]; j++) { + edges.push_back( + {std::size_t(temp[i + j]), std::size_t(temp[i + j + 1])}); + ranges::sort(edges.back()); + } + edges.push_back( + {std::size_t(temp[i + temp[i]]), std::size_t(temp[i + 1])}); + ranges::sort(edges.back()); + faces.push_back(edges); + } + return faces; + }(voronoi_cell); + + const auto face_normals = [](voro::voronoicell &voronoi_cell) { + std::vector<BoundaryRepresentation<std::size_t, double, 3>::Point> + face_normals(voronoi_cell.number_of_faces()); + std::vector<double> temp; + voronoi_cell.normals(temp); + for (const auto &[index, normal] : + ranges::views::enumerate(temp | ranges::views::chunk(3))) + ranges::copy(normal, face_normals[index].begin()); + return face_normals; + }(voronoi_cell); + + auto add_edge = + [](const BoundaryRepresentation<std::size_t, double, 3>::Edge &edge, + BoundaryRepresentation<std::size_t, double, 3>::Edges &edges) + -> std::size_t { + for (auto [index, connectivity] : ranges::views::enumerate(edges)) + if (edge == connectivity) + return index; + edges.push_back(edge); + return edges.size() - 1; + }; + + BoundaryRepresentation<std::size_t, double, 3> brep; + brep.faces.resize(voronoi_cell.number_of_faces()); + for (const auto &[index, face] : ranges::views::enumerate(faces)) + for (auto &edge : face) + brep.faces[index].push_back(add_edge(edge, brep.edges)); + + brep.vertices.resize(vertices.size() / 3); + for (const auto &[index, vertex] : + ranges::views::enumerate(vertices | ranges::views::chunk(3))) + ranges::copy(vertex, brep.vertices[index].begin()); + + if (periodic_faces) + for (std::size_t i = 0; i < face_normals.size(); i++) + for (std::size_t j = i + 1; j < face_normals.size(); j++) + if (Eigen::Map<const Eigen::Vector3d>(face_normals[i].data()) + .cross( + Eigen::Map<const Eigen::Vector3d>(face_normals[j].data())) + .isZero()) + periodic_faces->push_back({i, j}); + + return brep; +} + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/Context.cc b/meshing/src/cppgmsh/Context.cc new file mode 100644 index 0000000000000000000000000000000000000000..0a7cfbf701a1899706b01b377f75399dfcef0e54 --- /dev/null +++ b/meshing/src/cppgmsh/Context.cc @@ -0,0 +1,41 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +Context::Context(int const argc, char **const argv, const bool readConfigFiles, + const bool verbose) + : token_((initialize(argc, argv, readConfigFiles, verbose), this), + &finalize) {} + +void Context::initialize(int const argc, char **const argv, + const bool readConfigFiles, const bool verbose) { + gmsh::initialize(argc, argv, readConfigFiles); + if (verbose) + gmsh::option::setNumber("General.Verbosity", 5); + else + gmsh::option::setNumber("General.Verbosity", 0); +} + +void Context::finalize(void *) { gmsh::finalize(); } + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/Node.cc b/meshing/src/cppgmsh/Node.cc new file mode 100644 index 0000000000000000000000000000000000000000..f1a9b83a2c329797e5ec4b7d812aec1a36330024 --- /dev/null +++ b/meshing/src/cppgmsh/Node.cc @@ -0,0 +1,16 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Node.h" \ No newline at end of file diff --git a/meshing/src/cppgmsh/as_affine_transform.cc b/meshing/src/cppgmsh/as_affine_transform.cc new file mode 100644 index 0000000000000000000000000000000000000000..aa043e39f7ee44b3e6b6ea544c4223dd164cc792 --- /dev/null +++ b/meshing/src/cppgmsh/as_affine_transform.cc @@ -0,0 +1,41 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/as_affine_transform.h" +#include <Eigen/Dense> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::array<double, 16> +as_affine_transform(const std::array<double, 3> &translation) noexcept { + + const auto transform = + Eigen::Transform<double, 3, Eigen::Affine, Eigen::RowMajor>( + Eigen::Translation3d( + Eigen::Map<const Eigen::Vector3d>(translation.data()))); + + return [transform]() { + assert(transform.matrix().size() == 16); + std::array<double, 16> out; + std::move(transform.data(), transform.data() + 16, out.begin()); + return out; + }(); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/construct_box.cc b/meshing/src/cppgmsh/construct_box.cc new file mode 100644 index 0000000000000000000000000000000000000000..ea5c3bd64d89307b2c457399d84cacc32d30d1d9 --- /dev/null +++ b/meshing/src/cppgmsh/construct_box.cc @@ -0,0 +1,33 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/construct_box.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::pair<int, int> +construct_box(const std::array<double, 3> origin, + const std::array<double, 3> side_lengths) noexcept { + return {3, gmsh::model::occ::addBox(origin[0], origin[1], origin[2], + side_lengths[0], side_lengths[1], + side_lengths[2])}; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/construct_cylinders.cc b/meshing/src/cppgmsh/construct_cylinders.cc new file mode 100644 index 0000000000000000000000000000000000000000..466cf92e8a528f64dd612acebdebb5279acb1333 --- /dev/null +++ b/meshing/src/cppgmsh/construct_cylinders.cc @@ -0,0 +1,72 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/construct_cylinders.h" +#include <gmsh.h> +#include <range/v3/view/zip.hpp> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::pair<int, int> construct_cylinder(const std::array<double, 3> &p0, + const std::array<double, 3> &p1, + const double radius) { + return {3, + gmsh::model::occ::addCylinder(p0[0], p0[1], p0[2], p1[0] - p0[0], + p1[1] - p0[1], p1[2] - p0[2], radius)}; +} + +std::pair<int, int> capped_cylinder(const std::array<double, 3> &p0, + const std::array<double, 3> &p1, + const double radius) { + std::vector<gmsh::vectorpair> temp; + gmsh::vectorpair cappedCylinder; + gmsh::model::occ::fuse( + {construct_cylinder(p0, p1, radius)}, + {{3, gmsh::model::occ::addSphere(p0[0], p0[1], p0[2], radius)}, + {3, gmsh::model::occ::addSphere(p1[0], p1[1], p1[2], radius)}}, + cappedCylinder, temp); + return cappedCylinder[0]; +} + +std::vector<std::pair<int, int>> +construct_cylinders(const std::vector<std::array<double, 3>> &nodes, + const std::vector<std::array<std::size_t, 2>> &connectivity, + const std::vector<double> &radii, + const bool capped) noexcept { + + assert(connectivity.size() == radii.size()); + + gmsh::vectorpair cylinder_entities; + cylinder_entities.reserve(connectivity.size()); + for (const auto &&[segment, radius] : + ranges::views::zip(connectivity, radii)) { + + const auto &p0 = nodes[segment[0]]; + const auto &p1 = nodes[segment[1]]; + + if (capped) + cylinder_entities.push_back(capped_cylinder(p0, p1, radius)); + else + cylinder_entities.push_back(construct_cylinder(p0, p1, radius)); + } + + return cylinder_entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/construct_polyhedron.cc b/meshing/src/cppgmsh/construct_polyhedron.cc new file mode 100644 index 0000000000000000000000000000000000000000..f60d3a0b4c1a34d7f945c11018509e4e3535b606 --- /dev/null +++ b/meshing/src/cppgmsh/construct_polyhedron.cc @@ -0,0 +1,55 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/construct_polyhedron.h" +#include <gmsh.h> +#include <map> +#include <range/v3/view/enumerate.hpp> +#include <range/v3/view/transform.hpp> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +template <> +std::pair<int, int> construct_polyhedron( + const BoundaryRepresentation<std::size_t, double, 3> &brep) noexcept { + + std::map<std::size_t, int> point2tag; + for (auto &&[index, vertex] : ranges::views::enumerate(brep.vertices)) + point2tag[index] = + gmsh::model::occ::addPoint(vertex[0], vertex[1], vertex[2]); + + std::map<std::size_t, int> edge2tag; + for (auto &&[index, edge] : ranges::views::enumerate(brep.edges)) + edge2tag[index] = + gmsh::model::occ::addLine(point2tag.at(edge[0]), point2tag.at(edge[1])); + + std::vector<int> surfaceTags; + for (const auto &line_loop : brep.faces) + surfaceTags.push_back( + gmsh::model::occ::addPlaneSurface({gmsh::model::occ::addCurveLoop( + line_loop | ranges::view::transform([&edge2tag](int edge) { + return edge2tag.at(edge); + }) | + ranges::to<std::vector>)})); + + return {3, gmsh::model::occ::addVolume( + {gmsh::model::occ::addSurfaceLoop(surfaceTags)})}; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/construct_rectangle.cc b/meshing/src/cppgmsh/construct_rectangle.cc new file mode 100644 index 0000000000000000000000000000000000000000..fde7cf65804a77ed574a24a29e0f5824c5727fd5 --- /dev/null +++ b/meshing/src/cppgmsh/construct_rectangle.cc @@ -0,0 +1,33 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::pair<int, int> +construct_rectangle(const std::array<double, 3> origin, + const std::array<double, 2> side_lengths, + const double rounded_radius) noexcept { + return {2, gmsh::model::occ::addRectangle(origin[0], origin[1], origin[2], + side_lengths[0], side_lengths[1], + -1, rounded_radius)}; +} +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/copy_entities.cc b/meshing/src/cppgmsh/copy_entities.cc new file mode 100644 index 0000000000000000000000000000000000000000..127723685a664165375fc4207952d24cc5b12e37 --- /dev/null +++ b/meshing/src/cppgmsh/copy_entities.cc @@ -0,0 +1,32 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/copy_entities.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> +copy_entities(const std::vector<std::pair<int, int>> &entities) noexcept { + std::vector<std::pair<int, int>> copied_entities; + gmsh::model::occ::copy(entities, copied_entities); + return copied_entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/extract_mesh.cc b/meshing/src/cppgmsh/extract_mesh.cc new file mode 100644 index 0000000000000000000000000000000000000000..148b97ea25075c3a0da9291416642fd355b61704 --- /dev/null +++ b/meshing/src/cppgmsh/extract_mesh.cc @@ -0,0 +1,85 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/extract_mesh.h" +#include "ae108/meshing/cppgmsh/get_elements_in.h" +#include "ae108/meshing/cppgmsh/get_nodes_of.h" +#include <gmsh.h> +#include <range/v3/view/enumerate.hpp> +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +template <std::size_t coordinate_dimension> +std::tuple<std::vector<std::array<double, coordinate_dimension>>, + std::vector<std::vector<std::size_t>>, + std::map<std::size_t, std::size_t>, + std::map<std::size_t, std::size_t>> +extract_mesh(const std::size_t element_dimension) noexcept { + + const auto [nodeTagToIndex, + positions] = [](const std::size_t element_dimension) { + auto nodes = get_nodes_of<coordinate_dimension>({element_dimension, -1}); + + auto nodeTagToIndex = std::map<std::size_t, std::size_t>(); + auto positions = + std::vector<std::array<double, coordinate_dimension>>(nodes.size()); + for (const auto &&[index, node] : ranges::views::enumerate(nodes)) { + positions[index] = node.position; + nodeTagToIndex[node.id] = index; + } + + return std::make_tuple(nodeTagToIndex, positions); + }(element_dimension); + + const auto [elementTagToIndex, connectivity] = + [&nodeTagToIndex](const std::size_t element_dimension) { + const auto elements = get_elements_in({element_dimension, -1}); + + auto elementTagToIndex = std::map<std::size_t, std::size_t>(); + auto connectivity = std::vector<std::vector<std::size_t>>(); + connectivity.reserve(elements.size()); + for (auto element : elements) { + std::vector<std::size_t> nodeTags; + gmsh::model::mesh::getElement(element.second, element.first, + nodeTags); + + std::vector<std::size_t> nodeIndices(nodeTags.size()); + for (auto &&[index, nodeTag] : ranges::views::enumerate(nodeTags)) + nodeIndices[index] = nodeTagToIndex.at(nodeTag); + + elementTagToIndex[element.second] = connectivity.size(); + connectivity.push_back(nodeIndices); + } + + return std::make_tuple(elementTagToIndex, connectivity); + }(element_dimension); + + return {positions, connectivity, nodeTagToIndex, elementTagToIndex}; +} + +template std::tuple< + std::vector<std::array<double, 3>>, std::vector<std::vector<std::size_t>>, + std::map<std::size_t, std::size_t>, std::map<std::size_t, std::size_t>> +extract_mesh<3>(const std::size_t element_dimension) noexcept; + +template std::tuple< + std::vector<std::array<double, 2>>, std::vector<std::vector<std::size_t>>, + std::map<std::size_t, std::size_t>, std::map<std::size_t, std::size_t>> +extract_mesh<2>(const std::size_t element_dimension) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/extrude_entities.cc b/meshing/src/cppgmsh/extrude_entities.cc new file mode 100644 index 0000000000000000000000000000000000000000..c5dc1573a759fa6213878cc433485b91ca194cf1 --- /dev/null +++ b/meshing/src/cppgmsh/extrude_entities.cc @@ -0,0 +1,42 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/extrude_entities.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> +extrude_entities(const std::vector<std::pair<int, int>> &entities, + const std::array<double, 3> &translation, + const bool extrude_mesh, const int number_of_layers) noexcept { + std::vector<std::pair<int, int>> extruded_entities; + std::vector<int> numElements = {}; + std::vector<double> heights = {}; + if (extrude_mesh) { + numElements = {number_of_layers}; + heights = {1}; + } + gmsh::model::occ::extrude(entities, translation[0], translation[1], + translation[2], extruded_entities, numElements, + heights); + return extruded_entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/extrude_surface.cc b/meshing/src/cppgmsh/extrude_surface.cc new file mode 100644 index 0000000000000000000000000000000000000000..56c61483291d216d8b4127efdbe48e1f0ea96379 --- /dev/null +++ b/meshing/src/cppgmsh/extrude_surface.cc @@ -0,0 +1,64 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/extrude_surface.h" +#include "ae108/meshing/cppgmsh/copy_entities.h" +#include "ae108/meshing/cppgmsh/extrude_entities.h" +#include "ae108/meshing/cppgmsh/get_centroid_of.h" +#include "ae108/meshing/cppgmsh/rotate_entities.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include "ae108/meshing/cppgmsh/translate_entities.h" +#include <Eigen/Dense> +#include <Eigen/Geometry> +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::pair<int, int> +extrude_surface(const int surface_tag, const std::array<double, 3> &from, + const std::array<double, 3> &to, + const std::array<double, 3> &surface_normal) noexcept { + + auto crosssection = copy_entities({{2, surface_tag}}); + + const auto translation = [&] { + std::array<double, 3> from_to; + Eigen::Map<Eigen::Matrix<double, 3, 1>>(from_to.data()) = + (Eigen::Map<const Eigen::Vector3d>(to.data()) - + Eigen::Map<const Eigen::Vector3d>(from.data())); + return from_to; + }(); + + std::array<double, 3> axis; + Eigen::AngleAxisd angleAxis; + angleAxis = Eigen::Quaterniond().setFromTwoVectors( + Eigen::Map<const Eigen::Matrix<double, 3, 1>>(surface_normal.data()), + Eigen::Map<const Eigen::Matrix<double, 3, 1>>(translation.data())); + Eigen::Map<Eigen::Matrix<double, 3, 1>>(axis.data()) = angleAxis.axis(); + + rotate_entities(crosssection, {0, 0, 0}, axis, angleAxis.angle()); + + translate_entities(crosssection, from, false); + + const auto extruded_entities = extrude_entities(crosssection, translation); + + return extruded_entities[1]; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/fragment_entities.cc b/meshing/src/cppgmsh/fragment_entities.cc new file mode 100644 index 0000000000000000000000000000000000000000..8e5ac406da1a341a06ad60504eacf269114deb55 --- /dev/null +++ b/meshing/src/cppgmsh/fragment_entities.cc @@ -0,0 +1,34 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/fragment_entities.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> +fragment_entities(const std::vector<std::pair<int, int>> &entities) noexcept { + std::vector<std::pair<int, int>> fragmented_entities; + std::vector<gmsh::vectorpair> outDimTagsMap; + gmsh::model::occ::fragment(entities, entities, fragmented_entities, + outDimTagsMap, -1, true, true); + return fragmented_entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/fuse_entities.cc b/meshing/src/cppgmsh/fuse_entities.cc new file mode 100644 index 0000000000000000000000000000000000000000..5a883fa5a7667c0815a1d00b2348c6cc018b3ea1 --- /dev/null +++ b/meshing/src/cppgmsh/fuse_entities.cc @@ -0,0 +1,33 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/fuse_entities.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> +fuse_entities(const std::vector<std::pair<int, int>> &entities) noexcept { + std::vector<gmsh::vectorpair> temp; + gmsh::vectorpair fused_entities; + gmsh::model::occ::fuse(entities, entities, fused_entities, temp); + return fused_entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/generate_mesh.cc b/meshing/src/cppgmsh/generate_mesh.cc new file mode 100644 index 0000000000000000000000000000000000000000..d1e8cb2e7f362940e13e5538053e255eb2855c61 --- /dev/null +++ b/meshing/src/cppgmsh/generate_mesh.cc @@ -0,0 +1,32 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void generate_mesh(const int dimension, const int order, + const int algorithm) noexcept { + + gmsh::option::setNumber("Mesh.Algorithm", algorithm); + gmsh::model::mesh::generate(dimension); + gmsh::model::mesh::setOrder(order); +} +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_boundary_of.cc b/meshing/src/cppgmsh/get_boundary_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..f96d98996222fbf0386974da657cc818dcab1834 --- /dev/null +++ b/meshing/src/cppgmsh/get_boundary_of.cc @@ -0,0 +1,34 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_boundary_of.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> +get_boundary_of(const std::vector<std::pair<int, int>> &entities, + const bool recursive) noexcept { + gmsh::model::occ::synchronize(); + std::vector<std::pair<int, int>> boundary_entities; + gmsh::model::getBoundary(entities, boundary_entities, true, true, recursive); + return boundary_entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_centroid_of.cc b/meshing/src/cppgmsh/get_centroid_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..82c71c58b8a9390deda1e5c4221fcad61bf15045 --- /dev/null +++ b/meshing/src/cppgmsh/get_centroid_of.cc @@ -0,0 +1,33 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_centroid_of.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::array<double, 3> +get_centroid_of(const std::pair<int, int> &entity) noexcept { + std::array<double, 3> centroid; + gmsh::model::occ::getCenterOfMass(entity.first, entity.second, centroid[0], + centroid[1], centroid[2]); + return centroid; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_coords_of.cc b/meshing/src/cppgmsh/get_coords_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..c302d16f4309cf7c66ab6b61fd233e71cfe10a8c --- /dev/null +++ b/meshing/src/cppgmsh/get_coords_of.cc @@ -0,0 +1,39 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_coords_of.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::array<double, 3> get_coords_of(const int point_tag) noexcept { + std::vector<double> _, coord; + gmsh::model::getValue(0, point_tag, _, coord); + return {coord[0], coord[1], coord[2]}; +} + +std::vector<std::array<double, 3>> +get_coords_of(const std::vector<int> &point_tags) noexcept { + std::vector<std::array<double, 3>> coords(point_tags.size()); + for (std::size_t i = 0; i < point_tags.size(); i++) + coords[i] = get_coords_of(point_tags[i]); + return coords; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_elements_in.cc b/meshing/src/cppgmsh/get_elements_in.cc new file mode 100644 index 0000000000000000000000000000000000000000..3fe575d8bfd4a6269139be02d7cabad8db9f09d6 --- /dev/null +++ b/meshing/src/cppgmsh/get_elements_in.cc @@ -0,0 +1,42 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_elements_in.h" +#include <gmsh.h> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, std::size_t>> +get_elements_in(const std::pair<int, int> &entity) noexcept { + std::vector<int> elementTypes; + std::vector<std::vector<std::size_t>> elementTags; + std::vector<std::vector<std::size_t>> nodeTags; + gmsh::model::mesh::getElements(elementTypes, elementTags, nodeTags, + entity.first, entity.second); + + std::vector<std::pair<int, std::size_t>> elements; + for (std::size_t i = 0; i < elementTypes.size(); i++) + for (std::size_t j = 0; j < elementTags[i].size(); j++) + elements.push_back({elementTypes[i], elementTags[i][j]}); + + return elements; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_entities_in.cc b/meshing/src/cppgmsh/get_entities_in.cc new file mode 100644 index 0000000000000000000000000000000000000000..e09a46fa89c61b912e5ddc1a471678ab35b91108 --- /dev/null +++ b/meshing/src/cppgmsh/get_entities_in.cc @@ -0,0 +1,53 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_entities_in.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> +get_entities_in(const BoundingBox<std::array<double, 3>> &bounding_box, + const int dimension, const double tol) noexcept { + + gmsh::vectorpair entities; + gmsh::model::getEntitiesInBoundingBox( + bounding_box.min[0] - tol, bounding_box.min[1] - tol, + bounding_box.min[2] - tol, bounding_box.max[0] + tol, + bounding_box.max[1] + tol, bounding_box.max[2] + tol, entities, + dimension); + return entities; +} + +std::vector<std::pair<int, int>> +get_entities_in(const std::pair<int, int> &physical_group) noexcept { + + std::vector<int> tags; + gmsh::model::getEntitiesForPhysicalGroup(physical_group.first, + physical_group.second, tags); + + std::vector<std::pair<int, int>> entities; + entities.reserve(tags.size()); + for (const auto &tag : tags) + entities.push_back({physical_group.first, tag}); + + return entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_entities_of.cc b/meshing/src/cppgmsh/get_entities_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..1c95c0c2df20cde0a487a596c10e9377dff58ef7 --- /dev/null +++ b/meshing/src/cppgmsh/get_entities_of.cc @@ -0,0 +1,32 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include <gmsh.h> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> get_entities_of(const int dim) noexcept { + std::vector<std::pair<int, int>> entities; + gmsh::model::getEntities(entities, dim); + return entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_nodes_of.cc b/meshing/src/cppgmsh/get_nodes_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..05ede05c6cdea35c20c7ed1c63eb6be0aed29306 --- /dev/null +++ b/meshing/src/cppgmsh/get_nodes_of.cc @@ -0,0 +1,58 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_nodes_of.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +template <std::size_t Dimension> +std::vector<Node<Dimension>> +get_nodes_of(const std::pair<int, int> &entity, + const bool remove_duplicates) noexcept { + + std::vector<std::size_t> nodeTags; + std::vector<double> coord; + std::vector<double> _; + gmsh::model::mesh::getNodes(nodeTags, coord, _, entity.first, entity.second, + true, false); + + std::vector<Node<Dimension>> nodes(nodeTags.size()); + for (std::size_t i = 0; i < nodeTags.size(); i++) { + nodes[i].id = nodeTags[i]; + std::copy_n(coord.begin() + i * 3, Dimension, nodes[i].position.begin()); + } + + if (remove_duplicates) { + std::sort(nodes.begin(), nodes.end()); + nodes.erase(std::unique(nodes.begin(), nodes.end()), nodes.end()); + } + + return nodes; +} + +template std::vector<Node<3>> +get_nodes_of<3>(const std::pair<int, int> &entity, + const bool keep_duplicates) noexcept; + +template std::vector<Node<2>> +get_nodes_of<2>(const std::pair<int, int> &entity, + const bool keep_duplicates) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_normal_of.cc b/meshing/src/cppgmsh/get_normal_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..bb9de420d8813d4abb08378a5d4a8eb1dc1b254e --- /dev/null +++ b/meshing/src/cppgmsh/get_normal_of.cc @@ -0,0 +1,35 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_normal_of.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::array<double, 3> get_normal_of(const int surface_tag) noexcept { + + std::vector<double> normals; + gmsh::model::getNormal(surface_tag, {0, 0}, normals); + + std::array<double, 3> normal; + std::copy_n(normals.begin(), 3, normal.begin()); + return normal; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_periodic_nodes_of.cc b/meshing/src/cppgmsh/get_periodic_nodes_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..e1ea84f3f867dc99dfa938acb8f847efb1d9b73d --- /dev/null +++ b/meshing/src/cppgmsh/get_periodic_nodes_of.cc @@ -0,0 +1,54 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_periodic_nodes_of.h" +#include <cassert> +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::pair<std::vector<std::size_t>, std::vector<std::size_t>> +get_periodic_nodes_of(const std::pair<int, int> &target_entity, + std::pair<int, int> *source_entity, + std::array<double, 16> *affine_transform) noexcept { + + assert(target_entity.first == 1 || target_entity.first == 2); + + std::vector<size_t> targetNodeTags, sourceNodeTags; + std::vector<double> _; + + int source_tag; + std::vector<double> transform; + std::pair<std::vector<std::size_t>, std::vector<std::size_t>> node_tags; + gmsh::model::mesh::getPeriodicNodes(target_entity.first, target_entity.second, + source_tag, node_tags.first, + node_tags.second, transform, true); + if (source_entity) { + source_entity->first = target_entity.first; + source_entity->second = source_tag; + } + + if (affine_transform) + std::move(transform.data(), transform.data() + 16, + affine_transform->begin()); + + return node_tags; +}; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_physical_groups.cc b/meshing/src/cppgmsh/get_physical_groups.cc new file mode 100644 index 0000000000000000000000000000000000000000..5aeb167ec1e1b587c6e3d4c4dfaadeca4ce2bd81 --- /dev/null +++ b/meshing/src/cppgmsh/get_physical_groups.cc @@ -0,0 +1,31 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_physical_groups.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> get_physical_groups(const int dim) noexcept { + std::vector<std::pair<int, int>> entities; + gmsh::model::getPhysicalGroups(entities, dim); + return entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/get_points_of.cc b/meshing/src/cppgmsh/get_points_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..0cfe8431b198250e7f7dc745b14b5f5df0a57998 --- /dev/null +++ b/meshing/src/cppgmsh/get_points_of.cc @@ -0,0 +1,42 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include <gmsh.h> +#include <set> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<int> get_points_of(const std::pair<int, int> &entity) noexcept { + + std::set<int> tags = {entity.second}; + for (int dim = entity.first; dim > 0; dim--) { + std::set<int> dim_downward; + for (const auto &tag : tags) { + std::vector<int> upward, downward; + gmsh::model::getAdjacencies(dim, tag, upward, downward); + dim_downward.insert(downward.begin(), downward.end()); + } + tags = dim_downward; + } + + return std::vector(tags.begin(), tags.end()); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/heal_periodic_domains.cc b/meshing/src/cppgmsh/heal_periodic_domains.cc new file mode 100644 index 0000000000000000000000000000000000000000..7489e276fbd83a50fc0b19c82a4bcd00b8733c34 --- /dev/null +++ b/meshing/src/cppgmsh/heal_periodic_domains.cc @@ -0,0 +1,52 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/heal_periodic_domains.h" +#include "ae108/meshing/cppgmsh/get_centroid_of.h" +#include "ae108/meshing/cppgmsh/get_entities_in.h" +#include "ae108/meshing/cppgmsh/heal_periodic_surfaces.h" +#include <Eigen/Dense> +#include <array> +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void heal_periodic_domains(const BoundingBox<std::array<double, 3>> &source, + const BoundingBox<std::array<double, 3>> &target, + const double tol) noexcept { + std::array<double, 3> translation; + Eigen::Map<Eigen::Vector3d>(translation.data()) = + Eigen::Map<const Eigen::Vector3d>(target.min.data()) - + Eigen::Map<const Eigen::Vector3d>(source.min.data()); + for (const auto &source_surface : get_entities_in(source, 2)) { + const auto source_centroid = get_centroid_of(source_surface); + for (const auto &target_surface : get_entities_in(target, 2)) { + const auto target_centroid = get_centroid_of(target_surface); + if (Eigen::Map<const Eigen::Vector3d>(target_centroid.data()) + .isApprox( + Eigen::Map<const Eigen::Vector3d>(source_centroid.data()) + + Eigen::Map<const Eigen::Vector3d>(translation.data()), + tol)) + heal_periodic_surfaces(source_surface.second, target_surface.second, + translation); + } + } +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/heal_periodic_surfaces.cc b/meshing/src/cppgmsh/heal_periodic_surfaces.cc new file mode 100644 index 0000000000000000000000000000000000000000..44b561d59550483ff5bc2ebc7df801b436ba6a5f --- /dev/null +++ b/meshing/src/cppgmsh/heal_periodic_surfaces.cc @@ -0,0 +1,71 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/heal_periodic_surfaces.h" +#include "ae108/meshing/cppgmsh/get_coords_of.h" +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include <Eigen/Dense> +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void heal_periodic_surfaces(const int source_surface, const int target_surface, + const std::array<double, 3> &translation, + const double tol) noexcept { + + for (const auto &source : get_points_of({2, source_surface})) { + + std::array<double, 3> query; + Eigen::Map<Eigen::Vector3d>(query.data()) = + (Eigen::Map<const Eigen::Vector3d>(get_coords_of(source).data()) + + Eigen::Map<const Eigen::Vector3d>(translation.data())) + .eval(); + + bool target_found = false; + for (const auto &target : get_points_of({2, target_surface})) + target_found += + Eigen::Map<const Eigen::Vector3d>(get_coords_of(target).data()) + .isApprox(Eigen::Map<const Eigen::Vector3d>(query.data()), tol); + + if (!target_found) { + const auto missing_point = + gmsh::model::occ::addPoint(query[0], query[1], query[2]); + + std::vector<int> volumes, lines; + gmsh::model::getAdjacencies(2, target_surface, volumes, lines); + + gmsh::vectorpair ov; + std::vector<gmsh::vectorpair> ovv; + if (volumes.size()) + gmsh::model::occ::fragment( + [](const std::vector<int> &volumes) { + std::vector<std::pair<int, int>> volume_entities; + for (const auto &tag : volumes) + volume_entities.push_back({3, tag}); + return volume_entities; + }(volumes), + {{0, missing_point}}, ov, ovv); + else + gmsh::model::occ::fragment({{2, target_surface}}, {{0, missing_point}}, + ov, ovv); + } + } +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/import_shapes.cc b/meshing/src/cppgmsh/import_shapes.cc new file mode 100644 index 0000000000000000000000000000000000000000..1232c5f598ee70f263373e9b9112a46f2258cab6 --- /dev/null +++ b/meshing/src/cppgmsh/import_shapes.cc @@ -0,0 +1,32 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/import_shapes.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> +import_shapes(const std::string &fileName, const bool highestDimOnly) noexcept { + std::vector<std::pair<int, int>> outDimTags; + gmsh::model::occ::importShapes(fileName, outDimTags, highestDimOnly); + return outDimTags; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/intersect_entities.cc b/meshing/src/cppgmsh/intersect_entities.cc new file mode 100644 index 0000000000000000000000000000000000000000..2c9ea7466bd585f6a0f7f563bb2f73ee5c97dd74 --- /dev/null +++ b/meshing/src/cppgmsh/intersect_entities.cc @@ -0,0 +1,37 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/intersect_entities.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> +intersect_entities(const std::vector<std::pair<int, int>> &object_entities, + const std::vector<std::pair<int, int>> &tool_entities, + const bool remove_object, const bool remove_tool) noexcept { + std::vector<gmsh::vectorpair> temp; + gmsh::vectorpair intersected_entities; + gmsh::model::occ::intersect(object_entities, tool_entities, + intersected_entities, temp, -1, remove_object, + remove_tool); + return intersected_entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/read_file.cc b/meshing/src/cppgmsh/read_file.cc new file mode 100644 index 0000000000000000000000000000000000000000..357b50783797a5d400b989134753d29ec33a0671 --- /dev/null +++ b/meshing/src/cppgmsh/read_file.cc @@ -0,0 +1,27 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/read_file.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void read_file(const std::string &fname) noexcept { gmsh::open(fname); } + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/remove_entities.cc b/meshing/src/cppgmsh/remove_entities.cc new file mode 100644 index 0000000000000000000000000000000000000000..6c2ad72c6cb1d4ac405528089dd500c5519ec90a --- /dev/null +++ b/meshing/src/cppgmsh/remove_entities.cc @@ -0,0 +1,30 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/remove_entities.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void remove_entities(const std::vector<std::pair<int, int>> &entities, + const bool recursive) noexcept { + gmsh::model::occ::remove(entities, recursive); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/rotate_entities.cc b/meshing/src/cppgmsh/rotate_entities.cc new file mode 100644 index 0000000000000000000000000000000000000000..cdd6b5fe45de7aa6834b2bd0788ddc6ab564c57a --- /dev/null +++ b/meshing/src/cppgmsh/rotate_entities.cc @@ -0,0 +1,33 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/rotate_entities.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void rotate_entities(const std::vector<std::pair<int, int>> &entities, + const std::array<double, 3> ¢er, + const std::array<double, 3> &direction, + double angle) noexcept { + gmsh::model::occ::rotate(entities, center[0], center[1], center[2], + direction[0], direction[1], direction[2], angle); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/set_domain_entities_periodic.cc b/meshing/src/cppgmsh/set_domain_entities_periodic.cc new file mode 100644 index 0000000000000000000000000000000000000000..efe8fb83675f73c7f7e93d2fdb1be1913c7ce821 --- /dev/null +++ b/meshing/src/cppgmsh/set_domain_entities_periodic.cc @@ -0,0 +1,54 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/set_domain_entities_periodic.h" +#include "ae108/meshing/cppgmsh/as_affine_transform.h" +#include "ae108/meshing/cppgmsh/get_centroid_of.h" +#include "ae108/meshing/cppgmsh/get_entities_in.h" +#include "ae108/meshing/cppgmsh/set_periodic.h" +#include <Eigen/Dense> +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void set_domain_entities_periodic( + const BoundingBox<std::array<double, 3>> &source, + const BoundingBox<std::array<double, 3>> &target, const int dim, + const double tol) noexcept { + + assert(dim == 1 || dim == 2); + + std::array<double, 3> translation; + Eigen::Map<Eigen::Vector3d>(translation.data()) = + Eigen::Map<const Eigen::Vector3d>(target.min.data()) - + Eigen::Map<const Eigen::Vector3d>(source.min.data()); + + for (const auto &source_surface : get_entities_in(source, dim)) + for (const auto &target_surface : get_entities_in(target, dim)) + if (Eigen::Map<const Eigen::Vector3d>( + get_centroid_of(target_surface).data()) + .isApprox( + Eigen::Map<const Eigen::Vector3d>( + get_centroid_of(source_surface).data()) + + Eigen::Map<const Eigen::Vector3d>(translation.data()), + tol)) + set_periodic({{2, target_surface.second}}, {2, source_surface.second}, + as_affine_transform(translation)); +} +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/set_expert_mode.cc b/meshing/src/cppgmsh/set_expert_mode.cc new file mode 100644 index 0000000000000000000000000000000000000000..029393120b3ec7177215470545f01e8fe37f360b --- /dev/null +++ b/meshing/src/cppgmsh/set_expert_mode.cc @@ -0,0 +1,29 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/set_expert_mode.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void set_expert_mode(const bool enable) noexcept { + gmsh::option::setNumber("General.ExpertMode", double(enable)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/set_granularity.cc b/meshing/src/cppgmsh/set_granularity.cc new file mode 100644 index 0000000000000000000000000000000000000000..a22d8b28ee13064deea6b2901e2ec7bd463c205a --- /dev/null +++ b/meshing/src/cppgmsh/set_granularity.cc @@ -0,0 +1,30 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void set_granularity(const double granularity) noexcept { + gmsh::vectorpair point_entitites; + gmsh::model::getEntities(point_entitites, 0); + gmsh::model::mesh::setSize(point_entitites, granularity); +} +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/set_periodic.cc b/meshing/src/cppgmsh/set_periodic.cc new file mode 100644 index 0000000000000000000000000000000000000000..e1a053ce856a49b0331d7a8de56709181c212434 --- /dev/null +++ b/meshing/src/cppgmsh/set_periodic.cc @@ -0,0 +1,45 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/set_periodic.h" +#include <cassert> +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void set_periodic(const std::vector<std::pair<int, int>> &target_entities, + const std::pair<int, int> &source_entity, + const std::array<double, 16> &affine_transform) noexcept { + + assert(source_entity.first == 1 || source_entity.first == 2); + + std::vector<int> target_tags; + for (const auto &target_entity : target_entities) { + assert(source_entity.first == target_entity.first); + target_tags.push_back(target_entity.second); + } + + std::vector<double> transform(affine_transform.begin(), + affine_transform.end()); + + gmsh::model::mesh::setPeriodic(source_entity.first, target_tags, + {source_entity.second}, transform); +}; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/set_physical_group_of.cc b/meshing/src/cppgmsh/set_physical_group_of.cc new file mode 100644 index 0000000000000000000000000000000000000000..1786a8d93a2390ac149c34cdf1c4447cf7bd9544 --- /dev/null +++ b/meshing/src/cppgmsh/set_physical_group_of.cc @@ -0,0 +1,42 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/set_physical_group_of.h" +#include <cassert> +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::pair<int, int> set_physical_group_of( + const std::vector<std::pair<int, int>> &entities) noexcept { + assert(entities.size()); + + int dim = entities[0].first; + std::vector<int> tags; + tags.reserve(entities.size()); + for (const auto &entity : entities) { + assert(dim == entity.first); + tags.push_back(entity.second); + }; + + return {dim, gmsh::model::addPhysicalGroup(dim, tags)}; + ; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/synchronize.cc b/meshing/src/cppgmsh/synchronize.cc new file mode 100644 index 0000000000000000000000000000000000000000..55d7a4649127a6671f9d4b72487a9a3e2d6e73fc --- /dev/null +++ b/meshing/src/cppgmsh/synchronize.cc @@ -0,0 +1,27 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void synchronize() noexcept { gmsh::model::occ::synchronize(); } + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/translate_entities.cc b/meshing/src/cppgmsh/translate_entities.cc new file mode 100644 index 0000000000000000000000000000000000000000..bd6f79217748357a0ce6265aad202bc812e3a59d --- /dev/null +++ b/meshing/src/cppgmsh/translate_entities.cc @@ -0,0 +1,39 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/translate_entities.h" +#include "ae108/meshing/cppgmsh/copy_entities.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +std::vector<std::pair<int, int>> +translate_entities(std::vector<std::pair<int, int>> entities, + const std::array<double, 3> &translation, + const bool copy) noexcept { + if (copy) + entities = copy_entities(entities); + + gmsh::model::occ::translate(entities, translation[0], translation[1], + translation[2]); + + return entities; +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/cppgmsh/write_file.cc b/meshing/src/cppgmsh/write_file.cc new file mode 100644 index 0000000000000000000000000000000000000000..c19a40a575b2db0bfbb16f068c5b2d3fa1e553a4 --- /dev/null +++ b/meshing/src/cppgmsh/write_file.cc @@ -0,0 +1,27 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/write_file.h" +#include <gmsh.h> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +void write_file(const std::string &fname) noexcept { gmsh::write(fname); } + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/BoundaryRepresentation.h b/meshing/src/include/ae108/meshing/BoundaryRepresentation.h new file mode 100644 index 0000000000000000000000000000000000000000..cb0c1fe35ea49dbe339a8b368411c439bd11c3f0 --- /dev/null +++ b/meshing/src/include/ae108/meshing/BoundaryRepresentation.h @@ -0,0 +1,84 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once +#include <array> +#include <set> +#include <vector> + +namespace ae108 { +namespace meshing { +template <class SizeType_, class ValueType_, SizeType_ Dimension_> +struct BoundaryRepresentation { + using Point = std::array<ValueType_, Dimension_>; + + /** + * @brief The position per vertex. + */ + using Vertices = std::vector<Point>; + + /** + * @brief Indicies of two vertices that form an edge. + */ + using Edge = std::array<SizeType_, 2>; + + /** + * @brief Vector of all edges. + */ + using Edges = std::vector<Edge>; + + /** + * @brief Edges that enclose a face. + */ + using Faces = std::vector<std::vector<SizeType_>>; + + /** + * @brief Returns the dimension. + */ + static constexpr SizeType_ dimension() noexcept { return Dimension_; } + + /** + * @brief Returns all vertices of an edge. + */ + std::vector<Point> vertices_of_edge(SizeType_ edge) const noexcept { + std::vector<Point> edge_vertices; + for (const auto &vertex : edges[edge]) + edge_vertices.push_back(vertices[vertex]); + return edge_vertices; + }; + + /** + * @brief Returns all vertices of a face. + */ + std::vector<Point> vertices_of_face(SizeType_ index) const noexcept { + std::set<SizeType_> face_vertex_indices; + for (const auto &edge : faces[index]) + for (const auto &vertex : edges[edge]) + face_vertex_indices.insert(vertex); + + std::vector<Point> face_vertices; + face_vertices.reserve(face_vertex_indices.size()); + for (const auto &vertex_index : face_vertex_indices) + face_vertices.push_back(vertices[vertex_index]); + + return face_vertices; + }; + + Vertices vertices; + Edges edges; + Faces faces; +}; +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/BoundingBox.h b/meshing/src/include/ae108/meshing/BoundingBox.h new file mode 100644 index 0000000000000000000000000000000000000000..595d77a5e20aa345869773b8f7d8cd079df00cdc --- /dev/null +++ b/meshing/src/include/ae108/meshing/BoundingBox.h @@ -0,0 +1,27 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +namespace ae108 { +namespace meshing { + +template <class Point> struct BoundingBox { + Point min; + Point max; +}; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/bounding_box_of.h b/meshing/src/include/ae108/meshing/bounding_box_of.h new file mode 100644 index 0000000000000000000000000000000000000000..241098efa1de55f473c00c9092bd99913bfd566b --- /dev/null +++ b/meshing/src/include/ae108/meshing/bounding_box_of.h @@ -0,0 +1,45 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include "ae108/meshing/BoundingBox.h" +#include <cassert> +#include <vector> + +namespace ae108 { +namespace meshing { + +/** + * @brief Returns the bounding box of points + * + * @param points A vector of points. + */ + +template <class Point> +BoundingBox<Point> bounding_box_of(const std::vector<Point> &points) noexcept { + assert(points.size()); + Point min(points[0]); + Point max(points[0]); + for (const auto &point : points) + for (std::size_t i = 0; i < point.size(); i++) { + min[i] = std::min(point[i], min[i]); + max[i] = std::max(point[i], max[i]); + } + return {min, max}; +} + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/construct_periodic_point_cloud.h b/meshing/src/include/ae108/meshing/construct_periodic_point_cloud.h new file mode 100644 index 0000000000000000000000000000000000000000..1f1aaa7467b74aca3c3d779c2c3b35cfb084ba4e --- /dev/null +++ b/meshing/src/include/ae108/meshing/construct_periodic_point_cloud.h @@ -0,0 +1,47 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { + +/** + * @brief Returns a vector of points that is spanned by a set of discrete + * translations around the origin. It is also known as Bravais lattice. + * + * In 3D, each point is defined by + * + * R = n1 x a1 + n2 x a2 + n3 x a3, + * + * where ai is a translation vector and ni assumes any of the integers in set. + * + * @param translations An array containing the translation vectors. + * @param origin Location of the origin. + * @param set A set of integer permutations + * @note https://en.wikipedia.org/wiki/Bravais_lattice + */ + +template <std::size_t Dimension> +std::vector<std::array<double, Dimension>> construct_periodic_point_cloud( + const std::array<std::array<double, Dimension>, Dimension> &translations, + std::array<double, Dimension> origin, + std::vector<double> set = {-1, 0, 1}) noexcept; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/construct_rectilinear_grid.h b/meshing/src/include/ae108/meshing/construct_rectilinear_grid.h new file mode 100644 index 0000000000000000000000000000000000000000..7f8dc9bfd2d5dc51c70c94c794f3bef3c87a4cfb --- /dev/null +++ b/meshing/src/include/ae108/meshing/construct_rectilinear_grid.h @@ -0,0 +1,38 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { + +/** + * @brief Constructs a d-dimensional rectilinear grid based on the (non-)uniform + * input coordinates. Returns points and edges. + * + * @param coordinates d sets of coordinates that span the grid. + * @note https://en.wikipedia.org/wiki/Regular_grid + */ + +template <std::size_t Dimension> +std::tuple<std::vector<std::array<double, Dimension>>, + std::vector<std::array<std::size_t, 2>>> +construct_rectilinear_grid( + const std::array<std::vector<double>, Dimension> &coordinates) noexcept; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/construct_voronoi_cell.h b/meshing/src/include/ae108/meshing/construct_voronoi_cell.h new file mode 100644 index 0000000000000000000000000000000000000000..b4e6548659ab884892367c794fe0371b1dbd3d2f --- /dev/null +++ b/meshing/src/include/ae108/meshing/construct_voronoi_cell.h @@ -0,0 +1,39 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once +#include "ae108/meshing/BoundaryRepresentation.h" + +namespace ae108 { +namespace meshing { + +/** + * @brief Returns the boundary representation of the Voronoi cell spanned by a + * point cloud around the origin. The Voronoi cell is defined as the locus of + * all points closer to the origin than to any other point in the point cloud. + * + * @param point_cloud A vector of points, a.k.a. sites, forming the point cloud. + * @param periodic_faces A vector containing all periodic face pairs. + * @note https://en.wikipedia.org/wiki/Voronoi_diagram + */ + +template <class SizeType, class ValueType, SizeType Dimension> +BoundaryRepresentation<SizeType, ValueType, Dimension> construct_voronoi_cell( + const std::vector<std::array<ValueType, Dimension>> &point_cloud, + std::vector<std::pair<SizeType, SizeType>> *periodic_faces = + nullptr) noexcept; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/Context.h b/meshing/src/include/ae108/meshing/cppgmsh/Context.h new file mode 100644 index 0000000000000000000000000000000000000000..7c9b83fd0b07adb6ed4148b6914f8b7f63fd79e4 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/Context.h @@ -0,0 +1,57 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <memory> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +class Context { +public: + /** + * @brief Initializes Gmsh. Gmsh is finalized automatically when the + * instance of Context is destroyed. + * + * @param argc `argc` as provided to main(). + * @param argv `argv` as provided to main(). + * @param readConfigFiles Option to read config file. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L63 + */ + explicit Context(int const argc, char **const argv, + const bool readConfigFiles = true, + const bool verbose = false); + +private: + /** + * @brief Initializes Gmsh. + */ + static void initialize(int const argc, char **const argv, + const bool readConfigFiles, const bool verbose); + + /** + * @brief Finalizes Gmsh. + */ + static void finalize(void *); + + using Token = std::unique_ptr<Context, decltype(&finalize)>; + Token token_; +}; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/Node.h b/meshing/src/include/ae108/meshing/cppgmsh/Node.h new file mode 100644 index 0000000000000000000000000000000000000000..78467423cf58681d107cf2c3b482f28f90ecaf18 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/Node.h @@ -0,0 +1,43 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +template <std::size_t Dimension> struct Node { + + using Index = std::size_t; + using Position = std::array<double, Dimension>; + + Index id; + Position position; + + bool operator<(const Node<Dimension> &another) const { + return id < another.id; + } + + bool operator==(const Node<Dimension> &another) const { + return id == another.id; + } +}; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/as_affine_transform.h b/meshing/src/include/ae108/meshing/cppgmsh/as_affine_transform.h new file mode 100644 index 0000000000000000000000000000000000000000..2a210c08ce5b12a25d30725773cee8b845b8add1 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/as_affine_transform.h @@ -0,0 +1,35 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns affine transform (16 entries of a 4x4 matrix, by row) based on + * translation. + * + * @param translation The translation. + */ +std::array<double, 16> +as_affine_transform(const std::array<double, 3> &translation) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/construct_box.h b/meshing/src/include/ae108/meshing/cppgmsh/construct_box.h new file mode 100644 index 0000000000000000000000000000000000000000..8370430b23dc1dd872d2a361e100f4f88d3f6e09 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/construct_box.h @@ -0,0 +1,38 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Constructs a parallelepipedic box using gmsh. Returns the entity. + * + * @param origin Position of the box origin + * @param side_lengths Side lengths of x-, y-, and z-side. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2398 + */ +std::pair<int, int> +construct_box(const std::array<double, 3> origin, + const std::array<double, 3> side_lengths) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/construct_cylinders.h b/meshing/src/include/ae108/meshing/cppgmsh/construct_cylinders.h new file mode 100644 index 0000000000000000000000000000000000000000..bddafea9706c9fab4ff15af4ecf83b7055f6f39a --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/construct_cylinders.h @@ -0,0 +1,43 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Constructs cylinders of differing radius from each segment using gmsh. + * Returns the entity. + * + * @param nodes Node positions. + * @param connectivity Nodal connectivity of each segment. + * @param radii Radii of all segments. + * @param capped Option to add a cap on each cylinder end. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2414 + */ +std::vector<std::pair<int, int>> +construct_cylinders(const std::vector<std::array<double, 3>> &nodes, + const std::vector<std::array<std::size_t, 2>> &connectivity, + const std::vector<double> &radii, + const bool capped = true) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/construct_polyhedron.h b/meshing/src/include/ae108/meshing/cppgmsh/construct_polyhedron.h new file mode 100644 index 0000000000000000000000000000000000000000..6125490debc9e49798304fe0e7a9e7306fbf6fb6 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/construct_polyhedron.h @@ -0,0 +1,37 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include "ae108/meshing/BoundaryRepresentation.h" + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Constructs a solid polyhedron from a BoundaryRepresentation using + * gmsh. Returns the gmsh entity. + * + * @param brep A boundary representation containing the polyhedron. + * + */ +template <class SizeType, class ValueType> +std::pair<int, int> construct_polyhedron( + const BoundaryRepresentation<SizeType, ValueType, 3> &brep) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/construct_rectangle.h b/meshing/src/include/ae108/meshing/cppgmsh/construct_rectangle.h new file mode 100644 index 0000000000000000000000000000000000000000..9e9a981bd7a317831def8dfb722d2ad19dab7655 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/construct_rectangle.h @@ -0,0 +1,41 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Constructs a rectangle, with lower left corner at {x, y, z} and + * upper right corner at {x+dx,y+dy,z}. Returns the gmsh entity. + * + * @param origin Position of the rectangle origin {x,y,z}. + * @param side_lengths Side lengths: {dx,dy}, {dy,dz} or {dx,dz}, according to + * plane. + * @param rounded_radius If > 0 the corners are rounded. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2229 + */ +std::pair<int, int> +construct_rectangle(const std::array<double, 3> origin, + const std::array<double, 2> side_lengths, + const double rounded_radius = 0.) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/copy_entities.h b/meshing/src/include/ae108/meshing/cppgmsh/copy_entities.h new file mode 100644 index 0000000000000000000000000000000000000000..1c3ee77cfef473ad3364b36bb054878fd91bc915 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/copy_entities.h @@ -0,0 +1,35 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Copies the given entities and returns the copies. + * + * @param entities Original entities. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2729 + */ +std::vector<std::pair<int, int>> +copy_entities(const std::vector<std::pair<int, int>> &entities) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/extract_mesh.h b/meshing/src/include/ae108/meshing/cppgmsh/extract_mesh.h new file mode 100644 index 0000000000000000000000000000000000000000..9aa4766d672b7208b2109b2489e3abc92ce92403 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/extract_mesh.h @@ -0,0 +1,42 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <map> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Extract mesh from Gmsh. + * + * @param element_dimension dimension of the elements of interest. + */ +template <std::size_t coordinate_dimension> + +std::tuple<std::vector<std::array<double, coordinate_dimension>>, + std::vector<std::vector<std::size_t>>, + std::map<std::size_t, std::size_t>, + std::map<std::size_t, std::size_t>> +extract_mesh( + const std::size_t element_dimension = coordinate_dimension) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/extrude_entities.h b/meshing/src/include/ae108/meshing/cppgmsh/extrude_entities.h new file mode 100644 index 0000000000000000000000000000000000000000..603443852fb42491dc75be5800309d8ed2a9a1d6 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/extrude_entities.h @@ -0,0 +1,44 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Extrudes the given entities along a translation vector. Returns the + * extruded entities. + * @param entities Entities to extrude_entities. + * @param translation Extrusion vector. + * @param extrude_mesh If true, the mesh of the base area of the extruded bodies + * will be extruded as well, i.e. the same layer of 3D elements will be repeated + * several times. Otherwise, The bodies are meshed as general 3D bodies. + * @param number_of_layers Number of element layers (if extrude_mesh is true). + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2514 + */ +std::vector<std::pair<int, int>> +extrude_entities(const std::vector<std::pair<int, int>> &entities, + const std::array<double, 3> &translation, + const bool extrude_mesh = false, + const int number_of_layers = 1) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/extrude_surface.h b/meshing/src/include/ae108/meshing/cppgmsh/extrude_surface.h new file mode 100644 index 0000000000000000000000000000000000000000..048ab3bf82894cbb01aaa51b842457f8d992be30 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/extrude_surface.h @@ -0,0 +1,39 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Extrudes the surface entity from origin to target. + * + * @param surface_tag Tag of the surface defining the cross-section in xy-plane. + * @param from Position of the origin. + * @param to Position of the target. + * @param surface_normal Normal of the surface. + */ +std::pair<int, int> extrude_surface( + const int surface_tag, const std::array<double, 3> &from, + const std::array<double, 3> &to, + const std::array<double, 3> &surface_normal = {{0, 0, 1}}) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/fragment_entities.h b/meshing/src/include/ae108/meshing/cppgmsh/fragment_entities.h new file mode 100644 index 0000000000000000000000000000000000000000..62e9e57f91abd111a42c019fe18e7e8d47b8158a --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/fragment_entities.h @@ -0,0 +1,36 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Fuses the given entities, while keeping/creating a separate entity for + * each boolean fragment. All interfaces among the fragments are made conformal. + * + * @param entities Separate entities. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2651 + */ +std::vector<std::pair<int, int>> +fragment_entities(const std::vector<std::pair<int, int>> &entities) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/fuse_entities.h b/meshing/src/include/ae108/meshing/cppgmsh/fuse_entities.h new file mode 100644 index 0000000000000000000000000000000000000000..070177cbc05e339d9c2ce237ba6b3755099968a3 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/fuse_entities.h @@ -0,0 +1,35 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns vector of fused entities. + * + * @param entities Seperate entities. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2600 + */ +std::vector<std::pair<int, int>> +fuse_entities(const std::vector<std::pair<int, int>> &entities) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/generate_mesh.h b/meshing/src/include/ae108/meshing/cppgmsh/generate_mesh.h new file mode 100644 index 0000000000000000000000000000000000000000..a10fcd16f0ddbdb372ddfcb59e191788c7c78045 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/generate_mesh.h @@ -0,0 +1,36 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Generate mesh. The mesh can be exported with extract_mesh. + * + * @param dimension The desired meshing dimension (e.g. volume (3) or surface + * (2) mesh). + * @param order The desired element order. See gmsh docs. + * @param algorithm The desired meshing algorithm. See gmsh docs. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L585 + */ +void generate_mesh(const int dimension = 3, const int order = 1, + const int algorithm = 6) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_boundary_of.h b/meshing/src/include/ae108/meshing/cppgmsh/get_boundary_of.h new file mode 100644 index 0000000000000000000000000000000000000000..398f05e33389c9ec77e92328699c8561240d45d1 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_boundary_of.h @@ -0,0 +1,38 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns boundary entities (dim-1) of the specified entities, or + * optionally the boundary points, if recursive = true. + * + * @param entities Entities of interest. + * @param recursive If true, returns boundary points (dim=0). + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L284 + */ +std::vector<std::pair<int, int>> +get_boundary_of(const std::vector<std::pair<int, int>> &entities, + const bool recursive = false) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_centroid_of.h b/meshing/src/include/ae108/meshing/cppgmsh/get_centroid_of.h new file mode 100644 index 0000000000000000000000000000000000000000..21c34e514473b79676ef91966c24c323ee4a7fcb --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_centroid_of.h @@ -0,0 +1,35 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns the centroid coordinates of the entity. + * + * @param entity The point tag. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2834 + */ +std::array<double, 3> +get_centroid_of(const std::pair<int, int> &entity) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_coords_of.h b/meshing/src/include/ae108/meshing/cppgmsh/get_coords_of.h new file mode 100644 index 0000000000000000000000000000000000000000..76b48c85d1d50ef19087de1d153212d24848dddb --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_coords_of.h @@ -0,0 +1,42 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns coordinates of point + * + * @param point_tag The point tag. + */ +std::array<double, 3> get_coords_of(const int point_tag) noexcept; + +/** + * @brief Returns coordinates of points + * + * @param point_tags The point tags. + */ +std::vector<std::array<double, 3>> +get_coords_of(const std::vector<int> &point_tags) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_elements_in.h b/meshing/src/include/ae108/meshing/cppgmsh/get_elements_in.h new file mode 100644 index 0000000000000000000000000000000000000000..9197b77d9df203ceadd233a11d72f8d81628e5a7 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_elements_in.h @@ -0,0 +1,36 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns the element types and tags of the elements in the + * specified entity. + * + * @param entity The entity {dim, tag}. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L771 + */ +std::vector<std::pair<int, std::size_t>> +get_elements_in(const std::pair<int, int> &entity) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_entities_in.h b/meshing/src/include/ae108/meshing/cppgmsh/get_entities_in.h new file mode 100644 index 0000000000000000000000000000000000000000..821324387d6af9c24a6548d980724e9b14b0bc32 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_entities_in.h @@ -0,0 +1,49 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include "ae108/meshing/BoundingBox.h" +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns all entities of dimension inside of a bounding box + * + * @param bounding_box The bounding box or search domain. + * @param dimension Entity dimension, i.e 3-volume, 2-surface, 1-line, 0-point + * @param tol Spatial tolerance. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L307 + */ +std::vector<std::pair<int, int>> +get_entities_in(const BoundingBox<std::array<double, 3>> &bounding_box, + const int dimension, const double tol = 1e-6) noexcept; + +/** + * @brief Returns all entities in the specified physical group. + * + * @param physical_group The physical group {dim, tag}. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L230 + */ +std::vector<std::pair<int, int>> +get_entities_in(const std::pair<int, int> &physical_group) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_entities_of.h b/meshing/src/include/ae108/meshing/cppgmsh/get_entities_of.h new file mode 100644 index 0000000000000000000000000000000000000000..1dd2c496a90cf08400412837b4a3c03ed85abc60 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_entities_of.h @@ -0,0 +1,35 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns all geometric entities of all or just the specified dimension. + * + * @param dim The dimension of interest. If < 0, the entities of all dimensions + * are returned. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2792 + */ +std::vector<std::pair<int, int>> get_entities_of(const int dim = -1) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_nodes_of.h b/meshing/src/include/ae108/meshing/cppgmsh/get_nodes_of.h new file mode 100644 index 0000000000000000000000000000000000000000..9da697f096d3cdec6c7baaa7eaf434caaf49ce5b --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_nodes_of.h @@ -0,0 +1,44 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include "ae108/meshing/cppgmsh/Node.h" +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Get the nodes of one or more entities. Optionally avoids + * duplicate nodes (e.g. on entity boundaries). Returns a vector of Nodes. + * + * @param dim The dimension of the model entities of interest. Set to < 0 to get + * all nodes of the mesh. + * @param tag The tag of the model entity of interest. Set to < 0 to get the + * nodes of all entities of dimension dim. + * @param remove_duplicates If true, node duplicates are removed. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L662 + */ + +template <std::size_t Dimension> +std::vector<Node<Dimension>> +get_nodes_of(const std::pair<int, int> &entity, + const bool remove_duplicates = true) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_normal_of.h b/meshing/src/include/ae108/meshing/cppgmsh/get_normal_of.h new file mode 100644 index 0000000000000000000000000000000000000000..59f39d9728f18ba809c1bb5249a85f617b6ac535 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_normal_of.h @@ -0,0 +1,34 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns the normal of a surface. + * + * @param surface_tag The surface tag. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L462 + */ +std::array<double, 3> get_normal_of(const int surface_tag) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_periodic_nodes_of.h b/meshing/src/include/ae108/meshing/cppgmsh/get_periodic_nodes_of.h new file mode 100644 index 0000000000000000000000000000000000000000..476fa505685451992f4913e4472b81ea2a59a709 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_periodic_nodes_of.h @@ -0,0 +1,41 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns the corresponding node tags of the target entity (out.first) + * and the source entity (out.second) + * + * @param target_entity Target entity. + * @param source_entity Optional output of the source entity. + * @param affine_transform Optional output of the affine transformation. + */ +std::pair<std::vector<std::size_t>, std::vector<std::size_t>> +get_periodic_nodes_of( + const std::pair<int, int> &target_entity, + std::pair<int, int> *source_entity = nullptr, + std::array<double, 16> *affine_transform = nullptr) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_physical_groups.h b/meshing/src/include/ae108/meshing/cppgmsh/get_physical_groups.h new file mode 100644 index 0000000000000000000000000000000000000000..5a3cfbcad8b3a0153bc48452efd4834da320c4ae --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_physical_groups.h @@ -0,0 +1,36 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns the physical groups in the model. + * + * @param dim The dimension of the physical groups to return, if < 0, the groups + * of all dimensions are returned. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L223 + */ +std::vector<std::pair<int, int>> +get_physical_groups(const int dim = -1) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/get_points_of.h b/meshing/src/include/ae108/meshing/cppgmsh/get_points_of.h new file mode 100644 index 0000000000000000000000000000000000000000..d9f769d6efb8e31c707f47a5cf0fb8699a22f785 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/get_points_of.h @@ -0,0 +1,33 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns tags of all points of an entity. + * + * @param entity The entity. + */ +std::vector<int> get_points_of(const std::pair<int, int> &entity) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/heal_periodic_domains.h b/meshing/src/include/ae108/meshing/cppgmsh/heal_periodic_domains.h new file mode 100644 index 0000000000000000000000000000000000000000..e4de776c0c3cc4be6229e9754a29c7f29a113cf0 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/heal_periodic_domains.h @@ -0,0 +1,41 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include "ae108/meshing/BoundingBox.h" +#include <array> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Matches points between all periodic surfaces in the source and target + * domain. If a point on the source surface is missing on the target surface, + * it will be added to the target surface. Assumption: Source and target domain + * are translational periodic. + * + * @param source Source domain spanned by a bounding box. + * @param target Target domain spanned by a bounding box. + * @param tol Tolerance for point matching. + */ +void heal_periodic_domains(const BoundingBox<std::array<double, 3>> &source, + const BoundingBox<std::array<double, 3>> &target, + const double tol = 1e-9) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/heal_periodic_surfaces.h b/meshing/src/include/ae108/meshing/cppgmsh/heal_periodic_surfaces.h new file mode 100644 index 0000000000000000000000000000000000000000..eca339f8a2cd5dc11beb5ee3a397793b2271b3f2 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/heal_periodic_surfaces.h @@ -0,0 +1,41 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Matches points between source and target surface. If a point on the + * source surface is missing on the target surface, it will be added to the + * target surface. Source and target surface are translational periodic. + * + * @param source Source surface tag. + * @param target Target surface tag. + * @param translation Translation vector from source to target. + * @param tol Tolerance for point matching. + * + */ +void heal_periodic_surfaces(const int source, const int target, + const std::array<double, 3> &translation, + const double tol = 1e-9) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/import_shapes.h b/meshing/src/include/ae108/meshing/cppgmsh/import_shapes.h new file mode 100644 index 0000000000000000000000000000000000000000..568ac8ec79f833ddbf54f8ee6677618ce686be5e --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/import_shapes.h @@ -0,0 +1,38 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <string> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Imports shapes from a BREP, STEP or IGES file. + * @param fileName Name of the imported file. + * @param highestDimOnly If true, only the highest dimensional entities are + * imported. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2770 + */ +std::vector<std::pair<int, int>> +import_shapes(const std::string &fileName, + const bool highestDimOnly = true) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/intersect_entities.h b/meshing/src/include/ae108/meshing/cppgmsh/intersect_entities.h new file mode 100644 index 0000000000000000000000000000000000000000..0b84f6545266b10a1e001f654dbc38acca88bd60 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/intersect_entities.h @@ -0,0 +1,43 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Returns vector of intersected entities. + * + * @param object_entities Object entities. + * @param tool_entities Tool entities. + * @param remove_object If true, the object entities will be removed after the + * intersection was performed. + * @param remove_tool If true, the tool entities will be removed after the + * intersection was performed. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2616 + */ +std::vector<std::pair<int, int>> +intersect_entities(const std::vector<std::pair<int, int>> &object_entities, + const std::vector<std::pair<int, int>> &tool_entities, + const bool remove_object = true, + const bool remove_tool = true) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/read_file.h b/meshing/src/include/ae108/meshing/cppgmsh/read_file.h new file mode 100644 index 0000000000000000000000000000000000000000..d134002c4d426ad892182ef703f64cb3a28f440f --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/read_file.h @@ -0,0 +1,36 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <string> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Reads a file. The export format is determined by the file + * extension (e.g. *.vtk). + * + * @param file_name The file name. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L77 + */ + +void read_file(const std::string &file_name) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/remove_entities.h b/meshing/src/include/ae108/meshing/cppgmsh/remove_entities.h new file mode 100644 index 0000000000000000000000000000000000000000..b1e8370711b5a5b380d9d168ce3d1a673231e70e --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/remove_entities.h @@ -0,0 +1,37 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Removes the given entities. + * + * @param entities Entities to remove. + * @param recursive If true, all entities on the boundaries of the given entity + * are removed as well, down to dimension 0 (points). + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2737 + */ +void remove_entities(const std::vector<std::pair<int, int>> &entities, + const bool recursive = false) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/rotate_entities.h b/meshing/src/include/ae108/meshing/cppgmsh/rotate_entities.h new file mode 100644 index 0000000000000000000000000000000000000000..be15b35a62a53c4283fc462e4fd64ad49c1ebb25 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/rotate_entities.h @@ -0,0 +1,41 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Rotates the given entities. + * + * @param entities Entities to rotate. + * @param center Center of rotation. + * @param direction Direction of the axis of rotation. + * @param angle Angle of rotation measured in radians. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2673 + */ +void rotate_entities(const std::vector<std::pair<int, int>> &entities, + const std::array<double, 3> ¢er, + const std::array<double, 3> &direction, + double angle) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/set_domain_entities_periodic.h b/meshing/src/include/ae108/meshing/cppgmsh/set_domain_entities_periodic.h new file mode 100644 index 0000000000000000000000000000000000000000..28b8fc8b142cc72ed36e760ad2a51b46f6436611 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/set_domain_entities_periodic.h @@ -0,0 +1,41 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include "ae108/meshing/BoundingBox.h" +#include <array> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Set the meshes of the entities in domain target as + * periodic copies of the meshes of entities in domain source + * + * @param source Source domain. + * @param target Target domain. + * @param dim Dimension of the entities (1 or 2). + * @param tol Spatial tolerance for entity matching. + */ +void set_domain_entities_periodic( + const BoundingBox<std::array<double, 3>> &source, + const BoundingBox<std::array<double, 3>> &target, const int dim, + const double tol = 1e-9) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/set_expert_mode.h b/meshing/src/include/ae108/meshing/cppgmsh/set_expert_mode.h new file mode 100644 index 0000000000000000000000000000000000000000..59fc067bf7ad8378408c948faba17ae10dbd4b49 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/set_expert_mode.h @@ -0,0 +1,32 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Enables/disables expert mode (to disable all the messages and user + * input requests meant for inexperienced users) + * @param enable Specifies if the expert mode should be enabled (true) or + * disabled (false). + */ +void set_expert_mode(const bool enable = true) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/set_granularity.h b/meshing/src/include/ae108/meshing/cppgmsh/set_granularity.h new file mode 100644 index 0000000000000000000000000000000000000000..17ca0cad89203f63e9dd404843e5b8f9fba525ae --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/set_granularity.h @@ -0,0 +1,32 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Sets the mesh element length scale + * + * @param size The desired maximum mesh size for the volume mesh. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L1225 + */ +void set_granularity(const double size) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/set_periodic.h b/meshing/src/include/ae108/meshing/cppgmsh/set_periodic.h new file mode 100644 index 0000000000000000000000000000000000000000..0074219b895aa77107e2ffc4fe423945392c51d7 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/set_periodic.h @@ -0,0 +1,43 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Sets the mesh of all target entities as periodic copies of the source + * entity, using the affine transformation. + * + * The function supportes line (dim=1) and surface (dim=2) entities. Target and + * surface entity need to have the same dimension. + * + * @param target_entities Target entities. + * @param source_entity Source entity. + * @param affine_transform Affine transformation matrix (4x4 matrix, by row) + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L1423 + */ +void set_periodic(const std::vector<std::pair<int, int>> &target_entities, + const std::pair<int, int> &source_entity, + const std::array<double, 16> &affine_transform) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/set_physical_group_of.h b/meshing/src/include/ae108/meshing/cppgmsh/set_physical_group_of.h new file mode 100644 index 0000000000000000000000000000000000000000..21f3e4ff3ab949eff4fd58350a62589afd173e96 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/set_physical_group_of.h @@ -0,0 +1,36 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Adds entities to a physical group. Returns the tag of the added group. + * + * @param dim The dimension of the model entities to be grouped. + * @param tags The tags of the model entities to be grouped. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L247 + */ +std::pair<int, int> set_physical_group_of( + const std::vector<std::pair<int, int>> &entities) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/synchronize.h b/meshing/src/include/ae108/meshing/cppgmsh/synchronize.h new file mode 100644 index 0000000000000000000000000000000000000000..54e798a79eaddbe76a05ab022583036056da3910 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/synchronize.h @@ -0,0 +1,31 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Synchronize the built-in CAD representation with the current Gmsh + * model. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L1983 + */ +void synchronize() noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/translate_entities.h b/meshing/src/include/ae108/meshing/cppgmsh/translate_entities.h new file mode 100644 index 0000000000000000000000000000000000000000..deeacd3bf19a72c5c2e42cca62673e3467b87939 --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/translate_entities.h @@ -0,0 +1,41 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <array> +#include <vector> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Translates the given entities by a vector or makes a translated copy + * of the entities. Returns the translated entity. + * + * @param entities Entities to translate. + * @param translation translation vector. + * @param copy It true, a copy of the entities is translated. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L2663 + */ +std::vector<std::pair<int, int>> +translate_entities(std::vector<std::pair<int, int>> entities, + const std::array<double, 3> &translation, + const bool copy = false) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/src/include/ae108/meshing/cppgmsh/write_file.h b/meshing/src/include/ae108/meshing/cppgmsh/write_file.h new file mode 100644 index 0000000000000000000000000000000000000000..9bb87f5e31c7f20fceafed528fd018d7252b2c9d --- /dev/null +++ b/meshing/src/include/ae108/meshing/cppgmsh/write_file.h @@ -0,0 +1,35 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#pragma once + +#include <string> + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +/** + * @brief Writes a file. + * + * @param file_name The bounding box or search domain. + * @note https://gitlab.onelab.info/gmsh/gmsh/-/blob/gmsh_4_8_4/api/gmsh.h#L89 + */ + +void write_file(const std::string &file_name) noexcept; + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/BoundaryRepresentation_Test.cc b/meshing/test/BoundaryRepresentation_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..859bf9c83a4bd83c6eae458c81d080142f12fcd1 --- /dev/null +++ b/meshing/test/BoundaryRepresentation_Test.cc @@ -0,0 +1,110 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/BoundaryRepresentation.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +struct BoundaryRepresentation3D_Test : Test { + + using brep_type = BoundaryRepresentation<int, double, 3>; + using vertices_type = typename brep_type::Vertices; + using edges_type = typename brep_type::Edges; + using faces_type = typename brep_type::Faces; + + vertices_type vertices = {{ + {{0, 0, 0}}, + {{1, 0, 0}}, + {{0, 1, 0}}, + {{0, 0, 1}}, + }}; + edges_type edges = {{ + {{0, 1}}, + {{0, 2}}, + {{0, 3}}, + {{1, 3}}, + {{2, 3}}, + {{2, 1}}, + }}; + faces_type faces = {{ + {{0, 1, 5}}, + {{0, 1, 3}}, + {{0, 2, 3}}, + {{1, 2, 3}}, + }}; + + brep_type brep{vertices, edges, faces}; +}; + +struct BoundaryRepresentation2D_Test : Test { + + using brep_type = BoundaryRepresentation<int, double, 2>; + using vertices_type = typename brep_type::Vertices; + using edges_type = typename brep_type::Edges; + using faces_type = typename brep_type::Faces; + + vertices_type vertices = {{ + {{0, 0}}, + {{1, 0}}, + {{0, 1}}, + }}; + edges_type edges = {{ + {{0, 1}}, + {{0, 2}}, + {{2, 1}}, + }}; + faces_type faces = {{ + {{0, 1, 2}}, + }}; + + brep_type brep{vertices, edges, faces}; +}; + +TEST_F(BoundaryRepresentation3D_Test, returns_correct_dimension) { + EXPECT_THAT(brep.dimension(), Eq(3)); +}; + +TEST_F(BoundaryRepresentation3D_Test, returns_correct_vertices_of_edge) { + EXPECT_THAT(brep.vertices_of_edge(3)[0], Eq(vertices.at(1))); + EXPECT_THAT(brep.vertices_of_edge(3)[1], Eq(vertices.at(3))); +}; + +TEST_F(BoundaryRepresentation3D_Test, returns_correct_vertices_of_face) { + EXPECT_THAT(brep.vertices_of_face(0)[0], Eq(vertices.at(0))); + EXPECT_THAT(brep.vertices_of_face(0)[1], Eq(vertices.at(1))); + EXPECT_THAT(brep.vertices_of_face(0)[2], Eq(vertices.at(2))); +}; + +TEST_F(BoundaryRepresentation2D_Test, returns_correct_dimension) { + EXPECT_THAT(brep.dimension(), Eq(2)); +}; + +TEST_F(BoundaryRepresentation2D_Test, returns_correct_vertices_of_edge) { + EXPECT_THAT(brep.vertices_of_edge(2)[0], Eq(vertices.at(2))); + EXPECT_THAT(brep.vertices_of_edge(2)[1], Eq(vertices.at(1))); +}; + +TEST_F(BoundaryRepresentation2D_Test, returns_correct_vertices_of_face) { + EXPECT_THAT(brep.vertices_of_face(0)[0], Eq(vertices.at(0))); + EXPECT_THAT(brep.vertices_of_face(0)[1], Eq(vertices.at(1))); + EXPECT_THAT(brep.vertices_of_face(0)[2], Eq(vertices.at(2))); +}; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/BoundingBox_Test.cc b/meshing/test/BoundingBox_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..c06d530a11a7a7ce7b5ac953341be392a5e2e5e6 --- /dev/null +++ b/meshing/test/BoundingBox_Test.cc @@ -0,0 +1,35 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/BoundingBox.h" +#include <array> +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Test; + +namespace ae108 { +namespace meshing { +struct BoundingBox_Test : Test {}; + +TEST_F(BoundingBox_Test, returns_correct_bbox) { + const auto bbox = BoundingBox<std::array<double, 3>>({{0, 0, 0}, {1, 1, 1}}); + EXPECT_THAT(bbox.min, ElementsAre(DoubleEq(0.), DoubleEq(0.), DoubleEq(0.))); + EXPECT_THAT(bbox.max, ElementsAre(DoubleEq(1.), DoubleEq(1.), DoubleEq(1.))); +}; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/CMakeLists.txt b/meshing/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8363235b8b40a433842e05b1d13ac4a7921290a3 --- /dev/null +++ b/meshing/test/CMakeLists.txt @@ -0,0 +1,74 @@ +# © 2021 ETH Zurich, Mechanics and Materials Lab +# +# This file is part of ae108. +# +# ae108 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or any +# later version. +# +# ae108 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ae108. If not, see <https://www.gnu.org/licenses/>. + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +add_executable(${PROJECT_NAME}-MeshingTests + cppgmsh/construct_cylinders_Test.cc + cppgmsh/construct_polyhedron_Test.cc + cppgmsh/construct_rectangle_Test.cc + cppgmsh/construct_box_Test.cc + cppgmsh/copy_entities_Test.cc + cppgmsh/extrude_entities_Test.cc + cppgmsh/extrude_surface_Test.cc + cppgmsh/fragment_entities_Test.cc + cppgmsh/fuse_entities_Test.cc + cppgmsh/intersect_entities_Test.cc + cppgmsh/remove_entities_Test.cc + cppgmsh/rotate_entities_Test.cc + cppgmsh/translate_entities_Test.cc + cppgmsh/generate_mesh_Test.cc + cppgmsh/extract_mesh_Test.cc + # cppgmsh/heal_periodic_surfaces_Test.cc + # cppgmsh/heal_periodic_domains_Test.cc + cppgmsh/as_affine_transform_Test.cc + cppgmsh/get_boundary_of_Test.cc + cppgmsh/get_centroid_of_Test.cc + cppgmsh/get_coords_of_Test.cc + cppgmsh/get_elements_in_Test.cc + cppgmsh/get_entities_in_Test.cc + cppgmsh/get_entities_of_Test.cc + cppgmsh/get_nodes_of_Test.cc + cppgmsh/get_normal_of_Test.cc + cppgmsh/get_periodic_nodes_of_Test.cc + cppgmsh/get_physical_groups_Test.cc + cppgmsh/get_points_of_Test.cc + cppgmsh/set_domain_entities_periodic_Test.cc + cppgmsh/set_expert_mode_Test.cc + cppgmsh/set_granularity_Test.cc + cppgmsh/set_periodic_Test.cc + cppgmsh/set_physical_group_of_Test.cc + cppgmsh/synchronize_Test.cc + cppgmsh/import_shapes_Test.cc + cppgmsh/read_file_Test.cc + cppgmsh/write_file_Test.cc + BoundaryRepresentation_Test.cc + BoundingBox_Test.cc + bounding_box_of_Test.cc + construct_rectilinear_grid_Test.cc + construct_periodic_point_cloud_Test.cc + construct_voronoi_cell_Test.cc +) + +add_test(NAME ${PROJECT_NAME}-MeshingTests + COMMAND $<TARGET_FILE:${PROJECT_NAME}-MeshingTests>) + +find_package(GTest 1.8.1 CONFIG REQUIRED) +target_link_libraries(${PROJECT_NAME}-MeshingTests + PRIVATE ${PROJECT_NAME}::meshing + PRIVATE GTest::gmock_main +) diff --git a/meshing/test/bounding_box_of_Test.cc b/meshing/test/bounding_box_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..b895604191b3ffdccfd8a8def209b21b946544fc --- /dev/null +++ b/meshing/test/bounding_box_of_Test.cc @@ -0,0 +1,41 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/bounding_box_of.h" +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Test; + +namespace ae108 { +namespace meshing { +struct bounding_box_of_Test : Test {}; + +TEST_F(bounding_box_of_Test, returns_correct_bounding_box_of_single_point) { + const auto box = bounding_box_of<std::array<double, 2>>({{1, 2}}); + ASSERT_THAT(box.min, ElementsAre(DoubleEq(1), DoubleEq(2))); + ASSERT_THAT(box.max, ElementsAre(DoubleEq(1), DoubleEq(2))); +}; + +TEST_F(bounding_box_of_Test, returns_correct_bounding_box_for_multiple_point) { + const auto box = bounding_box_of<std::array<double, 3>>( + {{1, 2, 3}, {-1, 2, -3}, {3, 2, 1}}); + ASSERT_THAT(box.min, ElementsAre(DoubleEq(-1), DoubleEq(2), DoubleEq(-3))); + ASSERT_THAT(box.max, ElementsAre(DoubleEq(3), DoubleEq(2), DoubleEq(3))); +}; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/construct_periodic_point_cloud_Test.cc b/meshing/test/construct_periodic_point_cloud_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..5657743d56f9823647f4287076ec52630dcd41a4 --- /dev/null +++ b/meshing/test/construct_periodic_point_cloud_Test.cc @@ -0,0 +1,89 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/construct_periodic_point_cloud.h" +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +struct construct_periodic_point_cloud_Test : Test {}; + +TEST_F(construct_periodic_point_cloud_Test, + returns_correct_nonsymmetric_3D_point_cloud) { + + const auto point_cloud = construct_periodic_point_cloud<3>( + {{{1, 0, 0}, {0, 2, 0}, {0, 0, 3}}}, {0, 0, 0}, {1, 0}); + + ASSERT_THAT(point_cloud.size(), Eq(8)); + ASSERT_THAT(point_cloud[0], + ElementsAre(DoubleEq(1), DoubleEq(2), DoubleEq(3))); + ASSERT_THAT(point_cloud[7], + ElementsAre(DoubleEq(0), DoubleEq(0), DoubleEq(0))); +}; + +TEST_F(construct_periodic_point_cloud_Test, + returns_correct_3D_point_cloud_around_zero_origin) { + + const auto point_cloud = construct_periodic_point_cloud<3>( + {{{1, 0, 0}, {0, 2, 0}, {0, 0, 3}}}, {0, 0, 0}); + + ASSERT_THAT(point_cloud.size(), Eq(27)); + ASSERT_THAT(point_cloud[0], + ElementsAre(DoubleEq(-1), DoubleEq(-2), DoubleEq(-3))); + ASSERT_THAT(point_cloud[26], + ElementsAre(DoubleEq(1), DoubleEq(2), DoubleEq(3))); +}; + +TEST_F(construct_periodic_point_cloud_Test, + returns_correct_3D_point_cloud_around_nonzero_origin) { + + const auto point_cloud = construct_periodic_point_cloud<3>( + {{{1, 0, 0}, {0, 2, 0}, {0, 0, 3}}}, {1, 2, 3}); + + ASSERT_THAT(point_cloud.size(), Eq(27)); + ASSERT_THAT(point_cloud[0], + ElementsAre(DoubleEq(0), DoubleEq(0), DoubleEq(0))); + ASSERT_THAT(point_cloud[26], + ElementsAre(DoubleEq(2), DoubleEq(4), DoubleEq(6))); +}; + +TEST_F(construct_periodic_point_cloud_Test, + returns_correct_2D_point_cloud_around_zero_origin) { + + const auto point_cloud = + construct_periodic_point_cloud<2>({{{1, 0}, {0, 2}}}, {0, 0}); + + ASSERT_THAT(point_cloud.size(), Eq(9)); + ASSERT_THAT(point_cloud[0], ElementsAre(DoubleEq(-1), DoubleEq(-2))); + ASSERT_THAT(point_cloud[8], ElementsAre(DoubleEq(1), DoubleEq(2))); +}; + +TEST_F(construct_periodic_point_cloud_Test, + returns_correct_1D_point_cloud_around_zero_origin) { + + const auto point_cloud = construct_periodic_point_cloud<1>({{{2}}}, {0}); + + ASSERT_THAT(point_cloud.size(), Eq(3)); + ASSERT_THAT(point_cloud[0], ElementsAre(DoubleEq(-2))); + ASSERT_THAT(point_cloud[2], ElementsAre(DoubleEq(2))); +}; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/construct_rectilinear_grid_Test.cc b/meshing/test/construct_rectilinear_grid_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..ed769bbd22c00d672a45c8a18aded49a8019571e --- /dev/null +++ b/meshing/test/construct_rectilinear_grid_Test.cc @@ -0,0 +1,75 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/construct_rectilinear_grid.h" +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +struct construct_rectilinear_grid_Test : Test {}; + +TEST_F(construct_rectilinear_grid_Test, returns_correct_1D_grid) { + + std::array<std::vector<double>, 1> instances = {{{1, 2}}}; + const auto [nodes, segments] = construct_rectilinear_grid(instances); + + ASSERT_THAT(nodes.size(), Eq(2)); + ASSERT_THAT(segments.size(), Eq(1)); + ASSERT_THAT(nodes[0], ElementsAre(DoubleEq(1))); + ASSERT_THAT(nodes[1], ElementsAre(DoubleEq(2))); + ASSERT_THAT(segments[0], ElementsAre(Eq(0), Eq(1))); +}; + +TEST_F(construct_rectilinear_grid_Test, returns_correct_2D_grid) { + + std::array<std::vector<double>, 2> instances = {{{1, 2}, {3, 4}}}; + const auto [nodes, segments] = construct_rectilinear_grid(instances); + + ASSERT_THAT(nodes.size(), Eq(4)); + ASSERT_THAT(segments.size(), Eq(4)); + ASSERT_THAT(nodes[0], ElementsAre(DoubleEq(1), DoubleEq(3))); + ASSERT_THAT(nodes[1], ElementsAre(DoubleEq(1), DoubleEq(4))); + ASSERT_THAT(nodes[2], ElementsAre(DoubleEq(2), DoubleEq(3))); + ASSERT_THAT(nodes[3], ElementsAre(DoubleEq(2), DoubleEq(4))); + ASSERT_THAT(segments[0], ElementsAre(Eq(0), Eq(1))); + ASSERT_THAT(segments[1], ElementsAre(Eq(2), Eq(3))); + ASSERT_THAT(segments[2], ElementsAre(Eq(0), Eq(2))); + ASSERT_THAT(segments[3], ElementsAre(Eq(1), Eq(3))); +}; + +TEST_F(construct_rectilinear_grid_Test, returns_correct_3D_grid) { + + std::array<std::vector<double>, 3> instances = {{{1, 2}, {3, 4}, {0}}}; + const auto [nodes, segments] = construct_rectilinear_grid(instances); + + ASSERT_THAT(nodes.size(), Eq(4)); + ASSERT_THAT(segments.size(), Eq(4)); + ASSERT_THAT(nodes[0], ElementsAre(DoubleEq(1), DoubleEq(3), DoubleEq(0))); + ASSERT_THAT(nodes[1], ElementsAre(DoubleEq(1), DoubleEq(4), DoubleEq(0))); + ASSERT_THAT(nodes[2], ElementsAre(DoubleEq(2), DoubleEq(3), DoubleEq(0))); + ASSERT_THAT(nodes[3], ElementsAre(DoubleEq(2), DoubleEq(4), DoubleEq(0))); + ASSERT_THAT(segments[0], ElementsAre(Eq(0), Eq(1))); + ASSERT_THAT(segments[1], ElementsAre(Eq(2), Eq(3))); + ASSERT_THAT(segments[2], ElementsAre(Eq(0), Eq(2))); + ASSERT_THAT(segments[3], ElementsAre(Eq(1), Eq(3))); +}; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/construct_voronoi_cell_Test.cc b/meshing/test/construct_voronoi_cell_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..086547d4b7cea7b480d3f6280c9286830b552b27 --- /dev/null +++ b/meshing/test/construct_voronoi_cell_Test.cc @@ -0,0 +1,74 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/construct_periodic_point_cloud.h" +#include "ae108/meshing/construct_voronoi_cell.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +struct construct_voronoi_cell_Test : Test {}; + +TEST_F(construct_voronoi_cell_Test, returns_correct_cube) { + + const auto point_cloud = construct_periodic_point_cloud<3>( + {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}}, {0, 0, 0}); + + std::vector<std::pair<std::size_t, std::size_t>> periodic_faces; + const auto voronoi_cell = + construct_voronoi_cell(point_cloud, &periodic_faces); + + ASSERT_THAT(voronoi_cell.vertices.size(), Eq(8)); + ASSERT_THAT(voronoi_cell.edges.size(), Eq(12)); + ASSERT_THAT(voronoi_cell.faces.size(), Eq(6)); + ASSERT_THAT(periodic_faces.size(), Eq(3)); +}; + +TEST_F(construct_voronoi_cell_Test, returns_correct_hexagonal_prism) { + + const auto point_cloud = construct_periodic_point_cloud<3>( + {{{sqrt(3.) / 2, 0.5, 0}, {sqrt(3.) / 2, -0.5, 0}, {0, 0, 1}}}, + {0, 0, 0}); + + std::vector<std::pair<std::size_t, std::size_t>> periodic_faces; + const auto voronoi_cell = + construct_voronoi_cell(point_cloud, &periodic_faces); + + ASSERT_THAT(voronoi_cell.vertices.size(), Eq(12)); + ASSERT_THAT(voronoi_cell.edges.size(), Eq(18)); + ASSERT_THAT(voronoi_cell.faces.size(), Eq(8)); + ASSERT_THAT(periodic_faces.size(), Eq(4)); +}; + +TEST_F(construct_voronoi_cell_Test, returns_correct_bitruncated_octahedron) { + + const auto point_cloud = construct_periodic_point_cloud<3>( + {{{0.5, 0.5, 0.5}, {0.5, -0.5, 0.5}, {0.5, 0.5, -0.5}}}, {0, 0, 0}); + + std::vector<std::pair<std::size_t, std::size_t>> periodic_faces; + const auto voronoi_cell = + construct_voronoi_cell(point_cloud, &periodic_faces); + + ASSERT_THAT(voronoi_cell.vertices.size(), Eq(24)); + ASSERT_THAT(voronoi_cell.edges.size(), Eq(36)); + ASSERT_THAT(voronoi_cell.faces.size(), Eq(14)); + ASSERT_THAT(periodic_faces.size(), Eq(7)); +}; + +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/as_affine_transform_Test.cc b/meshing/test/cppgmsh/as_affine_transform_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..eb56904e5b3bb6f699a3a57bf18050809a106bc3 --- /dev/null +++ b/meshing/test/cppgmsh/as_affine_transform_Test.cc @@ -0,0 +1,41 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/as_affine_transform.h" +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct as_affine_transform_Test : Test {}; + +TEST_F(as_affine_transform_Test, returns_correct_translation_transform) { + const auto transform = as_affine_transform({1., 2., 3.}); + ASSERT_THAT(transform, ElementsAre(DoubleEq(1.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(1.), DoubleEq(0.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(2.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(1.), DoubleEq(3.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(1.))); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/construct_box_Test.cc b/meshing/test/cppgmsh/construct_box_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..f60e81fb386460eae8a1263b3335d0b48a00b493 --- /dev/null +++ b/meshing/test/cppgmsh/construct_box_Test.cc @@ -0,0 +1,43 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct construct_box_Test : Test {}; + +TEST_F(construct_box_Test, constructs_box) { + const auto gmshContext = Context(0, 0, true, true); + + const auto origin = std::array<double, 3>{0, 0, 0}; + const auto side_lengths = std::array<double, 3>{1, 2, 3}; + + const auto box = construct_box(origin, side_lengths); + + ASSERT_THAT(box.first, Eq(3)); + ASSERT_THAT(box.second, Eq(1)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/construct_cylinders_Test.cc b/meshing/test/cppgmsh/construct_cylinders_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..6afd12e2590433ebcee551bbffb0b98e9f981eec --- /dev/null +++ b/meshing/test/cppgmsh/construct_cylinders_Test.cc @@ -0,0 +1,75 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_cylinders.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct construct_cylinders_Test : Test {}; + +TEST_F(construct_cylinders_Test, constructs_empty) { + const auto gmshContext = Context(0, 0); + std::vector<std::array<double, 3>> nodes{{0, 0, 0}, {1, 0, 0}}; + std::vector<std::array<std::size_t, 2>> connectivity{}; + std::vector<double> radii{}; + bool capped = false; + + const auto result = construct_cylinders(nodes, connectivity, radii, capped); + ASSERT_THAT(result.size(), Eq(0)); +} + +TEST_F(construct_cylinders_Test, constructs_single_cylinder) { + const auto gmshContext = Context(0, 0); + std::vector<std::array<double, 3>> nodes{{0, 0, 0}, {1, 0, 0}}; + std::vector<std::array<std::size_t, 2>> connectivity{{0, 1}}; + std::vector<double> radii{1.}; + bool capped = false; + + const auto result = construct_cylinders(nodes, connectivity, radii, capped); + ASSERT_THAT(result.size(), Eq(1)); +} + +TEST_F(construct_cylinders_Test, constructs_two_cylinders) { + const auto gmshContext = Context(0, 0); + std::vector<std::array<double, 3>> nodes{ + {0, 0, 0}, {1, 0, 0}, {0, 0, 1}, {1, 0, 1}}; + std::vector<std::array<std::size_t, 2>> connectivity{{0, 1}, {2, 3}}; + std::vector<double> radii{0.1, 0.1}; + bool capped = false; + + const auto result = construct_cylinders(nodes, connectivity, radii, capped); + ASSERT_THAT(result.size(), Eq(2)); +} + +TEST_F(construct_cylinders_Test, constructs_capped_cylinder) { + const auto gmshContext = Context(0, 0); + std::vector<std::array<double, 3>> nodes{{0, 0, 0}, {1, 0, 0}}; + std::vector<std::array<std::size_t, 2>> connectivity{{0, 1}}; + std::vector<double> radii{1.}; + bool capped = true; + + const auto result = construct_cylinders(nodes, connectivity, radii, capped); + ASSERT_THAT(result.size(), Eq(1)); +} +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/construct_polyhedron_Test.cc b/meshing/test/cppgmsh/construct_polyhedron_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..b31856da1d6a4a3751a64012ff2f4b942e4c6437 --- /dev/null +++ b/meshing/test/cppgmsh/construct_polyhedron_Test.cc @@ -0,0 +1,104 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_polyhedron.h" +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct construct_polyhedron_Test : Test { + + using brep_type = BoundaryRepresentation<std::size_t, double, 3>; + using vertices_type = typename brep_type::Vertices; + using edges_type = typename brep_type::Edges; + using faces_type = typename brep_type::Faces; + + vertices_type vertices = {{ + {{0, 0, 0}}, + {{1, 0, 0}}, + {{0, 1, 0}}, + {{0, 0, 1}}, + }}; + edges_type edges = {{ + {{0, 1}}, + {{0, 2}}, + {{0, 3}}, + {{1, 2}}, + {{1, 3}}, + {{2, 3}}, + }}; + faces_type faces = {{ + {{0, 1, 3}}, + {{0, 2, 4}}, + {{1, 2, 5}}, + {{3, 4, 5}}, + }}; + + brep_type brep{vertices, edges, faces}; +}; + +TEST_F(construct_polyhedron_Test, constructs_tetrahedron) { + const auto gmshContext = Context(0, 0, true, true); + + const auto polyhedron = construct_polyhedron(brep); + + ASSERT_THAT(polyhedron.first, Eq(3)); + ASSERT_THAT(polyhedron.second, Eq(1)); +} + +TEST_F(construct_polyhedron_Test, returns_correct_number_of_volumes) { + const auto gmshContext = Context(0, 0, true, true); + + construct_polyhedron(brep); + synchronize(); + + const auto surfaces = get_entities_of(3); + + ASSERT_THAT(surfaces.size(), Eq(1)); +} + +TEST_F(construct_polyhedron_Test, returns_correct_number_of_surfaces) { + const auto gmshContext = Context(0, 0, true, true); + + construct_polyhedron(brep); + synchronize(); + + const auto surfaces = get_entities_of(2); + + ASSERT_THAT(surfaces.size(), Eq(4)); +} + +TEST_F(construct_polyhedron_Test, returns_correct_number_of_lines) { + const auto gmshContext = Context(0, 0, true, true); + + construct_polyhedron(brep); + synchronize(); + + const auto surfaces = get_entities_of(1); + + ASSERT_THAT(surfaces.size(), Eq(6)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/construct_rectangle_Test.cc b/meshing/test/cppgmsh/construct_rectangle_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..2a6c86d5ddfd6235a18c41942a33fc7b2c28d015 --- /dev/null +++ b/meshing/test/cppgmsh/construct_rectangle_Test.cc @@ -0,0 +1,55 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/get_coords_of.h" +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct construct_rectangle_Test : Test {}; + +TEST_F(construct_rectangle_Test, constructs_rectangle) { + const auto gmshContext = Context(0, 0, true, true); + + const auto origin = std::array<double, 3>{0, 0, 0}; + const auto side_lengths = std::array<double, 2>{1, 2}; + + const auto rectangle = construct_rectangle(origin, side_lengths); + + ASSERT_THAT(rectangle.first, Eq(2)); + ASSERT_THAT(rectangle.second, Eq(1)); + + synchronize(); + const auto points = get_coords_of(get_points_of(rectangle)); + ASSERT_THAT(points[0], ElementsAre(DoubleEq(0.), DoubleEq(0.), DoubleEq(0.))); + ASSERT_THAT(points[1], ElementsAre(DoubleEq(1.), DoubleEq(0.), DoubleEq(0.))); + ASSERT_THAT(points[2], ElementsAre(DoubleEq(1.), DoubleEq(2.), DoubleEq(0.))); + ASSERT_THAT(points[3], ElementsAre(DoubleEq(0.), DoubleEq(2.), DoubleEq(0.))); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/copy_entities_Test.cc b/meshing/test/cppgmsh/copy_entities_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..e90694ebefeb665ec1a9f25059a6b971d72127c3 --- /dev/null +++ b/meshing/test/cppgmsh/copy_entities_Test.cc @@ -0,0 +1,63 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/copy_entities.h" +#include "ae108/meshing/cppgmsh/get_coords_of.h" +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" + +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct copy_entities_Test : Test {}; + +TEST_F(copy_entities_Test, copies_box) { + const auto gmshContext = Context(0, 0, true, true); + + auto box = construct_box(std::array<double, 3>{0., 0., 0.}, + std::array<double, 3>{1., 1., 1.}); + + copy_entities({box}); + + synchronize(); + const auto entities = get_entities_of(3); + + ASSERT_THAT(entities.size(), Eq(2)); + auto points_0 = get_points_of(entities[0]); + auto points_1 = get_points_of(entities[1]); + ASSERT_THAT(points_0.size(), Eq(points_1.size())); + for (std::size_t i = 0; i < points_0.size(); i++) { + auto coords_0 = get_coords_of(points_0[i]); + auto coords_1 = get_coords_of(points_1[i]); + for (std::size_t d = 0; d < 3; d++) { + ASSERT_THAT(coords_0[d], DoubleEq(coords_1[d])); + } + } +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/extract_mesh_Test.cc b/meshing/test/cppgmsh/extract_mesh_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..486529db34a06800de50898672c0d9c10664f80a --- /dev/null +++ b/meshing/test/cppgmsh/extract_mesh_Test.cc @@ -0,0 +1,144 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/extract_mesh.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct extract_mesh_Test : Test {}; + +TEST_F(extract_mesh_Test, extract_Tet4_mesh) { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 1, 1}); + synchronize(); + set_granularity(1.); + + const int dimension = 3; + const int order = 1; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + + const auto [positions, connectivity, mapA, mapB] = extract_mesh<dimension>(); + + ASSERT_THAT(positions.size(), Eq(14)); + ASSERT_THAT(connectivity.size(), Eq(24)); + ASSERT_THAT(connectivity[0].size(), Eq(4)); +} + +TEST_F(extract_mesh_Test, extract_Tet10_mesh) { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 1, 1}); + synchronize(); + set_granularity(1.); + + const int dimension = 3; + const int order = 2; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + const auto [positions, connectivity, mapA, mapB] = extract_mesh<dimension>(); + + ASSERT_THAT(positions.size(), Eq(63)); + ASSERT_THAT(connectivity.size(), Eq(24)); + ASSERT_THAT(connectivity[0].size(), Eq(10)); +} + +TEST_F(extract_mesh_Test, extract_Tri3_mesh) { + const auto gmshContext = Context(0, 0); + construct_rectangle({0, 0, 0}, {1, 1}); + synchronize(); + set_granularity(1.); + + const int dimension = 2; + const int order = 1; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + const auto [positions, connectivity, mapA, mapB] = extract_mesh<dimension>(); + + ASSERT_THAT(positions.size(), Eq(5)); + ASSERT_THAT(connectivity.size(), Eq(4)); + ASSERT_THAT(connectivity[0].size(), Eq(3)); +} + +TEST_F(extract_mesh_Test, extract_Tri6_mesh) { + const auto gmshContext = Context(0, 0); + construct_rectangle({0, 0, 0}, {1, 1}); + synchronize(); + set_granularity(1.); + + const int dimension = 2; + const int order = 2; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + const auto [positions, connectivity, mapA, mapB] = extract_mesh<dimension>(); + + ASSERT_THAT(positions.size(), Eq(13)); + ASSERT_THAT(connectivity.size(), Eq(4)); + ASSERT_THAT(connectivity[0].size(), Eq(6)); +} + +TEST_F(extract_mesh_Test, extract_Quad4_mesh) { + const auto gmshContext = Context(0, 0); + construct_rectangle({0, 0, 0}, {1, 1}); + synchronize(); + set_granularity(1.); + gmsh::option::setNumber("Mesh.RecombineAll", 1); + gmsh::option::setNumber("Mesh.RecombinationAlgorithm", 2); + + const int dimension = 2; + const int order = 1; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + const auto [positions, connectivity, mapA, mapB] = extract_mesh<dimension>(); + + ASSERT_THAT(positions.size(), Eq(9)); + ASSERT_THAT(connectivity.size(), Eq(4)); + ASSERT_THAT(connectivity[0].size(), Eq(4)); +} + +TEST_F(extract_mesh_Test, extract_Quad9_mesh) { + const auto gmshContext = Context(0, 0); + construct_rectangle({0, 0, 0}, {1, 1}); + synchronize(); + set_granularity(1.); + gmsh::option::setNumber("Mesh.RecombineAll", 1); + gmsh::option::setNumber("Mesh.RecombinationAlgorithm", 2); + + const int dimension = 2; + const int order = 2; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + const auto [positions, connectivity, mapA, mapB] = extract_mesh<dimension>(); + + ASSERT_THAT(positions.size(), Eq(25)); + ASSERT_THAT(connectivity.size(), Eq(4)); + ASSERT_THAT(connectivity[0].size(), Eq(9)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/extrude_entities_Test.cc b/meshing/test/cppgmsh/extrude_entities_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..9b50f790f20dac67d6b7f810b5e5b8ae0e9c2187 --- /dev/null +++ b/meshing/test/cppgmsh/extrude_entities_Test.cc @@ -0,0 +1,121 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/extrude_entities.h" +#include "ae108/meshing/cppgmsh/fragment_entities.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_coords_of.h" +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include "ae108/meshing/cppgmsh/get_nodes_of.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/synchronize.h" + +#include <cmath> +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::DoubleEq; +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct extrude_Test : Test {}; + +TEST_F(extrude_Test, extrudes_rectangle) { + const auto gmshContext = Context(0, 0, true, true); + + const auto rectangle = construct_rectangle({0., 0., 0.}, {1., 1.}); + const std::array<double, 3> dr = {0.1, 0.2, 0.3}; + extrude_entities({rectangle}, dr); + synchronize(); + + const auto points = get_entities_of(0); + ASSERT_THAT(points.size(), Eq(8)); + const auto edges = get_entities_of(1); + ASSERT_THAT(edges.size(), Eq(12)); + const auto surfaces = get_entities_of(2); + ASSERT_THAT(surfaces.size(), Eq(6)); + const auto volumes = get_entities_of(3); + ASSERT_THAT(volumes.size(), Eq(1)); + + for (std::size_t i = 0; i < 4; i++) { + const auto coords_0 = get_coords_of(points[i].second); + const auto coords_1 = get_coords_of(points[i + 4].second); + for (std::size_t d = 0; d < 3; d++) { + ASSERT_THAT(coords_0[d] + dr[d], DoubleEq(coords_1[d])); + } + } +} + +TEST_F(extrude_Test, extrudes_mesh) { + const auto gmshContext = Context(0, 0); + const auto rectangle_1 = construct_rectangle({0., 0., 0.}, {1., 1.}); + const auto rectangle_2 = construct_rectangle({2., 0., 0.}, {1., 1.}); + const std::array<double, 3> dr = {0, 0, 1}; + auto extruded_entities_1 = extrude_entities({rectangle_1}, dr); + std::pair<int, int> box_1 = {-1, -1}; + for (std::size_t i = 0; i < extruded_entities_1.size(); i++) { + if (extruded_entities_1[i].first == 3) { + box_1 = extruded_entities_1[i]; + break; + } + } + const int number_of_layers = 3; + auto extruded_entities_2 = + extrude_entities({rectangle_2}, dr, true, number_of_layers); + std::pair<int, int> box_2 = {-1, -1}; + for (std::size_t i = 0; i < extruded_entities_2.size(); i++) { + if (extruded_entities_2[i].first == 3) { + box_2 = extruded_entities_2[i]; + break; + } + } + + synchronize(); + + set_granularity(0.5); + generate_mesh(3, 1, 6); + + const auto nodes_1 = get_nodes_of<3>(box_1); + bool at_least_one_node_not_on_plane = false; + for (std::size_t i = 0; i < nodes_1.size(); i++) { + if (fabs(double(int(nodes_1[i].position[2] / + (dr[2] / double(number_of_layers)) + + 1e-10)) - + (nodes_1[i].position[2] / (dr[2] / double(number_of_layers)))) > + 1e-10) { + at_least_one_node_not_on_plane = true; + break; + } + } + ASSERT_THAT(at_least_one_node_not_on_plane, Eq(true)); + + const auto nodes_2 = get_nodes_of<3>(box_2); + for (std::size_t i = 0; i < nodes_2.size(); i++) { + ASSERT_THAT( + double(int(nodes_2[i].position[2] / (dr[2] / double(number_of_layers)) + + 1e-10)), + DoubleEq(nodes_2[i].position[2] / (dr[2] / double(number_of_layers)))); + } +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/extrude_surface_Test.cc b/meshing/test/cppgmsh/extrude_surface_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..5331f571616f3672fae2207f994864afd5f65629 --- /dev/null +++ b/meshing/test/cppgmsh/extrude_surface_Test.cc @@ -0,0 +1,61 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/extrude_surface.h" +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include "ae108/meshing/cppgmsh/remove_entities.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include "ae108/meshing/cppgmsh/write_file.h" + +#include <cmath> +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::DoubleEq; +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct extrude_Test : Test {}; + +TEST_F(extrude_Test, extrude_rectangle_along_axis) { + const auto gmshContext = Context(0, 0, true, true); + + const auto rectangle = construct_rectangle({-.5, -.5, 0}, {1., 1.}); + const std::array<double, 3> from = {0, 0, 0}; + const std::array<double, 3> to = {0, 0, 10}; + + extrude_surface(rectangle.second, from, to); + remove_entities({rectangle}, true); + synchronize(); + + const auto points = get_entities_of(0); + ASSERT_THAT(points.size(), Eq(8)); + const auto edges = get_entities_of(1); + ASSERT_THAT(edges.size(), Eq(12)); + const auto surfaces = get_entities_of(2); + ASSERT_THAT(surfaces.size(), Eq(6)); + const auto volumes = get_entities_of(3); + ASSERT_THAT(volumes.size(), Eq(1)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/fragment_entities_Test.cc b/meshing/test/cppgmsh/fragment_entities_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..363fc8824f3075576feb199f3f594240cf2fac6b --- /dev/null +++ b/meshing/test/cppgmsh/fragment_entities_Test.cc @@ -0,0 +1,152 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/fragment_entities.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_boundary_of.h" +#include "ae108/meshing/cppgmsh/get_elements_in.h" +#include "ae108/meshing/cppgmsh/get_nodes_of.h" +#include "ae108/meshing/cppgmsh/intersect_entities.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct fragment_Test : Test {}; + +TEST_F(fragment_Test, returns_the_correct_entities) { + const auto gmshContext = Context(0, 0); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({0., 0., 1.}, {1., 1., 1.}); + const auto fragmented_entities = fragment_entities({box_1, box_2}); + + ASSERT_THAT(fragmented_entities.size(), Eq(2)); + ASSERT_THAT(fragmented_entities[0], Eq(box_1)); + ASSERT_THAT(fragmented_entities[1], Eq(box_2)); +} + +TEST_F(fragment_Test, no_elements_crossing_entity_interface) { + const auto gmshContext = Context(0, 0); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 6. / 7.}); + const auto box_2 = construct_box({0., 0., 6. / 7.}, {1., 1., 1. / 7.}); + const auto fragmented_entities = fragment_entities({box_1, box_2}); + synchronize(); + + set_granularity(0.5); + generate_mesh(3, 1, 6); + + const auto elements = get_elements_in({3, -1}); + const auto elements_1 = get_elements_in(box_1); + const auto elements_2 = get_elements_in(box_2); + ASSERT_THAT(elements_1.size() + elements_2.size(), Eq(elements.size())); + + const auto nodes_1 = get_nodes_of<3>(box_1); + for (const auto &element_1 : elements_1) { + + int elementType; + std::vector<std::size_t> nodes; + gmsh::model::mesh::getElement(element_1.second, elementType, nodes); + + bool is_in_nodes_1 = false; + for (const auto &node_1 : nodes_1) + is_in_nodes_1 += std::count(nodes.begin(), nodes.end(), node_1.id); + + ASSERT_THAT(is_in_nodes_1, Eq(true)); + } + + auto nodes_2 = get_nodes_of<3>(box_2); + for (const auto &element_2 : elements_2) { + + int elementType; + std::vector<std::size_t> nodes; + gmsh::model::mesh::getElement(element_2.second, elementType, nodes); + + bool is_in_nodes_2 = false; + for (const auto &node_2 : nodes_2) + is_in_nodes_2 += std::count(nodes.begin(), nodes.end(), node_2.id); + + ASSERT_THAT(is_in_nodes_2, Eq(true)); + } +} + +TEST_F(fragment_Test, conformal_mesh_at_interface) { + const auto gmshContext = Context(0, 0); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 6. / 7.}); + const auto box_2 = + construct_box({1. / 3., 1. / 3., 6. / 7.}, {1. / 3., 1. / 3., 1. / 7.}); + synchronize(); + + const auto boundary_1 = get_boundary_of({box_1}); + const auto boundary_2 = get_boundary_of({box_2}); + + const auto common_boundary = intersect_entities(boundary_1, boundary_2); + const auto fragmented_entities = fragment_entities({box_1, box_2}); + synchronize(); + + set_granularity(0.5); + generate_mesh(3, 1, 6); + + const auto nodes_1 = get_nodes_of<3>(box_1); + const auto nodes_2 = get_nodes_of<3>(box_2); + const auto nodes_interface = get_nodes_of<3>(common_boundary[0]); + + bool is_in_nodes_1 = false; + for (const auto &node_1 : nodes_1) + is_in_nodes_1 += + std::count(nodes_interface.begin(), nodes_interface.end(), node_1); + ASSERT_THAT(is_in_nodes_1, Eq(true)); + + bool is_in_nodes_2 = false; + for (const auto &node_2 : nodes_2) + is_in_nodes_2 += + std::count(nodes_interface.begin(), nodes_interface.end(), node_2); + ASSERT_THAT(is_in_nodes_2, Eq(true)); +} + +TEST_F(fragment_Test, handles_overlapping_entities) { + const auto gmshContext = Context(0, 0); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({0.5, 0.5, 0.5}, {1., 1., 1.}); + const auto fragmented_entities = fragment_entities({box_1, box_2}); + + ASSERT_THAT(fragmented_entities.size(), Eq(3)); +} + +TEST_F(fragment_Test, handles_unconnected_entities) { + const auto gmshContext = Context(0, 0); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({2., 2., 2.}, {1., 1., 1.}); + auto fragmented_entities = fragment_entities({box_1, box_2}); + + ASSERT_THAT(fragmented_entities.size(), Eq(2)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/fuse_entities_Test.cc b/meshing/test/cppgmsh/fuse_entities_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..b5d9564ea7e76a9b2215a023a72f3ec64fb21833 --- /dev/null +++ b/meshing/test/cppgmsh/fuse_entities_Test.cc @@ -0,0 +1,69 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_cylinders.h" +#include "ae108/meshing/cppgmsh/fuse_entities.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct fuse_entities_Test : Test {}; + +TEST_F(fuse_entities_Test, fuse_single_entity) { + const auto gmshContext = Context(0, 0); + std::vector<std::array<double, 3>> nodes{{0, 0, 0}, {1, 0, 0}}; + std::vector<std::array<std::size_t, 2>> connectivity{{0, 1}}; + std::vector<double> radii{1.}; + bool capped = false; + + const auto result = + fuse_entities(construct_cylinders(nodes, connectivity, radii, capped)); + ASSERT_THAT(result.size(), Eq(1)); +} + +TEST_F(fuse_entities_Test, fuse_two_entitities) { + const auto gmshContext = Context(0, 0); + std::vector<std::array<double, 3>> nodes{{0, 0, 0}, {1, 0, 0}, {2, 0, 0}}; + std::vector<std::array<std::size_t, 2>> connectivity{{0, 1}, {1, 2}}; + std::vector<double> radii{0.1, 0.1}; + bool capped = false; + + const auto result = + fuse_entities(construct_cylinders(nodes, connectivity, radii, capped)); + ASSERT_THAT(result.size(), Eq(1)); +} + +TEST_F(fuse_entities_Test, fuse_unconnected_entitities) { + const auto gmshContext = Context(0, 0); + std::vector<std::array<double, 3>> nodes{ + {0, 0, 0}, {1, 0, 0}, {0, 0, 1}, {1, 0, 1}}; + std::vector<std::array<std::size_t, 2>> connectivity{{0, 1}, {2, 3}}; + std::vector<double> radii{0.1, 0.1}; + bool capped = false; + + const auto result = + fuse_entities(construct_cylinders(nodes, connectivity, radii, capped)); + ASSERT_THAT(result.size(), Eq(2)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/generate_mesh_Test.cc b/meshing/test/cppgmsh/generate_mesh_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..ba1ecc750df5d9ff727fc1152a3f7b5753320ba9 --- /dev/null +++ b/meshing/test/cppgmsh/generate_mesh_Test.cc @@ -0,0 +1,172 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct generate_mesh_Test : Test { + void add_box() { + gmsh::model::occ::addBox(0, 0, 0, 1, 1, 1, 1); + gmsh::model::occ::synchronize(); + } + void add_rectangle() { + gmsh::model::occ::addRectangle(0, 0, 0, 1, 1, 1); + gmsh::model::occ::synchronize(); + } + + std::size_t number_of_nodes(const int dimension) { + std::vector<std::size_t> nodeTags; + std::vector<double> nodeCoordinates, parametricNodeCoordinates; + gmsh::model::mesh::getNodes(nodeTags, nodeCoordinates, + parametricNodeCoordinates, dimension, -1, true, + false); + return nodeTags.size(); + } + + std::size_t number_of_elements(const int dimension, const int elementType) { + std::vector<int> elementTypes{elementType}; + + std::vector<std::vector<std::size_t>> elementTypeTags, elementNodeTags; + gmsh::model::mesh::getElements(elementTypes, elementTypeTags, + elementNodeTags, dimension); + + return [&elementTypeTags]() { + auto numberOfElements = std::size_t{0}; + for (const auto &elementTags : elementTypeTags) + numberOfElements += elementTags.size(); + return numberOfElements; + }(); + } +}; + +TEST_F(generate_mesh_Test, generate_Tet4_mesh) { + + const auto gmshContext = Context(0, 0); + generate_mesh_Test::add_box(); + set_granularity(1.); + + const int dimension = 3; + const int order = 1; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + + const auto element_type = int(4); // 4-node tetrahedron. + ASSERT_THAT(generate_mesh_Test::number_of_elements(dimension, element_type), + Eq(24)); + ASSERT_THAT(generate_mesh_Test::number_of_nodes(dimension), Eq(14)); +} + +TEST_F(generate_mesh_Test, generate_Tet10_mesh) { + + const auto gmshContext = Context(0, 0); + generate_mesh_Test::add_box(); + set_granularity(1.); + + const int dimension = 3; + const int order = 2; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + + const auto element_type = int(11); // 10-node second order tetrahedron + ASSERT_THAT(generate_mesh_Test::number_of_elements(dimension, element_type), + Eq(24)); + ASSERT_THAT(generate_mesh_Test::number_of_nodes(dimension), Eq(63)); +} + +TEST_F(generate_mesh_Test, generate_Tri3_mesh) { + const auto gmshContext = Context(0, 0); + + generate_mesh_Test::add_rectangle(); + set_granularity(1.); + + const int dimension = 2; + const int order = 1; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + + const auto element_type = int(2); // 3-node triangle. + ASSERT_THAT(generate_mesh_Test::number_of_elements(dimension, element_type), + Eq(4)); + ASSERT_THAT(generate_mesh_Test::number_of_nodes(dimension), Eq(5)); +} + +TEST_F(generate_mesh_Test, generate_Tri6_mesh) { + + const auto gmshContext = Context(0, 0); + generate_mesh_Test::add_rectangle(); + set_granularity(1.); + + const int dimension = 2; + const int order = 2; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + + const auto element_type = int(9); // 6-node second order triangle + ASSERT_THAT(generate_mesh_Test::number_of_elements(dimension, element_type), + Eq(4)); + ASSERT_THAT(generate_mesh_Test::number_of_nodes(dimension), Eq(13)); +} + +TEST_F(generate_mesh_Test, generate_Quad4_mesh) { + + const auto gmshContext = Context(0, 0); + generate_mesh_Test::add_rectangle(); + set_granularity(1.); + gmsh::option::setNumber("Mesh.RecombineAll", 1); + gmsh::option::setNumber("Mesh.RecombinationAlgorithm", 2); + + const int dimension = 2; + const int order = 1; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + + const auto element_type = int(3); // 4-node quadrangle. + ASSERT_THAT(generate_mesh_Test::number_of_elements(dimension, element_type), + Eq(4)); + ASSERT_THAT(generate_mesh_Test::number_of_nodes(dimension), Eq(9)); +} + +TEST_F(generate_mesh_Test, generate_Quad9_mesh) { + + const auto gmshContext = Context(0, 0); + generate_mesh_Test::add_rectangle(); + set_granularity(1.); + gmsh::option::setNumber("Mesh.RecombineAll", 1); + gmsh::option::setNumber("Mesh.RecombinationAlgorithm", 2); + + const int dimension = 2; + const int order = 2; + const int algorithm = 6; + generate_mesh(dimension, order, algorithm); + + const auto element_type = int(10); // 9-node quadrangle. + ASSERT_THAT(generate_mesh_Test::number_of_elements(dimension, element_type), + Eq(4)); + ASSERT_THAT(generate_mesh_Test::number_of_nodes(dimension), Eq(25)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_boundary_of_Test.cc b/meshing/test/cppgmsh/get_boundary_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..7c285b1ae6e6697c7800d9ca4bfab838c2148bdb --- /dev/null +++ b/meshing/test/cppgmsh/get_boundary_of_Test.cc @@ -0,0 +1,91 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/get_boundary_of.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_boundary_of_Test : Test {}; + +TEST_F(get_boundary_of_Test, box_correctly) { + const auto gmshContext = Context(0, 0, true, true); + + const auto box = construct_box({0., 0., 0.}, {1., 1., 1.}); + + const auto boundary = get_boundary_of({box}); + + ASSERT_THAT(boundary.size(), Eq(6)); + for (std::size_t i = 0; i < boundary.size(); i++) { + ASSERT_THAT(boundary[i].first, Eq(2)); + } +} + +TEST_F(get_boundary_of_Test, rectangle_correctly) { + const auto gmshContext = Context(0, 0, true, true); + + const auto rectangle = construct_rectangle({0., 0., 0.}, {1., 1.}); + + const auto boundary = get_boundary_of({rectangle}); + + ASSERT_THAT(boundary.size(), Eq(4)); + for (std::size_t i = 0; i < boundary.size(); i++) { + ASSERT_THAT(boundary[i].first, Eq(1)); + } +} + +TEST_F(get_boundary_of_Test, line_correctly) { + const auto gmshContext = Context(0, 0, true, true); + + const auto point_1 = gmsh::model::occ::addPoint(0., 0., 0.); + const auto point_2 = gmsh::model::occ::addPoint(1., 1., 1.); + + const auto line = gmsh::model::occ::addLine(point_1, point_2); + + const auto boundary = get_boundary_of({{1, line}}); + + ASSERT_THAT(boundary.size(), Eq(2)); + for (std::size_t i = 0; i < boundary.size(); i++) { + ASSERT_THAT(boundary[i].first, Eq(0)); + } + ASSERT_THAT(boundary[0].second, Eq(point_1)); + ASSERT_THAT(boundary[1].second, Eq(point_2)); +} + +TEST_F(get_boundary_of_Test, recursive_rectangle_correctly) { + const auto gmshContext = Context(0, 0, true, true); + + const auto rectangle = construct_rectangle({0., 0., 0.}, {1., 1.}); + + const auto boundary = get_boundary_of({rectangle}, true); + + ASSERT_THAT(boundary.size(), Eq(4)); + for (std::size_t i = 0; i < boundary.size(); i++) { + ASSERT_THAT(boundary[i].first, Eq(0)); + } +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_centroid_of_Test.cc b/meshing/test/cppgmsh/get_centroid_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..6479179e887be528e9f83f0e7ffefe79b413faed --- /dev/null +++ b/meshing/test/cppgmsh/get_centroid_of_Test.cc @@ -0,0 +1,55 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/get_centroid_of.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_centroid_of_Test : Test {}; + +TEST_F(get_centroid_of_Test, returns_correct_get_centroid_of_line) { + const auto gmshContext = Context(0, 0); + const auto centroid = get_centroid_of( + {1, gmsh::model::occ::addLine(gmsh::model::occ::addPoint(0, 0, 0), + gmsh::model::occ::addPoint(1, 0, 0))}); + ASSERT_THAT(centroid, ElementsAre(DoubleEq(0.5), DoubleEq(0), DoubleEq(0))); +} + +TEST_F(get_centroid_of_Test, returns_correct_get_centroid_of_rectangle) { + const auto gmshContext = Context(0, 0); + const auto centroid = get_centroid_of(construct_rectangle({0, 0, 0}, {1, 1})); + ASSERT_THAT(centroid, ElementsAre(DoubleEq(.5), DoubleEq(.5), DoubleEq(0))); +} + +TEST_F(get_centroid_of_Test, returns_correct_get_centroid_of_box) { + const auto gmshContext = Context(0, 0); + const auto centroid = get_centroid_of(construct_box({0, 0, 0}, {1, 1, 1})); + ASSERT_THAT(centroid, ElementsAre(DoubleEq(.5), DoubleEq(.5), DoubleEq(.5))); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_coords_of_Test.cc b/meshing/test/cppgmsh/get_coords_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..3dc5c4e778a3eed8208754383c94368c4b428686 --- /dev/null +++ b/meshing/test/cppgmsh/get_coords_of_Test.cc @@ -0,0 +1,56 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/get_coords_of.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_coords_of_Test : Test {}; + +TEST_F(get_coords_of_Test, returns_correct_coords_of_point) { + const auto gmshContext = Context(0, 0); + const auto tag = gmsh::model::occ::addPoint(1, 2, 3); + gmsh::model::occ::synchronize(); + const auto coords = get_coords_of(tag); + ASSERT_THAT(coords[0], Eq(1)); + ASSERT_THAT(coords[1], Eq(2)); + ASSERT_THAT(coords[2], Eq(3)); +} + +TEST_F(get_coords_of_Test, returns_correct_coords_of_points) { + const auto gmshContext = Context(0, 0); + const auto tag_1 = gmsh::model::occ::addPoint(1, 2, 3); + const auto tag_2 = gmsh::model::occ::addPoint(4, 5, 6); + gmsh::model::occ::synchronize(); + const auto coords = get_coords_of({tag_1, tag_2}); + ASSERT_THAT(coords[0][0], Eq(1)); + ASSERT_THAT(coords[0][1], Eq(2)); + ASSERT_THAT(coords[0][2], Eq(3)); + ASSERT_THAT(coords[1][0], Eq(4)); + ASSERT_THAT(coords[1][1], Eq(5)); + ASSERT_THAT(coords[1][2], Eq(6)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_elements_in_Test.cc b/meshing/test/cppgmsh/get_elements_in_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..cea33c533b8a0397e592102916207c81f272a42c --- /dev/null +++ b/meshing/test/cppgmsh/get_elements_in_Test.cc @@ -0,0 +1,128 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_elements_in.h" +#include "ae108/meshing/cppgmsh/get_nodes_of.h" +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::ElementsAre; +using testing::Eq; +using testing::Ge; +using testing::Le; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_elements_in_Test : Test {}; + +TEST_F(get_elements_in_Test, returns_correct_number_of_tets_for_simple_box) { + const auto gmshContext = Context(0, 0); + + construct_box({0., 0., 0.}, {1., 1., 1.}); + gmsh::model::occ::synchronize(); + + set_granularity(1); + generate_mesh(3, 1, 6); + + auto elements = get_elements_in({3, -1}); + ASSERT_THAT(elements.size(), Eq(24)); + ASSERT_THAT(elements[0].first, Eq(4)); +} + +TEST_F(get_elements_in_Test, returns_the_correct_elements) { + const auto gmshContext = Context(0, 0); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({10., 10., 10.}, {1., 1., 1.}); + gmsh::model::occ::synchronize(); + + set_granularity(1.); + generate_mesh(3, 1, 6); + + auto elements = get_elements_in({3, -1}); + std::vector<bool> foundElement(elements.size(), false); + + auto elements_1 = get_elements_in({3, box_1.second}); + auto elements_2 = get_elements_in({3, box_2.second}); + + const auto all_nodes = get_nodes_of<3>({3, -1}); + for (std::size_t i = 0; i < elements_1.size(); i++) { + int type; + std::vector<std::size_t> nodes; + gmsh::model::mesh::getElement(elements_1[i].second, type, nodes); + ASSERT_THAT(elements_1[i].first, Eq(type)); + for (std::size_t j = 0; j < nodes.size(); j++) { + bool foundNode = false; + for (std::size_t k = 0; k < all_nodes.size(); k++) { + if (nodes[j] == all_nodes[k].id) { + foundNode = true; + ASSERT_THAT(all_nodes[k].position, + ElementsAre(Ge(0.), Ge(0.), Ge(0.))); + ASSERT_THAT(all_nodes[k].position, + ElementsAre(Le(1.), Le(1.), Le(1.))); + break; + } + } + ASSERT_THAT(foundNode, Eq(true)); + } + for (std::size_t j = 0; j < elements.size(); j++) { + if (elements_1[i].second == elements[j].second) { + ASSERT_THAT(foundElement[j], Eq(false)); + foundElement[j] = true; + } + } + } + + for (std::size_t i = 0; i < elements_2.size(); i++) { + int type; + std::vector<std::size_t> nodes; + gmsh::model::mesh::getElement(elements_2[i].second, type, nodes); + for (std::size_t j = 0; j < nodes.size(); j++) { + bool foundNode = false; + for (std::size_t k = 0; k < all_nodes.size(); k++) { + if (nodes[j] == all_nodes[k].id) { + foundNode = true; + ASSERT_THAT(all_nodes[k].position, + ElementsAre(Ge(10.), Ge(10.), Ge(10.))); + ASSERT_THAT(all_nodes[k].position, + ElementsAre(Le(11.), Le(11.), Le(11.))); + break; + } + } + ASSERT_THAT(foundNode, Eq(true)); + } + for (std::size_t j = 0; j < elements.size(); j++) { + if (elements_2[i].second == elements[j].second) { + ASSERT_THAT(foundElement[j], Eq(false)); + foundElement[j] = true; + } + } + } + for (std::size_t i = 0; i < elements.size(); i++) { + ASSERT_THAT(foundElement[i], Eq(true)); + } +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_entities_in_Test.cc b/meshing/test/cppgmsh/get_entities_in_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..a8d8959574b22bbe940be2c7dea2d2813d90c9da --- /dev/null +++ b/meshing/test/cppgmsh/get_entities_in_Test.cc @@ -0,0 +1,86 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/get_entities_in.h" +#include "ae108/meshing/cppgmsh/set_physical_group_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_entities_in_Test : Test {}; + +TEST_F(get_entities_in_Test, returns_correct_vertices_in_box) { + const auto gmshContext = Context(0, 0); + gmsh::model::occ::addBox(0, 0, 0, 1, 1, 1); + gmsh::model::occ::synchronize(); + const auto points = get_entities_in({{0, 0, 0}, {1, 1, 1}}, 0); + ASSERT_THAT(points[0].first, Eq(0)); + ASSERT_THAT(points.size(), Eq(8)); +} + +TEST_F(get_entities_in_Test, returns_correct_lines_in_box) { + const auto gmshContext = Context(0, 0); + gmsh::model::occ::addBox(0, 0, 0, 1, 1, 1); + gmsh::model::occ::synchronize(); + const auto lines = get_entities_in({{0, 0, 0}, {1, 1, 1}}, 1); + ASSERT_THAT(lines[0].first, Eq(1)); + ASSERT_THAT(lines.size(), Eq(12)); +} + +TEST_F(get_entities_in_Test, returns_correct_surfaces_in_box) { + const auto gmshContext = Context(0, 0); + gmsh::model::occ::addBox(0, 0, 0, 1, 1, 1); + gmsh::model::occ::synchronize(); + const auto surfaces = get_entities_in({{0, 0, 0}, {1, 1, 1}}, 2); + ASSERT_THAT(surfaces[0].first, Eq(2)); + ASSERT_THAT(surfaces.size(), Eq(6)); +} + +TEST_F(get_entities_in_Test, returns_correct_volumes_in_box) { + const auto gmshContext = Context(0, 0); + gmsh::model::occ::addBox(0, 0, 0, 1, 1, 1); + gmsh::model::occ::synchronize(); + const auto volumes = get_entities_in({{0, 0, 0}, {1, 1, 1}}, 3); + ASSERT_THAT(volumes[0].first, Eq(3)); + ASSERT_THAT(volumes.size(), Eq(1)); +} + +TEST_F(get_entities_in_Test, returns_the_correct_entities) { + const auto gmshContext = Context(0, 0, true, true); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({10., 10., 10.}, {1., 1., 1.}); + synchronize(); + + const auto group = set_physical_group_of({box_1, box_2}); + const auto entities = get_entities_in(group); + + ASSERT_THAT(entities.size(), Eq(2)); + ASSERT_THAT(entities[0], Eq(box_1)); + ASSERT_THAT(entities[1], Eq(box_2)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_entities_of_Test.cc b/meshing/test/cppgmsh/get_entities_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..587fdebb215cf910d15346ca2f02763a91d14b64 --- /dev/null +++ b/meshing/test/cppgmsh/get_entities_of_Test.cc @@ -0,0 +1,70 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_entities_of_Test : Test {}; + +TEST_F(get_entities_of_Test, gets_enities_of_dim3) { + const auto gmshContext = Context(0, 0, true, true); + + std::pair<int, int> box = construct_box(std::array<double, 3>{0., 0., 0.}, + std::array<double, 3>{1., 1., 1.}); + synchronize(); + + const auto entities = get_entities_of(3); + ASSERT_THAT(entities.size(), Eq(1)); + ASSERT_THAT(entities[0].first, Eq(3)); + ASSERT_THAT(entities[0].second, Eq(box.second)); +} + +TEST_F(get_entities_of_Test, gets_enities_of_dim2) { + const auto gmshContext = Context(0, 0, true, true); + + construct_box(std::array<double, 3>{0., 0., 0.}, + std::array<double, 3>{1., 1., 1.}); + synchronize(); + + const auto entities = get_entities_of(2); + ASSERT_THAT(entities.size(), Eq(6)); + ASSERT_THAT(entities[0].first, Eq(2)); +} + +TEST_F(get_entities_of_Test, gets_enities_of_all_dimensions) { + const auto gmshContext = Context(0, 0, true, true); + + construct_box(std::array<double, 3>{0., 0., 0.}, + std::array<double, 3>{1., 1., 1.}); + synchronize(); + + const auto entities = get_entities_of(); + ASSERT_THAT(entities.size(), + Eq(1 /*volume*/ + 6 /*surfaces*/ + 12 /*edges*/ + 8 /*points*/)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_nodes_of_Test.cc b/meshing/test/cppgmsh/get_nodes_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..e4b81e2a0697ea1b96ef0d9b22df1ffdfd00799a --- /dev/null +++ b/meshing/test/cppgmsh/get_nodes_of_Test.cc @@ -0,0 +1,85 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/fragment_entities.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_nodes_of.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Eq; +using testing::Ne; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_nodes_Test : Test {}; + +TEST_F(get_nodes_Test, returns_correct_nodes) { + const auto gmshContext = Context(0, 0); + + const auto box = construct_box({0., 0., 0.}, {1., 1., 1.}); + synchronize(); + + set_granularity(1.); + generate_mesh(); + + const auto nodes = get_nodes_of<3>(box); + ASSERT_THAT(nodes.size(), Eq(14)); + ASSERT_THAT(nodes[0].position, + ElementsAre(DoubleEq(0), DoubleEq(0), DoubleEq(1))); + ASSERT_THAT(nodes[1].position, + ElementsAre(DoubleEq(0), DoubleEq(0), DoubleEq(0))); + ASSERT_THAT(nodes[2].position, + ElementsAre(DoubleEq(0), DoubleEq(1), DoubleEq(1))); + ASSERT_THAT(nodes[3].position, + ElementsAre(DoubleEq(0), DoubleEq(1), DoubleEq(0))); + ASSERT_THAT(nodes[4].position, + ElementsAre(DoubleEq(1), DoubleEq(0), DoubleEq(1))); + ASSERT_THAT(nodes[5].position, + ElementsAre(DoubleEq(1), DoubleEq(0), DoubleEq(0))); + ASSERT_THAT(nodes[6].position, + ElementsAre(DoubleEq(1), DoubleEq(1), DoubleEq(1))); + ASSERT_THAT(nodes[7].position, + ElementsAre(DoubleEq(1), DoubleEq(1), DoubleEq(0))); +} + +TEST_F(get_nodes_Test, removes_duplicates) { + const auto gmshContext = Context(0, 0); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({0., 0., 1.}, {1., 1., 1.}); + const auto fused_entities = fragment_entities({box_1, box_2}); + synchronize(); + + set_granularity(1); + generate_mesh(3, 1, 6); + + const auto duplicate_nodes = get_nodes_of<3>({3, -1}, false); + const auto nodes = get_nodes_of<3>({3, -1}, true); + + ASSERT_THAT(duplicate_nodes.size(), Ne(nodes.size())); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_normal_of_Test.cc b/meshing/test/cppgmsh/get_normal_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..baa96c61f2010bd6ca25c07c4b8e9c08cb9023af --- /dev/null +++ b/meshing/test/cppgmsh/get_normal_of_Test.cc @@ -0,0 +1,43 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/get_normal_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_normal_of_Test : Test {}; + +TEST_F(get_normal_of_Test, returns_correct_normal_of_rectangle) { + const auto gmshContext = Context(0, 0); + const auto rectangle = construct_rectangle({0, 0, 0}, {1, 1}); + synchronize(); + const auto normal = get_normal_of(rectangle.second); + ASSERT_THAT(normal, ElementsAre(DoubleEq(0), DoubleEq(0), DoubleEq(1))); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_periodic_nodes_of_Test.cc b/meshing/test/cppgmsh/get_periodic_nodes_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..3b0be7234720f76dc0e1cd423ae66aee3604e2f3 --- /dev/null +++ b/meshing/test/cppgmsh/get_periodic_nodes_of_Test.cc @@ -0,0 +1,96 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_periodic_nodes_of.h" +#include "ae108/meshing/cppgmsh/set_periodic.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Eq; +using testing::Gt; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_periodic_nodes_of_Test : Test {}; + +TEST_F(get_periodic_nodes_of_Test, returns_correct_mesh_of_periodic_lines) { + const auto gmshContext = Context(0, 0); + const auto source_line = gmsh::model::occ::addLine( + gmsh::model::occ::addPoint(0, 0, 0), gmsh::model::occ::addPoint(1, 0, 0)); + const auto target_line = gmsh::model::occ::addLine( + gmsh::model::occ::addPoint(0, 0, 1), gmsh::model::occ::addPoint(1, 0, 1)); + gmsh::model::occ::synchronize(); + + set_periodic({{1, target_line}}, {1, source_line}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1}); + generate_mesh(1); + + std::array<double, 16> transform; + std::pair<int, int> source_entity; + const auto node_tags = + get_periodic_nodes_of({1, target_line}, &source_entity, &transform); + + ASSERT_THAT(source_entity.first, Eq(1)); + ASSERT_THAT(source_entity.second, Eq(source_line)); + ASSERT_THAT(node_tags.first.size(), Gt(0)); + ASSERT_THAT(node_tags.second.size(), Gt(0)); + ASSERT_THAT(node_tags.second.size(), Eq(node_tags.first.size())); + ASSERT_THAT(transform, ElementsAre(DoubleEq(1.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(1.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(1.))); +} + +TEST_F(get_periodic_nodes_of_Test, + returns_correct_mesh_of_periodic_rectangles) { + const auto gmshContext = Context(0, 0); + const auto source_rect = gmsh::model::occ::addRectangle(0, 0, 0, 1, 1); + const auto target_rect = gmsh::model::occ::addRectangle(0, 0, 1, 1, 1); + gmsh::model::occ::synchronize(); + + set_periodic({{2, target_rect}}, {2, source_rect}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1}); + generate_mesh(2); + + std::array<double, 16> transform; + std::pair<int, int> source_entity; + const auto node_tags = + get_periodic_nodes_of({2, target_rect}, &source_entity, &transform); + + ASSERT_THAT(source_entity.first, Eq(2)); + ASSERT_THAT(source_entity.second, Eq(source_rect)); + ASSERT_THAT(node_tags.first.size(), Gt(0)); + ASSERT_THAT(node_tags.second.size(), Gt(0)); + ASSERT_THAT(node_tags.second.size(), Eq(node_tags.first.size())); + ASSERT_THAT(transform, ElementsAre(DoubleEq(1.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(1.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(1.))); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_physical_groups_Test.cc b/meshing/test/cppgmsh/get_physical_groups_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..06a890551fb5b27e891c4bea6b77ac7494ad86e8 --- /dev/null +++ b/meshing/test/cppgmsh/get_physical_groups_Test.cc @@ -0,0 +1,82 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/get_physical_groups.h" +#include "ae108/meshing/cppgmsh/set_physical_group_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct get_physical_groups_Test : Test {}; + +TEST_F(get_physical_groups_Test, gets_all_groups) { + const auto gmshContext = Context(0, 0, true, true); + + const auto rectangle_1 = construct_rectangle({0, 0, 0}, {1, 1}); + const auto rectangle_2 = construct_rectangle({0, 1, 0}, {.5, .5}); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({10., 10., 10.}, {1., 1., 1.}); + const auto box_3 = construct_box({5., 10., 10.}, {1., 1., 1.}); + synchronize(); + + const auto group_1 = set_physical_group_of({rectangle_1, rectangle_2}); + const auto group_2 = set_physical_group_of({box_1, box_2}); + const auto group_3 = set_physical_group_of({box_3}); + + auto groups = get_physical_groups(); + ASSERT_THAT(groups.size(), Eq(3)); + ASSERT_THAT(groups[0], Eq(group_1)); + ASSERT_THAT(groups[1], Eq(group_2)); + ASSERT_THAT(groups[2], Eq(group_3)); +} + +TEST_F(get_physical_groups_Test, gets_groups_of_specified_dimension) { + const auto gmshContext = Context(0, 0, true, true); + + const auto rectangle_1 = construct_rectangle({0, 0, 0}, {1, 1}); + const auto rectangle_2 = construct_rectangle({0, 1, 0}, {.5, .5}); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({10., 10., 10.}, {1., 1., 1.}); + const auto box_3 = construct_box({5., 10., 10.}, {1., 1., 1.}); + synchronize(); + + const auto group_1 = set_physical_group_of({rectangle_1, rectangle_2}); + const auto group_2 = set_physical_group_of({box_1, box_2}); + const auto group_3 = set_physical_group_of({box_3}); + + auto groups_2D = get_physical_groups(2); + ASSERT_THAT(groups_2D.size(), Eq(1)); + ASSERT_THAT(groups_2D[0], Eq(group_1)); + + auto groups_3D = get_physical_groups(3); + ASSERT_THAT(groups_3D[0], Eq(group_2)); + ASSERT_THAT(groups_3D[1], Eq(group_3)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/get_points_of_Test.cc b/meshing/test/cppgmsh/get_points_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..c7238bb734c6cb3228d3b813610cc2f925ca80d9 --- /dev/null +++ b/meshing/test/cppgmsh/get_points_of_Test.cc @@ -0,0 +1,69 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct points_of_Test : Test {}; + +TEST_F(points_of_Test, returns_correct_points_of_point) { + const auto gmshContext = Context(0, 0); + const auto tag = gmsh::model::occ::addPoint(0, 0, 0); + gmsh::model::occ::synchronize(); + const auto points = get_points_of({0, tag}); + ASSERT_THAT(points.size(), Eq(1)); + ASSERT_THAT(points[0], Eq(tag)); +} + +TEST_F(points_of_Test, returns_correct_points_of_line) { + const auto gmshContext = Context(0, 0); + const auto A = gmsh::model::occ::addPoint(0, 0, 0); + const auto B = gmsh::model::occ::addPoint(1, 0, 0); + const auto tag = gmsh::model::occ::addLine(A, B); + gmsh::model::occ::synchronize(); + const auto points = get_points_of({1, tag}); + ASSERT_THAT(points.size(), Eq(2)); + ASSERT_THAT(points[0], Eq(A)); + ASSERT_THAT(points[1], Eq(B)); +} + +TEST_F(points_of_Test, returns_correct_points_of_rectangle) { + const auto gmshContext = Context(0, 0); + const auto tag = gmsh::model::occ::addRectangle(0, 0, 0, 1, 1); + gmsh::model::occ::synchronize(); + const auto points = get_points_of({2, tag}); + ASSERT_THAT(points.size(), Eq(4)); +} + +TEST_F(points_of_Test, returns_correct_points_of_box) { + const auto gmshContext = Context(0, 0); + const auto tag = gmsh::model::occ::addBox(0, 0, 0, 1, 1, 1); + gmsh::model::occ::synchronize(); + const auto points = get_points_of({3, tag}); + ASSERT_THAT(points.size(), Eq(8)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/heal_periodic_domains_Test.cc b/meshing/test/cppgmsh/heal_periodic_domains_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..e86faff1fd0f23090b41ec1a901be250c1b06572 --- /dev/null +++ b/meshing/test/cppgmsh/heal_periodic_domains_Test.cc @@ -0,0 +1,100 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/BoundingBox.h" +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/get_entities_in.h" +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include "ae108/meshing/cppgmsh/heal_periodic_domains.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct heal_periodic_domains_Test : Test {}; + +TEST_F(heal_periodic_domains_Test, heal_periodic_box_surfaces) { + const auto gmshContext = Context(0, 0); + const auto box = construct_box({0, 0, 0}, {1, 1, 1}); + + gmsh::vectorpair ov; + std::vector<gmsh::vectorpair> ovv; + gmsh::model::occ::fragment( + {box}, {{0, gmsh::model::occ::addPoint(0.5, 0, 0)}}, ov, ovv); + gmsh::model::occ::synchronize(); + + const auto source_bbox = + BoundingBox<std::array<double, 3>>{{0, 0, 0}, {1, 1, 0}}; + const auto target_bbox = + BoundingBox<std::array<double, 3>>{{0, 0, 1}, {1, 1, 1}}; + + heal_periodic_domains(source_bbox, target_bbox); + gmsh::model::occ::synchronize(); + + const auto source_surface = get_entities_in(source_bbox, 2); + const auto target_surface = get_entities_in(target_bbox, 2); + const auto source_points = get_points_of(source_surface[0]); + const auto target_points = get_points_of(target_surface[0]); + + gmsh::vectorpair points; + gmsh::model::getEntities(points, 0); + + ASSERT_THAT(points.size(), Eq(10)); + ASSERT_THAT(source_points.size(), Eq(5)); + ASSERT_THAT(target_points.size(), Eq(5)); +} + +TEST_F(heal_periodic_domains_Test, heal_two_periodic_box_surfaces) { + const auto gmshContext = Context(0, 0); + const auto boxA = construct_box({0, 0, 0}, {.4, .4, 1}); + construct_box({.5, .5, 0}, {.4, .4, 1}); + + gmsh::vectorpair ov; + std::vector<gmsh::vectorpair> ovv; + gmsh::model::occ::fragment( + {boxA}, {{0, gmsh::model::occ::addPoint(0.25, 0, 0)}}, ov, ovv); + gmsh::model::occ::synchronize(); + + const auto source_bbox = + BoundingBox<std::array<double, 3>>{{0, 0, 0}, {1, 1, 0}}; + const auto target_bbox = + BoundingBox<std::array<double, 3>>{{0, 0, 1}, {1, 1, 1}}; + + heal_periodic_domains(source_bbox, target_bbox); + gmsh::model::occ::synchronize(); + + const auto source_surface = get_entities_in(source_bbox, 2); + const auto target_surface = get_entities_in(target_bbox, 2); + const auto source_points = get_points_of(source_surface[0]).size() + + get_points_of(source_surface[1]).size(); + const auto target_points = get_points_of(target_surface[0]).size() + + get_points_of(target_surface[1]).size(); + + gmsh::vectorpair points; + gmsh::model::getEntities(points, 0); + + ASSERT_THAT(points.size(), Eq(18)); + ASSERT_THAT(source_points, Eq(9)); + ASSERT_THAT(target_points, Eq(9)); +} +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/heal_periodic_surfaces_Test.cc b/meshing/test/cppgmsh/heal_periodic_surfaces_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..2ee3fb2d35686366f14b8a34f7106adedef9bad9 --- /dev/null +++ b/meshing/test/cppgmsh/heal_periodic_surfaces_Test.cc @@ -0,0 +1,95 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/BoundingBox.h" +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/get_entities_in.h" +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include "ae108/meshing/cppgmsh/heal_periodic_surfaces.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct heal_periodic_surfaces_Test : Test {}; + +TEST_F(heal_periodic_surfaces_Test, heal_periodic_rectangles) { + const auto gmshContext = Context(0, 0); + const auto source_rect = construct_rectangle({0, 0, 0}, {1, 1}); + const auto target_rect = construct_rectangle({0, 0, 1}, {1, 1}); + + gmsh::vectorpair ov; + std::vector<gmsh::vectorpair> ovv; + gmsh::model::occ::fragment( + {source_rect}, {{0, gmsh::model::occ::addPoint(0.5, 0, 0)}}, ov, ovv); + gmsh::model::occ::synchronize(); + + heal_periodic_surfaces(source_rect.second, target_rect.second, {0, 0, 1}); + gmsh::model::occ::synchronize(); + + const auto source_points = get_points_of({2, source_rect}); + const auto target_points = get_points_of({2, target_rect}); + + gmsh::vectorpair points; + gmsh::model::getEntities(points, 0); + + ASSERT_THAT(points.size(), Eq(10)); + ASSERT_THAT(source_points.size(), Eq(5)); + ASSERT_THAT(target_points.size(), Eq(5)); +} + +TEST_F(heal_periodic_surfaces_Test, heal_periodic_box_surfaces) { + const auto gmshContext = Context(0, 0); + const auto box = construct_box({0, 0, 0}, {1, 1, 1}); + + gmsh::vectorpair ov; + std::vector<gmsh::vectorpair> ovv; + gmsh::model::occ::fragment( + {box}, {{0, gmsh::model::occ::addPoint(0.5, 0, 0)}}, ov, ovv); + gmsh::model::occ::synchronize(); + + const auto source_bbox = + BoundingBox<std::array<double, 3>>{{0, 0, 0}, {1, 1, 0}}; + const auto target_bbox = + BoundingBox<std::array<double, 3>>{{0, 0, 1}, {1, 1, 1}}; + + const auto source_surface = get_entities_in(source_bbox, 2); + const auto target_surface = get_entities_in(target_bbox, 2); + + heal_periodic_surfaces(source_surface[0].second, target_surface[0].second, + {0, 0, 1}); + gmsh::model::occ::synchronize(); + + const auto source_points = get_points_of(source_surface[0]); + const auto target_points = get_points_of(target_surface[0]); + + gmsh::vectorpair points; + gmsh::model::getEntities(points, 0); + + ASSERT_THAT(points.size(), Eq(10)); + ASSERT_THAT(source_points.size(), Eq(5)); + ASSERT_THAT(target_points.size(), Eq(5)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/import_shapes_Test.cc b/meshing/test/cppgmsh/import_shapes_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..fc13d1e40045619f249186d14d263c400e4cc8e9 --- /dev/null +++ b/meshing/test/cppgmsh/import_shapes_Test.cc @@ -0,0 +1,74 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/fragment_entities.h" +#include "ae108/meshing/cppgmsh/import_shapes.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include "ae108/meshing/cppgmsh/write_file.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct import_shapes_Test : Test {}; + +TEST_F(import_shapes_Test, imports_box) { + const auto gmshContext = Context(0, 0, true, false); + + const auto origin = std::array<double, 3>{0, 0, 0}; + const auto side_lengths = std::array<double, 3>{1, 2, 3}; + + const auto box_0 = construct_box(origin, side_lengths); + synchronize(); + write_file("box.stp"); + + const auto imported_shapes = import_shapes("box.stp"); + ASSERT_THAT(imported_shapes.size(), Eq(1)); + const auto box_1 = imported_shapes[0]; + + const auto fragments = fragment_entities({box_0, box_1}); + ASSERT_THAT(fragments.size(), Eq(1)); +} + +TEST_F(import_shapes_Test, imports_box_with_lower_dimensional_entities) { + const auto gmshContext = Context(0, 0, true, false); + + const auto origin = std::array<double, 3>{0, 0, 0}; + const auto side_lengths = std::array<double, 3>{1, 2, 3}; + + construct_box(origin, side_lengths); + synchronize(); + write_file("box.stp"); + + const auto imported_shapes = import_shapes("box.stp", false); + std::array<bool, 4> includes_iD_entities = {false, false, false, false}; + for (std::size_t i = 0; i < imported_shapes.size(); i++) { + for (int d = 0; d < 4; d++) + if (imported_shapes[i].first == d) + includes_iD_entities[d] = true; + } + for (std::size_t d = 0; d < 4; d++) + ASSERT_THAT(includes_iD_entities[d], Eq(true)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/intersect_entities_Test.cc b/meshing/test/cppgmsh/intersect_entities_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..20a3fcc52cb8b31726fb7016295e15490361bd08 --- /dev/null +++ b/meshing/test/cppgmsh/intersect_entities_Test.cc @@ -0,0 +1,99 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include "ae108/meshing/cppgmsh/intersect_entities.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct intersect_entities_Test : Test {}; + +TEST_F(intersect_entities_Test, self_intersect_single_entitity) { + const auto gmshContext = Context(0, 0); + + const auto object = construct_box({0, 0, 0}, {1, 1, 1}); + + const auto result = intersect_entities({object}, {object}); + ASSERT_THAT(result.size(), Eq(1)); +} + +TEST_F(intersect_entities_Test, intersect_two_entitities) { + const auto gmshContext = Context(0, 0); + + const auto object = construct_box({0, 0, 0}, {1, 1, 1}); + const auto tool = construct_box({.5, .5, .5}, {1, 1, 1}); + + const auto result = intersect_entities({object}, {tool}); + ASSERT_THAT(result.size(), Eq(1)); +} + +TEST_F(intersect_entities_Test, intersect_unconnected_entitities) { + const auto gmshContext = Context(0, 0); + + const auto object = construct_box({0, 0, 0}, {1, 1, 1}); + const auto tool = construct_box({2, 2, 2}, {1, 1, 1}); + + const auto result = intersect_entities({object}, {tool}); + ASSERT_THAT(result.size(), Eq(0)); +} + +TEST_F(intersect_entities_Test, keep_object) { + const auto gmshContext = Context(0, 0); + + const auto object = construct_box({0, 0, 0}, {1, 1, 1}); + const auto tool = construct_box({.5, .5, .5}, {1, 1, 1}); + + intersect_entities({object}, {tool}, false, true); + synchronize(); + const auto entities = get_entities_of(3); + ASSERT_THAT(entities.size(), Eq(2)); +} + +TEST_F(intersect_entities_Test, keep_tool) { + const auto gmshContext = Context(0, 0); + + const auto object = construct_box({0, 0, 0}, {1, 1, 1}); + const auto tool = construct_box({.5, .5, .5}, {1, 1, 1}); + + intersect_entities({object}, {tool}, true, false); + synchronize(); + const auto entities = get_entities_of(3); + ASSERT_THAT(entities.size(), Eq(2)); +} + +TEST_F(intersect_entities_Test, keep_object_and_tool) { + const auto gmshContext = Context(0, 0); + + const auto object = construct_box({0, 0, 0}, {1, 1, 1}); + const auto tool = construct_box({.5, .5, .5}, {1, 1, 1}); + + intersect_entities({object}, {tool}, false, false); + synchronize(); + const auto entities = get_entities_of(3); + ASSERT_THAT(entities.size(), Eq(3)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/read_file_Test.cc b/meshing/test/cppgmsh/read_file_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..32a1aa301d0c3086cebef251f527de9f32b66a1c --- /dev/null +++ b/meshing/test/cppgmsh/read_file_Test.cc @@ -0,0 +1,124 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/extract_mesh.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/read_file.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/write_file.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct read_file_Test : Test {}; + +TEST_F(read_file_Test, reads_step_file) { + + { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 2, 3}); + gmsh::model::occ::synchronize(); + write_file("test.stp"); + } + + const auto gmshContext = Context(0, 0); + + read_file("test.stp"); + gmsh::vectorpair dimTags; + gmsh::model::getEntities(dimTags, 3); + + ASSERT_THAT(dimTags.size(), Eq(1)); + ASSERT_THAT(dimTags[0].first, Eq(3)); + ASSERT_THAT(dimTags[0].second, Eq(1)); +} + +TEST_F(read_file_Test, reads_stl_file) { + + { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 1, 1}); + gmsh::model::occ::synchronize(); + set_granularity(1.); + generate_mesh(2, 1, 6); + write_file("test.stl"); + } + + const auto gmshContext = Context(0, 0); + + read_file("test.stl"); + const auto [positions, connectivity, mapA, mapB] = extract_mesh<2>(); + + ASSERT_THAT(positions.size(), Eq(14)); + ASSERT_THAT(connectivity.size(), Eq(24)); + ASSERT_THAT(connectivity[0].size(), Eq(3)); +} + +TEST_F(read_file_Test, reads_vtk_file) { + + { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 1, 1}); + gmsh::model::occ::synchronize(); + set_granularity(1.); + generate_mesh(3, 1, 6); + write_file("test.vtk"); + } + + const auto gmshContext = Context(0, 0); + + read_file("test.vtk"); + gmsh::model::mesh::createTopology(); + gmsh::model::mesh::classifySurfaces(0.1, true, false, 0.1); + gmsh::model::mesh::createGeometry(); + + const auto [positions, connectivity, mapA, mapB] = extract_mesh<3>(); + + ASSERT_THAT(positions.size(), Eq(14)); + ASSERT_THAT(connectivity.size(), Eq(24)); + ASSERT_THAT(connectivity[0].size(), Eq(4)); +} + +TEST_F(read_file_Test, reads_msh_file) { + + { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 1, 1}); + gmsh::model::occ::synchronize(); + set_granularity(1.); + generate_mesh(3, 1, 6); + write_file("test.msh"); + } + + const auto gmshContext = Context(0, 0); + + read_file("test.msh"); + const auto [positions, connectivity, mapA, mapB] = extract_mesh<3>(); + + ASSERT_THAT(positions.size(), Eq(14)); + ASSERT_THAT(connectivity.size(), Eq(24)); + ASSERT_THAT(connectivity[0].size(), Eq(4)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/remove_entities_Test.cc b/meshing/test/cppgmsh/remove_entities_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..1f11a5b7d4115321aa8f4aab8bd74ac71664639c --- /dev/null +++ b/meshing/test/cppgmsh/remove_entities_Test.cc @@ -0,0 +1,61 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include "ae108/meshing/cppgmsh/remove_entities.h" +#include "ae108/meshing/cppgmsh/synchronize.h" + +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Gt; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct remove_entities_Test : Test {}; + +TEST_F(remove_entities_Test, remove_box_keep_boundaries) { + const auto gmshContext = Context(0, 0, true, true); + + const auto box = construct_box({0., 0., 0.}, {1., 1., 1.}); + + remove_entities({box}); + + synchronize(); + auto entities = get_entities_of(3); + ASSERT_THAT(entities.size(), Eq(0)); + entities = get_entities_of(); + ASSERT_THAT(entities.size(), Gt(0)); +} + +TEST_F(remove_entities_Test, remove_box_and_boundaries) { + const auto gmshContext = Context(0, 0, true, true); + + const auto box = construct_box({0., 0., 0.}, {1., 1., 1.}); + + remove_entities({box}, true); + + const auto entities = get_entities_of(); + ASSERT_THAT(entities.size(), Eq(0)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/rotate_entities_Test.cc b/meshing/test/cppgmsh/rotate_entities_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..5e1b356260ab357c41057a035ced2809b3aadde9 --- /dev/null +++ b/meshing/test/cppgmsh/rotate_entities_Test.cc @@ -0,0 +1,70 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/get_coords_of.h" +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include "ae108/meshing/cppgmsh/rotate_entities.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct rotate_entities_Test : Test {}; + +TEST_F(rotate_entities_Test, rotates_rectangle_by_30_degrees) { + const auto gmshContext = Context(0, 0, true, true); + + const auto box = construct_rectangle({0, 0, 0}, {1, 1}); + rotate_entities({box}, {0., 0., 0.}, {0., 0., 1.}, 30. * M_PI / 180.); + synchronize(); + + const auto points = get_points_of(box); + std::vector<std::array<double, 3>> coords; + for (const auto &point : points) + coords.push_back(get_coords_of(point)); + + ASSERT_THAT(coords[0], ElementsAre(DoubleEq(0.), DoubleEq(0.), DoubleEq(0.))); + ASSERT_THAT(coords[1][1], DoubleEq(1. / 2.)); + ASSERT_THAT(coords[3][0], DoubleEq(-1. / 2.)); +} + +TEST_F(rotate_entities_Test, rotates_rectangle_by_pi_sixths) { + const auto gmshContext = Context(0, 0, true, true); + + const auto box = construct_rectangle({0, 0, 0}, {1, 1}); + rotate_entities({box}, {0., 0., 0.}, {0., 0., 1.}, M_PI / 6.); + synchronize(); + + const auto points = get_points_of(box); + std::vector<std::array<double, 3>> coords; + for (const auto &point : points) + coords.push_back(get_coords_of(point)); + + ASSERT_THAT(coords[0], ElementsAre(DoubleEq(0.), DoubleEq(0.), DoubleEq(0.))); + ASSERT_THAT(coords[1][1], DoubleEq(1. / 2.)); + ASSERT_THAT(coords[3][0], DoubleEq(-1. / 2.)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/set_domain_entities_periodic_Test.cc b/meshing/test/cppgmsh/set_domain_entities_periodic_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..4009ec87390ead39fe8b19d226328ea85f4f17ef --- /dev/null +++ b/meshing/test/cppgmsh/set_domain_entities_periodic_Test.cc @@ -0,0 +1,73 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_periodic_nodes_of.h" +#include "ae108/meshing/cppgmsh/set_domain_entities_periodic.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Eq; +using testing::Gt; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct set_domain_entities_periodic_Test : Test {}; + +TEST_F(set_domain_entities_periodic_Test, fuse_single_entity) { + const auto gmshContext = Context(0, 0); +} + +TEST_F(set_domain_entities_periodic_Test, + returns_correct_mesh_of_periodic_rectangles) { + const auto gmshContext = Context(0, 0); + const auto source_rect = construct_rectangle({0, 0, 0}, {1, 1}); + const auto target_rect = construct_rectangle({0, 0, 1}, {1, 1}); + synchronize(); + + const auto source_bbox = + BoundingBox<std::array<double, 3>>{{0, 0, 0}, {1, 1, 0}}; + const auto target_bbox = + BoundingBox<std::array<double, 3>>{{0, 0, 1}, {1, 1, 1}}; + + set_domain_entities_periodic(source_bbox, target_bbox, 2); + generate_mesh(2); + + std::pair<int, int> source; + std::array<double, 16> transform; + const auto [targetNodeTags, sourceNodeTags] = + get_periodic_nodes_of(target_rect, &source, &transform); + + ASSERT_THAT(source, Eq(source_rect)); + ASSERT_THAT(targetNodeTags.size(), Gt(0)); + ASSERT_THAT(sourceNodeTags.size(), Eq(targetNodeTags.size())); + ASSERT_THAT(transform, ElementsAre(DoubleEq(1.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(1.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(1.))); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/set_expert_mode_Test.cc b/meshing/test/cppgmsh/set_expert_mode_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..c5077cfc4a665399e74a84696adc8fb214e0f3ee --- /dev/null +++ b/meshing/test/cppgmsh/set_expert_mode_Test.cc @@ -0,0 +1,50 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/set_expert_mode.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::DoubleEq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct set_expert_mode_Test : Test {}; + +TEST_F(set_expert_mode_Test, enables_expert_mode) { + const auto gmshContext = Context(0, 0, true, true); + + set_expert_mode(); + double value; + gmsh::option::getNumber("General.ExpertMode", value); + ASSERT_THAT(value, DoubleEq(1.0)); +} + +TEST_F(set_expert_mode_Test, disables_expert_mode) { + const auto gmshContext = Context(0, 0, true, true); + + set_expert_mode(false); + double value; + gmsh::option::getNumber("General.ExpertMode", value); + ASSERT_THAT(value, DoubleEq(0.0)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/set_granularity_Test.cc b/meshing/test/cppgmsh/set_granularity_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..d77898965c26cedee301a56ddd5dced16e6e35e3 --- /dev/null +++ b/meshing/test/cppgmsh/set_granularity_Test.cc @@ -0,0 +1,35 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include <gmock/gmock.h> + +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct set_granularity_Test : Test {}; + +TEST_F(set_granularity_Test, fuse_single_entity) { + const auto gmshContext = Context(0, 0); + set_granularity(0.1); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/set_periodic_Test.cc b/meshing/test/cppgmsh/set_periodic_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..d8cfc8b083d7dfe6887bae89635c0f2bfb820f6d --- /dev/null +++ b/meshing/test/cppgmsh/set_periodic_Test.cc @@ -0,0 +1,94 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/get_periodic_nodes_of.h" +#include "ae108/meshing/cppgmsh/set_periodic.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Eq; +using testing::Gt; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct set_periodic_Test : Test {}; + +TEST_F(set_periodic_Test, returns_correct_mesh_of_periodic_lines) { + const auto gmshContext = Context(0, 0); + const auto source_line = gmsh::model::occ::addLine( + gmsh::model::occ::addPoint(0, 0, 0), gmsh::model::occ::addPoint(1, 0, 0)); + const auto target_line = gmsh::model::occ::addLine( + gmsh::model::occ::addPoint(0, 0, 1), gmsh::model::occ::addPoint(1, 0, 1)); + synchronize(); + + set_periodic({{1, target_line}}, {1, source_line}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1}); + generate_mesh(1); + + std::pair<int, int> master; + std::array<double, 16> transform; + const auto nodes = + get_periodic_nodes_of({1, target_line}, &master, &transform); + + ASSERT_THAT(master.second, Eq(source_line)); + ASSERT_THAT(nodes.first.size(), Gt(0)); + ASSERT_THAT(nodes.second.size(), Gt(0)); + ASSERT_THAT(nodes.first.size(), nodes.second.size()); + ASSERT_THAT(transform, ElementsAre(DoubleEq(1.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(1.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(1.))); +} + +TEST_F(set_periodic_Test, returns_correct_mesh_of_periodic_rectangles) { + const auto gmshContext = Context(0, 0); + const auto source_rect = construct_rectangle({0, 0, 0}, {1, 1}); + const auto target_rect = construct_rectangle({0, 0, 1}, {1, 1}); + synchronize(); + + set_periodic({target_rect}, source_rect, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1}); + generate_mesh(2); + + std::pair<int, int> master; + std::array<double, 16> transform; + const auto nodes = get_periodic_nodes_of(target_rect, &master, &transform); + + ASSERT_THAT(master.second, Eq(source_rect.second)); + ASSERT_THAT(nodes.first.size(), Gt(0)); + ASSERT_THAT(nodes.second.size(), Gt(0)); + ASSERT_THAT(nodes.first.size(), nodes.second.size()); + ASSERT_THAT(transform, ElementsAre(DoubleEq(1.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(0.), DoubleEq(1.), DoubleEq(1.), + DoubleEq(0.), DoubleEq(0.), DoubleEq(0.), + DoubleEq(1.))); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/set_physical_group_of_Test.cc b/meshing/test/cppgmsh/set_physical_group_of_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..d7a84dea069ad17f10fd183289b15803c77f9111 --- /dev/null +++ b/meshing/test/cppgmsh/set_physical_group_of_Test.cc @@ -0,0 +1,91 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/set_physical_group_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct set_physical_group_of_Test : Test {}; + +TEST_F(set_physical_group_of_Test, adds_1D_group) { + const auto gmshContext = Context(0, 0, true, true); + + const auto line_1 = gmsh::model::occ::addLine( + gmsh::model::occ::addPoint(0, 0, 0), gmsh::model::occ::addPoint(1, 0, 0)); + const auto line_2 = gmsh::model::occ::addLine( + gmsh::model::occ::addPoint(1, 0, 0), gmsh::model::occ::addPoint(1, 1, 0)); + synchronize(); + + const auto group = set_physical_group_of({{1, line_1}, {1, line_2}}); + ASSERT_THAT(group, Eq(std::pair<int, int>{1, 1})); +} + +TEST_F(set_physical_group_of_Test, adds_2D_group) { + const auto gmshContext = Context(0, 0, true, true); + + const auto rectangle_1 = construct_rectangle({0, 0, 0}, {1, 1}); + const auto rectangle_2 = construct_rectangle({0, 1, 0}, {0.5, 0.5}); + synchronize(); + + const auto group = set_physical_group_of({rectangle_1, rectangle_2}); + ASSERT_THAT(group, Eq(std::pair<int, int>{2, 1})); +} + +TEST_F(set_physical_group_of_Test, adds_3D_group) { + const auto gmshContext = Context(0, 0, true, true); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({10., 10., 10.}, {1., 1., 1.}); + synchronize(); + + const auto group = set_physical_group_of({box_1, box_2}); + ASSERT_THAT(group, Eq(std::pair<int, int>{3, 1})); +} + +TEST_F(set_physical_group_of_Test, adds_group_with_one_member) { + const auto gmshContext = Context(0, 0, true, true); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + synchronize(); + + const auto group = set_physical_group_of({box_1}); + ASSERT_THAT(group, Eq(std::pair<int, int>{3, 1})); +} + +TEST_F(set_physical_group_of_Test, adds_group_with_three_members) { + const auto gmshContext = Context(0, 0, true, true); + + const auto box_1 = construct_box({0., 0., 0.}, {1., 1., 1.}); + const auto box_2 = construct_box({10., 10., 10.}, {1., 1., 1.}); + const auto box_3 = construct_box({5., 10., 10.}, {1., 1., 1.}); + synchronize(); + + const auto group = set_physical_group_of({box_1, box_2, box_3}); + ASSERT_THAT(group, Eq(std::pair<int, int>{3, 1})); +} +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/synchronize_Test.cc b/meshing/test/cppgmsh/synchronize_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..c1253b0f650889737af5b578392a4bb6714eaa37 --- /dev/null +++ b/meshing/test/cppgmsh/synchronize_Test.cc @@ -0,0 +1,43 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include <gmock/gmock.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct synchronize_Test : Test {}; + +TEST_F(synchronize_Test, synchronizes) { + const auto gmshContext = Context(0, 0, true, true); + + construct_box({0., 0., 0.}, {1., 1., 1.}); + + ASSERT_THAT(get_entities_of(3).size(), Eq(0)); + synchronize(); + ASSERT_THAT(get_entities_of(3).size(), Eq(1)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/translate_entities_Test.cc b/meshing/test/cppgmsh/translate_entities_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..681d2bb4ceb81b8f28203b230dd4f92d0bb07da7 --- /dev/null +++ b/meshing/test/cppgmsh/translate_entities_Test.cc @@ -0,0 +1,90 @@ +// © 2022 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_rectangle.h" +#include "ae108/meshing/cppgmsh/get_coords_of.h" +#include "ae108/meshing/cppgmsh/get_entities_of.h" +#include "ae108/meshing/cppgmsh/get_points_of.h" +#include "ae108/meshing/cppgmsh/synchronize.h" +#include "ae108/meshing/cppgmsh/translate_entities.h" +#include <gmock/gmock.h> +#include <math.h> + +using testing::DoubleEq; +using testing::ElementsAre; +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct translate_entities_Test : Test {}; + +TEST_F(translate_entities_Test, translates_rectangle) { + const auto gmshContext = Context(0, 0, true, true); + + const auto rectangle = construct_rectangle({0, 0, 0}, {1, 1}); + + translate_entities({rectangle}, {0.1, 0.2, 0.3}); + + synchronize(); + const auto points = get_points_of(rectangle); + std::vector<std::array<double, 3>> coords; + for (const auto &point : points) + coords.push_back(get_coords_of(point)); + + ASSERT_THAT(coords[0], + ElementsAre(DoubleEq(0.1), DoubleEq(0.2), DoubleEq(0.3))); + ASSERT_THAT(coords[1], + ElementsAre(DoubleEq(1.1), DoubleEq(0.2), DoubleEq(0.3))); + ASSERT_THAT(coords[2], + ElementsAre(DoubleEq(1.1), DoubleEq(1.2), DoubleEq(0.3))); + ASSERT_THAT(coords[3], + ElementsAre(DoubleEq(0.1), DoubleEq(1.2), DoubleEq(0.3))); +} + +TEST_F(translate_entities_Test, makes_translated_copy_of_rectangle) { + const auto gmshContext = Context(0, 0, true, true); + + const auto rectangle = construct_rectangle({0, 0, 0}, {1, 1}); + + const auto translated_rectangle = + translate_entities({rectangle}, {0.1, 0.2, 0.3}, true)[0]; + + synchronize(); + + const auto rectangles = get_entities_of(2); + ASSERT_THAT(rectangles.size(), Eq(2)); + + const auto points = get_points_of(translated_rectangle); + std::vector<std::array<double, 3>> coords; + for (const auto &point : points) + coords.push_back(get_coords_of(point)); + + ASSERT_THAT(coords[0], + ElementsAre(DoubleEq(0.1), DoubleEq(0.2), DoubleEq(0.3))); + ASSERT_THAT(coords[1], + ElementsAre(DoubleEq(1.1), DoubleEq(0.2), DoubleEq(0.3))); + ASSERT_THAT(coords[2], + ElementsAre(DoubleEq(1.1), DoubleEq(1.2), DoubleEq(0.3))); + ASSERT_THAT(coords[3], + ElementsAre(DoubleEq(0.1), DoubleEq(1.2), DoubleEq(0.3))); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/meshing/test/cppgmsh/write_file_Test.cc b/meshing/test/cppgmsh/write_file_Test.cc new file mode 100644 index 0000000000000000000000000000000000000000..5c90d0a554e132dac120f728a1341094a289b43c --- /dev/null +++ b/meshing/test/cppgmsh/write_file_Test.cc @@ -0,0 +1,124 @@ +// © 2021 ETH Zurich, Mechanics and Materials Lab +// +// ae108 is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any +// later version. +// +// ae108 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ae108. If not, see <https://www.gnu.org/licenses/>. + +#include "ae108/meshing/cppgmsh/Context.h" +#include "ae108/meshing/cppgmsh/construct_box.h" +#include "ae108/meshing/cppgmsh/extract_mesh.h" +#include "ae108/meshing/cppgmsh/generate_mesh.h" +#include "ae108/meshing/cppgmsh/read_file.h" +#include "ae108/meshing/cppgmsh/set_granularity.h" +#include "ae108/meshing/cppgmsh/write_file.h" +#include <gmock/gmock.h> +#include <gmsh.h> + +using testing::Eq; +using testing::Test; + +namespace ae108 { +namespace meshing { +namespace cppgmsh { + +struct write_file_Test : Test {}; + +TEST_F(write_file_Test, writes_step_file) { + + { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 2, 3}); + gmsh::model::occ::synchronize(); + write_file("test.stp"); + } + + const auto gmshContext = Context(0, 0); + + read_file("test.stp"); + gmsh::vectorpair dimTags; + gmsh::model::getEntities(dimTags, 3); + + ASSERT_THAT(dimTags.size(), Eq(1)); + ASSERT_THAT(dimTags[0].first, Eq(3)); + ASSERT_THAT(dimTags[0].second, Eq(1)); +} + +TEST_F(write_file_Test, writes_stl_file) { + + { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 1, 1}); + gmsh::model::occ::synchronize(); + set_granularity(1.); + generate_mesh(2, 1, 6); + write_file("test.stl"); + } + + const auto gmshContext = Context(0, 0); + + read_file("test.stl"); + const auto [positions, connectivity, mapA, mapB] = extract_mesh<2>(); + + ASSERT_THAT(positions.size(), Eq(14)); + ASSERT_THAT(connectivity.size(), Eq(24)); + ASSERT_THAT(connectivity[0].size(), Eq(3)); +} + +TEST_F(write_file_Test, writes_vtk_file) { + + { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 1, 1}); + gmsh::model::occ::synchronize(); + set_granularity(1.); + generate_mesh(3, 1, 6); + write_file("test.vtk"); + } + + const auto gmshContext = Context(0, 0); + + read_file("test.vtk"); + gmsh::model::mesh::createTopology(); + gmsh::model::mesh::classifySurfaces(0.1, true, false, 0.1); + gmsh::model::mesh::createGeometry(); + + const auto [positions, connectivity, mapA, mapB] = extract_mesh<3>(); + + ASSERT_THAT(positions.size(), Eq(14)); + ASSERT_THAT(connectivity.size(), Eq(24)); + ASSERT_THAT(connectivity[0].size(), Eq(4)); +} + +TEST_F(write_file_Test, writes_msh_file) { + + { + const auto gmshContext = Context(0, 0); + construct_box({0, 0, 0}, {1, 1, 1}); + gmsh::model::occ::synchronize(); + set_granularity(1.); + generate_mesh(3, 1, 6); + write_file("test.msh"); + } + + const auto gmshContext = Context(0, 0); + + read_file("test.msh"); + const auto [positions, connectivity, mapA, mapB] = extract_mesh<3>(); + + ASSERT_THAT(positions.size(), Eq(14)); + ASSERT_THAT(connectivity.size(), Eq(24)); + ASSERT_THAT(connectivity[0].size(), Eq(4)); +} + +} // namespace cppgmsh +} // namespace meshing +} // namespace ae108 \ No newline at end of file diff --git a/tests/examples/periodic_rve_mesh/definition.json b/tests/examples/periodic_rve_mesh/definition.json new file mode 100644 index 0000000000000000000000000000000000000000..1eeebdd04cb5989073fe0f34a0ca0bcaf6b2e133 --- /dev/null +++ b/tests/examples/periodic_rve_mesh/definition.json @@ -0,0 +1,10 @@ +{ + "executable": [ + "examples/meshing", + "ae108-examples-PeriodicRVEMesh" + ], + "compare_stdout": "numeric", + "mpi_processes": [ + 1 + ] +} \ No newline at end of file diff --git a/tests/examples/periodic_rve_mesh/references/stdout.txt b/tests/examples/periodic_rve_mesh/references/stdout.txt new file mode 100644 index 0000000000000000000000000000000000000000..0ffd4bc50e16d49eaaff5aadb435d1001b77b1ac --- /dev/null +++ b/tests/examples/periodic_rve_mesh/references/stdout.txt @@ -0,0 +1,21 @@ +# target face (9) nodes: 150 +# source face (0) nodes: 150 + +# target face (11) nodes: 139 +# source face (1) nodes: 139 + +# target face (7) nodes: 76 +# source face (2) nodes: 76 + +# target face (6) nodes: 150 +# source face (3) nodes: 150 + +# target face (10) nodes: 76 +# source face (4) nodes: 76 + +# target face (8) nodes: 161 +# source face (5) nodes: 161 + +# target face (13) nodes: 76 +# source face (12) nodes: 76 + diff --git a/tests/examples/physical_groups/definition.json b/tests/examples/physical_groups/definition.json new file mode 100644 index 0000000000000000000000000000000000000000..391bfe1b1a10df6031a50fa0c2041a0891ea777e --- /dev/null +++ b/tests/examples/physical_groups/definition.json @@ -0,0 +1,10 @@ +{ + "executable": [ + "examples/meshing", + "ae108-examples-PhysicalGroups" + ], + "compare_stdout": "numeric", + "mpi_processes": [ + 1 + ] +} \ No newline at end of file diff --git a/tests/examples/physical_groups/references/stdout.txt b/tests/examples/physical_groups/references/stdout.txt new file mode 100644 index 0000000000000000000000000000000000000000..ad936f6f57f49bf6fc4eca47e2d819a30a4f9abb --- /dev/null +++ b/tests/examples/physical_groups/references/stdout.txt @@ -0,0 +1,80 @@ +Box 1: dim = 3, tag = 1 +Box 2: dim = 3, tag = 2 +Box 3: dim = 3, tag = 3 +Groups (dim, tag): (3,1) (3,2) +Group 1, dim: 3, entities: 1 3 +Group 2, dim: 3, entities: 2 +Elements in group 1: + tag index node indides + 1 0 2 16 6 17 + 2 1 6 16 5 17 + 3 2 1 16 2 17 + 4 3 5 16 1 17 + 5 4 0 1 16 3 + 6 5 7 2 16 6 + 7 6 1 16 4 0 + 8 7 16 6 5 7 + 9 8 2 7 16 3 + 10 9 16 7 5 4 + 11 10 1 16 3 2 + 12 11 5 16 4 1 + 25 24 18 13 8 19 + 26 25 19 11 18 13 + 27 26 8 19 10 18 + 28 27 11 10 19 18 + 29 28 19 11 13 15 + 30 29 8 19 13 12 + 31 30 9 13 18 11 + 32 31 8 14 19 12 + 33 32 13 18 8 9 + 34 33 14 11 19 15 + 35 34 11 14 19 10 + 36 35 14 8 19 10 +Elements in group 2: + tag index node indides + 13 12 11 10 18 17 + 14 13 2 18 17 11 + 15 14 1 18 10 17 + 16 15 18 1 2 17 + 17 16 17 6 11 5 + 18 17 2 11 17 6 + 19 18 2 18 11 9 + 20 19 2 8 18 9 + 21 20 11 10 17 5 + 22 21 18 1 10 8 + 23 22 17 10 1 5 + 24 23 8 2 18 1 +Nodes in group 1: + tag index x y z + 1 0 0 0 0 + 2 1 0 0 0.3 + 3 2 0 1 0.3 + 4 3 0 1 0 + 5 4 1 0 0 + 6 5 1 0 0.3 + 7 6 1 1 0.3 + 8 7 1 1 0 + 17 16 0.5 0.5 0 + 18 17 0.5 0.5 0.3 + 9 8 0 0 0.7 + 10 9 0 1 0.7 + 11 10 1 0 0.7 + 12 11 1 1 0.7 + 13 12 0 0 1 + 14 13 0 1 1 + 15 14 1 0 1 + 16 15 1 1 1 + 19 18 0.5 0.5 0.7 + 20 19 0.5 0.5 1 +Nodes in group 2: + tag index x y z + 2 1 0 0 0.3 + 3 2 0 1 0.3 + 6 5 1 0 0.3 + 7 6 1 1 0.3 + 9 8 0 0 0.7 + 10 9 0 1 0.7 + 11 10 1 0 0.7 + 12 11 1 1 0.7 + 18 17 0.5 0.5 0.3 + 19 18 0.5 0.5 0.7 diff --git a/tests/examples/segment_mesh/definition.json b/tests/examples/segment_mesh/definition.json new file mode 100644 index 0000000000000000000000000000000000000000..ded8a81ae2bd0f08f5264ad8b3b892bc97d63dbc --- /dev/null +++ b/tests/examples/segment_mesh/definition.json @@ -0,0 +1,10 @@ +{ + "executable": [ + "examples/meshing", + "ae108-examples-SegmentMesh" + ], + "compare_stdout": "numeric", + "mpi_processes": [ + 1 + ] +} \ No newline at end of file diff --git a/tests/examples/segment_mesh/references/stdout.txt b/tests/examples/segment_mesh/references/stdout.txt new file mode 100644 index 0000000000000000000000000000000000000000..284c37ec43c8bc92de0ad942109c23c34eb0131e --- /dev/null +++ b/tests/examples/segment_mesh/references/stdout.txt @@ -0,0 +1,2 @@ +# points: 121 +# elements: 260 diff --git a/tests/examples/two_phase_cube/definition.json b/tests/examples/two_phase_cube/definition.json new file mode 100644 index 0000000000000000000000000000000000000000..1cc5b6bb99bc7c474830c36eebd18e2807d9cf3b --- /dev/null +++ b/tests/examples/two_phase_cube/definition.json @@ -0,0 +1,10 @@ +{ + "executable": [ + "examples/meshing", + "ae108-examples-TwoPhaseCube" + ], + "compare_stdout": "numeric", + "mpi_processes": [ + 1 + ] +} \ No newline at end of file diff --git a/tests/examples/two_phase_cube/references/stdout.txt b/tests/examples/two_phase_cube/references/stdout.txt new file mode 100644 index 0000000000000000000000000000000000000000..a3c9fcc0fc7e26a3352ca082af3a71ce740c8dbe --- /dev/null +++ b/tests/examples/two_phase_cube/references/stdout.txt @@ -0,0 +1,86 @@ +Box 1: dim = 3, tag = 1 +Box 2: dim = 3, tag = 2 +Elements in box 1: + tag index node indices + 77 0 3 0 16 12 + 78 1 1 2 17 12 + 79 2 5 1 17 14 + 80 3 6 5 17 13 + 81 4 16 3 15 7 + 82 5 16 14 0 4 + 83 6 7 13 16 4 + 84 7 2 6 17 15 + 85 8 14 16 12 17 + 86 9 12 16 15 17 + 87 10 14 16 17 13 + 88 11 16 15 17 13 + 89 12 3 16 15 12 + 90 13 12 15 2 17 + 91 14 6 17 15 13 + 92 15 5 14 17 13 + 93 16 16 15 13 7 + 94 17 14 16 13 4 + 95 18 0 14 16 12 + 96 19 1 14 12 17 + 97 20 15 6 13 7 + 98 21 15 2 3 12 + 99 22 0 14 12 1 + 100 23 13 5 14 4 +Elements in box 2: + tag index node indices + 101 24 11 10 22 19 + 102 25 2 1 17 18 + 103 26 9 8 18 22 + 104 27 1 5 17 20 + 105 28 20 22 8 10 + 106 29 6 2 17 21 + 107 30 11 22 9 21 + 108 31 5 6 17 19 + 109 32 18 22 17 21 + 110 33 18 22 20 17 + 111 34 22 20 17 19 + 112 35 21 22 17 19 + 113 36 17 2 18 21 + 114 37 22 8 18 20 + 115 38 22 18 9 21 + 116 39 1 18 20 17 + 117 40 5 17 20 19 + 118 41 21 11 22 19 + 119 42 21 17 6 19 + 120 43 20 22 10 19 + 121 44 8 1 18 20 + 122 45 2 9 18 21 + 123 46 10 5 20 19 + 124 47 21 6 11 19 +Nodes in box 1: + tag index x y z + 1 0 0 0 0 + 2 1 0 0 0.5 + 3 2 0 1 0.5 + 4 3 0 1 0 + 5 4 1 0 0 + 6 5 1 0 0.5 + 7 6 1 1 0.5 + 8 7 1 1 0 + 13 12 0 0.5 0.25 + 14 13 1 0.5 0.25 + 15 14 0.5 0 0.25 + 16 15 0.5 1 0.25 + 17 16 0.5 0.5 0 + 18 17 0.5 0.5 0.5 +Nodes in box 2: + tag index x y z + 2 1 0 0 0.5 + 3 2 0 1 0.5 + 6 5 1 0 0.5 + 7 6 1 1 0.5 + 9 8 0 0 1 + 10 9 0 1 1 + 11 10 1 0 1 + 12 11 1 1 1 + 18 17 0.5 0.5 0.5 + 19 18 0 0.5 0.75 + 20 19 1 0.5 0.75 + 21 20 0.5 0 0.75 + 22 21 0.5 1 0.75 + 23 22 0.5 0.5 1