/// <summary>
        /// Función que indica si el árbol sobrevive o no después de "years" años
        /// </summary>
        /// <returns>Devuelve el porcentaje de árboles que sobreviven (que luego multiplica por EXPAN)
        public override double Survives(double years, Parcela plot, PieMayor tree)
        {
            double prob       = MyFunc.probabilidadSupervivenciaen10(plot.A_BASIMETRICA.Value, tree.BAL.Value / plot.A_BASIMETRICA.Value, plot.I_HART.Value / 100);
            double prob_years = Math.Pow(prob, years / 10);///el exponente years/10 es para interpolar a "years" años, ya que el modelo de supervivencia se construyó para un lapso de 10 años

            return(prob_years);
        }
Esempio n. 2
0
 /// <summary>
 /// Procedimiento que realiza los cálculos sobre un árbol.
 /// </summary>
 /// <param name="years"></param>
 /// <param name="plot"></param>
 /// <param name="tree"></param>
 public override void ProcessTree(double years, Parcela plot, PieMayor tree)
 {
     currentTree = tree;
     tree.VCC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_conCorteza); //Integración --> r2_conCorteza sobre HR en los limites 0 -> 1
     tree.VSC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_sinCorteza); //Integración --> d_sinCorteza sobre HR en los limites 0 -> 1
     currentTree = null;
 }
Esempio n. 3
0
        /// <summary>
        /// Función que indica si el árbol sobrevive o no después de "years" años
        /// </summary>
        /// <param name="years"></param>
        /// <param name="plot"></param>
        /// <param name="tree"></param>
        /// <returns>Devuelve el porcentaje de árboles que sobreviven</returns>
        public override double Survives(double years, Parcela plot, PieMayor tree)
        {
            double BA_Survives = 1 - (1 / (1 + Math.Exp(2.0968 + (4.7358 * tree.DAP.Value / plot.D_CUADRATICO.Value) - 0.0012 * plot.SI.Value * plot.A_BASIMETRICA.Value)));

            if (BA_Survives > 0)
            {
                return(BA_Survives);
            }
            return(0.0F);
        }
/// <summary>
/// Procedimiento que permite modificar las propiedades del árbol durante su crecimiento después de "years" años
/// </summary>
/// <param name="years"></param>
/// <param name="plot"></param>
/// <param name="oldTree"></param>
/// <param name="newTree"></param>
        public override void Grow(double years, Parcela plot, PieMayor oldTree, PieMayor newTree)
        {
            double DBHG5 = Math.Exp(-0.37110 + 0.2525 * Math.Log(oldTree.DAP.Value) + 0.7090 * Math.Log((oldTree.CR.Value + 0.2) / 1.2) + 0.9087 * Math.Log(plot.SI.Value) - 0.1545 * Math.Sqrt(plot.A_BASIMETRICA.Value) - 0.0004 * (oldTree.BAL.Value * oldTree.BAL.Value / Math.Log(oldTree.DAP.Value)));

            newTree.DAP += DBHG5 / 10;

            double HTG5 = (Math.Exp(3.1222 - 0.4939 * Math.Log(oldTree.DAP.Value) + 1.3763 * Math.Log(plot.SI.Value) - 0.0061 * oldTree.BAL.Value + 0.1876 * Math.Log(oldTree.CR.Value))) / 500;

            newTree.ALTURA += HTG5 / 100;
        }
