Example #1
0
 public static bool listedIdentifier(string identifier)
 {
     if (MaterialProperties.materials.Count < 1)
     {
         MaterialProperties.buildMaterialList();
     }
     return(MaterialProperties.materials.ContainsKey(identifier));
 }
Example #2
0
 public double reflection(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial)
 {
     if (previousMaterial.dominantOnLeave)
     {
         return(previousMaterial.enterReflection(trace, norm, this));
     }
     return(this.enterReflection(trace, norm, previousMaterial));
 }
Example #3
0
 private void setDefaults(Object3dCollection parent, MaterialProperties mp)
 {
     this.tag                = this.GetType().ToString();
     this.parseOrder         = TraceJournal.Instance.rnd.NextDouble();
     this.materialproperties = mp;
     this.parent             = parent;
     if (this.hasParent())
     {
         this.parent.addObject3d(this);
     }
 }
Example #4
0
 public static MaterialProperties FromIdentifier(string identifier)
 {
     if (MaterialProperties.materials.Count < 1)
     {
         MaterialProperties.buildMaterialList();
     }
     Scientrace.MaterialProperties retmat = MaterialProperties.getMaterial(identifier);
     if (retmat == null)
     {
         throw new ArgumentException("MaterialProperties Identifier \"" + identifier + "\" is unknown.");
     }
     return(retmat);
 }
Example #5
0
        public static void buildMaterialList( )
        {
            //For backwards compatibility:
            MaterialProperties.materials.Add("suncyclepmma", AltPMMAProperties.Instance);

            MaterialProperties.addMaterial(PMMAProperties.Instance);
            MaterialProperties.addMaterial(AltPMMAProperties.Instance);
            MaterialProperties.addMaterial(BlackBodySurface.Instance);
            MaterialProperties.addMaterial(AirProperties.Instance);
            MaterialProperties.addMaterial(PerfectMirror.Instance);
            MaterialProperties.addMaterial(GaAsSurface.Instance);
            MaterialProperties.addMaterial(SodaLimeGlassProperties.Instance);
            MaterialProperties.addMaterial(SchottBK7Properties.Instance);
            //MaterialProperties.materialstablebuilt = true;
        }
        public Scientrace.Sphere parseXSphere(XElement xSphere)
        {
            if (xSphere.Name.ToString() != "Sphere")
            {
                throw new XMLException("Sphere does not match its name: " + xSphere.Name.ToString());
            }
            double radius = this.X.getXDouble(xSphere, "Radius");

            Scientrace.Location loc = this.X.getXLocation(xSphere, "Location");
            // Replaced with below: Scientrace.MaterialProperties materialprops = this.getXMaterial(xSphere.Element("Material"));
            Scientrace.MaterialProperties materialprops = this.getXMaterialForObject(xSphere);
            Scientrace.Sphere             tRetSphere    = new Scientrace.Sphere(this.parentcollection,
                                                                                materialprops, loc, radius);

            tRetSphere.setRefAxis(this.X.getXNzVectorByName(xSphere, "RefVec", null));
            return(tRetSphere);
        }
        public Scientrace.RectangularPrism parseXRectangularPrism(XElement xrectprism)
        {
            //try {
            //Console.WriteLine("Adding Square Prism");
            //check basic prerequisites
            if (xrectprism.Name.ToString() != "RectangularPrism")
            {
                throw new XMLException("RectangularPrism does not match its name: " + xrectprism.Name.ToString());
            }
            Scientrace.Vector width  = this.X.getXVectorByName(xrectprism, "Width");
            Scientrace.Vector length = this.X.getXVectorByName(xrectprism, "Length");
            Scientrace.Vector height = this.X.getXVectorByName(xrectprism, "Height");
            if (width.length * length.length * height.length == 0)
            {
                Console.WriteLine("WARNING: Rectangular Prism " + xrectprism.Attribute("Tag").Value + " has no volume and will " +
                                  "therefor not be created.");
                return(null);
            }
            Scientrace.Location location = null;
            if (xrectprism.Element("Center") == null)
            {
                location = this.X.getXVectorByName(xrectprism, "Location").toLocation();
            }
            else
            {
                location = (this.X.getXVectorByName(xrectprism, "Center") + (width * -0.5) + (length * -0.5) + (height * -0.5))
                           .toLocation();
            }

            Scientrace.MaterialProperties materialprops = this.getXMaterialForObject(xrectprism);

            /*
             * string materialid = this.X.getXStringByAttribute(xrectprism,"Material");
             * Scientrace.MaterialProperties material = Scientrace.MaterialProperties.FromIdentifier(materialid); */
            //tryToNonzeroVector operations below are permitted since the prism has a volume as was tested above.
            Scientrace.RectangularPrism tretprism = new Scientrace.RectangularPrism(this.parentcollection,
                                                                                    materialprops, location, width.tryToNonzeroVector(), height.tryToNonzeroVector(), length.tryToNonzeroVector());
            this.addCommonObjectProperties(tretprism, xrectprism);
            return(tretprism);

            /*	} catch(Exception e) {Console.WriteLine("Couldn't create RectangularPrism: "+this.X.getXString(xrectprism.Attribute("Tag")));
             *              throw(e);
             *      }*/
        }
