// TODO: DYNAMIC component data adding for all factories
        /// <summary>
        /// Retrieve the components specified in the data and add them to the projectiles
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="data"></param>
        private static void AddExtraComponentData(ref Entity entity, ComponentDataStruct data)
        {
            switch (data.componentType)
            {
            case EComponentType.HeadShot:
                EntityManager.AddComponentData(entity, (HeadShotMultiplier)data.GetComponentData());
                return;

            case EComponentType.MultiHit:
                EntityManager.AddComponentData(entity, (MultiHit)data.GetComponentData());
                return;

            case EComponentType.EMP:
                Debug.LogWarning("EMP is not yet implemented.");
                return;

            case EComponentType.SuperCombine:
                EntityManager.AddComponentData(entity, (SuperCombine)data.GetComponentData());
                return;

            case EComponentType.Tracking:
                EntityManager.AddComponentData(entity, (TrackPlayer)data.GetComponentData());
                return;

            case EComponentType.Explosive:
                EntityManager.AddComponentData(entity, (Explosive)data.GetComponentData());
                return;

            case EComponentType.NotImplemented:
                Debug.Log("Not yet immplemented.");
                return;
            }
        }
Beispiel #2
0
        /*/// <summary>
         * /// Register presence of slurp
         * /// </summary>
         * [EventSubscribe("StartSlurp")]
         * private void OnStartSlurp(object sender, EventArgs e)
         * {
         *  Slurp newSlurp = sender as Slurp;
         *
         *  int senderIdx = FindComponentIndex(newSlurp.Name);
         *
         *  // If sender is unknown, add it to the list
         *  if (senderIdx == -1)
         *      throw new ApsimXException(FullPath, "Cannot find MicroClimate definition for Slurp");
         *  ComponentData[senderIdx].Name = newSlurp.Name;
         *  ComponentData[senderIdx].Type = newSlurp.CropType;
         *  Clear(ComponentData[senderIdx]);
         * } */

        /// <summary>Clears the specified componentdata</summary>
        /// <param name="c">The c.</param>
        private void Clear(ComponentDataStruct c)
        {
            c.CoverGreen = 0;
            c.CoverTot   = 0;
            c.Depth      = 0;
            c.Frgr       = 0;
            c.Height     = 0;
            c.K          = 0;
            c.Ktot       = 0;
            c.LAI        = 0;
            c.LAItot     = 0;
            Util.ZeroArray(c.layerLAI);
            Util.ZeroArray(c.layerLAItot);
            Util.ZeroArray(c.Ftot);
            Util.ZeroArray(c.Fgreen);
            Util.ZeroArray(c.Rs);
            Util.ZeroArray(c.Rl);
            Util.ZeroArray(c.Rsoil);
            Util.ZeroArray(c.Gc);
            Util.ZeroArray(c.Ga);
            Util.ZeroArray(c.PET);
            Util.ZeroArray(c.PETr);
            Util.ZeroArray(c.PETa);
            Util.ZeroArray(c.Omega);
            Util.ZeroArray(c.interception);
        }
Beispiel #3
0
        /// <summary>Calculate light extinction parameters</summary>
        /// <exception cref="System.Exception">Unrealistically high cover value in MicroMet i.e. > -.9999</exception>
        private void LightExtinction()
        {
            // Calculate effective K from LAI and cover
            // =========================================
            for (int j = 0; j <= ComponentData.Count - 1; j++)
            {
                ComponentDataStruct componentData = ComponentData[j];

                if (MathUtilities.FloatsAreEqual(ComponentData[j].CoverGreen, 1.0, 1E-05))
                {
                    throw new Exception("Unrealistically high cover value in MicroMet i.e. > -.9999");
                }

                componentData.K    = MathUtilities.Divide(-Math.Log(1.0 - componentData.CoverGreen), componentData.LAI, 0.0);
                componentData.Ktot = MathUtilities.Divide(-Math.Log(1.0 - componentData.CoverTot), componentData.LAItot, 0.0);
            }

            // Calculate extinction for individual layers
            // ============================================
            for (int i = 0; i <= numLayers - 1; i++)
            {
                layerKtot[i] = 0.0;
                for (int j = 0; j <= ComponentData.Count - 1; j++)
                {
                    ComponentDataStruct componentData = ComponentData[j];

                    layerKtot[i] += componentData.Ftot[i] * componentData.Ktot;
                }
            }
        }
