Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

LayeredTube.cxx

Go to the documentation of this file.
00001 // $Id: LayeredTube.cxx,v 1.5 2001/01/23 03:41:32 burnett Exp $
00002 //
00003 // This file is part of Gismo2
00004 //
00005 
00006 #ifdef HAVE_CONFIG_H
00007 #include "config.h"
00008 #endif
00009 
00010 #include "LayeredTube.h"
00011 
00012 #include "gismo/Detector.h"
00013 #include "gismo/Material.h"
00014 
00015 #include "geometry/Tube.h"
00016 #include "geometry/Ray.h"
00017 #include "geometry/Intersection.h"
00018 
00019 #include "geomrep/TubeRep.h"
00020 
00021 #include <strstream>
00022 #include <cassert>
00023 
00024 
00026 //                       construction
00027 
00028 LayeredTube::LayeredTube(Medium* parent, float dz, float r)
00029 : CompositeMedium(parent)
00030 , m_dz(dz)
00031 , m_r_inner(r)
00032 , first(0), last(0)
00033 {
00034 }
00035 LayeredTube::Layer::Layer(Medium* parent, const char* matname, Detector* det)
00036 : Medium(parent, (Shape*) 0, matname, det) {}
00037 
00038 Medium&
00039 LayeredTube::addLayer(float thickness, const char* matname, Detector* det)
00040 {
00041    Layer* newLayer = new Layer(this, matname, det);
00042 
00043    if( first == 0 )
00044    {
00045       first = last = newLayer;
00046       first->min_r = m_r_inner;
00047       m_r_outer = first->max_r = first->min_r+thickness;
00048       first->previous = 0;
00049       first->next = 0;
00050       setVolume( new Tube(m_dz, m_r_inner, m_r_outer) );
00051    }
00052    else
00053    {
00054       newLayer->min_r = last->max_r;
00055       m_r_outer =newLayer->max_r = newLayer->min_r+thickness;
00056       newLayer->previous = last;
00057       newLayer->next = 0;
00058       last->next = newLayer;
00059       last = newLayer;
00060       delete &tube();
00061       setVolume(new Tube(m_dz, m_r_inner, m_r_outer) );
00062    }
00063 
00064    newLayer->setVolume(new Tube(m_dz, newLayer->min_r, newLayer->max_r) );
00065    std::ostrstream label;
00066    label << "Layer " << innerMediaCount() << '\0';
00067    newLayer->setTitle(label.str());
00068    return *newLayer;
00069 }
00070 
00072 //                            propagation
00073 
00074 
00075 double
00076 LayeredTube::distanceToEnter(const Ray& r, const Medium*& m, double t)const
00077 {
00078   // override this to select a Layer to enter.
00079   // first, do we enter the overall volume?
00080   double d = Medium::distanceToEnter(r,m,t);
00081 
00082   if( d != FLT_MAX ){
00083 
00084     m = select(r.position(d));
00085    }
00086   return d;
00087 
00088 }
00089 
00090 double
00091 LayeredTube::distanceToLeave(const Ray& r, const Medium*& newStuff
00092                    , double maxDist)const
00093 {
00094   newStuff = parent();
00095   return 0.;
00096 }
00097 
00098 const LayeredTube::Layer*
00099 LayeredTube::select(const Point& x)const
00100 {
00101     Vector r = x - origin();
00102     double rlocal = sqrt( r.mag2() - sqr(r*axis()) );
00103     const Layer* layer=first;
00104 
00105     while( (rlocal>layer->max_r) && layer->next)
00106     {
00107          layer = layer->next;
00108     }
00109     return layer;
00110 }
00111 
00112 const Medium*
00113 LayeredTube::inside(const Point& x)const
00114 {
00115   if( ! tube().inside(x) ) return parent();
00116   return select(x);
00117 }
00118 
00119 double
00120 LayeredTube::Layer::distanceToLeave(const Ray& x, const Medium*& nextMed
00121                    , double maxStep)const
00122 {
00123 #ifdef _DEBUG
00124     const Tube* mytube=(const Tube*)(&volume());
00125     for( int i=0; i< mytube->surfaceCount(); i++){
00126         double dist = mytube->surface(i).how_near(x.position());
00127 
00128         assert( dist > -5e-6);
00129     }
00130 #endif
00131     // first get distance to leave using the local tube
00132     double d = volume().distanceToLeave(x,  maxStep);
00133 
00134     if( d==FLT_MAX ) {
00135         std::ostrstream error_text;
00136         Vector r = x.position()-origin();
00137 
00138         error_text << "LayeredTube::Layer::distanceToLeave: point not inside??\n"
00139                    << "\tRay= " << x << '\n'
00140                    << "\tlocal radius, z = " << sqrt( r.mag2() - sqr(r*axis()) )
00141                    <<     ", " << r*axis() << '\n'
00142                    << "\tOrigin= " << origin() << "; axis= "<< axis() << '\n'
00143                    << "\tmin_r, max_r = " << min_r << "  " << max_r << '\n';
00144         error_text << '\0';
00145         WARNING(error_text.str());
00146         return d;
00147     }
00148     else if( d < maxStep) {
00149         // now figure out which way we are going and return the next medium
00150         Vector r = x.position(d)-origin();
00151         double local_z = r*axis();
00152         if( fabs(local_z)>= parentTube().length()/2.0)
00153             nextMed=0;
00154         else {
00155             Vector rhohat = (r - local_z*axis()).unit(); // unit vector in rho direction
00156             double slope = x.direction(d)*rhohat;
00157             nextMed = slope>0 ? next : previous;
00158         }
00159         d += 1e-7; // a little push if hit boundary
00160     }
00161     if( nextMed==0 ) {  // maybe went out the front or back
00162         nextMed = parent();
00163     }
00164 #ifdef _DEBUG
00165     {
00166     mytube=(const Tube*)(&nextMed->volume());
00167     for( int i=0; i< mytube->surfaceCount(); i++){
00168         double dist = mytube->surface(i).how_near(x.position(d));
00169 
00170         assert( dist > -1e-7);
00171     }
00172     }
00173 #endif
00174 
00175     return d;
00176 }
00178 //                              transform
00179 GeomObject&
00180 LayeredTube::transform(const CoordTransform& T)
00181 {
00182     CompositeMedium::transform(T);
00183     m_origin.transform(T);
00184     return *this;
00185 }
00186 
00187 
00188 GeomObject&
00189 LayeredTube::Layer::transform(const CoordTransform& T)
00190 {
00191     Medium::transform(T);
00192     return *this;
00193 }
00194 
00195 
00197 //                              display
00198 static const Tube* motherTube;   // file scope variable allowing layers access to enclosing box
00199 static bool even;               // tag even/odd so can draw only every other layer
00200 void
00201 LayeredTube::createDetectorView(gui::DisplayRep& view)
00202 {
00203     motherTube = &tube();
00204     even = true;
00205     CompositeMedium::createDetectorView(view);
00206 }
00207 void
00208 LayeredTube::Layer::createDetectorView(gui::DisplayRep& view)
00209 {
00210     if( even )  view.append( TubeRep( (Tube&)volume()) );
00211     even = ! even;
00212 }
00214 //                              print
00215 void
00216 LayeredTube::Layer::printOn(std::ostream& os)const
00217 {
00218         os << " LayeredTube::Layer - title: "<<_title<<"\n"
00219            << "             _maxStep = " << maxStep()
00220            << " keCutOff = "<< kECutOff() << " \n";
00221 //      _field->printOn(os);
00222         os << " Material: "
00223            << _material->name() << "\tr-range: "<< min_r << " to " << max_r << "\n";
00224 
00225  }
00226 

Generated at Mon Nov 26 18:18:33 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000