PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
primitiveOccMesh.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. (See accompanying
8 * file LICENSE)
9 */
10
11#include "primitiveOccMesh.h"
12#include "gmshOccCompat.h"
13#include "geom/geomObjects.h"
15#include <algorithm>
16#include <cmath>
17#include <gmsh.h>
18#include <stdexcept>
19#include <vector>
20
21namespace mesh_gen {
22
24
25 if (c.d_r <= 0.)
26 throw std::runtime_error("buildCylinderOcc: radius must be positive.");
27 if (c.d_l <= 0.)
28 throw std::runtime_error("buildCylinderOcc: length must be positive.");
29
30 const double dx = c.d_l * c.d_xa.d_x;
31 const double dy = c.d_l * c.d_xa.d_y;
32 const double dz = c.d_l * c.d_xa.d_z;
33
34 gmsh::model::occ::addCylinder(c.d_xBegin.d_x, c.d_xBegin.d_y, c.d_xBegin.d_z, dx, dy, dz, c.d_r);
35 gmsh::model::occ::synchronize();
36}
37
38void buildEllipseOcc(const geom::Ellipse &e, double h) {
39
40 if (e.d_a <= 0. || e.d_b <= 0.)
41 throw std::runtime_error("buildEllipseOcc: semi-axes must be positive.");
42
43 const double rx = std::max(e.d_a, e.d_b);
44 const double ry = std::min(e.d_a, e.d_b);
45 double theta = e.d_theta;
46 if (e.d_a < e.d_b)
47 theta += M_PI / 2.;
48
49 const int s = addDiskOcc(e.d_x.d_x, e.d_x.d_y, e.d_x.d_z, rx, ry, theta);
50 gmsh::model::occ::synchronize();
51 const int p = gmsh::model::occ::addPoint(e.d_x.d_x, e.d_x.d_y, e.d_x.d_z, h);
52 gmsh::model::occ::synchronize();
53 gmsh::model::mesh::embed(0, {p}, 2, s);
54}
55
57
58 if (e.d_a <= 0. || e.d_b <= 0. || e.d_c <= 0.)
59 throw std::runtime_error("buildEllipsoidOcc: semi-axes must be positive.");
60
61 // Unit sphere at origin, then x' = R diag(r1,r2,r3) x + c (row-major 4×4 for gmsh).
62 double R[9];
64
65 std::vector<double> mat(16);
66 for (int i = 0; i < 3; ++i) {
67 mat[static_cast<size_t>(i * 4 + 0)] = R[i * 3 + 0] * e.d_a;
68 mat[static_cast<size_t>(i * 4 + 1)] = R[i * 3 + 1] * e.d_b;
69 mat[static_cast<size_t>(i * 4 + 2)] = R[i * 3 + 2] * e.d_c;
70 mat[static_cast<size_t>(i * 4 + 3)] = (i == 0) ? e.d_x.d_x : (i == 1) ? e.d_x.d_y : e.d_x.d_z;
71 }
72 mat[12] = mat[13] = mat[14] = 0.;
73 mat[15] = 1.;
74
75 const int v = gmsh::model::occ::addSphere(0., 0., 0., 1.);
76 gmsh::model::occ::synchronize();
77 gmsh::model::occ::affineTransform({{3, v}}, mat);
78 gmsh::model::occ::synchronize();
79 gmsh::model::occ::removeAllDuplicates();
80 gmsh::model::occ::synchronize();
81}
82
83} // namespace mesh_gen
Defines cylinder.
util::Point d_xBegin
Center point of cross-section at the beginning.
util::Point d_xa
Axis of cylinder (unit vector)
double d_l
Length.
double d_r
Radius.
Filled ellipse in the plane z = center.d_z, semi-axes in the xy plane.
double d_a
Semi-axis along local x before rotation (in-plane)
util::Point d_x
Center.
double d_b
Semi-axis along local y before rotation (in-plane)
double d_theta
Counter-clockwise rotation about +z through the center (radians)
Ellipsoid: center , semi-axes in a body frame rotated from world by axis–angle (Rodrigues)....
util::Point d_x
void ellipsoidRotationMatrix(const Ellipsoid &e, double R[9])
Row-major 3×3 rotation from ellipsoid axis–angle (identity if ).
void buildEllipsoidOcc(const geom::Ellipsoid &e)
int addDiskOcc(double xc, double yc, double zc, double rx, double ry, double theta=0.)
OCC disk compatible with older Gmsh (no zAxis/xAxis) and newer APIs.
void buildEllipseOcc(const geom::Ellipse &e, double h)
void buildCylinderOcc(const geom::Cylinder &c)
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