Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
GeometrySimple.cc
Go to the documentation of this file.
2#include <algorithm>
3#include <iostream>
4
5namespace Garfield {
6
8 m_className = "GeometrySimple";
9}
10
12 // Make sure the solid and the medium are defined.
13 if (!s || !m) {
14 std::cerr << m_className << "::AddSolid: Null pointer.\n";
15 return;
16 }
17
18 // Check if this medium is already in the list
19 const unsigned int nMedia = m_media.size();
20 unsigned int n = nMedia;
21 const int id = m->GetId();
22 for (unsigned int i = 0; i < nMedia; ++i) {
23 if (id == m_media[i]->GetId()) {
24 n = i;
25 break;
26 }
27 }
28 // If the medium does not exist yet, add it to the list
29 if (n == nMedia) m_media.push_back(m);
30
31 // Update the bounding box ranges
32 double xmin, ymin, zmin;
33 double xmax, ymax, zmax;
34 if (!s->GetBoundingBox(xmin, ymin, zmin, xmax, ymax, zmax)) {
35 std::cerr << m_className << "::AddSolid: Solid has no bounding box.\n";
36 return;
37 }
38
39 if (m_hasBoundingBox) {
40 m_xMinBoundingBox = std::min(m_xMinBoundingBox, xmin);
41 m_yMinBoundingBox = std::min(m_yMinBoundingBox, ymin);
42 m_zMinBoundingBox = std::min(m_zMinBoundingBox, zmin);
43 m_xMaxBoundingBox = std::max(m_xMaxBoundingBox, xmax);
44 m_yMaxBoundingBox = std::max(m_yMaxBoundingBox, ymax);
45 m_zMaxBoundingBox = std::max(m_zMaxBoundingBox, zmax);
46 } else {
47 m_xMinBoundingBox = xmin;
48 m_yMinBoundingBox = ymin;
49 m_zMinBoundingBox = zmin;
50 m_xMaxBoundingBox = xmax;
51 m_yMaxBoundingBox = ymax;
52 m_zMaxBoundingBox = zmax;
53 m_hasBoundingBox = true;
54 }
55
56 // Add the new solid to the list.
57 m_solids.emplace_back(std::make_pair(s, n));
58}
59
60Solid* GeometrySimple::GetSolid(const double x, const double y,
61 const double z) const {
62 for (const auto& solid : m_solids) {
63 if (solid.first->IsInside(x, y, z)) return solid.first;
64 }
65 return nullptr;
66}
67
68Medium* GeometrySimple::GetMedium(const double x, const double y,
69 const double z) const {
70 for (const auto& solid : m_solids) {
71 if (solid.first->IsInside(x, y, z)) {
72 if (solid.second < 0) return nullptr;
73 return m_media[solid.second];
74 }
75 }
76 return nullptr;
77}
78
79Solid* GeometrySimple::GetSolid(const unsigned int i) const {
80 if (i >= m_solids.size()) {
81 std::cerr << m_className << "::GetSolid:\n"
82 << " Requested solid " << i << " does not exist.\n";
83 return nullptr;
84 }
85
86 return m_solids[i].first;
87}
88
89Solid* GeometrySimple::GetSolid(const unsigned int i, Medium*& medium) const {
90 if (i >= m_solids.size()) {
91 std::cerr << m_className << "::GetSolid:\n"
92 << " Requested solid " << i << " does not exist.\n";
93 return nullptr;
94 }
95
96 medium = m_media[m_solids[i].second];
97 return m_solids[i].first;
98}
99
100Medium* GeometrySimple::GetMedium(const unsigned int i) const {
101 if (i >= m_media.size()) {
102 std::cerr << m_className << "::GetMedium:\n"
103 << " Requested medium " << i << " does not exist.\n";
104 return nullptr;
105 }
106 return m_media[i];
107}
108
110 m_media.clear();
111 m_solids.clear();
112}
113
115 std::cout << m_className << "::PrintSolids:\n";
116 const unsigned int nSolids = m_solids.size();
117 if (nSolids == 1) {
118 std::cout << " 1 solid\n";
119 } else {
120 std::cout << " " << nSolids << " solids\n";
121 }
122 if (m_solids.empty()) return;
123 std::cout << " Index Type Medium\n";
124 for (unsigned int i = 0; i < nSolids; ++i) {
125 std::cout << " " << i << " ";
126 if (m_solids[i].first->IsBox()) {
127 std::cout << "box ";
128 } else if (m_solids[i].first->IsTube()) {
129 std::cout << "tube ";
130 } else if (m_solids[i].first->IsSphere()) {
131 std::cout << "sphere ";
132 } else {
133 std::cout << "unknown ";
134 }
135 std::cout << m_media[m_solids[i].second]->GetName() << "\n";
136 }
137}
138
139bool GeometrySimple::IsInside(const double x, const double y,
140 const double z) const {
141 if (!IsInBoundingBox(x, y, z)) return false;
142
143 for (const auto& solid : m_solids) {
144 if (solid.first->IsInside(x, y, z)) return true;
145 }
146 return false;
147}
148
149bool GeometrySimple::IsInBoundingBox(const double x, const double y,
150 const double z) const {
151 if (!m_hasBoundingBox) {
152 if (m_debug) {
153 std::cerr << m_className << "::IsInBoundingBox:\n"
154 << " Bounding box is not defined.\n";
155 }
156 return true;
157 }
158
159 if (x >= m_xMinBoundingBox && x <= m_xMaxBoundingBox &&
162 return true;
163 return false;
164}
165}
Abstract base class for geometry classes.
Definition: GeometryBase.hh:13
Solid * GetSolid(const unsigned int i) const override
Get a solid from the list.
bool IsInside(const double x, const double y, const double z) const override
Check if a point is inside the geometry.
std::vector< std::pair< Solid *, int > > m_solids
List of solids.
Medium * GetMedium(const double x, const double y, const double z) const override
Retrieve the medium at a given point.
bool IsInBoundingBox(const double x, const double y, const double z) const
std::vector< Medium * > m_media
List of media.
void Clear()
Reset the geometry.
bool m_debug
Switch on/off debugging messages.
void AddSolid(Solid *s, Medium *m)
Add a solid to the geometry, together with the medium inside.
GeometrySimple()
Constructor.
Abstract base class for media.
Definition: Medium.hh:13
int GetId() const
Return the id number of the class instance.
Definition: Medium.hh:21
Abstract base class for solids.
Definition: Solid.hh:28
virtual bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const =0
Return the bounding box of the solid.