PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
openBoundaryWalls3D.cpp
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2026 Prashant K. Jha
4 * -------------------------------------------
5 * PeriDEM https://github.com/prashjha/PeriDEM
6 *
7 * Distributed under the Boost Software License, Version 1.0.
8 */
9
10#include "openBoundaryWalls3D.h"
11#include <algorithm>
12#include <cmath>
13#include <gmsh.h>
14#include <vector>
15
16namespace mesh_gen {
17
18namespace {
19
21double minEdge2D(double dx, double dy, double dz) {
22 const double a = std::min({dx, dy, dz});
23 return a;
24}
25
26double maxEdge2D(double dx, double dy, double dz) {
27 return std::max({dx, dy, dz});
28}
29
30} // namespace
31
32void physicalGroupsWallOpenFromFace3D(int volumeTag, int openFace, const util::Point &lo,
33 const util::Point &hi, double t, double tol,
34 const std::string &physWall, const std::string &physOpen) {
35
36 const double x0 = lo.d_x, y0 = lo.d_y, z0 = lo.d_z;
37 const double x1 = hi.d_x, y1 = hi.d_y, z1 = hi.d_z;
38 const double Lx = x1 - x0;
39 const double Ly = y1 - y0;
40 const double Lz = z1 - z0;
41 const double horizTol = std::max(tol, 1.0e-9 * std::max({Lx, Ly, Lz, 1.0}));
42
43 std::vector<std::pair<int, int>> bnd;
44 // Request unoriented boundary entities so tags are always valid entity IDs.
45 gmsh::model::getBoundary({{3, volumeTag}}, bnd, false, false);
46
47 std::vector<int> wallTags;
48 std::vector<int> openTags;
49 wallTags.reserve(bnd.size());
50 openTags.reserve(bnd.size());
51
52 for (const auto &pr : bnd) {
53 if (pr.first != 2)
54 continue;
55 const int surfTag = std::abs(pr.second);
56 double xmin = 0., ymin = 0., zmin = 0., xmax = 0., ymax = 0., zmax = 0.;
57 gmsh::model::getBoundingBox(pr.first, surfTag, xmin, ymin, zmin, xmax, ymax, zmax);
58 const double dx = xmax - xmin;
59 const double dy = ymax - ymin;
60 const double dz = zmax - zmin;
61 const double cx = 0.5 * (xmin + xmax);
62 const double cy = 0.5 * (ymin + ymax);
63 const double cz = 0.5 * (zmin + zmax);
64 const double emin = minEdge2D(dx, dy, dz);
65 const double emax = maxEdge2D(dx, dy, dz);
66 const bool thin = emin < horizTol * std::max(1.0, 0.1 * emax);
67
68 bool isOpen = false;
69 if (thin) {
70 switch (openFace) {
71 case 0: // +x
72 isOpen = cx > x1 - t - 2. * horizTol && std::abs(dx - t) < 0.25 * t + horizTol;
73 break;
74 case 1: // -x
75 isOpen = cx < x0 + t + 2. * horizTol && std::abs(dx - t) < 0.25 * t + horizTol;
76 break;
77 case 2: // +y
78 isOpen = cy > y1 - t - 2. * horizTol && std::abs(dy - t) < 0.25 * t + horizTol;
79 break;
80 case 3: // -y
81 isOpen = cy < y0 + t + 2. * horizTol && std::abs(dy - t) < 0.25 * t + horizTol;
82 break;
83 case 4: // +z — opening at top: rim / horizontal faces near z1 or cavity top
84 isOpen = cz > z1 - t - 2. * horizTol && dz < horizTol * 10.;
85 break;
86 case 5: // -z
87 isOpen = cz < z0 + t + 2. * horizTol && dz < horizTol * 10.;
88 break;
89 default:
90 break;
91 }
92 }
93
94 if (isOpen)
95 openTags.push_back(surfTag);
96 else
97 wallTags.push_back(surfTag);
98 }
99
100 if (!wallTags.empty()) {
101 const int g = gmsh::model::addPhysicalGroup(2, wallTags, -1);
102 gmsh::model::setPhysicalName(2, g, physWall);
103 }
104 if (!openTags.empty()) {
105 const int g = gmsh::model::addPhysicalGroup(2, openTags, -1);
106 gmsh::model::setPhysicalName(2, g, physOpen);
107 }
108}
109
110} // namespace mesh_gen
void physicalGroupsWallOpenFromFace3D(int volumeTag, int openFace, const util::Point &lo, const util::Point &hi, double t, double tol, const std::string &physWall, const std::string &physOpen)
A structure to represent 3d vectors.
Definition point.h:30
double d_y
the y coordinate
Definition point.h:36
double d_z
the z coordinate
Definition point.h:39
double d_x
the x coordinate
Definition point.h:33