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 "G4PVParameterised.hh"
00037 #include "G4VPVParameterisation.hh"
00038 #include "G4AffineTransform.hh"
00039 #include "G4UnitsTable.hh"
00040 #include "G4VSolid.hh"
00041 #include "G4LogicalVolume.hh"
00042
00043
00044
00045
00046 G4PVParameterised::G4PVParameterised( const G4String& pName,
00047 G4LogicalVolume* pLogical,
00048 G4VPhysicalVolume* pMother,
00049 const EAxis pAxis,
00050 const G4int nReplicas,
00051 G4VPVParameterisation *pParam,
00052 G4bool pSurfChk )
00053 : G4PVReplica(pName, pLogical, pMother, pAxis, nReplicas, 0, 0),
00054 fparam(pParam)
00055 {
00056 #ifdef G4VERBOSE
00057 if ((pMother) && (pMother->IsParameterised()))
00058 {
00059 std::ostringstream message, hint;
00060 message << "A parameterised volume is being placed" << G4endl
00061 << "inside another parameterised volume !";
00062 hint << "To make sure that no overlaps are generated," << G4endl
00063 << "you should verify the mother replicated shapes" << G4endl
00064 << "are of the same type and dimensions." << G4endl
00065 << " Mother physical volume: " << pMother->GetName() << G4endl
00066 << " Parameterised volume: " << pName << G4endl
00067 << " (To switch this warning off, compile with G4_NO_VERBOSE)";
00068 G4Exception("G4PVParameterised::G4PVParameterised()", "GeomVol1002",
00069 JustWarning, message, G4String(hint.str()));
00070 }
00071 #endif
00072 if (pSurfChk) { CheckOverlaps(); }
00073 }
00074
00075
00076
00077
00078 G4PVParameterised::G4PVParameterised( const G4String& pName,
00079 G4LogicalVolume* pLogical,
00080 G4LogicalVolume* pMotherLogical,
00081 const EAxis pAxis,
00082 const G4int nReplicas,
00083 G4VPVParameterisation *pParam,
00084 G4bool pSurfChk )
00085 : G4PVReplica(pName, pLogical, pMotherLogical, pAxis, nReplicas, 0, 0),
00086 fparam(pParam)
00087 {
00088 if (pSurfChk) { CheckOverlaps(); }
00089 }
00090
00091
00092
00093
00094
00095 G4PVParameterised::G4PVParameterised( __void__& a )
00096 : G4PVReplica(a), fparam(0)
00097 {
00098 }
00099
00100
00101
00102
00103 G4PVParameterised::~G4PVParameterised()
00104 {
00105 }
00106
00107
00108
00109
00110 G4VPVParameterisation* G4PVParameterised::GetParameterisation() const
00111 {
00112 return fparam;
00113 }
00114
00115
00116
00117
00118 G4bool G4PVParameterised::IsParameterised() const
00119 {
00120 return true;
00121 }
00122
00123
00124
00125
00126 void G4PVParameterised::GetReplicationData( EAxis& axis,
00127 G4int& nReplicas,
00128 G4double& width,
00129 G4double& offset,
00130 G4bool& consuming) const
00131 {
00132 axis = faxis;
00133 nReplicas = fnReplicas;
00134 width = fwidth;
00135 offset = foffset;
00136 consuming = false;
00137 }
00138
00139
00140
00141
00142 void G4PVParameterised::SetRegularStructureId( G4int Code )
00143 {
00144 G4PVReplica::SetRegularStructureId( Code );
00145
00146
00147 }
00148
00149
00150
00151
00152
00153 G4bool
00154 G4PVParameterised::CheckOverlaps(G4int res, G4double tol, G4bool verbose)
00155 {
00156 if (res<=0) { return false; }
00157
00158 G4VSolid *solidA = 0, *solidB = 0;
00159 G4LogicalVolume *motherLog = GetMotherLogical();
00160 G4VSolid *motherSolid = motherLog->GetSolid();
00161 std::vector<G4ThreeVector> points;
00162
00163 if (verbose)
00164 {
00165 G4cout << "Checking overlaps for parameterised volume "
00166 << GetName() << " ... ";
00167 }
00168
00169 for (G4int i=0; i<GetMultiplicity(); i++)
00170 {
00171 solidA = fparam->ComputeSolid(i, this);
00172 solidA->ComputeDimensions(fparam, i, this);
00173 fparam->ComputeTransformation(i, this);
00174
00175
00176
00177 G4AffineTransform Tm( GetRotation(), GetTranslation() );
00178
00179
00180
00181
00182
00183
00184 for (G4int n=0; n<res; n++)
00185 {
00186 G4ThreeVector mp = Tm.TransformPoint(solidA->GetPointOnSurface());
00187
00188
00189
00190 if (motherSolid->Inside(mp)==kOutside)
00191 {
00192 G4double distin = motherSolid->DistanceToIn(mp);
00193 if (distin > tol)
00194 {
00195 std::ostringstream message;
00196 message << "Overlap with mother volume !" << G4endl
00197 << " Overlap is detected for volume "
00198 << GetName() << ", parameterised instance: " << i << G4endl
00199 << " with its mother volume "
00200 << motherLog->GetName() << G4endl
00201 << " at mother local point " << mp << ", "
00202 << "overlapping by at least: "
00203 << G4BestUnit(distin, "Length");
00204 G4Exception("G4PVParameterised::CheckOverlaps()",
00205 "GeomVol1002", JustWarning, message);
00206 return true;
00207 }
00208 }
00209 points.push_back(mp);
00210 }
00211
00212
00213
00214 std::vector<G4ThreeVector>::iterator pos;
00215 for (G4int j=i+1; j<GetMultiplicity(); j++)
00216 {
00217 solidB = fparam->ComputeSolid(j,this);
00218 solidB->ComputeDimensions(fparam, j, this);
00219 fparam->ComputeTransformation(j, this);
00220
00221
00222
00223 G4AffineTransform Td( GetRotation(), GetTranslation() );
00224
00225 for (pos=points.begin(); pos!=points.end(); pos++)
00226 {
00227
00228
00229 G4ThreeVector md = Td.Inverse().TransformPoint(*pos);
00230
00231 if (solidB->Inside(md)==kInside)
00232 {
00233 G4double distout = solidB->DistanceToOut(md);
00234 if (distout > tol)
00235 {
00236 std::ostringstream message;
00237 message << "Overlap within parameterised volumes !" << G4endl
00238 << " Overlap is detected for volume "
00239 << GetName() << ", parameterised instance: " << i << G4endl
00240 << " with parameterised volume instance: " << j
00241 << G4endl
00242 << " at local point " << md << ", "
00243 << "overlapping by at least: "
00244 << G4BestUnit(distout, "Length")
00245 << ", related to volume instance: " << j << ".";
00246 G4Exception("G4PVParameterised::CheckOverlaps()",
00247 "GeomVol1002", JustWarning, message);
00248 return true;
00249 }
00250 }
00251 }
00252 }
00253 }
00254 if (verbose)
00255 {
00256 G4cout << "OK! " << G4endl;
00257 }
00258
00259 return false;
00260 }