Esempio n. 5
0
        /// <summary>
        /// Procedimiento que permite modificar las propiedades del árbol durante su crecimiento después de "years" años
        /// </summary>
        /// <param name="years"></param>
        /// <param name="plot"></param>
        /// <param name="oldTree"></param>
        /// <param name="newTree"></param>
        public override void Grow(double years, Parcela plot, PieMayor oldTree, PieMayor newTree)
        {
            double DBHG5 = Math.Exp(0.2030 * Math.Log(oldTree.DAP.Value * 10) + 0.4414 * Math.Log((oldTree.CR.Value + 0.2) / 1.2) + 0.8379 * Math.Log(plot.SI.Value) - 0.1295 * Math.Sqrt(plot.A_BASIMETRICA.Value) - 0.0007 * Math.Pow(oldTree.BAL.Value, 2) / Math.Log(oldTree.DAP.Value * 10));

            newTree.DAP += DBHG5 / 10;
            ///    HTG5=(1/100)*Exp(0.21603+0.40329*Log(DBHG5*10/2)-1.12721*Log(DBH*10)                   +1.18099*Log(HT*100)                       +3.01622*CR)
            double HTG5 = Math.Exp(0.21603 + 0.40329 * Math.Log(DBHG5 / 2) - 1.12721 * Math.Log(oldTree.DAP.Value * 10) + 1.18099 * Math.Log(oldTree.ALTURA.Value * 100) + 3.01622 * oldTree.CR.Value);

            newTree.ALTURA += HTG5 / 100;
            /// formula de la tesis--corregido error en base de datos    newTree.ALTURA+=(Math.Exp(4.1375+0.3762*Math.Log(DBHG5*10/2)-0.5260*Math.Log(oldTree.DAP.Value*10)+0.1727*Math.Log(oldTree.ALTURA.Value*100)+2.6468* oldTree.CR.Value))/100;
        }
        /// <summary>
        /// Procedimiento que permite modificar las propiedades del árbol durante su crecimiento después de "years" años
        /// </summary>
        /// <param name="years"></param>
        /// <param name="plot"></param>
        /// <param name="oldTree"></param>
        /// <param name="newTree"></param>
        public override void Grow(double years, Parcela plot, PieMayor oldTree, PieMayor newTree)
        {
            double STR   = 0; // su valor debe ser 1 cuando la masa esta en el estrato 1
            double DBHG5 = Math.Exp(0.8351 + 0.1273 * Math.Log(oldTree.DAP.Value) - 0.00006 * Math.Pow(oldTree.DAP.Value, 2)
                                    - 0.01216 * oldTree.BAL.Value - 0.00016 * plot.N_PIESHA.Value - 0.03386 * plot.H_DOMINANTE.Value
                                    + 0.04917 * plot.SI.Value - 0.1991 * STR);

            newTree.DAP += (DBHG5 - 1);
            // calculo de la altura en el estado 2
            ///     newTree.ALTURA+=HTG5/100;
        }
Esempio n. 7
0
        /// <summary>
        /// Procedimiento que realiza los cálculos sobre un árbol.
        /// </summary>
        /// <param name="years"></param>
        /// <param name="plot"></param>
        /// <param name="tree"></param>
        public override void ProcessTree(double years, Parcela plot, PieMayor tree)
        {
            // ecuacion Martinez Millán et al 1993

            double ParA = 0.056395;
            double ParB = 1.94631;
            double ParC = 0.92797;

            tree.VCC = (ParA * Math.Pow(tree.DAP.Value, ParB) * Math.Pow(tree.ALTURA.Value, ParC)) / 1000;
            // currentTree = null;
        }
