//---------------------------------------------------------------------

        /// <summary>
        /// Initializes the module.
        /// </summary>
        public static void Initialize()
        {
            cohorts = PlugIn.ModelCore.Landscape.NewSiteVar<Library.LeafBiomassCohorts.SiteCohorts>();
            biomassCohortsSiteVar = Landis.Library.Succession.CohortSiteVar<Landis.Library.BiomassCohorts.ISiteCohorts>.Wrap(cohorts);
            baseCohortsSiteVar = Landis.Library.Succession.CohortSiteVar<Landis.Library.AgeOnlyCohorts.ISiteCohorts>.Wrap(cohorts);
        
            timeOfLast = PlugIn.ModelCore.Landscape.NewSiteVar<int>();
            
            // Dead biomass:
            surfaceDeadWood     = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            soilDeadWood        = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            
            surfaceStructural   = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            surfaceMetabolic    = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            soilStructural      = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            soilMetabolic       = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            
            // Soil Layers
            som1surface         = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            som1soil            = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            som2                = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            som3                = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            
            // Other Layers
            stream              = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            sourceSink          = PlugIn.ModelCore.Landscape.NewSiteVar<Layer>();
            
            // Other variables
            mineralN            = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            resorbedN           = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            waterMovement       = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            availableWater      = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            liquidSnowPack      = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            soilWaterContent    = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            decayFactor         = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            soilTemperature     = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            anaerobicEffect     = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            
            // Annual accumulators
            grossMineralization = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            ag_nppC             = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            bg_nppC             = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            litterfallC         = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            monthlyAGNPPC       = PlugIn.ModelCore.Landscape.NewSiteVar<double[]>();
            monthlyBGNPPC       = PlugIn.ModelCore.Landscape.NewSiteVar<double[]>();
            monthlyNEE          = PlugIn.ModelCore.Landscape.NewSiteVar<double[]>();
            monthlyStreamN      = PlugIn.ModelCore.Landscape.NewSiteVar<double[]>();
            AnnualNEE           = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            FireCEfflux         = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            FireNEfflux         = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            monthlyResp         = PlugIn.ModelCore.Landscape.NewSiteVar<double[]>();

            cohortLeafN         = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            cohortFRootN         = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            cohortLeafC         = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            cohortFRootC     = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            cohortWoodN         = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            cohortCRootN   = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            cohortWoodC         = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            cohortCRootC = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
                        
            TotalWoodBiomass    = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            WoodMortality        = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            Nvol                = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            PrevYearMortality   = PlugIn.ModelCore.Landscape.NewSiteVar<int>();
            totalNuptake        = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            monthlymineralN     = PlugIn.ModelCore.Landscape.NewSiteVar<double[]>();
            frassC              = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            lai                 = PlugIn.ModelCore.Landscape.NewSiteVar<double>();
            HarvestPrescriptionName = PlugIn.ModelCore.GetSiteVar<string>("Harvest.PrescriptionName");

            CohortResorbedNallocation = PlugIn.ModelCore.Landscape.NewSiteVar<Dictionary<int, Dictionary<int, double>>>();




            PlugIn.ModelCore.RegisterSiteVar(cohorts, "Succession.LeafBiomassCohorts");
            PlugIn.ModelCore.RegisterSiteVar(baseCohortsSiteVar, "Succession.AgeCohorts");
            PlugIn.ModelCore.RegisterSiteVar(biomassCohortsSiteVar, "Succession.BiomassCohorts");
            
            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                //  site cohorts are initialized by the PlugIn.InitializeSite method
                
                //leafBiomassCohorts[site]    = new SiteCohorts();
                //Console.Write("-");
                surfaceDeadWood[site]       = new Layer(LayerName.Wood, LayerType.Surface);
                soilDeadWood[site]          = new Layer(LayerName.CoarseRoot, LayerType.Soil);
                
                surfaceStructural[site]     = new Layer(LayerName.Structural, LayerType.Surface);
                surfaceMetabolic[site]      = new Layer(LayerName.Metabolic, LayerType.Surface);
                soilStructural[site]        = new Layer(LayerName.Structural, LayerType.Soil);
                soilMetabolic[site]         = new Layer(LayerName.Metabolic, LayerType.Soil);
                
                som1surface[site]           = new Layer(LayerName.SOM1, LayerType.Surface);
                som1soil[site]              = new Layer(LayerName.SOM1, LayerType.Soil);
                
                som2[site]                  = new Layer(LayerName.SOM2, LayerType.Soil);
                som3[site]                  = new Layer(LayerName.SOM3, LayerType.Soil);
                
                stream[site]                = new Layer(LayerName.Other, LayerType.Other);
                sourceSink[site]            = new Layer(LayerName.Other, LayerType.Other);
                
                monthlyAGNPPC[site]           = new double[12];
                monthlyBGNPPC[site]           = new double[12];
                monthlyNEE[site]            = new double[12];
                monthlyStreamN[site]         = new double[12];
                monthlyResp[site]           = new double[12];
                //monthlymineralN[site]       = new double[12];

                CohortResorbedNallocation[site] = new Dictionary<int, Dictionary<int, double>>();
            }
            
        }
        public void TransferNitrogen(Layer destination, double CFlow, double totalC, double ratioCNtoDestination, ActiveSite site)
        {
            // this is the source.

            double mineralNFlow = 0.0;

            //...N flow is proportional to C flow.
            double NFlow = this.Nitrogen * CFlow / totalC;

            //...This was added to avoid a 0/0 error on the pc.
            if (CFlow <= 0.0 || NFlow <= 0.0)
            {
                return;
            }

            if ((NFlow - this.Nitrogen) > 0.01)
            {
                //PlugIn.ModelCore.UI.WriteLine("  Transfer N:  N flow > source N.");
                //PlugIn.ModelCore.UI.WriteLine("     NFlow={0:0.000}, SourceN={1:0.000}", NFlow, this.Nitrogen);
                //PlugIn.ModelCore.UI.WriteLine("     CFlow={0:0.000}, totalC={1:0.000}", CFlow, totalC);
                //PlugIn.ModelCore.UI.WriteLine("     this.Name={0}, this.Type={1}", this.Name, this.Type);
                //PlugIn.ModelCore.UI.WriteLine("     dest.Name  ={0}, dest.Type  ={1}", destination.Name, destination.Type);
                //PlugIn.ModelCore.UI.WriteLine("     ratio CN to dest={0}", ratioCNtoDestination);
           }

            //...If C/N of Box A > C/N of new material entering Box B
            if ((CFlow / NFlow) > ratioCNtoDestination)
            {
               //...IMMOBILIZATION occurs.
               //...Compute the amount of N immobilized.
               //     since  ratioCNtoDestination = netCFlow / (Nflow + immobileN),
               //     where immobileN is the extra N needed from the mineral pool
                double immobileN = (CFlow / ratioCNtoDestination) - NFlow;
                
                //PlugIn.ModelCore.UI.WriteLine("     CFlow={0:0.000}, totalC={1:0.000}", CFlow, totalC);
               
               // PlugIn.ModelCore.UI.WriteLine("     this.Name={0}, this.Type={1}", this.Name, this.Type);
                //PlugIn.ModelCore.UI.WriteLine("     NFlow={0:0.000}, SourceN={1:0.000},CNdestination={2:0}", NFlow, this.Nitrogen,ratioCNtoDestination);

                //PlugIn.ModelCore.UI.WriteLine("CalculatingImmobil.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                //...Schedule flow from Box A to Box B (outofa)
                //flow(anps,bnps,time,outofa);
                this.Nitrogen -= NFlow;
                destination.Nitrogen += NFlow;

                //PlugIn.ModelCore.UI.WriteLine("NFlow.  MineralN={0:0.00}, ImmobileN={1:0.000}.", SiteVars.MineralN[site],immobileN);

                // Schedule flow from mineral pool to Box B (immobileN)
                // flow(labile,bnps,time,immflo);
                //Don't allow mineral N to go to zero or negative.- ML
                
                if (immobileN > SiteVars.MineralN[site])
                    immobileN = SiteVars.MineralN[site] - 0.01; //leave some small amount of mineral N


                SiteVars.MineralN[site] -= immobileN;
                //PlugIn.ModelCore.UI.WriteLine("AfterImmobil.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                destination.Nitrogen += immobileN;

                //PlugIn.ModelCore.UI.WriteLine("AdjustImmobil.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                //PlugIn.ModelCore.UI.WriteLine("   TransferN immobileN={0:0.000}, C={1:0.000}, N={2:0.000}, ratioCN={3:0.000}.", immobileN, CFlow, NFlow, ratioCNtoDestination);
                //PlugIn.ModelCore.UI.WriteLine("     source={0}-{1}, destination={2}-{3}.", this.Name, this.Type, destination.Name, destination.Type);

                //...Return mineralization value.
                mineralNFlow = -1 * immobileN;
                //PlugIn.ModelCore.UI.WriteLine("MineralNflow.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
            }
            else

                //...MINERALIZATION occurs
                //...Schedule flow from Box A to Box B
            {
                //PlugIn.ModelCore.UI.WriteLine("  Transfer Nitrogen Min.");
                double mineralizedN = (CFlow / ratioCNtoDestination);
                

                this.Nitrogen -= mineralizedN;
                destination.Nitrogen += mineralizedN;

                //...Schedule flow from Box A to mineral pool

                mineralNFlow = NFlow - mineralizedN;

                if ((mineralNFlow - this.Nitrogen) > 0.01) 
                {
                    //PlugIn.ModelCore.UI.WriteLine("  Transfer N mineralization:  mineralN > source N.");
                    //PlugIn.ModelCore.UI.WriteLine("     MineralNFlow={0:0.000}, SourceN={1:0.000}", mineralNFlow, this.Nitrogen);
                    //PlugIn.ModelCore.UI.WriteLine("     CFlow={0:0.000}, totalC={1:0.000}", CFlow, totalC);
                    //PlugIn.ModelCore.UI.WriteLine("     this.Name={0}, this.Type={1}", this.Name, this.Type);
                   // PlugIn.ModelCore.UI.WriteLine("     dest.Name  ={0}, dest.Type  ={1}", destination.Name, destination.Type);
                    //PlugIn.ModelCore.UI.WriteLine("     ratio CN to dest={0}", ratioCNtoDestination);
                }

                this.Nitrogen -= mineralNFlow;

                SiteVars.MineralN[site] += mineralNFlow;
                //PlugIn.ModelCore.UI.WriteLine("     this.Name={0}, this.Type={1}", this.Name, this.Type);
                //PlugIn.ModelCore.UI.WriteLine("IfMinOccurs.  MineralN={0:0.00}.", SiteVars.MineralN[site]);

                //PlugIn.ModelCore.UI.WriteLine("  TransferN NFlow={0:0.000}, mineralizedN = {1:0.000}, N mineralalization = {1:0.000}", NFlow, mineralizedN, mineralNFlow);
                //PlugIn.ModelCore.UI.WriteLine("     Source:  this.Name={0}, this.Type={1}", this.Name, this.Type);
            }

            if (mineralNFlow > 0)
                SiteVars.GrossMineralization[site] += mineralNFlow;

            //...Net mineralization
            this.NetMineralization += mineralNFlow;

            //PlugIn.ModelCore.UI.WriteLine("     this.Nitrogen={0:0.000}.", this.Nitrogen);

            //PlugIn.ModelCore.UI.WriteLine("AfterMinOccurs.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
            return;
        }
        // --------------------------------------------------
        public Layer Clone()
        {
            Layer newLayer = new Layer(this.Name, this.Type);

            newLayer.carbon = this.carbon;
            newLayer.nitrogen = this.nitrogen ;

            newLayer.decayValue = this.decayValue ;
            newLayer.fractionLignin = this.fractionLignin ;

            newLayer.netMineralization = this.netMineralization ;
            newLayer.grossMineralization = this.grossMineralization ;

            return newLayer;
        }
        //---------------------------------------------------------------------
        public void TransferCarbon(Layer destination, double netCFlow)
        {

            if (netCFlow < 0)
            {
                //PlugIn.ModelCore.UI.WriteLine("NEGATIVE C FLOW!  Source: {0},{1}; Destination: {2},{3}.", this.Name, this.Type, destination.Name, destination.Type);
            }

            if (netCFlow > this.Carbon)
                netCFlow = this.Carbon;
                //PlugIn.ModelCore.UI.WriteLine("C FLOW EXCEEDS SOURCE!  Source: {0},{1}; Destination: {2},{3}.", this.Name, this.Type, destination.Name, destination.Type);

            this.Carbon -= netCFlow;
            destination.Carbon += netCFlow;

        }
        //---------------------------------------------------------------------

        private InitialBiomass(ISiteCohorts cohorts,
                
                Layer surfaceDeadWood,
                Layer surfaceStructural,
                Layer surfaceMetabolic,
                
                Layer soilDeadWood,
                Layer soilStructural,
                Layer soilMetabolic,
                
                Layer som1surface,
                Layer som1soil,
                Layer som2,
                Layer som3,
                
                double mineralN,
                double cohortLeafC,
                double cohortFRootC,
                double cohortLeafN,
                double cohortFRootN,
                double cohortWoodC,
                double cohortCRootC,
                double cohortWoodN,
                double cohortCRootN

                )
        {
            this.cohorts = cohorts;
            
            this.surfaceDeadWood = surfaceDeadWood;
            this.surfaceStructural = surfaceStructural;
            this.surfaceMetabolic = surfaceMetabolic;
            
            this.soilDeadWood = soilDeadWood;
            this.soilStructural = soilStructural;
            this.soilMetabolic = soilMetabolic;
            
            this.som1surface = som1surface;
            this.som1soil = som1soil;
            this.som2 = som2;
            this.som3 = som3;
            
            this.mineralN = mineralN;
            this.cohortLeafC = cohortLeafC;
            this.cohortFRootC = cohortFRootC;
            this.cohortLeafN = cohortLeafN;
            this.cohortFRootN = cohortFRootN;
            this.cohortWoodC = cohortWoodC;
            this.cohortCRootC = cohortCRootC;
            this.cohortWoodN = cohortWoodN;
            this.cohortCRootN = cohortCRootN;
        }