/* replaced by ShadowScientrace factory
 *      public Scientrace.DoubleConvexLens parseXDoubleConvexLens(XElement xLens) {
 *
 *              if (xLens.Name.ToString() != "DoubleConvexLens") {
 *                      throw new XMLException("DoubleConvexLens does not match its name: "+xLens.Name.ToString());
 *                      }
 *
 *              Scientrace.MaterialProperties materialprops = this.getXMaterial(xLens.Element("Material"));
 *              Scientrace.Location lensPlaneCenterLoc = this.X.getXLocation(xLens, "LensPlaneCenter");
 *              Scientrace.NonzeroVector lensPlaneNormal = this.X.getXNzVectorByName(xLens, "LensPlaneNormal");
 *              double r1 = this.X.getXDouble(xLens, "Radius1");
 *              double r2 = this.X.getXDouble(xLens, "Radius2");
 *              double lensDiameter = this.X.getXDouble(xLens, "LensDiameter");
 *
 *              Scientrace.DoubleConvexLens tRetLens = null;
 *
 *              Scientrace.DoubleConvexLens.CreateWithLensDiameter(
 *                      this.parentcollection, materialprops, lensPlaneCenterLoc, lensPlaneNormal,
 *                      lensDiameter, r1, r2);
 *
 *              return tRetLens;
 *              }
 */


        public Scientrace.PlanoConvexLens parseXPlanoConvexLens(XElement xLens)
        {
            if (xLens.Name.ToString() != "PlanoConvexLens")
            {
                throw new XMLException("PlanoConvexLens does not match its name: " + xLens.Name.ToString());
            }

            // Replaced with below: Scientrace.MaterialProperties materialprops = this.getXMaterial(xLens.Element("Material"));
            Scientrace.MaterialProperties materialprops     = this.getXMaterialForObject(xLens);
            Scientrace.Location           lensFlatCenterLoc = this.X.getXLocation(xLens, "PlanoCenter");;
            Scientrace.NonzeroVector      sphereRadiusVec   = this.X.getXNzVectorByName(xLens, "SphereRadius");
            double lensDiameter = this.X.getXDouble(xLens, "LensDiameter");;

            Scientrace.PlanoConvexLens tRetLens = null;

            Scientrace.PlanoConvexLens.CreateWithLensDiameter(
                this.parentcollection, materialprops, lensFlatCenterLoc, lensDiameter, sphereRadiusVec);

            return(tRetLens);
        }
        public Scientrace.PlaneBorderEnclosedVolume parseXTruncatedPyramid(XElement xTruncatedPyramid)
        {
            // Replaced with below: Scientrace.MaterialProperties materialprops = this.getXMaterial(xToppedPyramid.Element("Material"));
            Scientrace.MaterialProperties materialprops = this.getXMaterialForObject(xTruncatedPyramid);

            if ((xTruncatedPyramid.Name.ToString() != "TruncatedPyramid") && (xTruncatedPyramid.Name.ToString() != "ToppedPyramid"))
            {
                throw new XMLException("TruncatedPyramid does not match its name: " + xTruncatedPyramid.Name.ToString());
            }

            List <Scientrace.Location> front_corners = new List <Scientrace.Location>();

            Scientrace.Vector loc_sum = new Scientrace.Vector(0, 0, 0);
            foreach (XElement xFrontCorner in xTruncatedPyramid.Elements("Corner"))
            {
                Scientrace.Location loc = this.X.getXLocation(xFrontCorner);
                front_corners.Add(loc);
                loc_sum = loc_sum + loc;
            }
            Scientrace.Vector   loc_avg     = loc_sum / front_corners.Count;
            Scientrace.Location virtual_top = this.X.getXLocation(xTruncatedPyramid, "VirtualTop");
            // parsing topping plane data:
            XElement xTopPlane = xTruncatedPyramid.Element("TopPlane");

            if (xTopPlane == null)
            {
                throw new XMLException("TopPlane element not found... " + xTruncatedPyramid.ToString());
            }
            Scientrace.Location      topPlaneLoc    = this.X.getXLocation(xTopPlane, "Location");
            Scientrace.NonzeroVector topPlaneNormal = this.X.getXNzVectorByName(xTopPlane, "Normal");
            if (topPlaneNormal.dotProduct((topPlaneLoc - loc_avg)) > 0)
            {
                topPlaneNormal = topPlaneNormal.negative();
            }
            Scientrace.PlaneBorder topping_plane = new Scientrace.PlaneBorder(topPlaneLoc, topPlaneNormal);

            Scientrace.PlaneBorderEnclosedVolume tRetTruncatedPyramid = Scientrace.PlaneBorderEnclosedVolume.createTruncatedPyramid(this.parentcollection, materialprops,
                                                                                                                                    front_corners, virtual_top, topping_plane);
            return(tRetTruncatedPyramid);
        }