/// <summary>
/// Procedimiento que realiza los cálculos sobre un árbol.
/// </summary>
/// <param name="years"></param>
/// <param name="plot"></param>
/// <param name="tree"></param>
        public override void ProcessTree(double years, Parcela plot, PieMayor tree)
        {
            double exp = 1 / 0.9718;
            double DIB = Math.Pow((1 / 1.3285), exp) * Math.Pow(tree.DAP.Value * 10, exp);

            currentTree = tree;
            tree.VCC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_conCorteza);
            //Integración --> d_conCorteza sobre HR en los limites 0 -> 1
            tree.VSC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_sinCorteza); //Integración --> d_sinCorteza sobre HR en los limites 0 -> 1
            currentTree = null;
        }
 /// <summary>
 /// Procedimiento que permite la inicialización de variables de árbol necesarias para la ejecución del modelo
 /// </summary>
 /// <param name="plot"></param>
 /// <param name="tree"></param>
 public override void InitializeTree(Parcela plot, PieMayor tree)
 {
     if (!tree.ESTADO.HasValue || String.IsNullOrEmpty(tree.ESTADO.ToString()))
     {
         tree.BAL = 0;
         foreach (PieMayor pm in tree.Parcela.PiesMayores)
         {
             if (!pm.ESTADO.HasValue || String.IsNullOrEmpty(pm.ESTADO.ToString()))
             {
                 if (pm.DAP > tree.DAP)
                 {
                     tree.BAL += pm.SEC_NORMAL.Value * pm.EXPAN.Value / 10000;
                 }
             }
         }
     }
     if (!tree.ALTURA.HasValue)
     {
         tree.ALTURA = 1.3 + (3.099 - 0.00203 * plot.A_BASIMETRICA.Value + 1.02491 * plot.H_DOMINANTE.Value * Math.Exp(-8.5052 / tree.DAP.Value));
     }
     //      if (!tree.ALTURA_MAC.HasValue)
     //      {
     //			tree.ALTURA_MAC = tree.ALTURA.Value / (1 + Math.Exp((double)(-0.0012*tree.ALTURA.Value*10-0.0102*tree.BAL.Value-0.0168*plot.A_BASIMETRICA.Value )));
     //      }
     //      if (!tree.ALTURA_BC.HasValue)
     //      {
     //			tree.ALTURA_BC = tree.ALTURA_MAC.Value / (1+Math.Exp((double)(1.2425*(plot.A_BASIMETRICA.Value/(tree.ALTURA.Value*10)) + 0.0047*(plot.A_BASIMETRICA.Value) - 0.5725*Math.Log(plot.A_BASIMETRICA.Value)-0.0082*tree.BAL.Value)));
     //      }
     //      tree.CR=1-tree.ALTURA_BC.Value/tree.ALTURA.Value;
     //      if (!tree.LCW.HasValue)
     //      {
     //			tree.LCW=(1/10.0F)*(0.2518*tree.DAP.Value*10)*Math.Pow(tree.CR.Value,(0.2386+0.0046*(tree.ALTURA.Value-tree.ALTURA_BC.Value)*10));
     //      }
     tree.VCC = 0.000051 * Math.Pow(tree.DAP.Value, 1.86781) * Math.Pow(tree.ALTURA.Value, 0.989625);
     /// almacenamiento de variables de biomasa (eq. para Q. pyrenaica, Ruiz-Peinado et al 2011)
     if (tree.ESPECIE == 43)
     {
         /// Stem + Thick branches: Ws + Wb7 = 0.0261 · d2 · h
         tree.VAR_5 = 0.0261 * Math.Pow(tree.DAP.Value, 2) * tree.ALTURA.Value;
         /// Medium branches: Wb2–7 = –0.0260 · d2 + 0.536 · h + 0.00538 · d2 · h
         tree.VAR_2 = -0.0260 * Math.Pow(tree.DAP.Value, 2) + 0.536 * tree.ALTURA.Value + 0.00538 * Math.Pow(tree.DAP.Value, 2) * tree.ALTURA.Value;
         /// Thin branches: Wb2 = 0.898 · d – 0.445 · h
         tree.VAR_3 = 0.898 * tree.DAP.Value - 0.445 * tree.ALTURA.Value;
         /// Roots: Wr = 0.143 · d2
         tree.VAR_4 = 0.143 * Math.Pow(tree.DAP.Value, 2);
     }
 }
        /// <summary>
        /// Procedimiento que permite la inicialización de variables de parcelas necesarias para la ejecución del modelo
        /// Solo se ejecuta en el primer nodo.
        /// Variables que deben permanecer constantes como el índice de sitio deben calcularse sólo en este apartado del modelo
        /// </summary>
        /// <param name="plot"></param>
        public override void CalculateInitialInventory(Parcela plot)
        {
            IList <PieMayor> piesOrdenados = base.Sort(plot.PiesMayores, new PieMayorSortingCriteria.DescendingByField("DAP"));

            double bal            = 0;
            double old_sec_normal = 100000;
            double old_bal        = 0;

            //double sec_normal = tree.SEC_NORMAL;

            ///índice de sitio basado en la ecuación Ho-t para Pinus halepensis en el Valle del Ebro (GADA) (Rojo etal. 2017), edad de referencia 60 años
            plot.SI = MyFunc.Ecuacion_rojo_alboreca(plot.H_DOMINANTE.Value, plot.EDAD.Value, 60);

            foreach (PieMayor tree in piesOrdenados)
            {
                if (old_sec_normal > tree.SEC_NORMAL)
                {
                    tree.BAL = bal;
                    old_bal  = bal;
                }
                else
                {
                    tree.BAL = old_bal;
                }

                bal += tree.SEC_NORMAL.Value * tree.EXPAN.Value / 10000;

                old_sec_normal = tree.SEC_NORMAL.Value;

                if (!tree.ALTURA.HasValue)
                {
                    tree.ALTURA = MyFunc.alturaDiametroGeneralizada(plot.H_DOMINANTE.Value, tree.DAP.Value, plot.D_DOMINANTE.Value);///altura-diámetro generalizada. Alturas en m y diámetros en cm =======
                }

                if (!tree.ALTURA_BC.HasValue)
                {
                    tree.ALTURA_BC = MyFunc.alturaInicioCopa(tree.ALTURA.Value, plot.I_HART.Value / 100, plot.SI.Value, (tree.BAL.Value / plot.A_BASIMETRICA.Value));///altura de la base de la copa (altura de inicio de copa viva). Alturas en m y diámetros en cm
                }

                tree.LCW = MyFunc.diametroCopa(tree.DAP.Value, tree.ALTURA.Value);///diámetro de copa (m)

                currentTree = tree;
                tree.VCC    = Math.PI * 0.0001 * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_conCorteza); //Integración --> r2_conCorteza sobre HR en los limites 0 -> 1 // VCC en m³
                currentTree = null;
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Procedimiento que permite la inicialización de variables de parcelas necesarias para la ejecución del modelo
        /// Solo se ejecuta en el primer nodo.
        /// Variables que deben permanecer constantes como el índice de sitio deben calcularse solo en este apartado del modelo
        /// </summary>
        /// <param name="plot"></param>
        public override void CalculateInitialInventory(Parcela plot)
        {
            IList <PieMayor> piesOrdenados = base.Sort(plot.PiesMayores, new PieMayorSortingCriteria.DescendingByField("DAP"));
            double           bal = 0; double old_sec_normal = 100000; double old_bal = 0; //double sec_normal = tree.SEC_NORMAL;

            foreach (PieMayor tree in piesOrdenados)
            {
                if (old_sec_normal > tree.SEC_NORMAL)
                {
                    tree.BAL = bal; old_bal = bal;
                }
                else
                {
                    tree.BAL = old_bal;
                }
                bal           += tree.SEC_NORMAL.Value * tree.EXPAN.Value / 10000;
                old_sec_normal = tree.SEC_NORMAL.Value;
                if (!tree.ALTURA.HasValue || tree.ALTURA.Value == 0)
                {
                    tree.ALTURA = (13 + (32.3287 + 1.6688 * plot.H_DOMINANTE * 10 - 0.1279 * plot.D_CUADRATICO * 10) * Math.Exp(-11.4522 / Math.Sqrt(tree.DAP.Value * 10))) / 10.0;
                }
                if (!tree.ALTURA_MAC.HasValue || tree.ALTURA_MAC.Value == 0)
                {
                    tree.ALTURA_MAC = tree.ALTURA.Value / (1 + Math.Exp((double)(-0.0041 * tree.ALTURA.Value * 10 - 0.0093 * tree.BAL - 0.0123 * plot.A_BASIMETRICA)));
                }
                if (!tree.ALTURA_BC.HasValue || tree.ALTURA_BC.Value == 0)
                {
                    tree.ALTURA_BC = tree.ALTURA_MAC.Value / (1 + Math.Exp((double)(0.0078 * plot.A_BASIMETRICA - 0.5488 * Math.Log(plot.A_BASIMETRICA.Value) - 0.0085 * tree.BAL)));
                }
                tree.CR = 1 - tree.ALTURA_BC.Value / tree.ALTURA.Value;
                if (!tree.LCW.HasValue)
                {
                    tree.LCW = (1 / 10.0F) * (0.1826 * tree.DAP.Value * 10) * Math.Pow(tree.CR.Value, (0.1594 + 0.0014 * (tree.ALTURA.Value - tree.ALTURA_BC.Value) * 10));
                }
                //		tree.VAR_1	= tree.COORD_X;//añadido para tener coordenadas
                //		tree.VAR_2	= tree.COORD_Y;//añadido para tener coordenadas
                currentTree = tree;
                tree.VCC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_conCorteza); //Integración --> r2_conCorteza sobre HR en los limites 0 -> 1
                tree.VSC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_sinCorteza); //Integración --> r2_sinCorteza sobre HR en los limites 0 -> 1
                currentTree = null;
            }
            plot.SI = Math.Exp(4.016 +
                               (Math.Log(plot.H_DOMINANTE.Value) - 4.016) *
                               Math.Pow(80 / plot.EDAD.Value, -0.5031)
                               );
        }
 /// <summary>
 /// Procedimiento que realiza los cálculos sobre un árbol.
 /// </summary>
 /// <param name="years"></param>
 /// <param name="plot"></param>
 /// <param name="tree"></param>
 public override void ProcessTree(double years, Parcela plot, PieMayor tree)
 {
     tree.ALTURA = 1.3 + (3.099 - 0.00203 * plot.A_BASIMETRICA.Value + 1.02491 * plot.H_DOMINANTE.Value * Math.Exp(-8.5052 / tree.DAP.Value));
     //double DIB = Math.Pow((1/1.3285),exp)*Math.Pow(tree.DAP.Value*10,exp);
     tree.VCC = 0.000051 * Math.Pow(tree.DAP.Value, 1.86781) * Math.Pow(tree.ALTURA.Value, 0.989625);
     /// almacenamiento de variables de biomasa (eq. para Q. pyrenaica, Ruiz-Peinado et al 2011)
     if (tree.ESPECIE == 43)
     {
         /// Stem + Thick branches: Ws + Wb7 = 0.0261 · d2 · h
         tree.VAR_5 = 0.0261 * Math.Pow(tree.DAP.Value, 2) * tree.ALTURA.Value;
         /// Medium branches: Wb2–7 = –0.0260 · d2 + 0.536 · h + 0.00538 · d2 · h
         tree.VAR_2 = -0.0260 * Math.Pow(tree.DAP.Value, 2) + 0.536 * tree.ALTURA.Value + 0.00538 * Math.Pow(tree.DAP.Value, 2) * tree.ALTURA.Value;
         /// Thin branches: Wb2 = 0.898 · d – 0.445 · h
         tree.VAR_3 = 0.898 * tree.DAP.Value - 0.445 * tree.ALTURA.Value;
         /// Roots: Wr = 0.143 · d2
         tree.VAR_4 = 0.143 * Math.Pow(tree.DAP.Value, 2);
     }
 }
