Esempio n. 1
0
        /// <summary> Calculates wind speed from predictor met to Map node along path of nodes.  </summary>
        public void DoWS_EstAlongNodes(Continuum thisInst, ref MapNode thisMapNode, int WS_Est_Ind)
        {
            InvestCollection radiiList = thisInst.radiiList;
            ModelCollection  modelList = thisInst.modelList;
            NodeCollection   nodeList  = new NodeCollection();

            Met thisMet    = thisInst.metList.GetMet(thisMapNode.WS_Estimates[WS_Est_Ind].predictorMetName);
            int thisRadius = thisMapNode.WS_Estimates[WS_Est_Ind].radius;

            if (thisMet == null)
            {
                return;
            }

            int numWD       = thisInst.metList.numWD;
            int radiusIndex = 0;

            for (int i = 0; i < radiiList.ThisCount; i++)
            {
                if (thisRadius == radiiList.investItem[i].radius)
                {
                    radiusIndex = i;
                    break;
                }
            }

            Model[] models    = modelList.GetModels(thisInst, thisInst.metList.GetMetsUsed(), Met.TOD.All, Met.Season.All, thisInst.modeledHeight, false);
            Model   thisModel = models[radiusIndex];

            Nodes endNode = nodeList.GetMapAsNode(thisMapNode);

            ModelCollection.WS_Est_Struct WS_EstStr = modelList.DoWS_Estimate(thisMet, endNode, thisMapNode.WS_Estimates[WS_Est_Ind].pathOfNodes, thisModel, thisInst);

            thisMapNode.WS_Estimates[WS_Est_Ind].sectorWS = WS_EstStr.sectorWS;

            // Have sectorwise wind speed at map node now need to calculate avg WS using wind rose
            for (int WD = 0; WD < numWD; WD++)
            {
                thisMapNode.WS_Estimates[WS_Est_Ind].WS = thisMapNode.WS_Estimates[WS_Est_Ind].WS + thisMapNode.WS_Estimates[WS_Est_Ind].sectorWS[WD] * thisMapNode.windRose[WD];
            }
        }