Example #10
0
        public Object3dCollection[] division; //firsthalf, secondhalf;
        //public Scientrace.RectangularPrism dummyRect;

        /// <summary>
        /// The CircularFresnelPrism is developed specifically for the SunCycle system but can be used
        /// for different purposes. It generates a filled Object3dCollection with
        /// </summary>
        /// <param name="parent">
        /// A <see cref="Object3d"/>
        /// </param>
        /// <param name="surroundingsproperties">
        /// A <see cref="MaterialProperties"/>
        /// </param>
        /// <param name="loc">
        /// A <see cref="Location"/>
        /// </param>
        /// <param name="surfacev1">
        /// A <see cref="NonzeroVector"/> orthogonal to the prism-teeth "length"-direction.
        /// </param>
        /// <param name="surfacev2">
        /// A <see cref="NonzeroVector"/>
        /// </param>
        /// <param name="surfacev3">
        /// The Z axis </param>
        /// <param name="teethCount">
        /// A int representing the number of teeth over the fresnel surface.
        /// </param>
        /// <param name="fresnelMaterial">
        /// A <see cref="MaterialProperties"/>
        /// </param>

        public CircularFresnelPrism(Object3dCollection parent, MaterialProperties surroundingsproperties,
                                    Location loc, NonzeroVector surfacev1, NonzeroVector surfacev2, NonzeroVector zaxisheight,
                                    double largeAngle_rad, double shortAngle_rad, int teethCount,
                                    MaterialProperties fresnelMaterial)
            : base(parent, surroundingsproperties)
        {
            //check vectors
            try{ surfacev1.toUnitVector(); }
            catch { throw new ZeroNonzeroVectorException("Fresnel Prism surface 1 has length 0"); }
            try{ surfacev2.toUnitVector(); }
            catch { throw new ZeroNonzeroVectorException("Fresnel Prism surface 2 has length 0"); }
            try{ zaxisheight.toUnitVector(); }
            catch { throw new ZeroNonzeroVectorException("Z-axis height has length 0"); }

            //set attributes
            this.loc       = loc;
            this.surfacev1 = surfacev1;
            this.surfacev2 = surfacev2;
            this.surfacev3 = zaxisheight;

            this.largeAngle      = largeAngle_rad;
            this.relative_angle  = Math.PI - (shortAngle_rad + largeAngle_rad);
            this.teethCount      = teethCount;
            this.fresnelMaterial = fresnelMaterial;

            //create "divisions" that organises the Fresnel-zones in segments in order to boost performance.
            this.division = new Object3dCollection[this.divisioncount];
            for (int idiv = 0; idiv < this.divisioncount; idiv++)
            {
                this.division[idiv] = new Object3dCollection(this, surroundingsproperties);
                this.division[idiv].virtualCollection = true;
                this.division[idiv].tag = "fresnel_div_" + idiv;
            }

            this.addElements();
            this.dummyborder = new RectangularPrism(null, this.materialproperties, loc - (surfacev1 + surfacev2),
                                                    surfacev1 * 2, surfacev2 * 2, surfacev3.normalized() * this.total_prism_height);
        }
        public Scientrace.MaterialProperties getXMaterialForObject(XElement xmaterial)
        {
            ShadowClassConstruct scc = new ShadowClassConstruct(this.parentcollection);

            Scientrace.MaterialProperties matprop = scc.getXMaterial(xmaterial);
            return(matprop);

            /*
             * string materialid = this.X.getXStringByAttribute(xmaterial,"Class");
             * if (Scientrace.MaterialProperties.listedIdentifier(materialid)) {
             *      return Scientrace.MaterialProperties.FromIdentifier(materialid);
             *      }
             *
             * switch (materialid) {
             *      case "StaticNTransparant": //old type I once made... :S
             *      case "StaticNTransparent":
             *              double refindex = this.X.getXDouble(xmaterial, "RefractiveIndex");
             *              return new Scientrace.StaticNTransparentMaterial(refindex);
             *              //break;
             *      default:
             *              throw new XMLException("Material Class ["+materialid+"] unknown");
             *              //break;
             *      }*/
        }
        public Scientrace.ComplexBorderedVolume parsXBorderedVolume(XElement xBorVol)
        {
            // Replaced with below: Scientrace.MaterialProperties materialprops = this.getXMaterial(xBorVol.Element("Material"));
            Scientrace.MaterialProperties materialprops = this.getXMaterialForObject(xBorVol);
            if (xBorVol.Name.ToString() != "BorderedVolume")
            {
                throw new XMLException("BorderedVolume does not match its name: " + xBorVol.Name.ToString());
            }

            List <List <Scientrace.PlaneBorder> > nestedBorders = new List <List <Scientrace.PlaneBorder> >();

            foreach (XElement xSubVolume in xBorVol.Elements("SubVolume"))
            {
                List <Scientrace.PlaneBorder> tBorderList = new List <Scientrace.PlaneBorder>();
                foreach (XElement xBorder in xSubVolume.Elements("Plane"))
                {
                    if (xBorder.Element("Loc1") == null)               // No LocSet? Defined by location and AllowedNormal
                    {
                        Scientrace.Location      borderLoc      = this.X.getXLocation(xBorder, "Location");
                        Scientrace.NonzeroVector borderAllowDir = this.X.getXNzVectorByName(xBorder, "AllowedNormal");
                        tBorderList.Add(new Scientrace.PlaneBorder(borderLoc, borderAllowDir));
                    }
                    else                          // LocSet defined with 3 locations and an included-location to define the direction.
                    {
                        Scientrace.Location loc1       = this.X.getXLocation(xBorder, "Loc1");
                        Scientrace.Location loc2       = this.X.getXLocation(xBorder, "Loc2");
                        Scientrace.Location loc3       = this.X.getXLocation(xBorder, "Loc3");
                        Scientrace.Location includeLoc = this.X.getXLocation(xBorder, "IncludeLoc");
                        tBorderList.Add(Scientrace.PlaneBorder.createBetween3LocationsPointingTo(loc1, loc2, loc3, includeLoc));
                    }
                }
                nestedBorders.Add(tBorderList);
            }
            Scientrace.ComplexBorderedVolume tRetBoxVol = new Scientrace.ComplexBorderedVolume(this.parentcollection, materialprops, nestedBorders);
            return(tRetBoxVol);
        }