/// <summary>
/// Función que indica si el árbol sobrevive o no después de "years" años
/// </summary>
/// <param name="years"></param>
/// <param name="plot"></param>
/// <param name="tree"></param>
/// <returns>Devuelve el porcentaje de árboles que sobreviven</returns>
        public override double Survives(double years, Parcela plot, PieMayor tree)
        {
/// se calcula la desviacion estandar
            double sumOfDerivation = 0;
            double sumOfTrees      = 0;
            double DMedioCuadrado  = plot.D_MEDIO.Value * plot.D_MEDIO.Value;

            foreach (PieMayor pm in plot.PiesMayores)
            {
                sumOfDerivation += ((pm.DAP.Value) * (pm.DAP.Value) * (pm.EXPAN.Value));
                sumOfTrees      += pm.EXPAN.Value;
            }
            double sumOfDerivationAverage = sumOfDerivation / sumOfTrees;
            double StandardDeviation      = Math.Sqrt(sumOfDerivationAverage - DMedioCuadrado);

/// calculamos el coeficiente de variación -cvDAP- como el cociente entre la desviacion estandar y la media
            double cvDAP = (StandardDeviation / plot.D_MEDIO.Value);

            return(1 / (1 + Math.Exp(-6.8548 + (9.792 / tree.DAP.Value) + 0.121 * tree.BAL.Value * cvDAP + 0.037 * plot.SI.Value)));
            ///    return 1;
        }
