source: trunk/source/geometry/solids/CSG/test/testG4Sphere2.cc @ 1347

Last change on this file since 1347 was 1347, checked in by garnier, 13 years ago

geant4 tag 9.4

File size: 14.2 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26
27// $Id: testG4Sphere2.cc,v 1.6 2007/05/18 10:24:32 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-04-ref-00 $
29//
30// G4Sphere Test File
31//
32// o Basic asserts on each function +
33//   awkward cases for tracking / geom algorithms
34//
35// o Add tests on dicovering bugs in G4Sphere.cc...
36//
37// History:
38// 28.03.95 P.Kent Initial version
39// 20.10.96 V.Grichine Final modifications to commit
40
41#include "G4ios.hh"
42#include <assert.h>
43#include <cmath>
44#include "globals.hh"
45#include "geomdefs.hh"
46#include "G4GeometryTolerance.hh"
47
48#include "ApproxEqual.hh"
49
50#include "G4ThreeVector.hh"
51#include "G4RotationMatrix.hh"
52#include "G4AffineTransform.hh"
53#include "G4VoxelLimits.hh"
54#include "G4Sphere.hh"
55
56//const G4double kApproxEqualTolerance = kCarTolerance;
57
58// Return true if the double check is approximately equal to target
59//
60// Process:
61//
62// Return true is difference < kApproxEqualTolerance
63
64//G4bool ApproxEqual(const G4double check,const G4double target)
65//{
66//    return (std::fabs(check-target)<kApproxEqualTolerance) ? true : false ;
67//}
68
69// Return true if the 3vector check is approximately equal to target
70//G4bool ApproxEqual(const G4ThreeVector& check, const G4ThreeVector& target)
71//{
72//    return (ApproxEqual(check.x(),target.x())&&
73//         ApproxEqual(check.y(),target.y())&&
74//          ApproxEqual(check.z(),target.z()))? true : false;
75//}
76
77///////////////////////////////////////////////////////////////////
78//
79// Dave's auxiliary function
80
81const G4String OutputInside(const EInside a)
82{
83        switch(a) 
84        {
85                case kInside:  return "Inside"; 
86                case kOutside: return "Outside";
87                case kSurface: return "Surface";
88        }
89        return "????";
90}
91
92
93
94int main(void)
95{
96  G4double kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance();
97
98  G4ThreeVector pzero(0,0,0),px(30,0,0),py(0,30,0),pz(0,0,30);
99  G4ThreeVector Pmx(-30,0,0),pmy(0,-30,0),pmz(0,0,-30);
100  G4ThreeVector pbigx(100,0,0),pbigy(0,100,0),pbigz(0,0,100);
101  G4ThreeVector pbigmx(-100,0,0),pbigmy(0,-100,0),pbigmz(0,0,-100);
102
103  G4ThreeVector ponrmin1(45,0,0),ponrmax1(50,0,0),ponzmax(0,0,50),
104          ponrmin2(45/std::sqrt(2.),45/std::sqrt(2.),0),
105          ponrmin3(0,0,-45),ponrminJ(0,0,-300),ponrmaxJ(0,0,-500),
106          ponrmax2(50/std::sqrt(2.),50/std::sqrt(2.),0);
107  G4ThreeVector ponphi1(48/std::sqrt(2.),-48/std::sqrt(2.),0),
108                ponphi2(48/std::sqrt(2.),48/std::sqrt(2.),0),
109                pInPhi(48*0.866,-24,0),
110                pOverPhi(-48/std::sqrt(2.),48/std::sqrt(2.),0);
111  G4ThreeVector pontheta1(0,48*std::sin(pi/4),48*std::cos(pi/4)),
112                 pontheta2(0,48*std::sin(pi/4),-48*std::cos(pi/4));
113
114  G4ThreeVector ptestphi1(-100,-45/std::sqrt(2.),0),
115                ptestphi2(-100,45/std::sqrt(2.),0);
116  G4ThreeVector ptesttheta1(0,48/std::sqrt(2.),100),
117                ptesttheta2(0,48/std::sqrt(2.),-100);
118
119  G4ThreeVector vx(1,0,0),vy(0,1,0),vz(0,0,1);
120  G4ThreeVector vmx(-1,0,0),vmy(0,-1,0),vmz(0,0,-1);
121  G4ThreeVector vxy(1/std::sqrt(2.),1/std::sqrt(2.),0),
122                vmxmy(-1/std::sqrt(2.),-1/std::sqrt(2.),0);
123  G4ThreeVector vxmy(1/std::sqrt(2.),-1/std::sqrt(2.),0),
124                vmxy(-1/std::sqrt(2.),1/std::sqrt(2.),0);
125  G4ThreeVector v345exit1(-0.8,0.6,0),v345exit2(0.8,0.6,0),
126                v345exit3(0.6,0.8,0);
127  G4ThreeVector norm,*pNorm;
128  G4bool *pgoodNorm,goodNorm;
129
130  pNorm=&norm;
131  pgoodNorm=&goodNorm;
132
133
134  G4bool checkPoint( const G4Sphere& pSph, G4ThreeVector origin,
135                           G4double  d,    G4ThreeVector dir,    EInside  exp); 
136
137  G4Sphere SpAroundX("SpAroundX",  10.*mm, 1000.*mm, 
138         -1.0*degree, 2.0*degree, 0.*degree, 180.0*degree );
139
140  G4double  sinOneDeg = std::sin( 1.0 * degree );
141  G4double  radOne = 100.0 * mm;
142
143  G4ThreeVector  ptPhiSurfExct= G4ThreeVector( radOne * std::cos( -1.0 * degree ) , 
144                                     - radOne *  sinOneDeg, 
145                                      0.0 );
146  G4cout << " Starting from point " << ptPhiSurfExct << G4endl;
147  G4cout << "   using direction   " << vy << G4endl; 
148  checkPoint( SpAroundX, ptPhiSurfExct, -radOne * kAngTolerance * 1.5, 
149                    vy,   kOutside); 
150  checkPoint( SpAroundX, ptPhiSurfExct, -radOne * kAngTolerance * 0.49, 
151                    vy,   kSurface); 
152  checkPoint( SpAroundX, ptPhiSurfExct, -radOne * kAngTolerance * 0.25, 
153                    vy,   kSurface); 
154  checkPoint( SpAroundX, ptPhiSurfExct,  0.0,
155                    vy,   kSurface); 
156  checkPoint( SpAroundX, ptPhiSurfExct,  radOne * kAngTolerance * 0.25, 
157                    vy,   kSurface); 
158  checkPoint( SpAroundX, ptPhiSurfExct,  radOne * kAngTolerance * 0.49, 
159                    vy,   kSurface); 
160  checkPoint( SpAroundX, ptPhiSurfExct,  radOne * kAngTolerance * 1.5, 
161                    vy,   kInside); 
162
163  // Try one that has a 'deep' negative phi section
164  //   --> Vlad. Grichine test case, 30 Oct 2003
165  //
166  G4cout << G4endl << G4endl << "" << G4endl;
167  G4cout << "========================================================= " << G4endl; 
168
169  G4Sphere SphDeepNeg("DeepNegPhiSphere",  10.*mm, 1000.*mm, 
170                           -270.0*degree, 280.0*degree,          //  start Phi,   delta Phi
171                            0.*degree, 180.0*degree );        //  start Theta, delta Theta
172  G4double phiPoint = 160.0 * degree; 
173  G4ThreeVector  StartPt( radOne * std::cos(phiPoint), radOne * std::sin(phiPoint), 0.0); 
174  G4cout << "For sphere " << SphDeepNeg.GetName() << G4endl;
175  G4cout << " Starting from point " << ptPhiSurfExct << G4endl;
176
177  checkPoint( SphDeepNeg, StartPt,  0.0,  vy,   kInside); 
178
179  // Try the edges 
180  G4ThreeVector  NegEdgePt( radOne * std::cos(-270.0*degree), 
181                            radOne * std::sin(-270.0*degree), 0.0); 
182  G4ThreeVector  PosEdgePt( radOne * std::cos(10.0*degree), 
183                            radOne * std::sin(10.0*degree), 0.0); 
184
185  G4cout << "--------------------------------------------------------" << G4endl; 
186  G4cout << " New point " << NegEdgePt << " should be at Neg edge of -270.0 degrees " <<  G4endl;
187  checkPoint( SphDeepNeg, NegEdgePt,  0.0,  -vx,   kSurface); 
188  checkPoint( SphDeepNeg, NegEdgePt,  radOne*kAngTolerance * 0.25,  -vx,   kSurface); 
189  checkPoint( SphDeepNeg, NegEdgePt, -radOne*kAngTolerance * 0.25,  -vx,   kSurface); 
190  checkPoint( SphDeepNeg, NegEdgePt,  radOne*kAngTolerance * 1.25,  -vx,   kInside); 
191  checkPoint( SphDeepNeg, NegEdgePt, -radOne*kAngTolerance * 1.25,  -vx,   kOutside); 
192
193  G4cout << "--------------------------------------------------------" << G4endl; 
194  G4cout << " New point " << PosEdgePt << " should be at Pos edge of +10.0 degrees " <<  G4endl;
195  checkPoint( SphDeepNeg, PosEdgePt,  0.0,  -vy,   kSurface); 
196  checkPoint( SphDeepNeg, PosEdgePt,  radOne*kAngTolerance * 0.25,  -vy,   kSurface); 
197  checkPoint( SphDeepNeg, PosEdgePt, -radOne*kAngTolerance * 0.25,  -vy,   kSurface); 
198  checkPoint( SphDeepNeg, PosEdgePt, -radOne*kAngTolerance * 1.25,  -vy,   kOutside); 
199  checkPoint( SphDeepNeg, PosEdgePt,  radOne*kAngTolerance * 1.25,  -vy,   kInside); 
200
201  G4double radMax= 1000.0 * mm; 
202  NegEdgePt = G4ThreeVector( radMax * std::cos(-270.0*degree), 
203                             radMax * std::sin(-270.0*degree), 0.0); 
204  G4cout << "--------------------------------------------------------" << G4endl; 
205  G4cout << " New point " << NegEdgePt << " should be at RadMax / Neg edge of -270.0 degrees " <<  G4endl;
206  checkPoint( SphDeepNeg, NegEdgePt,  0.0,  -vx,   kSurface); 
207  checkPoint( SphDeepNeg, NegEdgePt,  radMax*kAngTolerance * 0.25,  -vx,   kSurface); 
208  checkPoint( SphDeepNeg, NegEdgePt, -radMax*kAngTolerance * 0.25,  -vx,   kSurface); 
209  checkPoint( SphDeepNeg, NegEdgePt,  radMax*kAngTolerance * 1.25,  -vx,   kSurface); 
210  checkPoint( SphDeepNeg, NegEdgePt, -radMax*kAngTolerance * 1.25,  -vx,   kOutside); 
211
212  PosEdgePt= G4ThreeVector( radMax * std::cos(10.0*degree), 
213                            radMax * std::sin(10.0*degree), 0.0);
214 
215  G4cout << "--------------------------------------------------------" << G4endl; 
216  G4cout << " New point " << PosEdgePt << " should be at RadMax Pos edge of +10.0 degrees " <<  G4endl;
217  checkPoint( SphDeepNeg, PosEdgePt,  0.0,  -vy,   kSurface); 
218  checkPoint( SphDeepNeg, PosEdgePt,  radMax*kAngTolerance * 0.25,  -vy,   kSurface); 
219  checkPoint( SphDeepNeg, PosEdgePt, -radMax*kAngTolerance * 0.25,  -vy,   kSurface); 
220  checkPoint( SphDeepNeg, PosEdgePt, -radMax*kAngTolerance * 1.25,  -vy,   kOutside); 
221  checkPoint( SphDeepNeg, PosEdgePt,  radMax*kAngTolerance * 1.25,  -vy,   kSurface); 
222
223  G4ThreeVector NormInDir = - std::cos(10.0*degree) * vy + std::sin(10.0*degree) * vx; 
224
225  checkPoint( SphDeepNeg, PosEdgePt,  0.0,  -vy,   kSurface); 
226  checkPoint( SphDeepNeg, PosEdgePt,  radMax*kAngTolerance * 0.25, NormInDir, kSurface); 
227  checkPoint( SphDeepNeg, PosEdgePt, -radMax*kAngTolerance * 0.25, NormInDir, kSurface); 
228  checkPoint( SphDeepNeg, PosEdgePt, -radMax*kAngTolerance * 1.25, NormInDir, kOutside); 
229  checkPoint( SphDeepNeg, PosEdgePt,  radMax*kAngTolerance * 1.25, NormInDir, kSurface); 
230
231  return 0;
232}
233
234// Given the sphere 'rSphere', a point 'origin'
235//                                               -->     -->              -->
236//   the function below checks that the point    pnew=( origin + dist * direction )
237//     - the point (p+dist*dir) is located in the part of the solid given by 'expectedInResult'
238//     - and that from there, the DistanceToIn along 'dir' is not negative or Infinite
239//
240//  Use cases expected:
241//   - 'origin' is on/near a surface and 'direction' is pointing towards the inside of the solid
242
243G4bool
244checkPoint( const G4Sphere &rSphere, 
245            G4ThreeVector  origin, 
246            G4double       dist, 
247            G4ThreeVector  direction, 
248            EInside        expectedInResult)
249{
250  G4int verbose = 0, verboseErr= 2; 
251  G4bool  testAll = false ;   //  if false, do not call DistToIn if Outside etc.
252
253  G4double kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance();
254
255  G4ThreeVector newPoint; 
256  G4double  distIn = -1.0, distOut = -1.0; 
257
258  newPoint = origin + dist * direction; 
259
260  G4int oldPrecision= G4cout.precision(10); 
261  // G4cout << " --- Sphere " << rSphere.GetName() << "" << G4endl;
262
263  if( verbose > 0 ) 
264  {
265    G4cout << G4endl;
266    if (verbose > 2 ) G4cout << " Sphere " << rSphere.GetName();
267    G4cout.precision(10); 
268    if (verbose > 1 ) G4cout << " dir= " << direction;
269    G4cout << " dist= " << dist;
270  } 
271  EInside  inSphere=  rSphere.Inside( newPoint ) ; 
272                              /*======*/
273  G4cout.precision(15); 
274  // G4cout << " NewPoint  " << newPoint << " is "
275  G4bool goodIn= (inSphere == expectedInResult); 
276
277  if ( !goodIn ) 
278  {
279    G4cout << " ************ Unexpected Result for Inside *************** " << G4endl;
280  } 
281  if ( verbose || !goodIn ) 
282  {
283    G4cout << " New point " 
284           << " is "  <<  OutputInside( inSphere ) 
285           <<  " vs " <<  OutputInside( expectedInResult ) 
286           <<  " expected." <<  G4endl ;
287  }
288  G4bool goodDistIn = true; 
289
290  distIn = rSphere.DistanceToIn( newPoint, direction ); 
291                    /*===========*/
292  if ( verbose )  G4cout << " DistToIn (p, dir) = " << distIn << G4endl;
293
294  if( (inSphere == kOutside) && (distIn < 0.0 ) // Cannot use 0.5*kCarTolerance for Angular tolerance!!
295    )
296  {
297       G4cout << " ********** Unexpected Result for DistanceToIn from outside ********* " << G4endl;
298       // G4cout << " It should be " << G4endl;
299       goodDistIn = false;
300  }
301  if( (inSphere == kSurface ) && 
302      ( (distIn < 0.0) || (distIn >= kInfinity )) )
303  {
304      G4cout << " ********** Unexpected Result for DistanceToIn on surface   ********* " << G4endl;
305       // if ( (distIn != 0.0) )
306       //  -  Can check that the return value must be 0.0
307       //     But in general case the direction can be away from the solid,
308       //        and then a finite or kInfinity answer is correct
309       //        --> must check the direction against the normal
310       //            in order to perform this check in general case.
311
312       goodDistIn = false;
313  }
314  if ( verbose || !goodDistIn )
315  {
316      G4cout << " DistToIn (p, dir) = " << distIn << G4endl;
317  }
318  G4bool good= (goodIn && goodDistIn); 
319 
320  if ( !good )
321  { 
322       // There was an error -- document the use case!
323    G4cout << " --- Sphere " << rSphere.GetName() << "" << G4endl;
324
325    if ( verboseErr > 1 )
326    { 
327      G4cout << "  dist= " << dist ; // << G4endl;
328      G4cout << "  Direction= " << direction  ; // << G4endl;
329      G4cout << "  dist/kAngTolerance = " << dist / kAngTolerance << G4endl;
330      G4cout << "  Original pt=  " << origin << G4endl; 
331    }
332    G4cout <<   "  Actual-point= " << newPoint << G4endl;
333    G4cout <<   "  Rho= " << G4ThreeVector(newPoint.x(), newPoint.y(), 0.).mag() << G4endl;
334  } 
335  if( testAll || (inSphere!=kOutside) ) 
336  { 
337    distOut = rSphere.DistanceToOut( newPoint, direction ); 
338                       /*=============*/
339    if ( verbose ) G4cout << " DistToOut (p, dir) = " << distOut << G4endl;
340  }
341  G4cout.precision(oldPrecision); 
342
343  return good;
344}
Note: See TracBrowser for help on using the repository browser.