Example #13
0
 public Object3dEnvironment(MaterialProperties mp, double radius)
     : base(null, mp)
 {
     this.radius = radius;
 }
Example #14
0
        public virtual double enterReflection(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial)
        {
            double ti = trace.traceline.direction.angleWith(norm.negative());
            double sti = Math.Sin(ti);
            double cti = Math.Cos(ti);
            /*debug		Console.WriteLine("reflecting prev.: "+ previousObject.GetType());	Console.WriteLine("reflecting prev. material: "+ previousObject.materialproperties.GetType());*/
            double n1 = previousMaterial.refractiveindex(trace);
            double n2 = this.refractiveindex(trace);
            //Fresnel Equations on a 50/50 distribution of parallel and perpendicular to the plane polarization
            double Rs = Math.Pow(
                    ( (n1*cti) - (n2*Math.Sqrt(1.0 - Math.Pow((n1/n2)*sti,2.0))) ) /
                    ( (n1*cti) + (n2*Math.Sqrt(1.0 - Math.Pow((n1/n2)*sti,2.0))) )
                    ,2.0);
            double Rp = Math.Pow(
                    ( (n1*Math.Sqrt(1.0-Math.Pow((n1/n2)*sti,2.0))) - (n2*cti) ) /
                    ( (n1*Math.Sqrt(1.0-Math.Pow((n1/n2)*sti,2.0))) + (n2*cti) )
                    ,2.0);
            double R = (Rs+Rp)/2.0;
            //		Console.WriteLine("Reflection (n1/n2) = ("+n1+"/"+n2+") for angle "+ti+" is ("+Rs+"+"+Rp+")/2 ="+R);
            //		Console.WriteLine("Reflection "+trace.traceline.direction.trico()+"->"+norm.trico()+" for angle "+ti+" is ("+Rs+"+"+Rp+")/2 ="+R);
            if (!((R>=0) && (R<1))) {
                Console.WriteLine("R==null("+R+", Rs:"+Rs+" Rp:"+Rp+" n1:"+n1+" n2:"+n2+" ti:"+ti+" rpnoem:"+
                                ((n1/n2)*sti)+") where "+this.ToString()+ " and "+previousMaterial.ToString());
            }

            /*StackTrace stackTrace = new StackTrace();
            MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
            Console.WriteLine(methodBase.Name); // e.g. */
            return R;
        }
 public Object3dEnvironment(MaterialProperties mp, double radius) : base(null, mp)
 {
     this.radius = radius;
 }
