Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G3Division.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id$
28//
29// by I.Hrivnacova, V.Berejnoi 13.10.99
30
31#include "G3Division.hh"
32#include "G3VolTableEntry.hh"
33#include "G3toG4MakeSolid.hh"
34#include "G4Para.hh"
35#include "G3Pos.hh"
36#include "G4SystemOfUnits.hh"
37#include "G4LogicalVolume.hh"
38#include "G4VPhysicalVolume.hh"
39#include "G4PVPlacement.hh"
40#include "G4PVReplica.hh"
41#ifndef G3G4_NO_REFLECTION
43#endif
44
46 G4double Rpar[], G4int npar);
47
49 G3VolTableEntry* mvte, G4int nofDivisions,
50 G4int iaxis, G4int nmed, G4double c0, G4double step)
51 : fType(type),
52 fVTE(vte),
53 fMVTE(mvte),
54 fNofDivisions(nofDivisions),
55 fIAxis(iaxis),
56 fNmed(nmed),
57 fC0(c0),
58 fStep(step),
59 fLowRange(0.),
60 fHighRange(0.),
61 fWidth(0.),
62 fOffset(0.),
63 fAxis(kXAxis)
64{
65 fVTE->SetHasNegPars(true);
66}
67
69 const G3Division& division)
70 : fVTE(vte),
71 fMVTE(mvte)
72{
73 // only "input" parameters are copied from division
74 fType = division.fType;
75 fNofDivisions = division.fNofDivisions;
76 fIAxis = division.fIAxis;
77 fNmed = division.fNmed;
78 fC0 = division.fC0;
79 fStep = division.fStep;
80
81 // other parameters are set as in standard constructor
82 fLowRange = 0.;
83 fHighRange = 0.;
84 fWidth = 0.;
85 fOffset = 0.;
86 fAxis = kXAxis;
87 fVTE->SetHasNegPars(true);
88}
89
91{}
92
93// public methods
94
96{
97 if (fVTE->HasNegPars() && !(fMVTE->HasNegPars())) {
98
99 // set nmed from mother
100 if (fNmed == 0) fNmed = fMVTE->GetNmed();
101 fVTE->SetNmed(fNmed);
102
103 SetRangeAndAxis();
104
105 // create envelope (if necessary)
106 // and solid
107 G3VolTableEntry* envVTE = 0;
108 if (fType == kDvn) envVTE = Dvn();
109 else if (fType == kDvn2) envVTE = Dvn2();
110 else if (fType == kDvt) envVTE = Dvt();
111 else if (fType == kDvt2) envVTE = Dvt2();
112
113 if (envVTE) {
114 // reset mother <-> daughter
115 fMVTE->ReplaceDaughter(fVTE, envVTE);
116 fVTE->ReplaceMother(fMVTE, envVTE);
117 envVTE->AddDaughter(fVTE);
118 envVTE->AddMother(fMVTE);
119
120 // replace mother with envelope
121 fMVTE = envVTE;
122 }
123 }
124}
125
127{
128 G4String name = fVTE->GetName();
129 G4LogicalVolume* lv = fVTE->GetLV();
130 G4LogicalVolume* mlv = fMVTE->GetLV();
131
132 G4String shape = fMVTE->GetShape();
133 if (shape == "PARA") {
134 // The para volume cannot be replicated using G4PVReplica.
135 // (Replicating a volume along a cartesian axis means "slicing" it
136 // with slices -perpendicular- to that axis.)
137
138 // position the replicated elements
139 for (G4int i=0; i<fNofDivisions; i++) {
141 position[fIAxis-1] = fLowRange + fWidth/2. + i*fWidth;
142 if (position.y()!=0.)
143 position.setX(position.y()*((G4Para*)lv->GetSolid())->GetTanAlpha());
144
145 #ifndef G3G4_NO_REFLECTION
147 ->Place(G4Translate3D(position), name, lv, mlv, 0, i);
148
149 #else
150 new G4PVPlacement(0, position, lv, name, mlv, 0, i);
151
152 #endif
153 }
154
155 // G4PVReplica cannot be created
156 return;
157 }
158
159 #ifdef G3G4DEBUG
160 G4cout << "Create G4PVReplica name " << name << " logical volume name "
161 << lv->GetName() << " mother logical volme name "
162 << mlv->GetName() << " axis " << fAxis << " ndivisions "
163 << fNofDivisions << " width " << fWidth << " Offset "
164 << fOffset << G4endl;
165 #endif
166
167 #ifndef G3G4_NO_REFLECTION
169 ->Replicate(name, lv, mlv, fAxis, fNofDivisions, fWidth, fOffset);
170
171 #else
172 new G4PVReplica(name, lv, mlv, fAxis, fNofDivisions, fWidth, fOffset);
173
174 #endif
175}
176
177// private methods
178
179void G3Division::Exception(G4String where, G4String what)
180{
181 G4String err_message = "G3Division::" + where + " for "
182 + what + " is not implemented";
183 G4Exception("G3Division::Exception()", "G3toG40004",
184 FatalException, err_message);
185 return;
186}
187
188void G3Division::SetRangeAndAxis()
189// set fHighRange, fLowRange, fAxis
190{
191 G4String shape = fMVTE->GetShape();
192 G4double *Rpar = fMVTE->GetRpar();
193
194 switch (fIAxis) {
195 case 1: fAxis = kXAxis;
196 break;
197 case 2: fAxis = kYAxis;
198 break;
199 case 3: fAxis = kZAxis;
200 break;
201 default: G4Exception("G3Division::SetRangeAndAxis()", "G3toG40005",
202 FatalException, "Wrong iaxis defenition!");
203 }
204
205 if ( shape == "BOX" ) {
206 fHighRange = Rpar[fIAxis-1]*cm;
207 fLowRange = -fHighRange;
208 }
209 else if ( shape == "TRD1" ) {
210 if (fIAxis == 1){
211 fHighRange = std::max(Rpar[0]*cm, Rpar[1]*cm);
212 }
213 else if( fIAxis == 2) {
214 fHighRange = Rpar[2]*cm;
215 }
216 else if( fIAxis == 3) {
217 fHighRange = Rpar[3]*cm;
218 }
219 fLowRange = - fHighRange;
220 }
221 else if ( shape == "TRD2" ) {
222 if (fIAxis == 1){
223 fHighRange = std::max(Rpar[0]*cm, Rpar[1]*cm);
224 }
225 else if( fIAxis == 2) {
226 fHighRange = std::max(Rpar[2]*cm, Rpar[3]*cm);
227 }
228 else if( fIAxis == 3) {
229 fHighRange = Rpar[4]*cm;
230 }
231 }
232 else if ( shape == "TRAP" ) {
233 if ( fIAxis == 3 ) fHighRange = Rpar[0]*cm;
234 else fHighRange = 0.;
235 fLowRange = -fHighRange;
236 }
237 else if ( shape == "TUBE" ) {
238 if (fIAxis == 1){
239 fHighRange = Rpar[1]*cm;
240 fLowRange = Rpar[0]*cm;
241 fAxis = kRho;
242 }
243 else if( fIAxis == 2) {
244 fHighRange = 360.*deg;
245 fLowRange = 0.;
246 fAxis = kPhi;
247 }
248 else if( fIAxis == 3) {
249 fHighRange = Rpar[2]*cm;
250 fLowRange = -fHighRange;
251 }
252 }
253 else if ( shape == "TUBS" ) {
254 if (fIAxis == 1){
255 fHighRange = Rpar[1]*cm;
256 fLowRange = Rpar[0]*cm;
257 fAxis = kRho;
258 }
259 else if( fIAxis == 2) {
260
261 fLowRange = Rpar[3]*deg;
262 fHighRange = Rpar[4]*deg - fLowRange;
263 if ( Rpar[4]*deg <= fLowRange )fHighRange = fHighRange + 360.*deg;
264 fHighRange = fHighRange + fLowRange;
265 fAxis = kPhi;
266 }
267 else if( fIAxis == 3) {
268 fHighRange = Rpar[2]*cm;
269 fLowRange = -fHighRange;
270 }
271 }
272 else if ( shape == "CONE" ) {
273 if (fIAxis == 1){
274 fHighRange = std::max(Rpar[2]*cm,Rpar[4]*cm);
275 fLowRange = std::max(Rpar[1]*cm,Rpar[3]*cm);
276 fAxis = kRho;
277 }
278 else if( fIAxis == 2) {
279
280 fLowRange = 0.;
281 fHighRange = 360.*deg;
282 fAxis = kPhi;
283 }
284 else if( fIAxis == 3) {
285 fHighRange = Rpar[0]*cm;
286 fLowRange = -fHighRange;
287 }
288 }
289 else if ( shape == "CONS" ) {
290 if (fIAxis == 1){
291 fHighRange = std::max(Rpar[2]*cm,Rpar[4]*cm);
292 fLowRange = std::max(Rpar[1]*cm,Rpar[3]*cm);
293 fAxis = kRho;
294 }
295 else if( fIAxis == 2) {
296
297 fLowRange = Rpar[5]*deg;
298 fHighRange = Rpar[6]*deg - fLowRange;
299 if ( Rpar[6]*deg <= fLowRange )fHighRange = fHighRange + 360.*deg;
300 fHighRange = fHighRange + fLowRange;
301 fAxis = kPhi;
302 }
303 else if( fIAxis == 3) {
304 fHighRange = Rpar[2]*cm;
305 fLowRange = -fHighRange;
306 }
307 }
308 else if ( shape == "SPHE" ) {
309 if (fIAxis == 1){
310 fHighRange = Rpar[1]*cm;
311 fLowRange = Rpar[0]*cm;
312 fAxis = kRho;
313 }
314 else if( fIAxis == 2) {
315 fLowRange = std::min(Rpar[2]*deg,Rpar[3]*deg);
316 fHighRange = std::max(Rpar[2]*deg,Rpar[3]*deg);
317 fAxis = kPhi;
318 }
319 else if( fIAxis == 3) {
320 fLowRange = std::min(Rpar[4]*deg,Rpar[5]*deg);
321 fHighRange = std::max(Rpar[4]*deg,Rpar[5]*deg);
322 fAxis = kPhi; // ??????
323 }
324 }
325 else if ( shape == "PARA" ) {
326 fHighRange = Rpar[fIAxis-1]*cm;
327 fLowRange = -fHighRange;
328 }
329 else if ( shape == "PGON" ) {
330 G4int i;
331 G4int nz = G4int(Rpar[3]);
332
333 G4double pPhi1 = Rpar[0]*deg;
334 G4double dPhi = Rpar[1]*deg;
335
336 G4double *DzArray = new G4double[nz];
337 G4double *Rmax = new G4double[nz];
338 G4double *Rmin = new G4double[nz];
339 G4double rangehi[3], rangelo[3];
340 rangehi[0] = -kInfinity ;
341 rangelo[0] = kInfinity ;
342 rangehi[2] = -kInfinity ;
343 rangelo[2] = kInfinity ;
344
345 for(i=0; i<nz; i++)
346 {
347 G4int i4=3*i+4;
348 G4int i5=i4+1;
349 G4int i6=i4+2;
350
351 DzArray[i] = Rpar[i4]*cm;
352 Rmin[i] = Rpar[i5]*cm;
353 Rmax[i] = Rpar[i6]*cm;
354 rangelo[0] = std::min(rangelo[0], Rmin[i]);
355 rangehi[0] = std::max(rangehi[0], Rmax[i]);
356 rangelo[2] = std::min(rangelo[2], DzArray[i]);
357 rangehi[2] = std::max(rangehi[2], DzArray[i]);
358 }
359 for (i=0;i<nz;i++){
360 assert(Rmin[i]>=0 && Rmax[i]>=Rmin[i]);
361 }
362 rangehi[1] = pPhi1 + dPhi;
363 rangelo[1] = pPhi1;
364 fHighRange = rangehi[fIAxis-1];
365 fLowRange = rangelo[fIAxis-1];
366 if (fIAxis == 1)fAxis = kRho;
367 else if (fIAxis == 2)fAxis = kPhi;
368 else if (fIAxis == 3)fAxis = kZAxis;
369
370 delete [] DzArray;
371 delete [] Rmin;
372 delete [] Rmax;
373
374 }
375 else if ( shape == "PCON" ) {
376
377 G4int i;
378 G4double pPhi1 = Rpar[0]*deg;
379 G4double dPhi = Rpar[1]*deg;
380 G4int nz = G4int(Rpar[2]);
381
382 G4double *DzArray = new G4double[nz];
383 G4double *Rmax = new G4double[nz];
384 G4double *Rmin = new G4double[nz];
385 G4double rangehi[3],rangelo[3];
386
387 rangehi[0] = -kInfinity ;
388 rangelo[0] = kInfinity ;
389 rangehi[2] = -kInfinity ;
390 rangelo[2] = kInfinity ;
391
392 for(i=0; i<nz; i++){
393 G4int i4=3*i+3;
394 G4int i5=i4+1;
395 G4int i6=i4+2;
396
397 DzArray[i] = Rpar[i4]*cm;
398 Rmin[i] = Rpar[i5]*cm;
399 Rmax[i] = Rpar[i6]*cm;
400 rangelo[0] = std::min(rangelo[0], Rmin[i]);
401 rangehi[0] = std::max(rangehi[0], Rmax[i]);
402 rangelo[2] = std::min(rangelo[2], DzArray[i]);
403 rangehi[2] = std::max(rangehi[2], DzArray[i]);
404 }
405 for (i=0;i<nz;i++){
406 assert(Rmin[i]>=0 && Rmax[i]>=Rmin[i]);
407 }
408 rangehi[1] = pPhi1 + dPhi;
409 rangelo[1] = pPhi1;
410 fHighRange = rangehi[fIAxis-1];
411 fLowRange = rangelo[fIAxis-1];
412 if (fIAxis == 1)fAxis = kRho;
413 else if (fIAxis == 2)fAxis = kPhi;
414 else if (fIAxis == 3)fAxis = kZAxis;
415
416
417 delete [] DzArray;
418 delete [] Rmin;
419 delete [] Rmax;
420 }
421 else if ( shape == "ELTU" || shape == "HYPE" || shape == "GTRA" ||
422 shape == "CTUB") {
423 Exception("SetRangeAndAxis", shape);
424 }
425 else {
426 Exception("SetRangeAndAxis", "Unknown shape" + shape);
427 }
428
429 // verbose
430 #ifdef G3G4DEBUG
431 G4cout << "Shape " << shape << " SetRangeAndAxis: "
432 << fLowRange << " " << fHighRange << " " << fAxis << G4endl;
433 #endif
434}
435
436G3VolTableEntry* G3Division::CreateEnvelope(G4String shape, G4double hi,
437 G4double lo, G4double par[], G4int npar)
438// create new VTE with G3Pos corresponding to the
439// envelope of divided volume
440{
441 // verbose
442 // G4cout << " G3Division::CreateEnvelope " << "fIAaxis= " << fIAxis
443 // << " hi= " << hi
444 // << " lo= " << lo
445 // << G4endl;
446
447 G4double *Rpar = new G4double[npar+2];
448 for (G4int i=0; i<npar; ++i){ Rpar[i] = par[i];}
449 G4double pos[3] = {0.,0.,0.};
450
451 if ( shape == "BOX" ) {
452 Rpar[fIAxis-1] = (hi - lo)/2./cm;
453 pos [fIAxis-1] = (hi + lo)/2.;
454 }
455 else if ( shape == "TRD1" ) {
456 if ( fIAxis == 1 || fIAxis == 2 ) {
457 Exception("CreateEnvelope","TRD1-x,y");
458 }
459 else if ( fIAxis == 3 ) {
460 // x = x1 + (c-z1)(x2 -x1)/(z2-z1)
461 G4double tn, x1, z1;
462 tn = (Rpar[1] - Rpar[0])/(2.* Rpar[3]);
463 x1 = Rpar[0]; z1 = -Rpar[3];
464 Rpar[0] = x1 + tn * (lo/cm - z1);
465 Rpar[1] = x1 + tn * (hi/cm - z1);
466 Rpar[3] = (hi - lo)/2./cm;
467 pos[2] = (hi + lo)/2.;
468 }
469 }
470 else if ( shape == "TRD2" ) {
471 if ( fIAxis == 1 || fIAxis == 2) {
472 Exception("CreateEnvelope","TRD2-x,y");
473 }
474 else if ( fIAxis == 3 ) {
475 // x = x1 + (c-z1)(x2 -x1)/(z2-z1)
476 // y = y1 + (c-z1)(y2 -y1)/(z2-z1)
477 G4double tn1, tn2, x1, y1, z1;
478 tn1 = (Rpar[1] - Rpar[0])/(2.* Rpar[4]);
479 tn2 = (Rpar[3] - Rpar[2])/(2.* Rpar[4]);
480 x1 = Rpar[0]; y1 = Rpar[2]; z1 = -Rpar[3];
481 Rpar[0] = x1 + tn1 * (lo/cm - z1);
482 Rpar[1] = x1 + tn1 * (hi/cm - z1);
483 Rpar[2] = y1 + tn2 * (lo/cm - z1);
484 Rpar[3] = y1 + tn2 * (hi/cm - z1);
485 Rpar[4] = (hi - lo)/2./cm;
486 pos[2] = (hi + lo)/2.;
487 }
488 }
489 else if ( shape == "TRAP" ) {
490 Exception("CreateEnvelope","TRAP-x,y,z");
491 }
492 else if ( shape == "TUBE" ) {
493 if ( fIAxis == 1 ) {
494 Rpar[0] = lo/cm;
495 Rpar[1] = hi/cm;
496 }
497 else if ( fIAxis == 2 ) {
498 Rpar[3] = lo/deg;
499 Rpar[4] = hi/deg;
500 npar = npar + 2;
501 shape = "TUBS";
502 }
503 else if ( fIAxis == 3 ) {
504 Rpar[2] = (hi - lo)/2./cm;
505 pos [2] = (hi + lo)/2.;
506 }
507 }
508 else if ( shape == "TUBS" ) {
509 if ( fIAxis == 1 ) {
510 Rpar[0] = lo/cm;
511 Rpar[1] = hi/cm;
512 }
513 else if ( fIAxis == 2 ) {
514 Rpar[3] = lo/deg;
515 Rpar[4] = hi/deg;
516 }
517 else if ( fIAxis == 3 ) {
518 Rpar[2] = (hi - lo)/2./cm;
519 pos [2] = (hi + lo)/2.;
520 }
521 }
522 else if ( shape == "CONE" ) {
523 if ( fIAxis == 1) {
524 Exception("CreateEnvelope","CONE-x,z");
525 }
526 else if ( fIAxis == 2 ) {
527 Rpar[5] = lo/deg;
528 Rpar[6] = hi/deg;
529 npar = npar + 2;
530 shape = "CONS";
531 }
532 else if ( fIAxis == 3 ) {
533 G4double tn1, tn2, rmin, rmax, z1;
534 tn1 = (Rpar[3] - Rpar[1])/(2.* Rpar[0]);
535 tn2 = (Rpar[4] - Rpar[2])/(2.* Rpar[0]);
536 rmin = Rpar[1]; rmax = Rpar[2]; z1 = -Rpar[0];
537 Rpar[1] = rmin + tn1 * (lo/cm - z1);
538 Rpar[3] = rmin + tn1 * (hi/cm - z1);
539 Rpar[2] = rmax + tn2 * (lo/cm - z1);
540 Rpar[4] = rmax + tn2 * (hi/cm - z1);
541 Rpar[0] = (hi - lo)/2./cm;
542 pos[2] = (hi + lo)/2.;
543 }
544 }
545 else if ( shape == "CONS" ) {
546 if ( fIAxis == 1 ) {
547 Exception("CreateEnvelope","CONS-x");
548 }
549 else if ( fIAxis == 2 ) {
550 Rpar[5] = lo/deg;
551 Rpar[6] = hi/deg;
552 }
553 else if ( fIAxis == 3 ) {
554 G4double tn1, tn2, rmin, rmax, z1;
555 tn1 = (Rpar[3] - Rpar[1])/(2.* Rpar[0]);
556 tn2 = (Rpar[4] - Rpar[2])/(2.* Rpar[0]);
557 rmin = Rpar[1]; rmax = Rpar[2]; z1 = -Rpar[0];
558 Rpar[1] = rmin + tn1 * (lo/cm - z1);
559 Rpar[3] = rmin + tn1 * (hi/cm - z1);
560 Rpar[2] = rmax + tn2 * (lo/cm - z1);
561 Rpar[4] = rmax + tn2 * (hi/cm - z1);
562 Rpar[0] = (hi - lo)/2./cm;
563 pos[2] = (hi + lo)/2.;
564 }
565 }
566 else if ( shape == "SPHE" ) {
567 Exception("CreateEnvelope","SPHE-x,y,z");
568 }
569 else if ( shape == "PARA" ) {
570 Exception("CreateEnvelope","PARA-x,y,z");
571 }
572 else if ( shape == "PGON" ) {
573 if ( fIAxis == 2) {
574 Rpar[0] = lo/deg;
575 Rpar[1] = hi/deg;
576 // rotm = ???
577 }
578 else {
579 Exception("CreateEnvelope","PGON-x,z");
580 }
581 }
582 else if ( shape == "PCON" ) {
583 if ( fIAxis == 2) {
584 Rpar[0] = lo/deg;
585 Rpar[1] = hi/deg;
586 // rotm = ???
587 }
588 else {
589 Exception("CreateEnvelope","PCON-x,z");
590 }
591 }
592 else {
593 Exception("CreateEnvelope", "Unknown shape" + shape);
594 }
595
596 // create new VTE corresponding to envelope
597 G4String envName = fVTE->GetName() + "_ENV";
598 G3VolTableEntry* envVTE
599 = G4CreateVTE(envName, shape, fNmed, Rpar, npar);
600
601 // create a G3Pos object and add it to envVTE
602 G4String motherName = fMVTE->GetMasterClone()->GetName();
603 G4ThreeVector* offset = new G4ThreeVector(pos[0],pos[1],pos[2]);
604 G4String only = "ONLY";
605 G3Pos* aG3Pos = new G3Pos(motherName, 1, offset, 0, only);
606 envVTE->AddG3Pos(aG3Pos);
607
608 delete [] Rpar;
609
610 return envVTE;
611}
612
613void G3Division::CreateSolid(G4String shape, G4double par[], G4int npar)
614// create the solid corresponding to divided volume
615// and set the fOffset for replica
616{
617 G4double *Rpar = new G4double[npar+2];
618 for (G4int i=0; i<npar; ++i){ Rpar[i] = par[i];}
619
620 // verbose
621 // G4cout << "G3Division::CreateSolid volume before: "
622 // << fVTE->GetName() << " " << shape << G4endl;
623 // G4cout << " npar,Rpar: " << npar;
624 // for (G4int ii = 0; ii < npar; ++ii) G4cout << " " << Rpar[ii];
625 // G4cout << G4endl;
626
627 if ( shape == "BOX" ) {
628 if ( fIAxis == 1 ) Rpar[0] = fWidth/2./cm;
629 else if ( fIAxis == 2 ) Rpar[1] = fWidth/2./cm;
630 else if ( fIAxis == 3 ) Rpar[2] = fWidth/2./cm;
631 }
632 else if ( shape == "TRD1" ) {
633 if ( fIAxis == 1 || fIAxis == 2 ) {
634 Exception("CreateSolid", "TRD1-x,y");
635 }
636 else if ( fIAxis == 3 ) {
637 Rpar[3] = fWidth/2./cm;
638 }
639 }
640 else if ( shape == "TRD2" ) {
641 if ( fIAxis == 1 || fIAxis == 2 ) {
642 Exception("CreateSolid", "TRD2-x,y");
643 }
644 else if ( fIAxis == 3 ) {
645 Rpar[4] = fWidth/2./cm;
646 }
647 }
648 else if ( shape == "TRAP" ) {
649 if ( fIAxis == 1 || fIAxis == 2) {
650 Exception("CreateSolid", "TRAP-x,y");
651 }
652 else if ( fIAxis == 3 ) {
653 Rpar[0] = fWidth/2./cm;
654 }
655 }
656 else if ( shape == "TUBE" ) {
657 if ( fIAxis == 1 ) {
658 Rpar[1] = Rpar[0] + fWidth/cm;
659 fOffset = Rpar[0]*cm;
660 }
661 else if ( fIAxis == 2 ) {
662 Rpar[3] = 0.;
663 Rpar[4] = fWidth/deg;
664 shape = "TUBS";
665 npar = npar + 2;
666 }
667 else if ( fIAxis == 3 ) {
668 Rpar[2] = fWidth/2./cm;
669 }
670 }
671 else if ( shape == "TUBS" ) {
672 if ( fIAxis == 1 ) {
673 Rpar[1] = Rpar[0] + fWidth/cm;
674 fOffset = Rpar[0]*cm;
675 }
676 else if ( fIAxis == 2 ) {
677 fOffset = Rpar[3]*deg;
678 Rpar[3] = 0.;
679 Rpar[4] = fWidth/deg;
680 }
681 else if ( fIAxis == 3 ) {
682 Rpar[2] = fWidth/2./cm;
683 }
684 }
685 else if ( shape == "CONE" ) {
686 if ( fIAxis == 1 ) {
687 Exception("CreateSolid", "CONE-x");
688 }
689 else if ( fIAxis == 2 ) {
690 Rpar[5] = 0.;
691 Rpar[6] = fWidth/deg;
692 shape = "CONS";
693 npar = npar + 2;
694 }
695 else if ( fIAxis == 3 ) {
696 Rpar[0] = fWidth/2./cm;
697 }
698 }
699 else if ( shape == "CONS" ) {
700 if ( fIAxis == 1 ) {
701 Exception("CreateSolid", "CONS-x");
702 }
703 else if ( fIAxis == 2 ) {
704 fOffset = Rpar[5]*deg;
705 Rpar[5] = 0.;
706 Rpar[6] = fWidth/deg;
707 }
708 else if ( fIAxis == 3 ) {
709 Rpar[0] = fWidth/2./cm;
710 }
711 }
712 else if (shape == "PARA") {
713 if ( fIAxis == 1 ) {
714 Rpar[0] = fWidth/2./cm;
715 }
716 else if ( Rpar[4] == 0. && Rpar[5] == 0. ) {
717 // only special case for axis 2,3 is supported
718 if ( fIAxis == 2 ) {
719 Rpar[1] = fWidth/2./cm;
720 }
721 else if ( fIAxis == 3) {
722 Rpar[2] = fWidth/2./cm;
723 }
724 }
725 else
726 Exception("CreateSolid", shape);
727 }
728 else if (shape == "SPHE") {
729 Exception("CreateSolid", shape);
730 }
731 else if ( shape == "PGON" ) {
732 if ( fIAxis == 2 ) {
733 fOffset = Rpar[0]*deg;
734 Rpar[0] = 0.;
735 Rpar[1] = fWidth/deg;
736 Rpar[2] = 1.;
737 }
738 else
739 Exception("CreateSolid", shape);
740 }
741 else if ( shape == "PCON" ) {
742 if ( fIAxis == 2 ) {
743 fOffset = Rpar[0]*deg;
744 Rpar[0] = 0.;
745 Rpar[1] = fWidth/deg;
746 }
747 else {
748 Exception("CreateSolid", shape);
749 }
750 }
751 else {
752 Exception("CreateSolid", "Unknown shape" + shape);
753 }
754
755 // create solid and set it to fVTE
756 G4bool hasNegPars;
757 G4bool deferred;
758 G4bool okAxis[3];
759 G4VSolid* solid
760 = G3toG4MakeSolid(fVTE->GetName(), shape, Rpar, npar, hasNegPars, deferred, okAxis);
761
762 if (hasNegPars) {
763 G4String err_message = "CreateSolid VTE " + fVTE->GetName()
764 + " has negative parameters.";
765 G4Exception("G3Division::CreateSolid()", "G3toG40006",
766 FatalException, err_message);
767 return;
768 }
769
770 // update vte
771 fVTE->SetSolid(solid);
772 fVTE->SetNRpar(npar, Rpar);
773 fVTE->SetHasNegPars(hasNegPars);
774
775 // verbose
776 // G4cout << "G3Division::CreateSolid volume after: "
777 // << fVTE->GetName() << " " << shape << G4endl;
778 // G4cout << " npar,Rpar: " << npar;
779 // for (G4int iii = 0; iii < npar; ++iii) G4cout << " " << Rpar[iii];
780 // G4cout << G4endl;
781 delete [] Rpar;
782}
783
784
785G3VolTableEntry* G3Division::Dvn()
786{
787 // no envelope need to be created
788
789 // get parameters from mother
790 G4String shape = fMVTE->GetShape();
791 G4double* Rpar = fMVTE->GetRpar();
792 G4int npar = fMVTE->GetNpar();
793
794 // set width for replica and create solid
795 fWidth = (fHighRange - fLowRange)/fNofDivisions;
796 CreateSolid(shape, Rpar, npar);
797
798 return 0;
799}
800
801G3VolTableEntry* G3Division::Dvn2()
802{
803 // to be defined as const of this class
804 G4double Rmin = 0.0001*cm;
805
806 G4String shape = fMVTE->GetShape();
807 G4double* Rpar = fMVTE->GetRpar();
808 G4int npar = fMVTE->GetNpar();
809
810 G4double c0 = fC0;
811 if (fAxis == kPhi) c0 = c0*deg;
812 else c0 = c0*cm;
813
814 // create envelope (if needed)
815 G3VolTableEntry* envVTE = 0;
816 if( std::abs(c0 - fLowRange) > Rmin) {
817 envVTE = CreateEnvelope(shape, fHighRange, c0, Rpar, npar);
818 Rpar = envVTE->GetRpar();
819 npar = envVTE->GetNpar();
820 }
821
822 // set width for replica and create solid
823 fWidth = (fHighRange - c0)/fNofDivisions;
824 CreateSolid(shape, Rpar, npar);
825
826 return envVTE;
827}
828
829G3VolTableEntry* G3Division::Dvt()
830{
831 // to be defined as const of this class
832 G4double Rmin = 0.0001*cm;
833
834 // get parameters from mother
835 G4String shape = fMVTE->GetShape();
836 G4double* Rpar = fMVTE->GetRpar();
837 G4int npar = fMVTE->GetNpar();
838
839 // calculate the number of divisions
840 G4int ndvmx = fNofDivisions;
841 G4double step = fStep;
842
843 if (fAxis == kPhi) step = step*deg;
844 else step = step*cm;
845
846 G4int ndiv = G4int((fHighRange - fLowRange + Rmin)/step);
847 // to be added warning
848 if (ndvmx > 255) ndvmx = 255;
849 if (ndiv > ndvmx && ndvmx > 0 ) ndiv = ndvmx;
850
851 // create envVTE (if needed)
852 G3VolTableEntry* envVTE = 0;
853 G4double delta = std::abs((fHighRange - fLowRange) - ndiv*step);
854 if (delta > Rmin) {
855 envVTE
856 = CreateEnvelope(shape, fHighRange-delta/2., fLowRange+delta/2.,
857 Rpar, npar);
858 Rpar = envVTE->GetRpar();
859 npar = envVTE->GetNpar();
860 }
861
862 // set width for replica and create solid
863 fWidth = step;
864 fNofDivisions = ndiv;
865 CreateSolid(shape, Rpar, npar);
866
867 return envVTE;
868}
869
870G3VolTableEntry* G3Division::Dvt2()
871{
872 // to be defined as const of this class
873 G4double Rmin = 0.0001*cm;
874
875 // get parameters from mother
876 G4String shape = fMVTE->GetShape();
877 G4double* Rpar = fMVTE->GetRpar();
878 G4int npar = fMVTE->GetNpar();
879
880 // calculate the number of divisions
881 G4int ndvmx = fNofDivisions;
882 G4double step = fStep;
883 G4double c0 = fC0;
884
885 if(fAxis == kPhi){
886 step = step*deg;
887 c0 = c0*deg;
888 }
889 else {
890 step = step*cm;
891 c0 = c0*cm;
892 }
893
894 G4int ndiv = G4int((fHighRange - c0 + Rmin)/step);
895 // to be added warning
896 if (ndvmx > 255) ndvmx = 255;
897 if (ndiv > ndvmx && ndvmx > 0 ) ndiv = ndvmx;
898
899 // create envelope (if needed)
900 G3VolTableEntry* envVTE = 0;
901 G4double delta = std::abs((fHighRange - c0) - ndiv*step);
902 if (std::abs(c0 - fLowRange) > Rmin) {
903 envVTE
904 = CreateEnvelope(shape, fHighRange-delta/2., c0+delta/2., Rpar, npar);
905 Rpar = envVTE->GetRpar();
906 npar = envVTE->GetNpar();
907 }
908
909 // set with for replica and create solid
910 fWidth = step;
911 fNofDivisions = ndiv;
912 CreateSolid(shape, Rpar, npar);
913
914 return envVTE;
915}
G3VolTableEntry * G4CreateVTE(G4String vname, G4String shape, G4int nmed, G4double Rpar[], G4int npar)
Definition: G4gsvolu.cc:51
G3DivType
Definition: G3Division.hh:53
@ kDvt
Definition: G3Division.hh:53
@ kDvt2
Definition: G3Division.hh:53
@ kDvn2
Definition: G3Division.hh:53
@ kDvn
Definition: G3Division.hh:53
G4VSolid * G3toG4MakeSolid(const G4String &vname, const G4String &shape, const G4double *Rpar, const G4int npar, G4bool &NegVolPars, G4bool &Deferred, G4bool *OKAxis)
G3G4DLL_API G4double Rpar[1000]
Definition: clparse.cc:67
@ FatalException
CLHEP::Hep3Vector G4ThreeVector
HepGeom::Translate3D G4Translate3D
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
G3Division(G3DivType type, G3VolTableEntry *vte, G3VolTableEntry *mvte, G4int nofDivision, G4int iaxis, G4int nmed, G4double c0, G4double step)
Definition: G3Division.cc:48
void CreatePVReplica()
Definition: G3Division.cc:126
void UpdateVTE()
Definition: G3Division.cc:95
virtual ~G3Division()
Definition: G3Division.cc:90
Definition: G3Pos.hh:44
void AddMother(G3VolTableEntry *aDaughter)
void SetNmed(G4int nmed)
G3VolTableEntry * GetMasterClone()
void ReplaceDaughter(G3VolTableEntry *vteOld, G3VolTableEntry *vteNew)
void ReplaceMother(G3VolTableEntry *vteOld, G3VolTableEntry *vteNew)
void AddG3Pos(G3Pos *aG3Pos)
void SetHasNegPars(G4bool hasNegPars)
G4double * GetRpar()
void SetNRpar(G4int npar, G4double *Rpar)
void AddDaughter(G3VolTableEntry *aDaughter)
G4LogicalVolume * GetLV()
void SetSolid(G4VSolid *solid)
G4VSolid * GetSolid() const
G4String GetName() const
Definition: G4Para.hh:77
static G4ReflectionFactory * Instance()
G4PhysicalVolumesPair Place(const G4Transform3D &transform3D, const G4String &name, G4LogicalVolume *LV, G4LogicalVolume *motherLV, G4bool isMany, G4int copyNo, G4bool surfCheck=false)
G4PhysicalVolumesPair Replicate(const G4String &name, G4LogicalVolume *LV, G4LogicalVolume *motherLV, EAxis axis, G4int nofReplicas, G4double width, G4double offset=0)
@ kPhi
Definition: geomdefs.hh:54
@ kYAxis
Definition: geomdefs.hh:54
@ kXAxis
Definition: geomdefs.hh:54
@ kZAxis
Definition: geomdefs.hh:54
@ kRho
Definition: geomdefs.hh:54
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41