/** * @file Phase1CROSS.cc * @author Ibrahin Pinera * @date 2017 SoLid - University of Antwerp */ #include "Phase1CROSS.hh" #include "SolidMaterials.hh" #include "SolidUtils.hh" #include "G4Material.hh" #include "G4MaterialTable.hh" #include "G4VisAttributes.hh" #include "G4Transform3D.hh" #include "G4PVPlacement.hh" #include "G4UnitsTable.hh" #include "G4SystemOfUnits.hh" #include "G4Box.hh" #include "G4SubtractionSolid.hh" #include "G4UnionSolid.hh" Phase1CROSS::Phase1CROSS(G4int verboseLevel, G4bool isCrossCalibration, G4TwoVector sourcePosXY, G4double sourcePosZ) { m_verboseLevel = verboseLevel; // source entrance gutter (assumed values) m_gutterLength = 174.*mm; // 200.*mm --> changed to the measured value m_gutterHeight = 49.*mm; // 45.*mm --> changed to the measured value m_gutterWidth = 350.*mm; // corrected to allow CROSS going between 5th module and PPL m_gutterThickness = 5.*mm; m_gutterOffSetZ = 80.*mm; // back fixing arms along the Y direction (piece 0) m_piece0Length = 45.*mm; m_piece0Height = 355.*mm; m_piece0Width = 45.*mm; // internal covers along the Z direction (piece 1) m_piece1Length = 5.*mm; m_piece1Height = 110.*mm; m_piece1Width = 420.*mm; // top hor bars along the Z direction (piece 2) m_piece2Length = 45.*mm; m_piece2Height = 90.*mm; m_piece2Width = 3100.*mm; // hor bars along the X direction (piece 3) m_piece3Length = 775.*mm; m_piece3Height = 80.*mm; m_piece3Width = 40.*mm; // front ver bars for source entrance (piece 4) m_piece4Length = 40.*mm; m_piece4Height = 420.*mm; m_piece4Width = 80.*mm; m_piece4Gap = m_gutterLength; // bottom hor bars along the Z direction (piece 5) m_piece5Length = 80.*mm; m_piece5Height = 80.*mm; m_piece5Width = m_piece2Width; // hor covers along the X direction (piece 6) m_piece6Length = 210.*mm; m_piece6Height = 80.*mm; m_piece6Width = 5.*mm; m_piece6OffSetX = 54.*mm; //assumed value // ver covers along the Y direction (piece 7) m_piece7Length = 45.*mm; m_piece7Height = 165.*mm; m_piece7Width = 5.*mm; // bottom piece along the Z direction (piece 8) m_piece8Length = 6.*mm; m_piece8Height = 56.*mm; m_piece8Width = m_piece2Width; // bottom piece along the Z direction (piece 9) m_piece9Length = 48.*mm; m_piece9Height = 10.*mm; m_piece9Width = m_piece2Width; // bottom piece along the Z direction (piece 10) m_piece10Length = 15.*mm; m_piece10Height = 15.*mm; m_piece10Width = 3000.*mm; m_piece5to10delY = 63.*mm; // full size of all CROSS fixed structures (excl. carrier) m_crossFullLength = m_piece3Length + 2.*(m_piece5Length + m_piece6OffSetX); // size in X m_crossFullHeight = m_piece0Height + m_piece4Height + m_piece7Height; // size in Y m_crossFullWidth = m_piece2Width + m_piece4Width + m_piece6Width + m_gutterOffSetZ; // size in Z // offSets for placing CROSS wrt the container m_crossOffSetX = 0.; // center m_crossOffSetY = 0.5*m_crossFullHeight; // top m_crossOffSetZ = -0.5*m_crossFullWidth; // back //////////////////////////////////////////// // CROSS carrier //////////////////////////////////////////// m_isCrossCalibration = isCrossCalibration; m_crossCarrier = new Phase1CROSSCarrier(m_verboseLevel, sourcePosXY); m_carrierPosX = m_crossCarrier->GetOffSetX(); m_carrierPosZ = -0.5*m_crossFullWidth + sourcePosZ + m_crossCarrier->GetOffSetZ(); // calculate the min and max possible position for the Carrier G4double minPosZ = -0.5*(m_crossFullWidth - m_crossCarrier->GetWidth()) + m_piece7Width + m_piece3Width; G4double maxPosZ = 0.5*(m_crossFullWidth - m_crossCarrier->GetWidth()) - m_gutterWidth; if( !m_isCrossCalibration ) {// if no CROSS, locate the Carrier in max position m_carrierPosZ = maxPosZ; } else if( m_carrierPosZ > maxPosZ || m_carrierPosZ < minPosZ ) { printf("\n\n!!! ERROR !!!\n"); printf("==================================================\n"); printf("CROSS source Z position NOT ALLOWED\n"); printf("==================================================\n\n"); exit(1); } //////////////////////////////////////////// if( m_verboseLevel > 0 ) { G4cout << G4endl; G4cout << "=== dimensions of the CROSS System ===" << G4endl; G4cout << m_crossFullLength << " x " << m_crossFullHeight << " x " << m_crossFullWidth << G4endl; G4cout << "======================================" << G4endl; G4cout << G4endl; } } Phase1CROSS::~Phase1CROSS() { } G4LogicalVolume *Phase1CROSS::CrossConstruction(G4bool bSourceCapsule) { G4Material * mateAir; mateAir = G4Material::GetMaterial("Air"); // for pieces 1, 6, 7 G4Material * mateAl; mateAl = G4Material::GetMaterial("Aluminium"); // for pieces 8, 9 G4Material * mateSteel; mateSteel = G4Material::GetMaterial("G4_STAINLESS-STEEL"); // POM, for piece 10 G4Material * matePOM; matePOM = G4Material::GetMaterial("G4_POLYOXYMETHYLENE"); // make colours ********************************************************* G4Colour white (1.0, 1.0, 1.0) ; G4Colour white_t (1.0, 1.0, 1.0, .95) ; G4Colour grey (0.5, 0.5, 0.5) ; G4Colour lgrey (.75, .75, .75) ; G4Colour red (1.0, 0.0, 0.0, 0.5) ; G4Colour blue (0.0, 0.0, 1.0) ; G4Colour blue_t (0.0, 0.0, 1.0, .75) ; G4Colour cyan (0.0, 1.0, 1.0, 0.5) ; G4Colour magenta (1.0, 0.0, 1.0) ; G4Colour yellow (1.0, 1.0, 0.0, 0.5) ; G4Colour lblue (0.0, 0.0, .75) ; G4Colour black (0.0, 0.0, 0.0) ; G4Colour green (0.0, 1.0, 0.0) ; G4Colour lgreen (0.0, .75, 0.0) ; G4cout << G4endl << "************** Start CROSS construction****************" << G4endl; G4bool forceSolid = true; // G4bool forceSolid = false; // construct full CROSS box G4Box* crossBoxTop = new G4Box("crossBoxTop", 0.5*m_crossFullLength, 0.5*m_crossFullHeight, 0.5*m_crossFullWidth); // extent the logVol to include the carrier central structures G4double delX = m_crossCarrier->GetLength(); G4double delY1 = m_crossCarrier->GetOffSetY() - (m_piece4Height - m_piece5Height - m_piece5to10delY - m_piece10Height); G4double delZ = m_crossCarrier->GetWidth(); G4Box* crossBoxBottom1 = new G4Box("crossBoxBottom1", 0.5*delX, 0.5*delY1, 0.5*delZ); G4UnionSolid * crossBox = new G4UnionSolid("crossBox", crossBoxTop, crossBoxBottom1, 0, G4ThreeVector(m_carrierPosX, -0.5*(m_crossFullHeight + delY1), m_carrierPosZ)); if( m_isCrossCalibration ) { // extent the logVol to include also the source carrier tubes G4double delY2 = 0.5*m_crossCarrier->GetHeight(); delZ = m_crossCarrier->GetCarrierThickness(); G4Box* crossBoxBottom2 = new G4Box("crossBoxBottom2", 0.5*delX, 0.5*delY2, 0.5*delZ); crossBox = new G4UnionSolid("crossBox", crossBox, crossBoxBottom2, 0, G4ThreeVector(m_carrierPosX, -0.5*(m_crossFullHeight + delY2) - delY1, m_carrierPosZ - m_crossCarrier->GetOffSetZ())); } G4VisAttributes* vatAl = new G4VisAttributes(grey); vatAl->SetVisibility(true); vatAl->SetForceSolid(forceSolid); logCROSS = new G4LogicalVolume(crossBox, mateAir, "logCROSS", 0, 0, 0); logCROSS->SetVisAttributes(G4VisAttributes::Invisible); // fixing arms on back top along the Y direction G4LogicalVolume* logPiece0 = AlternativeExtrusionConstruction(1, m_piece0Height, m_piece0Length, vatAl); G4RotationMatrix* rotBar = new G4RotationMatrix(); rotBar->rotateX(90.*deg); G4double xPos = 0.5*(m_crossFullLength - m_piece0Length) - m_piece6OffSetX; G4double yPos = 0.5*(m_crossFullHeight - m_piece0Height); G4double zPos = 0.5*(-m_crossFullWidth + m_piece0Width); new G4PVPlacement(rotBar, G4ThreeVector(-xPos, yPos, zPos), logPiece0, "physCrossPiece0", logCROSS, false, 0); new G4PVPlacement(rotBar, G4ThreeVector(xPos, yPos, zPos), logPiece0, "physCrossPiece0", logCROSS, false, 0); // pieces 2 on top along the Z direction G4LogicalVolume* logPiece2 = AlternativeExtrusionConstruction(2, m_piece2Width, m_piece2Length, vatAl); rotBar = new G4RotationMatrix(); rotBar->rotateZ(-90.*deg); xPos = 0.5*(m_crossFullLength - m_piece2Length) - m_piece6OffSetX; yPos = 0.5*(m_crossFullHeight - m_piece2Height) - m_piece0Height; zPos = 0.5*(-m_crossFullWidth + m_piece2Width) + m_piece7Width; new G4PVPlacement(rotBar, G4ThreeVector(-xPos, yPos, zPos), logPiece2, "physCrossPiece2", logCROSS, false, 0); new G4PVPlacement(rotBar, G4ThreeVector(xPos, yPos, zPos), logPiece2, "physCrossPiece2", logCROSS, false, 0); // pieces 3 along the X direction G4LogicalVolume* logPiece3 = AlternativeExtrusionConstruction(2, m_piece3Length, m_piece3Width, vatAl); rotBar = new G4RotationMatrix(); rotBar->rotateZ(-90.*deg); rotBar->rotateX(90.*deg); xPos = 0.; yPos = 0.5*(-m_crossFullHeight - m_piece3Height) + m_piece4Height; zPos = 0.5*(-m_crossFullWidth + m_piece3Width) + m_piece7Width; new G4PVPlacement(rotBar, G4ThreeVector(xPos, yPos, zPos), logPiece3, "physCrossPiece3", logCROSS, false, 0); zPos = 0.5*(m_crossFullWidth - m_piece3Width) - m_piece4Width - m_gutterOffSetZ; new G4PVPlacement(rotBar, G4ThreeVector(xPos, yPos, zPos), logPiece3, "physCrossPiece3", logCROSS, false, 0); // pieces 4 along the Y direction on the front for source entrance G4LogicalVolume* logPiece4 = AlternativeExtrusionConstruction(2, m_piece4Height, m_piece4Length, vatAl); rotBar = new G4RotationMatrix(); rotBar->rotateZ(-90.*deg); rotBar->rotateY(90.*deg); xPos = 0.5*(m_piece4Gap + m_piece4Length); yPos = 0.5*(-m_crossFullHeight + m_piece4Height); zPos = 0.5*(m_crossFullWidth - m_piece4Width) - m_gutterOffSetZ; new G4PVPlacement(rotBar, G4ThreeVector(-xPos, yPos, zPos), logPiece4, "physCrossPiece4", logCROSS, false, 0); new G4PVPlacement(rotBar, G4ThreeVector(xPos, yPos, zPos), logPiece4, "physCrossPiece4", logCROSS, false, 0); // source entrance gutter G4Box* gutterBox1 = new G4Box("gutterBox1", 0.5*m_gutterLength, 0.5*m_gutterHeight, 0.5*m_gutterWidth); G4Box* gutterBox2 = new G4Box("gutterBox2", 0.5*m_gutterLength - m_gutterThickness, 0.5*m_gutterHeight, 0.5*m_gutterWidth+0.5*mm); G4SubtractionSolid* gutterBox = new G4SubtractionSolid("gutterBox", gutterBox1, gutterBox2, 0, G4ThreeVector(0., m_gutterThickness, 0.)); G4LogicalVolume* logGutter = new G4LogicalVolume(gutterBox, mateAl, "logGutter", 0, 0, 0); logGutter->SetVisAttributes(vatAl); xPos = 0.; yPos = 0.5*(-m_crossFullHeight + m_gutterHeight); zPos = 0.5*(m_crossFullWidth - m_gutterWidth); new G4PVPlacement(0, G4ThreeVector(-xPos, yPos, zPos), logGutter, "physCrossGutter", logCROSS, false, 0); // pieces 5 on bottom along the Z direction G4LogicalVolume* logPiece5 = AlternativeExtrusionConstruction(1, m_piece5Width, m_piece5Length, vatAl); rotBar = new G4RotationMatrix(); rotBar->rotateZ(-90.*deg); xPos = 0.5*(m_piece3Length + m_piece5Length); yPos = 0.5*(-m_crossFullHeight - m_piece5Height) + m_piece4Height; zPos = 0.5*(-m_crossFullWidth + m_piece5Width) + m_piece7Width; new G4PVPlacement(rotBar, G4ThreeVector(-xPos, yPos, zPos), logPiece5, "physCrossPiece5", logCROSS, false, 0); new G4PVPlacement(rotBar, G4ThreeVector(xPos, yPos, zPos), logPiece5, "physCrossPiece5", logCROSS, false, 0); // pieces 1 along the Z direction (6 each side) G4Box* piece1Box = new G4Box("piece1Box", 0.5*m_piece1Length, 0.5*m_piece1Height, 0.5*m_piece1Width); G4LogicalVolume* logPiece1 = new G4LogicalVolume(piece1Box, mateAl, "logPiece1", 0, 0, 0); logPiece1->SetVisAttributes(vatAl); G4int nPiece1 = 6; G4double zGap = (m_piece5Width - 2.*m_piece3Width - nPiece1*m_piece1Width)/(nPiece1 - 1); xPos = 0.5*(m_piece3Length - m_piece1Length); yPos = 0.5*(-m_crossFullHeight - m_piece5Height - m_piece1Height) + m_piece4Height; zPos = 0.5*(-m_crossFullWidth + m_piece1Width) + m_piece7Width + m_piece3Width; for( int i = 0; i < nPiece1; i++ ) { new G4PVPlacement(0, G4ThreeVector(-xPos, yPos, zPos + i*(zGap + m_piece1Width)), logPiece1, "physCrossPiece1", logCROSS, false, 0); new G4PVPlacement(0, G4ThreeVector(xPos, yPos, zPos + i*(zGap + m_piece1Width)), logPiece1, "physCrossPiece1", logCROSS, false, 0); } // pieces 6 horizontal on the corners G4Box* piece6Box = new G4Box("piece6Box", 0.5*m_piece6Length, 0.5*m_piece6Height, 0.5*m_piece6Width); G4LogicalVolume* logPiece6 = new G4LogicalVolume(piece6Box, mateAl, "logPiece6", 0, 0, 0); logPiece6->SetVisAttributes(vatAl); xPos = 0.5*(m_crossFullLength - m_piece6Length); yPos = 0.5*(-m_crossFullHeight - m_piece6Height) + m_piece4Height; zPos = 0.5*(-m_crossFullWidth + m_piece6Width); new G4PVPlacement(0, G4ThreeVector(-xPos, yPos, zPos), logPiece6, "physCrossPiece6", logCROSS, false, 0); new G4PVPlacement(0, G4ThreeVector(xPos, yPos, zPos), logPiece6, "physCrossPiece6", logCROSS, false, 0); zPos = 0.5*(m_crossFullWidth + m_piece6Width) - m_piece4Width - m_gutterOffSetZ; new G4PVPlacement(0, G4ThreeVector(-xPos, yPos, zPos), logPiece6, "physCrossPiece6", logCROSS, false, 0); new G4PVPlacement(0, G4ThreeVector(xPos, yPos, zPos), logPiece6, "physCrossPiece6", logCROSS, false, 0); // pieces 7 vertical on the corners G4Box* piece7Box = new G4Box("piece7Box", 0.5*m_piece7Length, 0.5*m_piece7Height, 0.5*m_piece7Width); G4LogicalVolume* logPiece7 = new G4LogicalVolume(piece7Box, mateAl, "logPiece7", 0, 0, 0); logPiece7->SetVisAttributes(vatAl); xPos = 0.5*(m_crossFullLength - m_piece7Length) - m_piece6OffSetX; yPos = 0.5*(-m_crossFullHeight + m_piece7Height) + m_piece4Height; zPos = 0.5*(-m_crossFullWidth + m_piece7Width); new G4PVPlacement(0, G4ThreeVector(-xPos, yPos, zPos), logPiece7, "physCrossPiece7", logCROSS, false, 0); new G4PVPlacement(0, G4ThreeVector(xPos, yPos, zPos), logPiece7, "physCrossPiece7", logCROSS, false, 0); zPos = 0.5*(m_crossFullWidth + m_piece7Width) - m_piece4Width - m_gutterOffSetZ; new G4PVPlacement(0, G4ThreeVector(-xPos, yPos, zPos), logPiece7, "physCrossPiece7", logCROSS, false, 0); new G4PVPlacement(0, G4ThreeVector(xPos, yPos, zPos), logPiece7, "physCrossPiece7", logCROSS, false, 0); // pieces 8 on the bottom G4Box* piece8Box = new G4Box("piece8Box", 0.5*m_piece8Length, 0.5*m_piece8Height, 0.5*m_piece8Width); G4LogicalVolume* logPiece8 = new G4LogicalVolume(piece8Box, mateAl, "logPiece8", 0, 0, 0); logPiece8->SetVisAttributes(vatAl); xPos = 0.5*(m_piece3Length + m_piece8Length); yPos = 0.5*(-m_crossFullHeight - m_piece5to10delY) + m_piece4Height - m_piece5Height; zPos = 0.5*(-m_crossFullWidth + m_piece8Width) + m_piece7Width; new G4PVPlacement(0, G4ThreeVector(-xPos, yPos, zPos), logPiece8, "physCrossPiece8", logCROSS, false, 0); new G4PVPlacement(0, G4ThreeVector(xPos, yPos, zPos), logPiece8, "physCrossPiece8", logCROSS, false, 0); // pieces 9 on the bottom (steel) G4Box* piece9Box = new G4Box("piece9Box", 0.5*m_piece9Length, 0.5*m_piece9Height, 0.5*m_piece9Width); G4LogicalVolume* logPiece9 = new G4LogicalVolume(piece9Box, mateSteel, "logPiece9", 0, 0, 0); logPiece9->SetVisAttributes(vatAl); xPos = 0.5*(m_piece3Length + m_piece9Length) + m_piece8Length; new G4PVPlacement(0, G4ThreeVector(-xPos, yPos, zPos), logPiece9, "physCrossPiece9", logCROSS, false, 0); new G4PVPlacement(0, G4ThreeVector(xPos, yPos, zPos), logPiece9, "physCrossPiece9", logCROSS, false, 0); // pieces 10 on the bottom (POM material) G4Box* piece10Box = new G4Box("piece10Box", 0.5*m_piece10Length, 0.5*m_piece10Height, 0.5*m_piece10Width); G4LogicalVolume* logPiece10 = new G4LogicalVolume(piece10Box, matePOM, "logPiece10", 0, 0, 0); logPiece10->SetVisAttributes(vatAl); xPos = 0.5*(m_piece3Length + m_piece10Length); yPos = 0.5*(-m_crossFullHeight - m_piece10Height) + m_piece4Height - m_piece5Height - m_piece5to10delY; new G4PVPlacement(0, G4ThreeVector(-xPos, yPos, zPos), logPiece10, "physCrossPiece10", logCROSS, false, 0); new G4PVPlacement(0, G4ThreeVector(xPos, yPos, zPos), logPiece10, "physCrossPiece10", logCROSS, false, 0); // CROSS carrier logCrossCarrier = m_crossCarrier->CrossCarrierConstruction( m_isCrossCalibration, bSourceCapsule ); // carrier is rotated 180 in X (it has been constructed inverted) G4RotationMatrix* rotCarrier = new G4RotationMatrix(); rotCarrier->rotateY(180.*deg); yPos -= ( 0.5*m_piece10Height + m_crossCarrier->GetOffSetY() ); new G4PVPlacement(rotCarrier, G4ThreeVector(m_carrierPosX, yPos, m_carrierPosZ), logCrossCarrier, "physCrossCarrier", logCROSS, false, 0); if( m_verboseLevel > 0 ) { G4cout << G4endl; G4cout << "=== location of the CROSS carrier wrt CROSS system ===" << G4endl; G4cout << m_carrierPosX << ", " << yPos << ", " << m_carrierPosZ << G4endl; G4cout << "======================================" << G4endl; G4cout << G4endl; } if( m_verboseLevel > 0 ) { G4float densityAl = mateAl->GetDensity()/(g/cm3); G4float piece0Mass = logPiece0->GetMass()/g; G4float piece0Vol = piece0Mass / densityAl; G4float piece1Mass = logPiece1->GetMass()/g; G4float piece1Vol = piece1Box->GetCubicVolume()/cm3; G4float piece2Mass = logPiece2->GetMass()/g; G4float piece2Vol = piece2Mass / densityAl; G4float piece3Mass = logPiece3->GetMass()/g; G4float piece3Vol = piece3Mass / densityAl; G4float piece4Mass = logPiece4->GetMass()/g; G4float piece4Vol = piece4Mass / densityAl; G4float piece5Mass = logPiece5->GetMass()/g; G4float piece5Vol = piece5Mass / densityAl; G4float piece6Mass = logPiece6->GetMass()/g; G4float piece6Vol = piece6Box->GetCubicVolume()/cm3; G4float piece7Mass = logPiece7->GetMass()/g; G4float piece7Vol = piece7Box->GetCubicVolume()/cm3; G4float piece8Mass = logPiece8->GetMass()/g; G4float piece8Vol = piece8Box->GetCubicVolume()/cm3; G4float piece9Mass = logPiece9->GetMass()/g; G4float piece9Vol = piece9Box->GetCubicVolume()/cm3; G4float piece10Mass = logPiece10->GetMass()/g; G4float piece10Vol = piece10Box->GetCubicVolume()/cm3; G4float totalMass = 2.*(piece0Mass + piece2Mass + piece3Mass + piece4Mass + piece5Mass + piece8Mass + piece9Mass + piece10Mass) + nPiece1*piece1Mass + 4.*(piece6Mass + piece7Mass); G4float totalVol = 2.*(piece0Vol + piece2Vol + piece3Vol + piece4Vol + piece5Vol + piece8Vol + piece9Vol + piece10Vol) + nPiece1*piece1Vol + 4.*(piece6Vol + piece7Vol); G4cout << "**************VOLUME MASS****************" << G4endl; G4cout << " part: mass (g)\t volume (cm^3)" << G4endl; G4cout << " piece 0: " << piece0Mass << ", \t" << piece0Vol << G4endl; G4cout << " piece 1: " << piece1Mass << ", \t" << piece1Vol << G4endl; G4cout << " piece 2: " << piece2Mass << ", \t" << piece2Vol << G4endl; G4cout << " piece 3: " << piece3Mass << ", \t" << piece3Vol << G4endl; G4cout << " piece 4: " << piece4Mass << ", \t" << piece4Vol << G4endl; G4cout << " piece 5: " << piece5Mass << ", \t" << piece5Vol << G4endl; G4cout << " piece 6: " << piece6Mass << ", \t" << piece6Vol << G4endl; G4cout << " piece 7: " << piece7Mass << ", \t" << piece7Vol << G4endl; G4cout << " piece 8: " << piece8Mass << ", \t" << piece8Vol << G4endl; G4cout << " piece 9: " << piece9Mass << ", \t" << piece9Vol << G4endl; G4cout << " piece 10: " << piece10Mass << ", \t" << piece10Vol << G4endl; G4cout << " CROSS total: " << totalMass << ", \t" << totalVol << G4endl; G4cout << "**********END VOLUME MASS****************" << G4endl; } G4cout << G4endl << "************** END CROSS construction****************" << G4endl; return logCROSS; }