Example #16
0
 /******************** INSTANCE METHODS *****************/
 public virtual double absorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial)
 {
     if (previousMaterial.dominantOnLeave)
     return (previousMaterial.enterAbsorption(trace, norm, this));
     return this.enterAbsorption(trace, norm, previousMaterial);
 }
Example #17
0
 //materials can transmit, reflect and absorp light.
 public virtual double enterAbsorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial)
 {
     return 0;
 }
Example #18
0
 public virtual double getLeaveAbsorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties nextMaterial)
 {
     throw new NotImplementedException("getLeaveAbsorption is not implemented for "+this.GetType().ToString());
 }
Example #19
0
 public static void addMaterial(MaterialProperties mp)
 {
     MaterialProperties.materials.Add((mp.identifier()).ToLower(), mp);
 }
Example #20
0
 /// <summary>
 /// All Object3d instances should be created with an assigned parent,
 /// an ObjectCollection instance. Except for Environment instances which
 /// are "top level" collections. Their parent is automatically set "null".
 /// </summary>
 /// <param name="parent">
 /// A <see cref="Object3d"/>
 /// </param>
 public Object3d(Object3dCollection parent, MaterialProperties mp)
 {
     this.setDefaults(parent, mp);
 }
Example #21
0
 /*
 /// <summary>
 /// If a collection contains a lot of objects, it might be usefull to specify a large border
 /// whithin they all should exist. This way the raytracer can check whether they all should
 /// be parsed individually in the first place or not. Leaving this object "null" it doesn't
 /// perform this check. Any type of object will do, including collections. Of course always
 /// keep in mind the only purpose is to gain performance.
 /// </summary>
 // public Object3d contentsWithinVirtualObject = null; MADE OBSOLETE BY DUMMYBORDER */
 /// <summary>
 /// A collection of objects which will be iterated one by one when the collection is addressed.
 /// </summary>
 /// <param name="parent">
 /// A <see cref="Object3dCollection"/>. There always has to be a parent collection in which
 /// an object (including objectcollections which are also objects as such) exists. The top 
 /// collection (root) is the Object3dEnvironment collection.
 /// </param>
 /// <param name="mp">
 /// A <see cref="MaterialProperties"/>. The surroundings in which the objects are situated?
 /// </param>
 public Object3dCollection(Object3dCollection parent, MaterialProperties mp)
     : base(parent, mp)
 {
 }