/// <summary>
/// Procedimiento que permite la inicialización de variables de árbol necesarias para la ejecución del modelo
/// </summary>
/// <param name="plot"></param>
/// <param name="tree"></param>
        public override void InitializeTree(Parcela plot, PieMayor tree)
        {
            if (!tree.ESTADO.HasValue || String.IsNullOrEmpty(tree.ESTADO.ToString()))
            {
                tree.BAL = 0;
                foreach (PieMayor pm in tree.Parcela.PiesMayores)
                {
                    if (!pm.ESTADO.HasValue || String.IsNullOrEmpty(pm.ESTADO.ToString()))
                    {
                        if (pm.DAP > tree.DAP)
                        {
                            tree.BAL += pm.SEC_NORMAL.Value * pm.EXPAN.Value / 10000;
                        }
                    }
                }
            }
            if (!tree.ALTURA.HasValue)
            {
                tree.ALTURA = (13 + (27.0392 + 1.4853 * plot.H_DOMINANTE.Value * 10 - 0.1437 * plot.D_CUADRATICO.Value * 10) * Math.Exp(-8.0048 / Math.Sqrt(tree.DAP.Value * 10))) / 10;
            }
            if (!tree.ALTURA_MAC.HasValue)
            {
                tree.ALTURA_MAC = tree.ALTURA.Value / (1 + Math.Exp((double)(-0.0012 * tree.ALTURA.Value * 10 - 0.0102 * tree.BAL.Value - 0.0168 * plot.A_BASIMETRICA.Value)));
            }
            if (!tree.ALTURA_BC.HasValue)
            {
                tree.ALTURA_BC = tree.ALTURA_MAC.Value / (1 + Math.Exp((double)(1.2425 * (plot.A_BASIMETRICA.Value / tree.ALTURA.Value * 10) + 0.0047 * (plot.A_BASIMETRICA.Value) - 0.5725 * Math.Log(plot.A_BASIMETRICA.Value) - 0.0082 * tree.BAL.Value)));
            }
            tree.CR = (1 - tree.ALTURA_BC / tree.ALTURA);
            if (!tree.LCW.HasValue)
            {
                tree.LCW = (0.2518 * tree.DAP.Value) * Math.Pow(tree.CR.Value, (0.2386 + 0.0046 * (tree.ALTURA.Value - tree.ALTURA_BC.Value)));
            }
            currentTree = tree;
            tree.VCC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_conCorteza); //Integración --> r2_conCorteza sobre HR en los limites 0 -> 1
            tree.VSC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_sinCorteza); //Integración --> d_sinCorteza sobre HR en los limites 0 -> 1
            currentTree = null;
        }
