DLG4::VolumeBuilders
A fluent interface for Geant4 geometry definition.
Loading...
Searching...
No Matches
RZBuilder.cc
Go to the documentation of this file.
1/*
2 * VolumeMaker.cc
3 *
4 * Created on: Jun 29, 2024
5 * Author: D. S. Leonard
6 */
7// Presently includes src for VolumeMaker and GeantMultiPlane classes
8// See header for documentation.
9
10#include "RZBuilder.hh"
11#include <string>
12#include <VolumeBuilderTypes.hh>
13#include <G4Polycone.hh>
14#include <G4Polyhedra.hh>
15//#include "disableable_shared_from_this.hh"
16#include "i_shared_ptr.hh"
17#include "StructureBuilder.hh"
18#include "StructureBuilder.hpp"
19
20class G4String;
21using namespace DLG4::Utilities;
22
23//GeantMultiPlane methods //////////////////////////////////////////////////
24namespace DLG4::VolumeBuilders {
25 //Factories
26 RZBuilderPtr CreatePolyconeBuilder(const G4String &name, G4double phi_start, G4double phi_tot) {
27 // We could actually construct these as RZBuilderPtr without using new, vis i_shared_ptr constructor.
28 // But maybe we can unfriend i_shared_ptr in the future if we use new here, and avoid exposing
29 // a backdoor to the general ctor, which doesn't select a MakeSolidFunctionPtr.
30 // ReSharper disable once CppDFAMemoryLeak
31 auto object = RZBuilderPtr(new RZBuilder(name, phi_start, phi_tot, 0));
32 object->MakeSolidFunctionPtr_ = &RZBuilder::MakePolycone;
33 return RZBuilderPtr(object);
34 }
35
36 RZBuilderPtr CreatePolyhedraBuilder(const G4String &name, int sides, G4double phi_start,
37 G4double phi_tot) {
38 // ReSharper disable once CppDFAMemoryLeak
39 auto object = new RZBuilder(name, phi_start, phi_tot, sides);
40 object->MakeSolidFunctionPtr_ = &RZBuilder::MakePolyhedra;
41 return RZBuilderPtr(object);
42 }
43
45 G4double unit, const G4String &name, G4double endz, G4double h, G4double OR, G4double IR) {
46 // ReSharper disable once CppDFAMemoryLeak
47 auto object = RZBuilderPtr(new RZBuilder(name));
48 object->MakeSolidFunctionPtr_ = &RZBuilder::MakePolycone;
49 RZPlane plane;
50 plane.unit = unit;
51 plane.z = endz;
52 plane.IR = IR;
53 plane.OR = OR;
54 object->AddPlane(plane);
55 plane.z += h;
56 object->AddPlane(plane);
57 return RZBuilderPtr(object);
58 }
59
60 RZBuilderPtr CreateCylinderBuilder(const G4String &name, G4double endz, G4double h, G4double OR,
61 G4double IR) {
63 }
64
65 RZBuilder::RZBuilder(const G4String &name, G4double init_phi_start, G4double init_phi_tot,
66 int init_sides) :
67 VolumeBuilder<RZBuilder>(), sides_(init_sides), phi_start_deg_(init_phi_start),
68 phi_tot_deg(init_phi_tot) {
70 SetName(name);
72 }
73
74 //Private default copy ctor.
75 //This is used by clone methods of concrete classes
76 RZBuilder::RZBuilder(const RZBuilder &other) :
77 VolumeBuilder<RZBuilder>(other), // Call base class copy constructor
78 sides_(other.sides_), phi_start_deg_(other.phi_start_deg_), phi_tot_deg(other.phi_tot_deg),
79 num_planes_(other.num_planes_), z_(other.z_), IR_(other.IR_), OR_(other.OR_),
80 MakeSolidFunctionPtr_(other.MakeSolidFunctionPtr_) {
82 SetName(other.GetBuilderName());
84 }
85
86
88 if (solid_ptr_) {
89 throw std::runtime_error("Error in RZBuilder::FillSolidConfig\"\n"
90 "Cannot fill a solid builder CONFIGURATION, when the solid is already built from it."
91 "Use ForkAndReset(\"new_name\") first to get an unbuilt copy.\n\n");
92 }
93
94 // set all ID's to 0.
95 for (int i = 0; i < num_planes_; i++) {
96 this->IR_[i] = 0;
97 }
98 return this->shared_from_this();
99 }
100
101
103 if (solid_ptr_) {
104 throw std::runtime_error("Error in RZBuilder::ReflectZSolidConfig\"\n"
105 "Cannot flip a solid builder CONFIGURATION, when the solid is already built from it.\n"
106 "Use ReflectZFinalSolidCopy(\"new_name\") instead to copy and flip the solid.\n\n");
107 }
108 // Mirror z values
109 for (int i = 0; i < num_planes_; i++) {
110 this->z_[i] = -this->z_[i];
111 }
112 return this->shared_from_this();
113 }
114
116 if (MakeSolidFunctionPtr_ == &RZBuilder::MakePolyhedra) {
117 sides_ = n;
118 } else {
119 G4cout <<
120 "Warning in RZBuilder: Calling SetNumSides() on a builder that makes round things"
121 << " might be as clever as giving a balloon to a hedgehog. \n Ignoring call." <<
122 G4endl;
123 }
124 return shared_from_this();
125 }
126
127 // Overloads are handled a lot more implicitly in VolumeBuilder, but it would all have to be redone
128 // here since the vector parameter names need to be different.
129 // overload to take direct values
131 if (plane.IR < 0 || plane.OR < 0) {
132 throw std::runtime_error("Error in RZBuilder::AddPlane()"
133 " for builder " + GetBuilderName() + ".\n"
134 "IR and OR must be non-negative.");
135 }
136 IR_.push_back(plane.IR * plane.unit);
137 OR_.push_back(plane.OR * plane.unit);
138 z_.push_back(plane.z * plane.unit);
139 num_planes_++;
140 return shared_from_this();
141 }
142
143 RZBuilderPtr RZBuilder::AddPlane(G4double unit, G4double IR, G4double OR, G4double z) {
144 auto plane = RZPlane{unit, IR, OR, z};
145 return AddPlane(plane);
146 }
147
148 // overload to take direct values with default unit
149 RZBuilderPtr RZBuilder::AddPlane(G4double IR, G4double OR, G4double z) {
150 auto plane = RZPlane{GetEffectiveDefaultUnit(), IR, OR, z};
151 return AddPlane(plane);
152 }
153
154 //Overloads for adding multiple planes at once:
155 // 1. Vector of full RZPlane objects (each with their own units)
156 RZBuilderPtr RZBuilder::AddPlanes(const std::vector<RZPlane> &planes) {
157 for (const auto &plane : planes) {
158 AddPlane(plane);
159 }
160 return shared_from_this();
161 }
162
163 // 2. Unitless planes using builder's preset default unit
164 RZBuilderPtr RZBuilder::AddPlanes(const std::vector<RZPlaneUnitless> &planes) {
165 for (const auto &plane : planes) {
166 G4double unit = this->GetEffectiveDefaultUnit();
167 auto rzplane = RZPlane{unit, plane.IR, plane.OR, plane.z};
168 AddPlane(rzplane);
169 }
170 return shared_from_this();
171 }
172
173 // 3. Most compact - one unit for all planes
174 RZBuilderPtr RZBuilder::AddPlanes(G4double unit, const std::vector<RZPlaneUnitless> &planes) {
175 for (const auto &plane : planes) {
176 auto rzplane = RZPlane{unit, plane.IR, plane.OR, plane.z};
177 AddPlane(rzplane);
178 }
179 return shared_from_this();
180 }
181
182
183 G4VSolid *RZBuilder::MakePolycone(const G4String &name) {
184 if (this->solid_ptr_.get() != nullptr) {
185 std::string error = "Error in MakePolycone: A solid was already built\n"
186 "You can copy and rename the builder to reset it and build again.";
187 throw std::runtime_error(error);
188 }
189 G4cout << G4endl;
190 G4cout << "New Polycone:" << GetBuilderName() << " phi_start: " << phi_start_deg_ <<
191 " degrees, phi_tot: " << phi_tot_deg
192 << " degrees" << G4endl;
193 for (int i = 0; i < z_.size(); i++) {
194 G4cout << "z: " << z_[i] << " IR: " << IR_[i] << " OR: " << OR_[i] << G4endl;
195 }
196 auto retval = new G4Polycone(
197 name, phi_start_deg_ * CLHEP::deg, phi_tot_deg * CLHEP::deg, num_planes_, z_.data(),
198 IR_.data(),
199 OR_.data());
200 return retval;
201 }
202
203 G4VSolid *RZBuilder::MakePolyhedra(const G4String &name) {
204 if (this->solid_ptr_.get() != nullptr) {
205 std::string error = "Error in MakePolyhedra: A solid was already built\n"
206 "You can copy and rename the builder to reset it and build again.";
207 throw std::runtime_error(error);
208 }
209 G4cout << G4endl;
210 G4cout << "New Polyhedra:" << GetBuilderName() << " with " << sides_ << " sides, "
211 << " phi_start: " << phi_start_deg_ << " degrees, phi_tot: " << phi_tot_deg <<
212 " degrees" << G4endl;
213 for (int i = 0; i < z_.size(); i++) {
214 G4cout << "z: " << z_[i] << " IR: " << IR_[i] << " OR: " << OR_[i] << G4endl;
215 }
216 auto retval = new G4Polyhedra(
217 name, phi_start_deg_ * CLHEP::deg, phi_tot_deg * CLHEP::deg, sides_, num_planes_,
218 z_.data(),
219 IR_.data(), OR_.data());
220 return retval;
221 }
222
223
224 // Could use a displaced box macro too...
225 // Can use something like G4VSolid *displacedBox = new G4DisplacedSolid("displacedBox",aBox,rotvet,G4ThreeVector(x,y,z));
226 // But I had issues making that work in the past.
227 // Probably should just have a separate class, no need for z planes.
228
229 // Development notes:
230 // Presently, no deletion is done. It's assumed this is used in a typical sloppy environment where the geometry generator has no
231 // instance lifetime so cannot manage lifetime of its generated things.
232 // However, we could add an optional "take_ownership" flag that signals the builder should delete all its owned Geant things.
233 // We'd need a move constructor for the return by value in the methods, or the internal copy would delete the resources.
234 // This avoids the user messing with unique_ptrs and doesn't require a change in user code.
235 // We'd need to track all volumes used in unions, and decide if we own materials or not (probably not).
236 // Could copy them, but then I think they need new names in geant.
237 // Anyway, this can all be done without breaking anything.
238}
Builder class for RZ mult-plane defined solids.
Definition RZBuilder.hh:132
VolumeBuilder: Common functionality for volume builder classes.
DerivedPtr SetName(const G4String &name)
SetName Sets name used for solid and derived product names.
A wrapper for std::shared_ptr that allows and facilitates many implicit(i) type conversions.
RZBuilderPtr CreatePolyhedraBuilder(const G4String &name, int sides, G4double phi_start=0., G4double phi_tot=360)
Create a builder for associated IR,OR,Z defined object.
Definition RZBuilder.cc:36
RZBuilderPtr CreateCylinderBuilder(G4double unit, const G4String &name, G4double endz, G4double height, G4double OR, G4double IR=0)
Create a simple cylinder builder.
Definition RZBuilder.cc:44
RZBuilderPtr CreatePolyconeBuilder(const G4String &name, G4double phi_start=0., G4double phi_tot=360)
Create a builder for associated IR,OR,Z defined object.
Definition RZBuilder.cc:26
RZBuilderPtr ReflectZSolidConfig()
Flip Solid Configuration.
Definition RZBuilder.cc:102
virtual RZBuilderPtr SetNumSides(G4double N)
Set number of sides.
Definition RZBuilder.cc:115
RZBuilderPtr AddPlane(const RZPlane &plane)
Adds a plane defining one IR,OR,Z triplet in the volume design.
Definition RZBuilder.cc:130
RZBuilderPtr AddPlanes(const std::vector< RZPlane > &planes)
Adds multiple RZ planes each defining one unit,IR,OR,Z set in the volume design.
Definition RZBuilder.cc:156
RZBuilderPtr FillSolidConfig()
Modifies a Solid CONFIGURATION to set all inner diameters (IDs) to 0.
Definition RZBuilder.cc:87
G4double GetEffectiveDefaultUnit() const
Get the builder default unit or global if not set.
SharedPtr< RZBuilder > RZBuilderPtr
Definition RZBuilder.hh:68
Struct for adding planes to GeantMultiPlane –DSLeonard 2024 Overloads make this not strictly needed.
Definition RZBuilder.hh:44