Garfield++ v2r0
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.
1#include <iostream>
2#include "GeometrySimple.hh"
3
4namespace Garfield {
5
7 : m_nMedia(0), m_nSolids(0),
8 m_hasBoundingBox(false), m_debug(false) {
9
10 m_className = "GeometrySimple";
11
12 m_media.clear();
13 m_solids.clear();
14}
15
17
18 // Make sure the solid and the medium are defined.
19 if (!s) {
20 std::cerr << m_className << "::AddSolid:\n";
21 std::cerr << " Solid pointer is null.\n";
22 return;
23 }
24
25 if (!m) {
26 std::cerr << m_className << "::AddSolid:\n";
27 std::cerr << " Medium pointer is null.\n";
28 return;
29 }
30
31 int n = -1;
32 int id = m->GetId();
33 // Check if this medium is already in the list
34 for (unsigned int i = 0; i < m_nMedia; ++i) {
35 if (id == m_media[i].medium->GetId()) {
36 n = i;
37 break;
38 }
39 }
40 // If the medium does not exist yet, add it to the list
41 if (n < 0) {
42 medium newMedium;
43 newMedium.medium = m;
44 m_media.push_back(newMedium);
45 n = m_nMedia;
46 ++m_nMedia;
47 }
48
49 // Update the bounding box ranges
50 double xmin, ymin, zmin;
51 double xmax, ymax, zmax;
52 if (!s->GetBoundingBox(xmin, ymin, zmin, xmax, ymax, zmax)) {
53 std::cerr << m_className << "::AddSolid:\n";
54 std::cerr << " Solid has no bounding box.\n";
55 return;
56 }
57
58 if (m_hasBoundingBox) {
59 if (xmin < m_xMinBoundingBox) m_xMinBoundingBox = xmin;
60 if (ymin < m_yMinBoundingBox) m_yMinBoundingBox = ymin;
61 if (zmin < m_zMinBoundingBox) m_zMinBoundingBox = zmin;
62 if (xmax > m_xMaxBoundingBox) m_xMaxBoundingBox = xmax;
63 if (ymax > m_yMaxBoundingBox) m_yMaxBoundingBox = ymax;
64 if (zmax > m_zMaxBoundingBox) m_zMaxBoundingBox = zmax;
65 } else {
66 m_xMinBoundingBox = xmin;
67 m_yMinBoundingBox = ymin;
68 m_zMinBoundingBox = zmin;
69 m_xMaxBoundingBox = xmax;
70 m_yMaxBoundingBox = ymax;
71 m_zMaxBoundingBox = zmax;
72 m_hasBoundingBox = true;
73 }
74
75 // Add the new solid to the list
76 solid newSolid;
77 newSolid.solid = s;
78 newSolid.medium = n;
79 m_solids.push_back(newSolid);
80 ++m_nSolids;
81}
82
83Solid* GeometrySimple::GetSolid(const double x, const double y,
84 const double z) const {
85
86 for (unsigned int i = 0; i < m_nSolids; ++i) {
87 if (m_solids[i].solid->IsInside(x, y, z)) {
88 return m_solids[i].solid;
89 }
90 }
91 return NULL;
92}
93
94Medium* GeometrySimple::GetMedium(const double x, const double y, const double z) const {
95
96 for (unsigned int i = 0; i < m_nSolids; ++i) {
97 if (m_solids[i].solid->IsInside(x, y, z)) {
98 if (m_solids[i].medium < 0) return NULL;
99 return m_media[m_solids[i].medium].medium;
100 }
101 }
102 return NULL;
103}
104
105Solid* GeometrySimple::GetSolid(const unsigned int i) const {
106
107 if (i >= m_nSolids) {
108 std::cerr << m_className << "::GetSolid:\n";
109 std::cerr << " Requested solid " << i << " does not exist.\n";
110 return NULL;
111 }
112
113 return m_solids[i].solid;
114}
115
116Medium* GeometrySimple::GetMedium(const unsigned int i) const {
117
118 if (i >= m_nMedia) {
119 std::cerr << m_className << "::GetMedium:\n";
120 std::cerr << " Requested medium " << i << " does not exist.\n";
121 return NULL;
122 }
123
124 return m_media[i].medium;
125}
126
128
129 m_media.clear();
130 m_solids.clear();
131 m_nMedia = 0;
132 m_nSolids = 0;
133}
134
136
137 std::cout << m_className << "::PrintSolids:\n";
138 if (m_nSolids == 1) {
139 std::cout << " 1 solid\n";
140 } else {
141 std::cout << " " << m_nSolids << " solids\n";
142 }
143 if (m_nSolids == 0) return;
144 std::cout << " Index Type Medium\n";
145 for (unsigned int i = 0; i < m_nSolids; ++i) {
146 std::cout << " " << i << " ";
147 if (m_solids[i].solid->IsBox()) {
148 std::cout << "box ";
149 } else if (m_solids[i].solid->IsTube()) {
150 std::cout << "tube ";
151 } else {
152 std::cout << "unknown ";
153 }
154 std::cout << m_media[m_solids[i].medium].medium->GetName() << "\n";
155 }
156}
157
158bool GeometrySimple::IsInside(const double x, const double y,
159 const double z) const {
160
161 if (!IsInBoundingBox(x, y, z)) return false;
162
163 for (unsigned int i = 0; i < m_nSolids; ++i) {
164 if (m_solids[i].solid->IsInside(x, y, z)) return true;
165 }
166 return false;
167}
168
169bool GeometrySimple::IsInBoundingBox(const double x, const double y,
170 const double z) const {
171
172 if (!m_hasBoundingBox) {
173 if (m_debug) {
174 std::cerr << m_className << "::IsInBoundingBox:\n";
175 std::cerr << " Bounding box is not defined.\n";
176 }
177 return true;
178 }
179
180 if (x >= m_xMinBoundingBox && x <= m_xMaxBoundingBox &&
181 y >= m_yMinBoundingBox && y <= m_yMaxBoundingBox &&
183 return true;
184 return false;
185}
186}
std::vector< medium > m_media
bool IsInBoundingBox(const double x, const double y, const double z) const
Medium * GetMedium(const double x, const double y, const double z) const
Solid * GetSolid(const double x, const double y, const double z) const
void AddSolid(Solid *s, Medium *m)
bool IsInside(const double x, const double y, const double z) const
std::vector< solid > m_solids
Abstract base class for media.
Definition: Medium.hh:11
int GetId() const
Definition: Medium.hh:20
Abstract base class for solids.
Definition: Solid.hh:8
virtual bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const =0
Return the bounding box of the solid.