00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "G4VDivisionParameterisation.hh"
00037 #include "G4VSolid.hh"
00038 #include "G4VPhysicalVolume.hh"
00039 #include "G4RotationMatrix.hh"
00040 #include "G4ReflectedSolid.hh"
00041 #include "G4GeometryTolerance.hh"
00042
00043 G4int G4VDivisionParameterisation::verbose = 5;
00044
00045
00046 G4VDivisionParameterisation::
00047 G4VDivisionParameterisation( EAxis axis, G4int nDiv,
00048 G4double step, G4double offset,
00049 DivisionType divType, G4VSolid* motherSolid )
00050 : faxis(axis), fnDiv( nDiv), fwidth(step), foffset(offset),
00051 fDivisionType(divType), fmotherSolid( motherSolid ), fReflectedSolid(false),
00052 fDeleteSolid(false), theVoluFirstCopyNo(1), fhgap(0.)
00053 {
00054 #ifdef G4DIVDEBUG
00055 if (verbose >= 1)
00056 {
00057 G4cout << " G4VDivisionParameterisation no divisions " << fnDiv
00058 << " = " << nDiv << G4endl
00059 << " offset " << foffset << " = " << offset << G4endl
00060 << " step " << fwidth << " = " << step << G4endl;
00061 }
00062 #endif
00063 kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
00064 }
00065
00066
00067 G4VDivisionParameterisation::~G4VDivisionParameterisation()
00068 {
00069 if (fDeleteSolid) delete fmotherSolid;
00070 }
00071
00072
00073 G4VSolid*
00074 G4VDivisionParameterisation::
00075 ComputeSolid( const G4int i, G4VPhysicalVolume* pv )
00076 {
00077 G4VSolid* solid = G4VPVParameterisation::ComputeSolid(i, pv);
00078 if (solid->GetEntityType() == "G4ReflectedSolid")
00079 {
00080 solid = ((G4ReflectedSolid*)solid)->GetConstituentMovedSolid();
00081 }
00082 return solid;
00083 }
00084
00085
00086 void
00087 G4VDivisionParameterisation::
00088 ChangeRotMatrix( G4VPhysicalVolume *physVol, G4double rotZ ) const
00089 {
00090 G4RotationMatrix* rm = new G4RotationMatrix();
00091 rm->rotateZ( rotZ );
00092
00093
00094 G4RotationMatrix* rmold = physVol->GetRotation();
00095 delete rmold;
00096 physVol->SetRotation(rm);
00097 }
00098
00099
00100 G4int
00101 G4VDivisionParameterisation::
00102 CalculateNDiv( G4double motherDim, G4double width, G4double offset ) const
00103 {
00104 #ifdef G4DIVDEBUG
00105 G4cout << " G4VDivisionParameterisation::CalculateNDiv: "
00106 << ( motherDim - offset ) / width
00107 << " Motherdim: " << motherDim << ", Offset: " << offset
00108 << ", Width: " << width << G4endl;
00109 #endif
00110
00111 return G4int( ( motherDim - offset ) / width );
00112 }
00113
00114
00115 G4double
00116 G4VDivisionParameterisation::
00117 CalculateWidth( G4double motherDim, G4int nDiv, G4double offset ) const
00118 {
00119 #ifdef G4DIVDEBUG
00120 G4cout << " G4VDivisionParameterisation::CalculateWidth: "
00121 << ( motherDim - offset ) / nDiv
00122 << ", Motherdim: " << motherDim << ", Offset: " << offset
00123 << ", Number of divisions: " << nDiv << G4endl;
00124 #endif
00125
00126 return ( motherDim - offset ) / nDiv;
00127 }
00128
00129
00130 void G4VDivisionParameterisation::CheckParametersValidity()
00131 {
00132 G4double maxPar = GetMaxParameter();
00133 CheckOffset( maxPar );
00134 CheckNDivAndWidth( maxPar );
00135 }
00136
00137
00138 void G4VDivisionParameterisation::CheckOffset( G4double maxPar )
00139 {
00140 if( foffset >= maxPar )
00141 {
00142 std::ostringstream message;
00143 message << "Configuration not supported." << G4endl
00144 << "Division of solid " << fmotherSolid->GetName()
00145 << " has too big offset = " << G4endl
00146 << " " << foffset << " > " << maxPar << " !";
00147 G4Exception("G4VDivisionParameterisation::CheckOffset()",
00148 "GeomDiv0001", FatalException, message);
00149 }
00150 }
00151
00152
00153 void G4VDivisionParameterisation::CheckNDivAndWidth( G4double maxPar )
00154 {
00155 if( (fDivisionType == DivNDIVandWIDTH)
00156 && (foffset + fwidth*fnDiv - maxPar > kCarTolerance ) )
00157 {
00158 std::ostringstream message;
00159 message << "Configuration not supported." << G4endl
00160 << "Division of solid " << fmotherSolid->GetName()
00161 << " has too big offset + width*nDiv = " << G4endl
00162 << " " << foffset + fwidth*fnDiv << " > "
00163 << foffset << ". Width = "
00164 << G4endl
00165 << " " << fwidth << ". nDiv = " << fnDiv << " !";
00166 G4Exception("G4VDivisionParameterisation::CheckNDivAndWidth()",
00167 "GeomDiv0001", FatalException, message);
00168 }
00169 }
00170
00171
00172 G4double G4VDivisionParameterisation::OffsetZ() const
00173 {
00174
00175 G4double offset = foffset;
00176 if (fReflectedSolid) offset = GetMaxParameter() - fwidth*fnDiv - foffset;
00177
00178 return offset;
00179 }
00180
00181