Beispiel #4
0
        /// <summary>Calculate the Penman-Monteith water demand</summary>
        private void CalculatePM()
        {
            // zero a few things, and sum a few others
            double sumRl           = 0.0;
            double sumRsoil        = 0.0;
            double sumInterception = 0.0;
            double freeEvapGa      = 0.0;

            for (int i = 0; i <= numLayers - 1; i++)
            {
                for (int j = 0; j <= ComponentData.Count - 1; j++)
                {
                    ComponentDataStruct componentData = ComponentData[j];
                    componentData.PET[i]  = 0.0;
                    componentData.PETr[i] = 0.0;
                    componentData.PETa[i] = 0.0;
                    sumRl           += componentData.Rl[i];
                    sumRsoil        += componentData.Rsoil[i];
                    sumInterception += componentData.interception[i];
                    freeEvapGa      += componentData.Ga[i];
                }
            }

            double netRadiation = ((1.0 - _albedo) * sumRs + sumRl + sumRsoil) * 1000000.0;

            // MJ/J
            netRadiation = Math.Max(0.0, netRadiation);
            double freeEvapGc = freeEvapGa * 1000000.0;
            // =infinite surface conductance
            double freeEvap = CalcPenmanMonteith(netRadiation, mint, maxt, vp, air_pressure, dayLength, freeEvapGa, freeEvapGc);

            dryleaffraction = 1.0 - MathUtilities.Divide(sumInterception * (1.0 - night_interception_fraction), freeEvap, 0.0);
            dryleaffraction = Math.Max(0.0, dryleaffraction);

            for (int i = 0; i <= numLayers - 1; i++)
            {
                for (int j = 0; j <= ComponentData.Count - 1; j++)
                {
                    ComponentDataStruct componentData = ComponentData[j];

                    netRadiation = 1000000.0 * ((1.0 - _albedo) * componentData.Rs[i] + componentData.Rl[i] + componentData.Rsoil[i]);
                    // MJ/J
                    netRadiation = Math.Max(0.0, netRadiation);

                    if (j == 39)
                    {
                        netRadiation += 0.0;
                    }
                    componentData.PETr[i] = CalcPETr(netRadiation * dryleaffraction, mint, maxt, air_pressure, componentData.Ga[i], componentData.Gc[i]);

                    componentData.PETa[i] = CalcPETa(mint, maxt, vp, air_pressure, dayLength * dryleaffraction, componentData.Ga[i], componentData.Gc[i]);

                    componentData.PET[i] = componentData.PETr[i] + componentData.PETa[i];
                }
            }
        }
Beispiel #5
0
        /// <summary>Calculate the aerodynamic decoupling for system compartments</summary>
        private void CalculateOmega()
        {
            for (int i = 0; i <= numLayers - 1; i++)
            {
                for (int j = 0; j <= ComponentData.Count - 1; j++)
                {
                    ComponentDataStruct componentData = ComponentData[j];

                    componentData.Omega[i] = CalcOmega(mint, maxt, air_pressure, componentData.Ga[i], componentData.Gc[i]);
                }
            }
        }
Beispiel #6
0
        /// <summary>Setups the crop types.</summary>
        /// <param name="Name">The name.</param>
        /// <param name="Type">The type.</param>
        private void SetupCropTypes(string Name, string Type)
        {
            ComponentDataStruct CropType = new ComponentDataStruct();

            CropType.Name = Name;

            //Set defalst
            CropType.Albedo     = 0.15;
            CropType.Gsmax      = 0.01;
            CropType.Emissivity = 0.96;
            CropType.R50        = 200;

            //Override type specific values
            if (Type.Equals("Crop"))
            {
                CropType.Albedo = 0.26;
                CropType.Gsmax  = 0.011;
            }
            if (Type.Equals("Potato"))
            {
                CropType.Albedo = 0.26;
                CropType.Gsmax  = 0.03;
            }
            else if (Type.Equals("Grass"))
            {
                CropType.Albedo = 0.23;
            }
            else if (Type.Equals("C4grass"))
            {
                CropType.Albedo = 0.23;
                CropType.Gsmax  = 0.015;
                CropType.R50    = 150;
            }
            else if (Type.Equals("Tree"))
            {
                CropType.Albedo = 0.15;
                CropType.Gsmax  = 0.005;
            }
            else if (Type.Equals("Tree2"))
            {
                CropType.Albedo = 0.15;
                CropType.R50    = 100;
            }
            else if (Type.Equals("Pasture") || Type.Equals("Legume") || Type.Equals("Forage"))
            { // added by rcichota when spliting species in agpasture, still setting all parameters the same, will change in the future
                CropType.Albedo = 0.26;
                CropType.Gsmax  = 0.011;
            }

            ComponentDataDefinitions.Add(CropType);
        }
