@@ -68,6 +68,7 @@ using namespace moab;
6868#include " DagSolid.hh"
6969
7070#define plot true
71+ #define debug false
7172
7273// #define G4SPECSDEBUG 1
7374// /////////////////////////////////////////////////////////////////////////////
@@ -121,27 +122,30 @@ DagSolid::DagSolid(const G4String& name, DagMC* dagmc, int volID)
121122
122123 Interface* moab = dagmc->moab_instance ();
123124 moab->get_child_meshsets (fvolEntity, surfs, 1 );
124-
125+ int sense = 0 ;
125126 if (plot) {
126127 for (unsigned i = 0 ; i < surfs.size (); i++) {
127128 My_sulf_hit = surfs[i];
128129 moab->get_number_entities_by_type (surfs[i], MBTRI, num_entities);
129-
130130 moab->get_entities_by_type (surfs[i], MBTRI, tris);
131-
131+ dagmc-> surface_sense (fvolEntity,surfs[i],sense);
132132 for (unsigned j = 0 ; j < tris.size (); j++) {
133133 moab->get_connectivity (tris[j], tri_conn, n_verts);
134134 moab->get_coords (tri_conn, n_verts, coords[0 ].array ());
135135
136- vertex[0 ] = G4ThreeVector (coords[0 ][0 ] * cm, coords[0 ][1 ] * cm,
137- coords[0 ][2 ] * cm);
138- vertex[1 ] = G4ThreeVector (coords[1 ][0 ] * cm, coords[1 ][1 ] * cm,
139- coords[1 ][2 ] * cm);
140- vertex[2 ] = G4ThreeVector (coords[2 ][0 ] * cm, coords[2 ][1 ] * cm,
141- coords[2 ][2 ] * cm);
142-
143- G4TriangularFacet* facet =
144- new G4TriangularFacet (vertex[0 ], vertex[1 ], vertex[2 ], ABSOLUTE);
136+ vertex[0 ] = G4ThreeVector (coords[0 ][0 ] * cm, coords[0 ][1 ] * cm,
137+ coords[0 ][2 ] * cm);
138+ vertex[1 ] = G4ThreeVector (coords[1 ][0 ] * cm, coords[1 ][1 ] * cm,
139+ coords[1 ][2 ] * cm);
140+ vertex[2 ] = G4ThreeVector (coords[2 ][0 ] * cm, coords[2 ][1 ] * cm,
141+ coords[2 ][2 ] * cm);
142+
143+ G4TriangularFacet* facet = NULL ;
144+ if ( sense > 0 ) {
145+ facet = new G4TriangularFacet (vertex[0 ], vertex[1 ], vertex[2 ], ABSOLUTE);
146+ } else {
147+ facet = new G4TriangularFacet (vertex[2 ], vertex[1 ], vertex[0 ], ABSOLUTE);
148+ }
145149 AddFacet ((G4VFacet*)facet);
146150
147151 for (G4int k = 0 ; k < 3 ; k++) {
@@ -190,40 +194,45 @@ DagSolid::~DagSolid() {}
190194EInside DagSolid::Inside (const G4ThreeVector& p) const {
191195 G4double point[3 ] = {p.x () / cm, p.y () / cm, p.z () / cm}; // convert to cm
192196
193- double u = rand ();
194- double v = rand ();
195- double w = rand ();
196-
197- const double magnitude = sqrt (u * u + v * v + w * w);
198- u /= magnitude;
199- v /= magnitude;
200- w /= magnitude;
201-
202- G4double direction[3 ] = {u, v, w};
203-
204197 G4double minDist = 0.0 ;
205198
206199 int result;
207200 ErrorCode ec;
208- ec = fdagmc->point_in_volume (
209- fvolEntity, point, result,
210- direction); // if uvw is not given, this function generate uvw ran
211201
212- if (ec != MB_SUCCESS) {
213- G4cout << " failed to get point in volume" << std::endl;
214- exit (1 );
202+ if (debug) {
203+ std::cout << " Inside: " << std::endl;
215204 }
216-
217- ec = fdagmc->closest_to_location (fvolEntity, point, minDist);
205+
206+ // are we inside
207+ fdagmc->point_in_volume (fvolEntity, point, result);
208+ // also need to know how far from the surface
209+ fdagmc->closest_to_location (fvolEntity, point, minDist);
218210
219211 // if on surface
220- if (minDist <= 0.5 * kCarTolerance ) {
212+ if (minDist <= kCarToleranceHalf ) {
213+ if (debug) {
214+ std::cout << " dist: " << minDist << std::endl;
215+ std::cout << " inside: " << result << std::endl;
216+ std::cout << " return: (onsurf) " << kSurface << std::endl;
217+ }
221218 return kSurface ;
222219 } else {
223- if (result == 0 )
220+ // result == 0 is outside
221+ if (result == 0 || minDist > kCarToleranceHalf ) {
222+ if (debug) {
223+ std::cout << " dist: " << minDist << std::endl;
224+ std::cout << " inside: " << result << std::endl;
225+ std::cout << " return: (outside) " << kOutside << std::endl;
226+ }
224227 return kOutside ;
225- else
228+ } else {
229+ if (debug) {
230+ std::cout << " dist: " << minDist << std::endl;
231+ std::cout << " inside: " << result << std::endl;
232+ std::cout << " return: (inside) " << kInside << std::endl;
233+ }
226234 return kInside ;
235+ }
227236 }
228237}
229238
@@ -237,7 +246,9 @@ EInside DagSolid::Inside(const G4ThreeVector& p) const {
237246G4ThreeVector DagSolid::SurfaceNormal (const G4ThreeVector& p) const {
238247 G4double ang[3 ] = {0 , 0 , 1 };
239248 G4double position[3 ] = {p.x () / cm, p.y () / cm, p.z () / cm}; // convert to cm
240-
249+
250+ // currently get warnings from RTI.cpp in double down since the
251+ // point may not be on the surface
241252 fdagmc->get_angle (My_sulf_hit, position, ang);
242253
243254 G4ThreeVector normal = G4ThreeVector (ang[0 ], ang[1 ], ang[2 ]);
@@ -253,24 +264,44 @@ G4double DagSolid::DistanceToIn(const G4ThreeVector& p,
253264 const G4ThreeVector& v) const {
254265 G4double minDist = kInfinity ;
255266 G4double position[3 ] = {p.x () / cm, p.y () / cm, p.z () / cm}; // convert to cm
256- G4double dir[3 ] = {v.x (), v.y (), v.z ()};
267+ G4ThreeVector vec = v.unit ();
268+ G4double dir[3 ] = {vec.x (), vec.y (), vec.z ()};
257269 EntityHandle next_surf;
258270 G4double distance;
259-
260- DagMC::RayHistory history;
271+ G4double forwardDistance,reverseDistance;
261272
262273 // perform the ray fire with modified dag call
263- fdagmc->ray_fire (fvolEntity, position, dir, next_surf, distance, &history , 0 ,
264- -1 );
265- history. reset () ;
274+ fdagmc->ray_fire (fvolEntity, position, dir, next_surf, forwardDistance, NULL , 0 , 1 );
275+ fdagmc-> ray_fire (fvolEntity, position, dir, next_surf, reverseDistance, NULL , 0 , -1 );
276+ distance = reverseDistance ;
266277 distance *= cm; // convert back to mm
267278
268- if (next_surf == 0 ) // no intersection
279+ if (debug) {
280+ std::cout << " DistanceToIn(trace) " << std::endl;
281+ std::cout << " pos: " << p.x () << " " << p.y () << " " << p.z () << std::endl;
282+ std::cout << " distance: " << distance << std::endl;
283+ std::cout << " direction: " << v.x () << " " << v.y () << " " << v.z () << std::endl;
284+ std::cout << " forwraddistance: " << forwardDistance << std::endl;
285+ }
286+ if (next_surf == 0 ) { // no intersection
287+ if (debug) {
288+ std::cout << " hit:nothing" << std::endl;
289+ std::cout << " return: " << kInfinity << std::endl;
290+ }
269291 return kInfinity ;
270- else if (-kCarTolerance * 0.5 >= distance && distance <= kCarTolerance * 0.5 )
292+ } else if (distance <= std::abs (kCarToleranceHalf )) {
293+ if (debug) {
294+ std::cout << " hit:on surface" << std::endl;
295+ std::cout << " return: " << 0.0 << std::endl;
296+ }
271297 return 0.0 ;
272- else
298+ } else {
299+ if (debug) {
300+ std::cout << " hit:surface" << std::endl;
301+ std::cout << " return: " << distance << std::endl;
302+ }
273303 return distance;
304+ }
274305}
275306
276307// /////////////////////////////////////////////////////////////////////////////
@@ -287,10 +318,17 @@ G4double DagSolid::DistanceToIn(const G4ThreeVector& p) const {
287318
288319 fdagmc->closest_to_location (fvolEntity, point, minDist);
289320 minDist *= cm; // convert back to mm
290- if (minDist <= kCarTolerance * 0.5 )
291- return 0.0 ;
292- else
293- return minDist;
321+
322+ if (debug) {
323+ std::cout << " DistanceToIn(point)" << std::endl;
324+ std::cout << " pos: " << p.x () << " " << p.y () << " " << p.z () << std::endl;
325+ std::cout << " return: " << minDist << std::endl;
326+ }
327+
328+ // if (minDist <= kCarToleranceHalf)
329+ // return 0.0;
330+ // else
331+ return minDist;
294332}
295333
296334// /////////////////////////////////////////////////////////////////////////////
@@ -314,40 +352,71 @@ G4double DagSolid::DistanceToIn(const G4ThreeVector& p) const {
314352G4double DagSolid::DistanceToOut (const G4ThreeVector& p, const G4ThreeVector& v,
315353 const G4bool calcNorm, G4bool* validNorm,
316354 G4ThreeVector* n) const {
317- G4double minDist = kInfinity ;
318- double position[3 ] = {p.x () / cm, p.y () / cm,
319- p. z () / cm}; // convert position to cm
320- double dir[3 ] = {v .x (), v .y (), v .z ()};
355+
356+ double position[3 ] = {p.x ()/ cm, p.y ()/cm, p. z ()/cm}; // convert position to cm
357+ G4ThreeVector vec = v. unit ();
358+ double dir[3 ] = {vec .x (), vec .y (), vec .z ()};
321359
322360 EntityHandle next_surf;
323- double next_dist ;
324- DagMC::RayHistory history ;
361+ G4double distance ;
362+ G4double forwardDistance, backwardDistance ;
325363
326- fdagmc->ray_fire (fvolEntity, position, dir, next_surf, next_dist, &history, 0 ,
327- 1 );
328- history.reset ();
329- next_dist *= cm; // convert back to mm
364+ fdagmc->ray_fire (fvolEntity,position,dir,next_surf,forwardDistance,NULL ,0 ,1 );
365+ fdagmc->ray_fire (fvolEntity,position,dir,next_surf,backwardDistance,NULL ,0 ,-1 );
330366
331- // no more surfaces
332- if (next_surf == 0 ) return kInfinity ;
367+ distance = forwardDistance;
333368
369+ if (debug) {
370+ std::cout << " DistanceToOut(trace) " << std::endl;
371+ std::cout << " pos: " << p.x () << " " << p.y () << " " << p.z () << std::endl;
372+ std::cout << " distance: " << distance << std::endl;
373+ std::cout << " direction: " << v.x () << " " << v.y () << " " << v.z () << std::endl;
374+ std::cout << " forwraddistance: " << forwardDistance << std::endl;
375+ }
376+
377+ // no surfaces to hit
378+ if (next_surf == 0 ) {
379+ if (debug) {
380+ std::cout << " return: kInfinity" << std::endl;
381+ }
382+ return kInfinity ;
383+ }
384+
385+ // calculate the normal
334386 if (calcNorm) {
335- *n = SurfaceNormal (p + minDist * v);
336- *validNorm = false ;
387+ *n = SurfaceNormal (p + v*distance);
388+ DagMC::RayHistory history;
389+ // fire twice
390+ fdagmc->ray_fire (fvolEntity,position,dir,next_surf,forwardDistance,&history,0 ,1 );
391+ fdagmc->ray_fire (fvolEntity,position,dir,next_surf,forwardDistance,&history,0 ,1 );
392+ if (next_surf != 0 )
393+ *validNorm = true ;
394+ else
395+ *validNorm = false ;
337396 }
338397
339- if (next_dist < minDist) minDist = next_dist;
340-
341- // particle considered to be on surface
342- if (minDist > 0.0 && minDist <= 0.5 * kCarTolerance ) {
398+ // must convert here since previous needs it in cm
399+ distance *= cm; // convert back to mm
400+
401+ // we are on a surface
402+ if ( distance > 0.0 && distance <= kCarToleranceHalf ) {
403+ if (debug) {
404+ std::cout << " on a surface" << std::endl;
405+ std::cout << " distance: " << distance << std::endl;
406+ }
343407 return 0.0 ;
344- } else if (minDist < kInfinity ) {
345- if (calcNorm) // if calc norm true,s should set validNorm true
346- *validNorm = true ;
347- return minDist;
348- } else {
349- return 0.0 ; // was kinfinity
350408 }
409+
410+ // distance greater than kCarTolerance
411+ if ( distance > 0.0 ) {
412+ if (debug) {
413+ std::cout << " normal intersection" << std::endl;
414+ std::cout << " distance: " << distance << std::endl;
415+ }
416+ return distance;
417+ }
418+ std::cout << " help" << std::endl;
419+ return 0.0 ;
351420}
352421
353422// /////////////////////////////////////////////////////////////////////////////
@@ -361,11 +430,11 @@ G4double DagSolid::DistanceToOut(const G4ThreeVector& p) const {
361430 G4double point[3 ] = {p.x () / cm, p.y () / cm, p.z () / cm}; // convert to cm
362431
363432 fdagmc->closest_to_location (fvolEntity, point, minDist);
364- minDist *= cm; // convert back to mm
365- if (minDist < kCarTolerance / 2.0 )
433+ minDist *= cm;
434+ if (minDist < kCarToleranceHalf )
366435 return 0.0 ;
367436 else
368- return minDist;
437+ return minDist; // convert back to mm
369438}
370439
371440// /////////////////////////////////////////////////////////////////////////////
0 commit comments