Example #22
0
        public virtual double enterReflection(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial)
        {
            double ti  = trace.traceline.direction.angleWith(norm.negative());
            double sti = Math.Sin(ti);
            double cti = Math.Cos(ti);
            /*debug		Console.WriteLine("reflecting prev.: "+ previousObject.GetType());	Console.WriteLine("reflecting prev. material: "+ previousObject.materialproperties.GetType());*/
            double n1 = previousMaterial.refractiveindex(trace);
            double n2 = this.refractiveindex(trace);
            //Fresnel Equations on a 50/50 distribution of parallel and perpendicular to the plane polarization
            double Rs = Math.Pow(
                ((n1 * cti) - (n2 * Math.Sqrt(1.0 - Math.Pow((n1 / n2) * sti, 2.0)))) /
                ((n1 * cti) + (n2 * Math.Sqrt(1.0 - Math.Pow((n1 / n2) * sti, 2.0))))
                , 2.0);
            double Rp = Math.Pow(
                ((n1 * Math.Sqrt(1.0 - Math.Pow((n1 / n2) * sti, 2.0))) - (n2 * cti)) /
                ((n1 * Math.Sqrt(1.0 - Math.Pow((n1 / n2) * sti, 2.0))) + (n2 * cti))
                , 2.0);
            double R = (Rs + Rp) / 2.0;

            //		Console.WriteLine("Reflection (n1/n2) = ("+n1+"/"+n2+") for angle "+ti+" is ("+Rs+"+"+Rp+")/2 ="+R);
            //		Console.WriteLine("Reflection "+trace.traceline.direction.trico()+"->"+norm.trico()+" for angle "+ti+" is ("+Rs+"+"+Rp+")/2 ="+R);
            if (!((R >= 0) && (R < 1)))
            {
                Console.WriteLine("R==null(" + R + ", Rs:" + Rs + " Rp:" + Rp + " n1:" + n1 + " n2:" + n2 + " ti:" + ti + " rpnoem:" +
                                  ((n1 / n2) * sti) + ") where " + this.ToString() + " and " + previousMaterial.ToString());
            }


            /*StackTrace stackTrace = new StackTrace();
             * MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
             * Console.WriteLine(methodBase.Name); // e.g. */
            return(R);
        }
 public AttachedObject3dCollection(Object3dCollection parent, MaterialProperties mp) : base(parent, mp)
 {
 }
Example #24
0
 public static void addMaterial(MaterialProperties mp)
 {
     MaterialProperties.materials.Add((mp.identifier()).ToLower(), mp);
 }
Example #25
0
 private void setDefaults(Object3dCollection parent, MaterialProperties mp)
 {
     this.tag = this.GetType().ToString();
     this.parseOrder = TraceJournal.Instance.rnd.NextDouble();
     this.materialproperties = mp;
     this.parent = parent;
     if (this.hasParent())
     this.parent.addObject3d(this);
 }
Example #26
0
 //materials can transmit, reflect and absorp light.
 public virtual double enterAbsorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial)
 {
     return(0);
 }
Example #27
0
 /// <summary>
 /// All Object3d instances should be created with an assigned parent,
 /// an ObjectCollection instance. Except for Environment instances which
 /// are "top level" collections. Their parent is automatically set "null".
 /// </summary>
 /// <param name="parent">
 /// A <see cref="Object3d"/>
 /// </param>
 public Object3d(Object3dCollection parent, MaterialProperties mp)
 {
     this.setDefaults(parent, mp);
 }
Example #28
0
 public virtual double getLeaveAbsorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties nextMaterial)
 {
     throw new NotImplementedException("getLeaveAbsorption is not implemented for " + this.GetType().ToString());
 }