Beispiel #7
0
        /// <summary>Break the components into layers</summary>
        private void DivideComponents()
        {
            double[] Ld = new double[ComponentData.Count];
            for (int j = 0; j <= ComponentData.Count - 1; j++)
            {
                ComponentDataStruct componentData = ComponentData[j];

                componentData.layerLAI    = new double[numLayers];
                componentData.layerLAItot = new double[numLayers];
                Ld[j] = MathUtilities.Divide(componentData.LAItot, componentData.Depth, 0.0);
            }
            double top    = 0.0;
            double bottom = 0.0;

            for (int i = 0; i <= numLayers - 1; i++)
            {
                bottom         = top;
                top            = top + DeltaZ[i];
                layerLAIsum[i] = 0.0;

                // Calculate LAI for layer i and component j
                // ===========================================
                for (int j = 0; j <= ComponentData.Count - 1; j++)
                {
                    ComponentDataStruct componentData = ComponentData[j];

                    if ((componentData.Height > bottom) && (componentData.Height - componentData.Depth < top))
                    {
                        componentData.layerLAItot[i] = Ld[j] * DeltaZ[i];
                        componentData.layerLAI[i]    = componentData.layerLAItot[i] * MathUtilities.Divide(componentData.LAI, componentData.LAItot, 0.0);
                        layerLAIsum[i] += componentData.layerLAItot[i];
                    }
                }

                // Calculate fractional contribution for layer i and component j
                // ====================================================================
                for (int j = 0; j <= ComponentData.Count - 1; j++)
                {
                    ComponentDataStruct componentData = ComponentData[j];

                    componentData.Ftot[i] = MathUtilities.Divide(componentData.layerLAItot[i], layerLAIsum[i], 0.0);
                    // Note: Sum of Fgreen will be < 1 as it is green over total
                    componentData.Fgreen[i] = MathUtilities.Divide(componentData.layerLAI[i], layerLAIsum[i], 0.0);
                }
            }
        }
Beispiel #8
0
        /// <summary>Send an energy balance event</summary>
        private void SendEnergyBalanceEvent()
        {
            for (int j = 0; j <= ComponentData.Count - 1; j++)
            {
                ComponentDataStruct componentData = ComponentData[j];

                if (componentData.Canopy != null)
                {
                    CanopyEnergyBalanceInterceptionlayerType[] lightProfile = new CanopyEnergyBalanceInterceptionlayerType[numLayers];
                    double totalPotentialEp  = 0;
                    double totalInterception = 0.0;
                    for (int i = 0; i <= numLayers - 1; i++)
                    {
                        lightProfile[i]           = new CanopyEnergyBalanceInterceptionlayerType();
                        lightProfile[i].thickness = Convert.ToSingle(DeltaZ[i]);
                        lightProfile[i].amount    = Convert.ToSingle(componentData.Rs[i] * RadnGreenFraction(j));
                        totalPotentialEp         += componentData.PET[i];
                        totalInterception        += componentData.interception[i];
                    }

                    componentData.Canopy.PotentialEP  = totalPotentialEp;
                    componentData.Canopy.LightProfile = lightProfile;
                }

                else if (componentData.Crop2 != null)
                {
                    CanopyEnergyBalanceInterceptionlayerType[] lightProfile = new CanopyEnergyBalanceInterceptionlayerType[numLayers];
                    double totalPotentialEp  = 0;
                    double totalInterception = 0.0;
                    for (int i = 0; i <= numLayers - 1; i++)
                    {
                        lightProfile[i]           = new CanopyEnergyBalanceInterceptionlayerType();
                        lightProfile[i].thickness = Convert.ToSingle(DeltaZ[i]);
                        lightProfile[i].amount    = Convert.ToSingle(componentData.Rs[i] * RadnGreenFraction(j));
                        totalPotentialEp         += componentData.PET[i];
                        totalInterception        += componentData.interception[i];
                    }

                    componentData.Crop2.demandWater  = totalPotentialEp;
                    componentData.Crop2.LightProfile = lightProfile;
                }
            }
        }
Beispiel #9
0
        /// <summary>Calculate the canopy conductance for system compartments</summary>
        private void CalculateGc()
        {
            double Rin = radn;

            for (int i = numLayers - 1; i >= 0; i += -1)
            {
                double Rflux = Rin * 1000000.0 / (dayLength * hr2s) * (1.0 - _albedo);
                double Rint  = 0.0;

                for (int j = 0; j <= ComponentData.Count - 1; j++)
                {
                    ComponentDataStruct componentData = ComponentData[j];

                    componentData.Gc[i] = CanopyConductance(componentData.Gsmax, componentData.R50, componentData.Frgr, componentData.Fgreen[i], layerKtot[i], layerLAIsum[i], Rflux);

                    Rint += componentData.Rs[i];
                }
                // Calculate Rin for the next layer down
                Rin -= Rint;
            }
        }
