60 const G4double& halfWidth)
const
62 G4double sectionLength = 0;
63 G4double cumulativeAngle = 0;
65 G4double cumulativeX = 0;
67 sectionLength = ((*proposedEnd)->GetReferencePositionEnd() - (*proposedStart)->GetReferencePositionStart()).mag();
69 for (; it != proposedEnd; ++it)
71 cumulativeAngle += (*it)->GetAngle();
72 cumulativeX += std::cos((*it)->GetTilt()) * std::sin((*it)->GetAngle());
76 G4bool result =
false;
78 G4bool lengthTest =
false;
82 G4bool angleTest =
false;
83 if (std::abs(cumulativeAngle) >
maxAngle)
86 G4bool nItemsTest =
false;
90 G4bool dispXTest =
false;
94 result = lengthTest || angleTest || nItemsTest || dispXTest;
97 G4bool lengthTestFail = sectionLength <
minLength;
100 if (lengthTestFail && result && angleIsFinite)
108 G4double s = 1.5*halfWidth * std::abs(cumulativeAngle);
109 G4bool willOverlapFaces = sectionLength < 1.2*s;
110 if (willOverlapFaces)
114 G4cout << __METHOD_NAME__ <<
"testing cumulative parameters" << G4endl;
115 G4cout <<
"Cumulative Length (mm): " << sectionLength <<
" > " <<
maxLength <<
" test-> " << BDS::BoolToString(lengthTest) << G4endl;
116 G4cout <<
"Cumulative Angle (rad): " << cumulativeAngle <<
" > " <<
maxAngle <<
" test-> " << BDS::BoolToString(angleTest) << G4endl;
117 G4cout <<
"# of items: " << nItems <<
" > " <<
maxItems <<
" test-> " << BDS::BoolToString(nItemsTest) << G4endl;
119 <<
" test-> " << BDS::BoolToString(dispXTest) << G4endl;
120 G4cout <<
"Length: " << sectionLength <<
" < " <<
minLength <<
" test-> " << BDS::BoolToString(lengthTestFail) << G4endl;
121 G4cout <<
"Overlap Faces: " << s <<
" < " << sectionLength <<
" test-> " << BDS::BoolToString(willOverlapFaces) << G4endl;
122 G4cout <<
"Result: " << BDS::BoolToString(result) << G4endl;
136 G4int nTunnelSections = 0;
159 defaultModel->thickness,
160 defaultModel->soilThickness,
161 defaultModel->material,
162 defaultModel->soilMaterial,
163 defaultModel->buildFloor,
164 defaultModel->floorOffset,
177 for (; it != flatBeamline->
end(); ++it)
180 G4cout << __METHOD_NAME__ <<
"iterator at: " << (*it)->GetPlacementName() << G4endl;
181 G4cout << __METHOD_NAME__ <<
"start iterator at: " << (*startElement)->GetPlacementName() << G4endl;
182 G4cout << __METHOD_NAME__ <<
"end iterator at: " << (*endElement)->GetPlacementName() << G4endl;
184 G4bool breakIt =
BreakTunnel(startElement, endElement, halfWidth);
186 G4bool isEnd = (it == (flatBeamline->
end() - 1));
193 G4cout <<
"End of beam line - forcing break in tunnel" << G4endl;
194 G4cout <<
"End element for tunnel set to: " << (*endElement)->GetPlacementName() << G4endl;
195 G4cout <<
"Start element is: " << (*startElement)->GetPlacementName() << G4endl;
201 if (breakIt || isEnd)
204 std::string name =
"tunnel_" + std::to_string(nTunnelSections);
207 G4ThreeVector startPoint = (*startElement)->GetReferencePositionStart();
208 G4ThreeVector startOffsetLocal = G4ThreeVector(offsetX, offsetY, 0);
210 G4RotationMatrix* startRot =
new G4RotationMatrix(*(*startElement)->GetReferenceRotationStart());
211 G4ThreeVector startOffsetGlobal = startOffsetLocal.transform(*startRot);
212 startPoint += startOffsetGlobal;
218 G4ThreeVector endPoint = (*endElement)->GetReferencePositionEnd();
219 G4ThreeVector endOffsetLocal = G4ThreeVector(offsetX, offsetY, 0);
220 G4RotationMatrix* endRot =
new G4RotationMatrix(*(*endElement)->GetReferenceRotationEnd());
221 G4ThreeVector endOffsetGlobal = endOffsetLocal.transform(*endRot);
222 endPoint += endOffsetGlobal;
224 G4double sStart = (*startElement)->GetSPositionStart();
225 G4double sEnd = (*endElement)->GetSPositionEnd();
226 G4double sMid = 0.5*(sStart + sEnd);
230 G4ThreeVector midPoint = 0.5*(startPoint + endPoint);
237 G4ThreeVector delta = midPoint - startPoint;
238 G4ThreeVector newUnitZ = delta.unit();
240 G4ThreeVector unitXPrevious = G4ThreeVector(1,0,0).transform(*startRot);
241 G4ThreeVector newUnitY = newUnitZ.cross(unitXPrevious).unit();
243 G4ThreeVector unitYPrevious = G4ThreeVector(0,1,0).transform(*startRot);
244 G4ThreeVector newUnitX = unitYPrevious.cross(newUnitZ).unit();
247 G4RotationMatrix* rotationMiddle =
new G4RotationMatrix(newUnitX, newUnitY, newUnitZ);
250 G4double segmentLength = (endPoint - startPoint).mag() - 1*CLHEP::um;
254 G4ThreeVector unitZStart = G4ThreeVector(0,0,1).transform(*startRot);
255 G4ThreeVector unitZEnd = G4ThreeVector(0,0,1).transform(*endRot);
257 G4ThreeVector unitZDiff = unitZEnd - unitZStart;
258 G4bool isAngled = unitZDiff.mag() > 1e-30;
261 G4cout << __METHOD_NAME__ <<
"determined tunnel segment to have the following parameters:" << G4endl;
262 G4cout <<
"Start element name: " << (*startElement)->GetPlacementName() << G4endl;
263 G4cout <<
"End element name: " << (*endElement)->GetPlacementName() << G4endl;
264 G4cout <<
"Start point (global): " << startPoint << G4endl;
265 G4cout <<
"End point (global): " << endPoint << G4endl;
266 G4cout <<
"Input and output unit Z: " << unitZStart <<
" " << unitZEnd << G4endl;
267 G4cout <<
"Has a finite angle: " << isAngled << G4endl;
268 G4cout <<
"Section length: " << segmentLength << G4endl;
269 G4cout <<
"Rotation start: " << *startRot << G4endl;
270 G4cout <<
"Rotation middle: " << *rotationMiddle << G4endl;
271 G4cout <<
"Rotation end: " << *endRot << G4endl;
287 G4RotationMatrix* middleInverse =
new G4RotationMatrix(*rotationMiddle);
288 middleInverse->invert();
289 G4RotationMatrix* inputFaceRotation =
new G4RotationMatrix((*startRot) * (*middleInverse));
290 G4ThreeVector inputFace = G4ThreeVector(0,0,-1).transform(*inputFaceRotation);
291 G4RotationMatrix* outputFaceRotation =
new G4RotationMatrix((*endRot) * (*middleInverse));
292 G4ThreeVector outputFace = G4ThreeVector(0,0,1).transform(*outputFaceRotation);
298 G4cout <<
"tunnel segment input face normal determined to be: " << inputFace << G4endl;
299 G4cout <<
"tunnel segment output face normal determined to be: " << outputFace << G4endl;
307 defaultModel->thickness,
308 defaultModel->soilThickness,
309 defaultModel->material,
310 defaultModel->soilMaterial,
311 defaultModel->buildFloor,
312 defaultModel->floorOffset,
316 delete middleInverse;
323 defaultModel->thickness,
324 defaultModel->soilThickness,
325 defaultModel->material,
326 defaultModel->soilMaterial,
327 defaultModel->buildFloor,
328 defaultModel->floorOffset,
337 G4RotationMatrix* startRot2 =
new G4RotationMatrix(*startRot);
338 G4RotationMatrix* midRot2 =
new G4RotationMatrix(*rotationMiddle);
339 G4RotationMatrix* endRot2 =
new G4RotationMatrix(*endRot);
360 nTunnelSections += 1;
365 G4cout << __METHOD_NAME__ <<
"previous tunnel start element: " << (*startElement)->GetPlacementName() << G4endl;
366 G4cout << __METHOD_NAME__ <<
"previous tunnel end element: " << (*endElement)->GetPlacementName() << G4endl;
367 previousEndElement = endElement;
369 startElement = endElement;
371 endElement = startElement;
373 G4cout << __METHOD_NAME__ <<
"new start element: " << (*startElement)->GetPlacementName() << G4endl;
374 G4cout << __METHOD_NAME__ <<
"new tunnel start element: " << (*startElement)->GetPlacementName() << G4endl;
375 G4cout << __METHOD_NAME__ <<
"new tunnel previous end element: " << (*previousEndElement)->GetPlacementName() << G4endl;
383 G4cout << __METHOD_NAME__ <<
"moving to next item in beamline" << G4endl;