Esempio n. 2
0
        /// <summary> Conducts wind speed estimate from Met 1 to Met 2 and vice-versa and calculates WS cross-prediction struct (WS_CrossPreds[,]) </summary>
        public void DoMetCrossPred(int crossPredInd, int radiusIndex, Continuum thisInst)
        {
            int            numWD    = thisInst.metList.numWD;
            int            numNodes = 0;
            NodeCollection nodeList = new NodeCollection();

            if (WS_Pred[crossPredInd, radiusIndex].nodePath == null)
            {
                numNodes = 0;
            }
            else
            {
                numNodes = WS_Pred[crossPredInd, radiusIndex].nodePath.Length;
            }

            if (numNodes > 0)
            {
                WS_Pred[crossPredInd, radiusIndex].nodeWS_Ests1to2       = new double[numNodes];
                WS_Pred[crossPredInd, radiusIndex].nodeSectorWS_Ests1to2 = new double[numNodes, numWD];

                WS_Pred[crossPredInd, radiusIndex].nodeWS_Ests2to1       = new double[numNodes];
                WS_Pred[crossPredInd, radiusIndex].nodeSectorWS_Ests2to1 = new double[numNodes, numWD];
            }

            Nodes[] pathOfNodes;
            Model   thisModel = WS_Pred[crossPredInd, radiusIndex].model;

            // Get WS distributions at each site (used to calculate the cross-prediction percent error)
            Met.WSWD_Dist met1Dist = met1.GetWS_WD_Dist(thisInst.modeledHeight, thisModel.timeOfDay, thisModel.season);
            Met.WSWD_Dist met2Dist = met2.GetWS_WD_Dist(thisInst.modeledHeight, thisModel.timeOfDay, thisModel.season);

            // Conduct cross-prediction from Met 1 to Met 2
            Nodes endNode = nodeList.GetMetNode(met2);

            ModelCollection.WS_Est_Struct WS_EstStr = thisInst.modelList.DoWS_Estimate(met1, endNode, WS_Pred[crossPredInd, radiusIndex].nodePath, thisModel, thisInst);

            // Get sectorwise wind speed and calculate sectorwise percent error (for Met 1 predicting Met 2)
            for (int WD_Ind = 0; WD_Ind < numWD; WD_Ind++)
            {
                WS_Pred[crossPredInd, radiusIndex].sectorWS_Ests[0, WD_Ind] = WS_EstStr.sectorWS[WD_Ind];
                double met2WS = met2Dist.WS * met2Dist.sectorWS_Ratio[WD_Ind];
                WS_Pred[crossPredInd, radiusIndex].percErrSector[0, WD_Ind] = (WS_EstStr.sectorWS[WD_Ind] - met2WS) / met2WS;
            }

            WS_Pred[crossPredInd, radiusIndex].nodeSectorWS_Ests1to2 = WS_EstStr.sectorWS_AtNodes;
            double avgWS    = 0;
            double WR_count = 0;

            // Get overall wind speed at nodes (for Met 1 predicting Met 2)
            for (int nodeInd = 0; nodeInd < numNodes; nodeInd++)
            {
                avgWS    = 0;
                WR_count = 0;
                Nodes    thisNode     = WS_Pred[crossPredInd, radiusIndex].nodePath[nodeInd];
                double[] nodeWindRose = thisInst.metList.GetInterpolatedWindRose(thisModel.metsUsed, thisNode.UTMX, thisNode.UTMY, thisModel.timeOfDay, thisModel.season, thisInst.modeledHeight);

                for (int WD_Ind = 0; WD_Ind < numWD; WD_Ind++)
                {
                    avgWS    = avgWS + nodeWindRose[WD_Ind] * WS_Pred[crossPredInd, radiusIndex].nodeSectorWS_Ests1to2[nodeInd, WD_Ind];
                    WR_count = WR_count + nodeWindRose[WD_Ind];
                }

                WS_Pred[crossPredInd, radiusIndex].nodeWS_Ests1to2[nodeInd] = avgWS / WR_count;
            }

            avgWS    = 0;
            WR_count = 0;

            for (int WD = 0; WD < numWD; WD++)
            {
                avgWS    = avgWS + WS_Pred[crossPredInd, radiusIndex].sectorWS_Ests[0, WD] * met2Dist.windRose[WD];
                WR_count = WR_count + met2Dist.windRose[WD];
            }

            // Calculate avg WS estimate and overall error at Met 2
            avgWS = avgWS / WR_count;
            WS_Pred[crossPredInd, radiusIndex].WS_Ests[0] = avgWS;
            WS_Pred[crossPredInd, radiusIndex].percErr[0] = (avgWS - met2Dist.WS) / met2Dist.WS;

            // Now conduct same calculations but going from Met 2 to Met 1.
            endNode = nodeList.GetMetNode(met1);

            if (numNodes > 0)
            {
                pathOfNodes = new Nodes[numNodes];
            }
            else
            {
                pathOfNodes = null;
            }

            // Reverse order of nodes when going from Met 2 to Met 1
            for (int i = 0; i < numNodes; i++)
            {
                pathOfNodes[i] = WS_Pred[crossPredInd, radiusIndex].nodePath[numNodes - 1 - i];
            }

            // Do WS Estimate for Met 2 predicting Met 1
            WS_EstStr = thisInst.modelList.DoWS_Estimate(met2, endNode, pathOfNodes, thisModel, thisInst);

            // Get sectorwise wind speed and sectorwise percent error (for Met 2 predicting Met 1)
            for (int WD_Ind = 0; WD_Ind < numWD; WD_Ind++)
            {
                WS_Pred[crossPredInd, radiusIndex].sectorWS_Ests[1, WD_Ind] = WS_EstStr.sectorWS[WD_Ind];
                WS_Pred[crossPredInd, radiusIndex].percErrSector[1, WD_Ind] = (WS_EstStr.sectorWS[WD_Ind] - met1Dist.WS * met1Dist.sectorWS_Ratio[WD_Ind])
                                                                              / (met1Dist.WS * met1Dist.sectorWS_Ratio[WD_Ind]);
            }

            WS_Pred[crossPredInd, radiusIndex].nodeSectorWS_Ests2to1 = WS_EstStr.sectorWS_AtNodes;
            avgWS    = 0;
            WR_count = 0;
            // Get overall wind speed at nodes (for Met 2 predicting Met 1)
            for (int nodeInd = 0; nodeInd < numNodes; nodeInd++)
            {
                avgWS    = 0;
                WR_count = 0;
                Nodes    thisNode     = pathOfNodes[nodeInd];
                double[] nodeWindRose = thisInst.metList.GetInterpolatedWindRose(thisModel.metsUsed, thisNode.UTMX, thisNode.UTMY, thisModel.timeOfDay, thisModel.season, thisInst.modeledHeight);

                for (int WD_Ind = 0; WD_Ind < numWD; WD_Ind++)
                {
                    avgWS    = avgWS + nodeWindRose[WD_Ind] * WS_Pred[crossPredInd, radiusIndex].nodeSectorWS_Ests2to1[nodeInd, WD_Ind];
                    WR_count = WR_count + nodeWindRose[WD_Ind];
                }

                WS_Pred[crossPredInd, radiusIndex].nodeWS_Ests2to1[nodeInd] = avgWS / WR_count;
            }

            avgWS    = 0;
            WR_count = 0;
            for (int WD = 0; WD < numWD; WD++)
            {
                avgWS    = avgWS + WS_Pred[crossPredInd, radiusIndex].sectorWS_Ests[1, WD] * met1Dist.windRose[WD];
                WR_count = WR_count + met1Dist.windRose[WD];
            }

            // Calculate avg WS estimate and overall error at Met 1
            avgWS = avgWS / WR_count;
            WS_Pred[crossPredInd, radiusIndex].WS_Ests[1] = avgWS;
            WS_Pred[crossPredInd, radiusIndex].percErr[1] = (avgWS - met1Dist.WS) / met1Dist.WS;
        }