Esempio n. 15
0
        /// <summary>
        /// Procedimiento que permite modificar las propiedades del árbol durante su crecimiento después de "years" años
        /// </summary>
        /// <param name="years"></param>
        /// <param name="plot"></param>
        /// <param name="oldTree"></param>
        /// <param name="newTree"></param>


        public override void Grow(double years, Parcela plot, PieMayor oldTree, PieMayor newTree)
        {
            // ecuacion Calama y Montero 2005
            // Andalucia, Meseta central y Sistema Central(cat es 0)

            double DBHG5 = Math.Exp(2.2451 - 0.2615 * oldTree.DAP.Value - 0.0369 * oldTree.ALTURA.Value - 0.1368 * Math.Log(plot.N_PIESHA.Value)
                                    + 0.0448 * plot.SI.Value + 0.1984 * oldTree.DAP.Value / plot.D_CUADRATICO.Value) + 1;

            newTree.DAP = oldTree.DAP + DBHG5;

            double parA            = 4.1437;
            double parB            = -0.3935;
            double H_DOMINANTE_new = Math.Exp((double)parA + Math.Log(plot.H_DOMINANTE.Value) - parA / Math.Pow((100 / plot.EDAD.Value), parB));

            // calculo de rango de diametros entre los percentiles 10 y 90
            double P1090      = 10;
            double ALTURA_old = 1.3 + Math.Exp((double)(1.7306 + 0.0882 * plot.H_DOMINANTE.Value - 0.0062 * P1090 - 0.0936)
                                               + (-25.2776 + 1.6999 * Math.Log(plot.N_PIESHA.Value) + 4.743) / (oldTree.DAP.Value + 1));
            double ALTURA_new = 1.3 + Math.Exp((double)(1.7306 + 0.0882 * H_DOMINANTE_new - 0.0062 * P1090 - 0.0936)
                                               + (-25.2776 + 1.6999 * Math.Log(plot.N_PIESHA.Value) + 4.743) / (newTree.DAP.Value + 1));

            newTree.ALTURA = oldTree.ALTURA * ALTURA_new / ALTURA_old;
        }
/// <summary>
/// Procedimiento que permite modificar las propiedades del árbol durante su crecimiento después de "years" años
/// </summary>
/// <param name="years"></param>
/// <param name="plot"></param>
/// <param name="oldTree"></param>
/// <param name="newTree"></param>
        public override void Grow(double years, Parcela plot, PieMayor oldTree, PieMayor newTree)
        {
            // Para Cataluña (cat es 1)
            double DBHG5 = Math.Exp(2.2451 - 0.2615 * oldTree.DAP.Value - 0.0369 * oldTree.ALTURA.Value - 0.1368 * Math.Log(plot.N_PIESHA.Value) + 0.0448 * plot.SI.Value + 0.1984 * oldTree.DAP.Value / plot.D_CUADRATICO.Value - 0.5542 + 0.0277 * plot.SI.Value) + 1;

            newTree.DAP       = oldTree.DAP + DBHG5;
            newTree.EDAD_BASE = Convert.ToInt32(years + oldTree.EDAD_BASE.Value);
            double parA    = 4.1437;
            double parB    = -0.3935;
            double logSI   = Math.Log(plot.SI.Value);
            double potEDAD = Math.Pow(100 / (years + plot.EDAD.Value), parB);

            newTree.VAR_8 = plot.EDAD.Value; newTree.VAR_6 = logSI; newTree.VAR_5 = potEDAD;
            double H_DOMINANTE_new = Math.Exp(parA + (logSI - parA) / potEDAD);

            plot.VAR_7 = H_DOMINANTE_new; newTree.VAR_7 = H_DOMINANTE_new;

            // calculo de rango de diametros entre los percentiles 10 y 90
            double P1090      = plot.VAR_10.Value - plot.VAR_9.Value;
            double ALTURA_old = 1.3 + Math.Exp(1.7306 + 0.0882 * plot.H_DOMINANTE.Value - 0.0062 * P1090 - 0.0936 + (-25.2776 + 1.6999 * Math.Log(plot.N_PIESHA.Value) + 4.743) / (oldTree.DAP.Value + 1)); newTree.VAR_9 = ALTURA_old;
            double ALTURA_new = 1.3 + Math.Exp(1.7306 + 0.0882 * H_DOMINANTE_new - 0.0062 * P1090 - 0.0936 + (-25.2776 + 1.6999 * Math.Log(plot.N_PIESHA.Value) + 4.743) / (newTree.DAP.Value + 1)); newTree.VAR_10 = ALTURA_new;

            newTree.ALTURA = oldTree.ALTURA * ALTURA_new / ALTURA_old;
        }
 /// <summary>
 /// Procedimiento que permite la inicialización de variables de parcelas necesarias para la ejecución del modelo
 /// Solo se ejecuta en el primer nodo.
 /// Variables que deben permanecer constantes como el índice de sitio deben calcularse solo en este apartado del modelo
 /// </summary>
 /// <param name="plot"></param>
 public override void CalculateInitialInventory(Parcela plot)
 {
     foreach (PieMayor tree in plot.PiesMayores)
     {
         tree.BAL = 0;
         foreach (PieMayor pm in tree.Parcela.PiesMayores)
         {
             if (pm.DAP > tree.DAP)
             {
                 tree.BAL += pm.SEC_NORMAL.Value * pm.EXPAN.Value / 10000;
             }
         }
         if (!tree.ALTURA.HasValue)
         {
             tree.ALTURA = (13 + (27.0392 + 1.4853 * plot.H_DOMINANTE.Value * 10 - 0.1437 * plot.D_CUADRATICO.Value * 10) * Math.Exp(-8.0048 / Math.Sqrt(tree.DAP.Value * 10))) / 10;
         }
         if (!tree.ALTURA_MAC.HasValue)
         {
             tree.ALTURA_MAC = tree.ALTURA.Value / (1 + Math.Exp((double)(-0.0012 * tree.ALTURA.Value * 10 - 0.0102 * tree.BAL.Value - 0.0168 * plot.A_BASIMETRICA.Value)));
         }
         if (!tree.ALTURA_BC.HasValue)
         {
             tree.ALTURA_BC = tree.ALTURA_MAC.Value / (1 + Math.Exp((double)(1.2425 * (plot.A_BASIMETRICA.Value / tree.ALTURA.Value * 10) + 0.0047 * (plot.A_BASIMETRICA.Value) - 0.5725 * Math.Log(plot.A_BASIMETRICA.Value) - 0.0082 * tree.BAL.Value)));
         }
         tree.CR = (1 - tree.ALTURA_BC / tree.ALTURA);
         if (!tree.LCW.HasValue)
         {
             tree.LCW = (0.2518 * tree.DAP.Value) * Math.Pow(tree.CR.Value, (0.2386 + 0.0046 * (tree.ALTURA.Value - tree.ALTURA_BC.Value)));
         }
         currentTree = tree;
         tree.VCC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_conCorteza); //Integración --> d_conCorteza sobre HR en los limites 0 -> 1
         tree.VSC    = Math.PI * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_sinCorteza); //Integración --> d_sinCorteza sobre HR en los limites 0 -> 1
         currentTree = null;
     }
     plot.SI = (plot.H_DOMINANTE.Value * 0.8534446) / Math.Pow((1 - Math.Exp((double)(-0.270 * plot.EDAD.Value / 10))), 2.2779);
 }
