109 {
110
111
114 assert(tMgr);
116 assert(navigator);
117
119 const G4Field* globalField = 0;
120 const G4String intro =
"G4VFieldModel::DescribeYourselfTo: ";
121 if (globalFieldMgr) {
124 if (!globalField) {
125 static G4bool warned =
false;
126 if (!warned) {
127 G4cout << intro <<
"Null global field pointer." <<
G4endl;
128 warned = true;
129 }
130 }
131 }
132 } else {
133 static G4bool warned =
false;
134 if (!warned) {
135 G4cout << intro <<
"No global field manager." <<
G4endl;
136 warned = true;
137 }
138 }
139
147 const G4double xHalfScene = 0.5 * (xMax - xMin);
148 const G4double yHalfScene = 0.5 * (yMax - yMin);
149 const G4double zHalfScene = 0.5 * (zMax - zMin);
150 const G4double xSceneCentre = 0.5 * (xMax + xMin);
151 const G4double ySceneCentre = 0.5 * (yMax + yMin);
152 const G4double zSceneCentre = 0.5 * (zMax + zMin);
154 std::max(xHalfScene,std::max(yHalfScene,zHalfScene));
155 if (maxHalfScene <= 0.) {
157 return;
158 }
159
160
161 const G4double interval = maxHalfScene / fNDataPointsPerMaxHalfScene;
162 const G4int nDataPointsPerXHalfScene =
G4int(xHalfScene / interval);
163 const G4int nDataPointsPerYHalfScene =
G4int(yHalfScene / interval);
164 const G4int nDataPointsPerZHalfScene =
G4int(zHalfScene / interval);
165 const G4int nXSamples = 2 * nDataPointsPerXHalfScene + 1;
166 const G4int nYSamples = 2 * nDataPointsPerYHalfScene + 1;
167 const G4int nZSamples = 2 * nDataPointsPerZHalfScene + 1;
168 const G4int nSamples = nXSamples * nYSamples * nZSamples;
169 const G4double arrowLengthMax = 0.8 * interval;
170
171
172 std::vector<G4Point3D> Field(nSamples);
173 std::vector<G4Point3D> xyz(nSamples);
174 G4double FieldMagnitudeMax = -std::numeric_limits<G4double>::max();
175
176
177 for (
G4int i = 0; i < nXSamples; i++) {
178 G4double x = xSceneCentre + (i - nDataPointsPerXHalfScene) * interval;
179
180 for (
G4int j = 0; j < nYSamples; j++) {
181 G4double y = ySceneCentre + (j - nDataPointsPerYHalfScene) * interval;
182
183 for (
G4int k = 0; k < nZSamples; k++) {
184 G4double z = zSceneCentre + (k - nDataPointsPerZHalfScene) * interval;
185
186
187 const G4int ijk = i * nYSamples * nZSamples + j * nZSamples + k;
188 xyz[ijk].set(x,y,z);
189
191
192
194 const auto& ext = fExtentForField;
195 if (x < ext.GetXmin() || x > ext.GetXmax() ||
196 y < ext.GetYmin() || y > ext.GetYmax() ||
197 z < ext.GetZmin() || z > ext.GetZmax())
198 continue;
199 }
200
201
202 if (!fPVFindings.empty()) {
204 for (const auto& findings: fPVFindings) {
206 G4int copyNo = findings.fFoundPVCopyNo;
209 if (pvParam) {
211 solid = param->ComputeSolid(copyNo,pvParam);
213 }
214
215 const auto& transform = findings.fFoundObjectTransformation;
216 auto rotation = transform.getRotation();
217 auto translation = transform.getTranslation();
220 isInPV = true;
221 break;
222 }
223 }
224 if (!isInPV) continue;
225 }
226
227
228
231 const G4Field* field = globalField;
232 if (pPV) {
233
235 if (pLV) {
236
238 if (pRegion) {
240 if (pRegionFieldMgr) {
242
243 }
244 }
245
247 if (pLVFieldMgr) {
249
250 }
251 }
252 }
253
255
256
258
260 if (mag > FieldMagnitudeMax) FieldMagnitudeMax = mag;
261 }
262 }
263 }
264
265 if (FieldMagnitudeMax <= 0.) {
266 G4cout <<
"No " << fTypeOfField <<
" field in this extent." <<
G4endl;
267 return;
268 }
269
270 for (
G4int i = 0; i < nSamples; i++) {
271 const G4double Fmag = Field[i].mag();
272 const G4double f = Fmag / FieldMagnitudeMax;
273 if (f <= 0.) continue;
274
276 if (f < 0.5) {
277 green = 2. * f;
278 red = 2. * (0.5 - f);
279 } else {
280 blue = 2. * (f - 0.5);
281 green = 2. * (1.0 - f);
282 }
283 const G4Colour arrowColour(red,green,blue,alpha);
284
285
286 G4bool drawAsLine =
false;
287 switch (fRepresentation) {
289 if (f < 0.1) {
290 drawAsLine = true;
291 }
292 break;
294 drawAsLine = true;
295 break;
296 default:
297 break;
298 }
299
300
301 G4double arrowLength = arrowLengthMax * f;
302
303 if (f < 0.01) arrowLength = arrowLengthMax * 0.01;
304 const G4Point3D head = xyz[i] + arrowLength*Field[i]/Fmag;
305
306 if (drawAsLine) {
309 va.SetLineWidth(2.);
311 FArrowLite.push_back(xyz[i]);
312 FArrowLite.push_back(head);
316 } else {
318 head.
x(), head.
y(), head.
z(),
319 arrowLength/5, arrowColour,
320 fArrowPrefix+"Field",
321 fArrow3DLineSegmentsPerCircle);
322 FArrow.DescribeYourselfTo(sceneHandler);
323 }
324 }
325}
G4GLOB_DLL std::ostream G4cout
Hep3Vector & transform(const HepRotation &)
const G4Field * GetDetectorField() const
G4bool DoesFieldExist() const
G4VSolid * GetSolid() const
G4Region * GetRegion() const
G4FieldManager * GetFieldManager() const
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
G4VPVParameterisation * GetParameterisation() const
G4FieldManager * GetFieldManager() const
static G4TransportationManager * GetTransportationManager()
G4Navigator * GetNavigatorForTracking() const
G4FieldManager * GetFieldManager() const
virtual void GetFieldAtLocation(const G4Field *field, const G4Point3D &position, G4double time, G4Point3D &result) const =0
virtual void BeginPrimitives(const G4Transform3D &objectTransformation=G4Transform3D())=0
virtual void AddPrimitive(const G4Polyline &)=0
virtual const G4VisExtent & GetExtent() const
virtual void EndPrimitives()=0
G4LogicalVolume * GetLogicalVolume() const
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
void SetVisAttributes(const G4VisAttributes *)