Beispiel #10
0
        /// <summary>Gets all canopies in simulation</summary>
        private void GetAllCanopies()
        {
            foreach (ICanopy canopy in Apsim.FindAll(this.Parent, typeof(ICanopy)))
            {
                ComponentDataStruct componentData = ComponentData.Find(c => c.Name == canopy.CanopyType);
                if (componentData == null)
                {
                    componentData = CreateNewComonentData(canopy.CanopyType);
                    Clear(componentData);
                }

                componentData.Name       = canopy.CanopyType;
                componentData.Type       = canopy.CanopyType;
                componentData.Canopy     = canopy;
                componentData.LAI        = canopy.LAI;
                componentData.LAItot     = canopy.LAITotal;
                componentData.CoverGreen = canopy.CoverGreen;
                componentData.CoverTot   = canopy.CoverTotal;
                componentData.Height     = Math.Round(canopy.Height, 5) / 1000.0; // Round off a bit and convert mm to m
                componentData.Depth      = Math.Round(canopy.Depth, 5) / 1000.0;  // Round off a bit and convert mm to m
                componentData.Canopy     = canopy;
            }
        }
Beispiel #11
0
        /*/// <summary>
        /// Register presence of slurp
        /// </summary>
        [EventSubscribe("StartSlurp")]
        private void OnStartSlurp(object sender, EventArgs e)
        {
            Slurp newSlurp = sender as Slurp;

            int senderIdx = FindComponentIndex(newSlurp.Name);

            // If sender is unknown, add it to the list
            if (senderIdx == -1)
                throw new ApsimXException(FullPath, "Cannot find MicroClimate definition for Slurp");
            ComponentData[senderIdx].Name = newSlurp.Name;
            ComponentData[senderIdx].Type = newSlurp.CropType;
            Clear(ComponentData[senderIdx]);
        } */
        /// <summary>Clears the specified componentdata</summary>
        /// <param name="c">The c.</param>
        private void Clear(ComponentDataStruct c)
        {
            c.CoverGreen = 0;
            c.CoverTot = 0;
            c.Depth = 0;
            c.Frgr = 0;
            c.Height = 0;
            c.K = 0;
            c.Ktot = 0;
            c.LAI = 0;
            c.LAItot = 0;
            Util.ZeroArray(c.layerLAI);
            Util.ZeroArray(c.layerLAItot);
            Util.ZeroArray(c.Ftot);
            Util.ZeroArray(c.Fgreen);
            Util.ZeroArray(c.Rs);
            Util.ZeroArray(c.Rl);
            Util.ZeroArray(c.Rsoil);
            Util.ZeroArray(c.Gc);
            Util.ZeroArray(c.Ga);
            Util.ZeroArray(c.PET);
            Util.ZeroArray(c.PETr);
            Util.ZeroArray(c.PETa);
            Util.ZeroArray(c.Omega);
            Util.ZeroArray(c.interception);
        }
Beispiel #12
0
        /// <summary>Setups the crop types.</summary>
        /// <param name="Name">The name.</param>
        /// <param name="Type">The type.</param>
        private void SetupCropTypes(string Name, string Type)
        {
            ComponentDataStruct CropType = new ComponentDataStruct();
            CropType.Name = Name;

            //Set defalst
            CropType.Albedo = 0.15;
            CropType.Gsmax = 0.01;
            CropType.Emissivity = 0.96;
            CropType.R50 = 200;

            //Override type specific values
            if (Type.Equals("Crop"))
            {
                CropType.Albedo = 0.26;
                CropType.Gsmax=0.011;
            }
            if (Type.Equals("Potato"))
            {
                CropType.Albedo = 0.26;
                CropType.Gsmax = 0.03;
            }
            else if (Type.Equals("Grass"))
            {
                CropType.Albedo = 0.23;
            }
            else if (Type.Equals("C4grass"))
            {
                CropType.Albedo = 0.23;
                CropType.Gsmax = 0.015;
                CropType.R50 = 150;
            }
            else if (Type.Equals("Tree"))
            {
                CropType.Albedo = 0.15;
                CropType.Gsmax = 0.005;
            }
            else if (Type.Equals("Tree2"))
            {
                CropType.Albedo = 0.15;
                CropType.R50 = 100;
            }
            else if (Type.Equals("Pasture") || Type.Equals("Legume") || Type.Equals("Forage"))
            { // added by rcichota when spliting species in agpasture, still setting all parameters the same, will change in the future
                CropType.Albedo = 0.26;
                CropType.Gsmax = 0.011;
            }

            ComponentDataDefinitions.Add(CropType);
        }