/// <summary>
/// Procedimiento que realiza los cálculos sobre un árbol.
/// </summary>
/// <param name="years"></param>
/// <param name="plot"></param>
/// <param name="tree"></param>
        public override void ProcessTree(double years, Parcela plot, PieMayor tree)
        {
        }
/// <summary>
/// Función que indica si el árbol sobrevive o no después de "years" años
/// </summary>
/// <param name="years"></param>
/// <param name="plot"></param>
/// <param name="tree"></param>
/// <returns>Devuelve el porcentaje de árboles que sobreviven</returns>
        public override double Survives(double years, Parcela plot, PieMayor tree)
        {
            return(1);
        }
/// <summary>
/// Procedimiento que permite la inicialización de variables de árbol necesarias para la ejecución del modelo
/// </summary>
/// <param name="plot"></param>
/// <param name="tree"></param>
        public override void InitializeTree(Parcela plot, PieMayor tree)
        {
        }
        /// <summary>
        /// Procedimiento que permite modificar las propiedades del árbol durante su crecimiento después de "years" años (LAPSOS DE 5 AÑOS)
        /// </summary>
        /// <param name="years"></param>
        /// <param name="plot"></param>
        /// <param name="oldTree"></param>
        /// <param name="newTree"></param>
        public override void Grow(double years, Parcela plot, PieMayor oldTree, PieMayor newTree)
        {
            double id10 = MyFunc.incrementoDiametroConCortezaen10(oldTree.DAP.Value, plot.A_BASIMETRICA.Value, plot.SI.Value, oldTree.BAL.Value / plot.A_BASIMETRICA.Value);

            newTree.DAP = oldTree.DAP + id10 * (years / 10);///el factor years/10 es para interpolar a "years" años, ya que el modelo de incremento diametral se construyó para un lapso de 10 años
        }
        /// <summary>
        /// Función que indica si el árbol sobrevive o no después de "years" años
        /// </summary>
        /// <param name="years"></param>
        /// <param name="plot"></param>
        /// <param name="tree"></param>
        /// <returns>Devuelve el porcentaje de árboles que sobreviven</returns>
        public override double Survives(double years, Parcela plot, PieMayor tree)
        {
            double p_mort = 1 / (1 + Math.Exp(1.3286 - 9.791 / tree.DAP.Value + 3.5383 * tree.ALTURA.Value / plot.H_DOMINANTE.Value));

            return(1 - p_mort);
        }
 /// <summary>
 /// Procedimiento que realiza los cálculos sobre un árbol.
 /// </summary>
 /// <param name="years"></param>
 /// <param name="plot"></param>
 /// <param name="tree"></param>
 public override void ProcessTree(double years, Parcela plot, PieMayor tree)
 {
     ///currentTree = tree;
     ///tree.VCC = Math.PI * 0.0001 * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_conCorteza);
     ///currentTree = null;
 }
        /// <summary>
        /// Procedimiento que realiza los cálculos sobre una parcela.
        /// </summary>
        /// <param name="years"></param>
        /// <param name="plot"></param>
        /// <param name="trees"></param>
        public override void ProcessPlot(double years, Parcela plot, PieMayor[] trees)
        {
            ///recalcula la Ho para la nueva edad basándose en el índice de sitio
            if (plot.VAR_5.HasValue == false)
            {
                plot.VAR_5 = plot.EDAD.Value;
            }
            plot.VAR_5      += years;
            plot.H_DOMINANTE = MyFunc.Ecuacion_rojo_alboreca(plot.SI.Value, 60, plot.VAR_5.Value);
            ///recalcula IH
            plot.I_HART = 10000 / (plot.H_DOMINANTE.Value * Math.Sqrt(plot.N_PIESHA.Value));

            IList <PieMayor> piesOrdenados = base.Sort(plot.PiesMayores, new PieMayorSortingCriteria.DescendingByField("DAP"));
            double           bal = 0; double old_sec_normal = 100000; double old_bal = 0;

            foreach (PieMayor tree in piesOrdenados)
            {
                if (!tree.ESTADO.HasValue || String.IsNullOrEmpty(tree.ESTADO.ToString()))
                {
                    if (old_sec_normal > tree.SEC_NORMAL)
                    {
                        tree.BAL = bal;
                        old_bal  = bal;
                    }
                    else
                    {
                        tree.BAL = old_bal;
                    }
                    bal           += tree.SEC_NORMAL.Value * tree.EXPAN.Value / 10000;
                    old_sec_normal = tree.SEC_NORMAL.Value;

                    tree.ALTURA    = MyFunc.alturaDiametroGeneralizada(plot.H_DOMINANTE.Value, tree.DAP.Value, plot.D_DOMINANTE.Value);
                    tree.ALTURA_BC = MyFunc.alturaInicioCopa(tree.ALTURA.Value, plot.I_HART.Value / 100, plot.SI.Value, (tree.BAL.Value / plot.A_BASIMETRICA.Value));
                    tree.LCW       = MyFunc.diametroCopa(tree.DAP.Value, tree.ALTURA.Value);
                }
                else
                {
                    tree.BAL = 0; tree.CR = 0; tree.LCW = 0; tree.ALTURA_MAC = 0; tree.ALTURA_BC = 0;
                }
            }

            ///recalcula correctamente la altura media, diámetros de copa medios, FCC y VCC por hectárea
            double exp_temp = 0;
            double h_exp_temp = 0;
            double dcopa_exp_temp  = 0;
            double dcopa2_exp_temp = 0;
            double vcc_exp_temp    = 0;

            foreach (PieMayor tree in piesOrdenados)
            {
                if (!tree.ESTADO.HasValue || String.IsNullOrEmpty(tree.ESTADO.ToString()))
                {
                    exp_temp        = exp_temp + (tree.EXPAN.Value);
                    h_exp_temp      = h_exp_temp + (tree.ALTURA.Value * tree.EXPAN.Value);
                    dcopa_exp_temp  = dcopa_exp_temp + (tree.LCW.Value * tree.EXPAN.Value);
                    dcopa2_exp_temp = dcopa2_exp_temp + (Math.Pow(tree.LCW.Value, 2) * tree.EXPAN.Value);

                    currentTree  = tree;
                    tree.VCC     = Math.PI * 0.0001 * tree.ALTURA.Value * IntegralBySimpson(0, 1, 0.01, r2_conCorteza);                ///recalcula el vcc de cada árbol con la altura correcta
                    currentTree  = null;
                    vcc_exp_temp = vcc_exp_temp + (tree.VCC.Value * tree.EXPAN.Value);
                }
            }

            ///double h_media_new = h_exp_temp / exp_temp;
            plot.H_MEDIA = h_exp_temp / exp_temp;
            plot.DM_COPA = dcopa_exp_temp / exp_temp;
            plot.DG_COPA = Math.Sqrt(dcopa2_exp_temp / exp_temp);
            plot.VCC     = vcc_exp_temp;
            plot.FCC     = 0.25 * Math.PI * dcopa2_exp_temp / 10000;
        }