/// <summary> Calculates gross energy production at referenced mapNode. </summary> public void CalcGrossAEP_AtMapNode(ref MapNode thisMapNode, MetCollection metList, TurbineCollection turbineList) { int numWS = metList.numWS; int numWD = metList.numWD; thisMapNode.sectorGross = new double[numWD]; TurbineCollection.PowerCurve thisPowerCurve = turbineList.GetPowerCurve(powerCurve); thisMapNode.grossAEP = 0; for (int k = 0; k < numWS; k++) { double thisWS = metList.GetWS_atWS_Ind(k); double thisPower = turbineList.GetInterpPowerOrThrust(thisWS, thisPowerCurve, "Power"); thisMapNode.grossAEP = thisMapNode.grossAEP + thisMapNode.WS_Dist[k] * thisPower; for (int WD_Ind = 0; WD_Ind < numWD; WD_Ind++) { thisMapNode.sectorGross[WD_Ind] = thisMapNode.sectorGross[WD_Ind] + thisMapNode.sectDist[WD_Ind, k] * thisPower; } } thisMapNode.grossAEP = thisMapNode.grossAEP * 365 * 24 / 1000; for (int WD_Ind = 0; WD_Ind < numWD; WD_Ind++) { thisMapNode.sectorGross[WD_Ind] = thisMapNode.sectorGross[WD_Ind] * 365 * 24 / 1000 * thisMapNode.windRose[WD_Ind]; } }
/// <summary> Calculates and returns the average wind speed for specified wind speed range, time interval range, /// wind direction range, time of day, and season </summary> public double CalcAvgWS(MCP.Site_data[] site, DateTime startTime, DateTime endTime, double minWD, double maxWD, Met.TOD TOD, Met.Season season, MetCollection metList) { double avgWS = 0; int avgCount = 0; foreach (MCP.Site_data thisSite in site) { if (thisSite.thisDate >= startTime && thisSite.thisDate <= endTime) { Met.TOD thisTOD = metList.GetTOD(thisSite.thisDate); Met.Season thisSeason = metList.GetSeason(thisSite.thisDate); if ((TOD == thisTOD || TOD == Met.TOD.All) && (thisSeason == season || season == Met.Season.All)) { if (((maxWD > minWD) && (thisSite.thisWD >= minWD && thisSite.thisWD <= maxWD)) || ((maxWD < minWD) && (thisSite.thisWD >= minWD || thisSite.thisWD <= maxWD))) { avgWS = avgWS + thisSite.thisWS; avgCount = avgCount + 1; } } } } if (avgCount > 0) { avgWS = avgWS / avgCount; } return(avgWS); }
/// <summary> Returns the count of Site_data for specified start/end time, WD bounds, time of day bin and season bin. </summary> public int GetDataCount(MCP.Site_data[] site, DateTime startTime, DateTime endTime, int WD_index, Met.TOD TOD, Met.Season season, MetCollection metList, bool getAll) { int avgCount = 0; foreach (MCP.Site_data thisSite in site) { if (thisSite.thisDate >= startTime && thisSite.thisDate <= endTime) { if (getAll == true) { avgCount++; } else { int thisWD_Ind = metList.GetWD_Ind(thisSite.thisWD); Met.TOD thisTOD = metList.GetTOD(thisSite.thisDate); Met.Season thisSeason = metList.GetSeason(thisSite.thisDate); if (((thisWD_Ind == WD_index) || WD_index == metList.numWD) && (thisTOD == TOD) && (thisSeason == season)) { avgCount++; } } } } return(avgCount); }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Generates wind speed estimates at referenced map node using each met and each Continuum model (i.e. each radius of investigation). </summary> public void DoMapCalcs(ref MapNode thisMapNode, Continuum thisInst) { MetCollection metList = thisInst.metList; int numMetsUsed = metsUsed.Length; int numRadii = thisInst.radiiList.ThisCount; NodeCollection nodeList = new NodeCollection(); Met[] theseMets = metList.GetMets(metList.GetMetsUsed(), null); // For each met and each radius of investigation (i.e. each Continuum model), generate wind speed estimate at map node. for (int j = 0; j < numMetsUsed; j++) { for (int r = 0; r < numRadii; r++) { int thisRadius = thisInst.radiiList.investItem[r].radius; WS_Ests newWS_Est = new WS_Ests(); newWS_Est.predictorMetName = theseMets[j].name; newWS_Est.radius = thisRadius; AddWS_Estimate(ref thisMapNode, ref newWS_Est); int WS_Est_ind = thisMapNode.WS_Estimates.Length - 1; Nodes targetNode = nodeList.GetMapAsNode(thisMapNode); Nodes startNode = nodeList.GetMetNode(theseMets[j]); thisMapNode.WS_Estimates[WS_Est_ind].pathOfNodes = nodeList.FindPathOfNodes(startNode, targetNode, model[r], thisInst); thisMapNode.WS_Estimates[WS_Est_ind].radius = model[r].radius; DoWS_EstAlongNodes(thisInst, ref thisMapNode, WS_Est_ind); } } }
/// <summary> Checks to see if map has already been created. Returns false if has not been created. </summary> public bool CheckForDuplicate(string[] metsUsed, double minUTMX, double minUTMY, int numX, int numY, int reso, int whatToMap, string powerCurve, bool useSR, bool useSepModel, Wake_Model thisWakeModel, bool useTimeSeries) { bool alreadyExists = false; WakeCollection wakeList = new WakeCollection(); MetCollection metList = new MetCollection(); if (ThisCount > 0) { for (int i = 0; i < ThisCount; i++) { if (mapItem[i].minUTMX == minUTMX && mapItem[i].minUTMY == minUTMY && mapItem[i].numX == numX && mapItem[i].numY == numY && mapItem[i].reso == reso && mapItem[i].modelType == whatToMap && metList.sameMets(metsUsed, mapItem[i].metsUsed) && mapItem[i].powerCurve == powerCurve && mapItem[i].useSR == useSR && mapItem[i].useFlowSep == useSepModel && wakeList.IsSameWakeModel(mapItem[i].wakeModel, thisWakeModel) && mapItem[i].useTimeSeries == useTimeSeries) { MessageBox.Show("An identical map has already been created.", "Continuum 3"); alreadyExists = true; break; } } } return(alreadyExists); }
public void CalcWS_DeficitEddyViscosityGrid_Test() { WakeCollection wakeModelList = new WakeCollection(); TurbineCollection turbineList = new TurbineCollection(); double[] power = new double[23]; string Power_file = testingFolder + "\\CalcWS_DeficitEddyViscosityGrid\\Power.txt"; StreamReader sr = new StreamReader(Power_file); for (int i = 0; i <= 22; i++) { power[i] = Convert.ToSingle(sr.ReadLine()); } double[] Thrust = new double[23]; string Thrust_file = testingFolder + "\\CalcWS_DeficitEddyViscosityGrid\\Thrust.txt"; sr = new StreamReader(Thrust_file); for (int i = 0; i <= 22; i++) { Thrust[i] = Convert.ToSingle(sr.ReadLine()); } turbineList.AddPowerCurve("GW 1500/87", 3, 22, 1500, power, Thrust, 87, 16, 10, 1, 0); wakeModelList.AddWakeModel(0, 5, 10, turbineList.powerCurves[0], 10, 3.5f, 0.03f, "Linear"); MetCollection metList = new MetCollection(); metList.metItem = new Met[1]; metList.metItem[0] = new Met(); double[,] Vel_Def = wakeModelList.CalcWS_DeficitEddyViscosityGrid(2, 30, 0.1f, 0.025f, 8, wakeModelList.wakeModels[0], metList); Assert.AreEqual(Vel_Def[16, 2], 0.450777, 0.01, "Wrong Vel Def Test 1 r = 0.05"); Assert.AreEqual(Vel_Def[16, 10], 0.196172, 0.01, "Wrong Vel Def Test 1 r = 0.25"); Assert.AreEqual(Vel_Def[16, 17], 0.03166, 0.01, "Wrong Vel Def Test 1 r = 0.425"); Assert.AreEqual(Vel_Def[40, 0], 0.255068, 0.01, "Wrong Vel Def Test 2 r = 0.05"); Assert.AreEqual(Vel_Def[40, 7], 0.194434, 0.01, "Wrong Vel Def Test 2 r = 0.25"); Assert.AreEqual(Vel_Def[40, 18], 0.02328, 0.01, "Wrong Vel Def Test 2 r = 0.425"); wakeModelList.AddWakeModel(0, 10, 14, turbineList.powerCurves[0], 10, 3.5f, 0.03f, "Linear"); Vel_Def = wakeModelList.CalcWS_DeficitEddyViscosityGrid(2, 30, 0.1f, 0.025f, 6, wakeModelList.wakeModels[1], metList); Assert.AreEqual(Vel_Def[4, 2], 0.513121, 0.01, "Wrong Vel Def Test 3 r = 0.05"); Assert.AreEqual(Vel_Def[4, 10], 0.20352, 0.01, "Wrong Vel Def Test 3 r = 0.25"); Assert.AreEqual(Vel_Def[4, 16], 0.04366, 0.01, "Wrong Vel Def Test 3 r = 0.4"); Assert.AreEqual(Vel_Def[42, 4], 0.18052, 0.01, "Wrong Vel Def Test 4 r = 0.05"); Assert.AreEqual(Vel_Def[42, 19], 0.01031, 0.01, "Wrong Vel Def Test 4 r = 0.25"); }
/// <summary> Goes through each met and turbine site and check elev at 8 points +/- 12000 m. If elev = -999, return false </summary> public bool NewTopo(TopoInfo topo, MetCollection metList, TurbineCollection turbList) { bool goodToGo = true; for (int i = 0; i < metList.ThisCount; i++) { goodToGo = TopoCheck(topo, metList.metItem[i].UTMX, metList.metItem[i].UTMY, metList.metItem[i].name, true); } for (int i = 0; i < turbList.TurbineCount; i++) { goodToGo = TopoCheck(topo, turbList.turbineEsts[i].UTMX, turbList.turbineEsts[i].UTMY, turbList.turbineEsts[i].name, true); } return(goodToGo); }
/// <summary> Compares turbine name to met site names to ensure there are no duplicate names. </summary> /// <returns> Returns false if a turbine with same name exists </returns> public bool CheckTurbName(string turbineName, MetCollection metList) { bool inputTurbine = true; int numMets = metList.ThisCount; for (int i = 0; i < numMets; i++) { if (metList.metItem[i].name == turbineName) { inputTurbine = false; MessageBox.Show("There is a met with the same name as turbine site: " + turbineName + ". There cannot be a turbine and met site with the same name.", "Continuum 3"); break; } } return(inputTurbine); }
public void CalcDAWM_Deficit_Test() { WakeCollection WakeModList = new WakeCollection(); TurbineCollection turbineList = new TurbineCollection(); double[] power = new double[23]; string Power_file = testingFolder + "\\CalcDAWM_Deficit\\Power.txt"; StreamReader sr = new StreamReader(Power_file); for (int i = 0; i <= 22; i++) { power[i] = Convert.ToSingle(sr.ReadLine()); } double[] Thrust = new double[23]; string Thrust_file = testingFolder + "\\CalcDAWM_Deficit\\Thrust.txt"; sr = new StreamReader(Thrust_file); for (int i = 0; i <= 22; i++) { Thrust[i] = Convert.ToSingle(sr.ReadLine()); } turbineList.AddPowerCurve("GW 1500/87", 3, 22, 1500, power, Thrust, 87, 16, 10, 1, 0); Turbine[] UW_Turbs = new Turbine[1]; UW_Turbs[0] = new Turbine(); UW_Turbs[0].UTMX = 283000; UW_Turbs[0].UTMY = 4553300; MetCollection metList = new MetCollection(); metList.metItem = new Met[1]; metList.metItem[0] = new Met(); metList.WS_FirstInt = 0.5f; metList.WS_IntSize = 1; metList.numWS = 30; WakeModList.AddWakeModel(1, 5, 10, turbineList.powerCurves[0], 10, 3.5f, 0.03f, "Linear"); double This_Def = WakeModList.Calc_DAWM_Deficit(UW_Turbs, 280000, 4553500, 90, 8, WakeModList.wakeModels[0], metList, 80.0); Assert.AreEqual(This_Def, 0.04742, 1, "Wrong wind speed deficit in DAWM"); }
/// <summary> Goes through each met and turbine site and check land cover at 8 points +/- 12000 m. If elev = -999, return false </summary> public bool NewLandCover(TopoInfo topo, MetCollection metList, TurbineCollection turbList) { // Go through each met and turbine site and check land cover at 8 points +/- 12000 m. If elev = -999, return false bool goodToGo = true; for (int i = 0; i < metList.ThisCount; i++) { goodToGo = LandCoverCheck(topo, metList.metItem[i].UTMX, metList.metItem[i].UTMY, metList.metItem[i].name, true); } for (int i = 0; i < turbList.TurbineCount; i++) { goodToGo = LandCoverCheck(topo, turbList.turbineEsts[i].UTMX, turbList.turbineEsts[i].UTMY, turbList.turbineEsts[i].name, true); } return(goodToGo); }
public void InterpolateFindWakedDist_Test() { string fileName = testingFolder + "\\InterpolateFindWakedDist\\Dist.csv"; StreamReader sr = new StreamReader(fileName); double[] dist = new double[31]; double[] wakedDistWS = new double[31]; int counter = 0; while (sr.EndOfStream == false) { double thisVal = Convert.ToDouble(sr.ReadLine()); dist[counter] = thisVal; counter++; } sr.Close(); fileName = testingFolder + "\\InterpolateFindWakedDist\\WakedDistWS.csv"; sr = new StreamReader(fileName); counter = 0; while (sr.EndOfStream == false) { double thisVal = Convert.ToDouble(sr.ReadLine()); wakedDistWS[counter] = thisVal; counter++; } MetCollection metList = new MetCollection(); metList.WS_FirstInt = 0.5; metList.WS_IntSize = 1; WakeCollection wakeList = new WakeCollection(); double[] wakedDist = wakeList.InterpolateFindWakedDist(wakedDistWS, dist, metList); Assert.AreEqual(wakedDist[2], 0.1715, 0.001, "Wrong waked dist Test 1"); Assert.AreEqual(wakedDist[4], 0.296506, 0.001, "Wrong waked dist Test 2"); Assert.AreEqual(wakedDist[6], 0.01881, 0.001, "Wrong waked dist Test 3"); Assert.AreEqual(wakedDist[8], 0.0059, 0.001, "Wrong waked dist Test 4"); sr.Close(); }
/// <summary> Calculates overall and sectorwise wind speed distribution for referenced map node. </summary> public void CalcWS_DistAtMapNode(ref MapNode thisMapNode, MetCollection metList, int numWD, double height) { string[] metsUsed = metList.GetMetsUsed(); int numWS = metList.numWS; thisMapNode.sectDist = new double[numWD, numWS]; for (int WD = 0; WD < numWD; WD++) { double[] WS_Dist = metList.CalcWS_DistForTurbOrMap(metsUsed, thisMapNode.sectorWS[WD], WD, Met.TOD.All, Met.Season.All, height); for (int WS = 0; WS < numWS; WS++) { thisMapNode.sectDist[WD, WS] = WS_Dist[WS]; } } thisMapNode.WS_Dist = metList.CalcOverallWS_Dist(thisMapNode.sectDist, thisMapNode.windRose); }
public void CalcIBL_H1_Test() { WakeCollection WakeModList = new WakeCollection(); TurbineCollection turbineList = new TurbineCollection(); double[] power = new double[23]; string Power_file = testingFolder + "\\Calc_IBL_H1\\Power.txt"; StreamReader sr = new StreamReader(Power_file); for (int i = 0; i <= 22; i++) { power[i] = Convert.ToSingle(sr.ReadLine()); } double[] Thrust = new double[23]; string Thrust_file = testingFolder + "\\Calc_IBL_H1\\Thrust.txt"; sr = new StreamReader(Thrust_file); for (int i = 0; i <= 22; i++) { Thrust[i] = Convert.ToSingle(sr.ReadLine()); } turbineList.AddPowerCurve("GW 1500/87", 3, 22, 1500, power, Thrust, 87, 16, 10, 1, 0); Turbine[] UW_Turbs = new Turbine[1]; UW_Turbs[0] = new Turbine(); UW_Turbs[0].UTMX = 283000; UW_Turbs[0].UTMY = 4553300; MetCollection metList = new MetCollection(); metList.metItem = new Met[1]; metList.metItem[0] = new Met(); WakeModList.AddWakeModel(1, 5, 10, turbineList.powerCurves[0], 10, 3.5f, 0.03f, "Linear"); double This_IBL_H1 = WakeModList.Calc_IBL_H1(UW_Turbs[0], 280000, 4553500, WakeModList.wakeModels[0], 90f, 1.9316f, 80.0); Assert.AreEqual(This_IBL_H1, 750.4, 1, "Wrong IBL H1"); }
public void CalcEquivRoughness_Test() { WakeCollection WakeModList = new WakeCollection(); TurbineCollection turbineList = new TurbineCollection(); double[] power = new double[23]; string Power_file = testingFolder + "\\CalcEquivRoughness\\Power.txt"; StreamReader sr = new StreamReader(Power_file); for (int i = 0; i <= 22; i++) { power[i] = Convert.ToSingle(sr.ReadLine()); } double[] Thrust = new double[23]; string Thrust_file = testingFolder + "\\CalcEquivRoughness\\Thrust.txt"; sr = new StreamReader(Thrust_file); for (int i = 0; i <= 22; i++) { Thrust[i] = Convert.ToSingle(sr.ReadLine()); } turbineList.AddPowerCurve("GW 1500/87", 3, 22, 1500, power, Thrust, 87, 16, 10, 1, 0); WakeModList.AddWakeModel(1, 5, 10, turbineList.powerCurves[0], 10, 3.5f, 0.03f, "Linear"); MetCollection metList = new MetCollection(); metList.metItem = new Met[1]; metList.metItem[0] = new Met(); metList.WS_FirstInt = 0.5; metList.WS_IntSize = 1; metList.numWS = 30; double This_Equiv_Rough = WakeModList.CalcEquivRoughness(metList, 8, WakeModList.wakeModels[0], 80.0); Assert.AreEqual(This_Equiv_Rough, 1.9316, 0.01, "Wrong equivalent roughness for DAWM"); }
/// <summary> Return Map index of incomplete map if it exists, return -999 if not. </summary> public int GetIncompleteMapInd(Map thisMap) { WakeCollection wakeList = new WakeCollection(); MetCollection metList = new MetCollection(); int mapInd = -999; if (ThisCount > 0) { for (int i = 0; i < ThisCount; i++) { if (mapItem[i].isComplete == false && mapItem[i].minUTMX == thisMap.minUTMX && mapItem[i].minUTMY == thisMap.minUTMY && mapItem[i].numX == thisMap.numX && mapItem[i].numY == thisMap.numY && mapItem[i].reso == thisMap.reso && mapItem[i].modelType == thisMap.modelType && metList.sameMets(thisMap.metsUsed, mapItem[i].metsUsed) && mapItem[i].powerCurve == thisMap.powerCurve && mapItem[i].useSR == thisMap.useSR && mapItem[i].useFlowSep == thisMap.useFlowSep && wakeList.IsSameWakeModel(mapItem[i].wakeModel, thisMap.wakeModel) && mapItem[i].useTimeSeries == thisMap.useTimeSeries) { mapInd = i; break; } } } return(mapInd); }
public void CalcWakeLosses_Test() { WakeCollection WakeModList = new WakeCollection(); TurbineCollection turbineList = new TurbineCollection(); double[] power = new double[31]; string Power_file = testingFolder + "\\CalcWakeLosses\\power.txt"; StreamReader sr = new StreamReader(Power_file); for (int i = 0; i <= 22; i++) { power[i] = Convert.ToSingle(sr.ReadLine()); } double[] Thrust = new double[31]; string Thrust_file = testingFolder + "\\CalcWakeLosses\\Thrust.txt"; sr = new StreamReader(Thrust_file); for (int i = 0; i <= 22; i++) { Thrust[i] = Convert.ToSingle(sr.ReadLine()); } turbineList.AddPowerCurve("GW 1500/87", 3, 22, 1500, power, Thrust, 87, 16, 10, 1, 0); WakeModList.AddWakeModel(0, 5, 10, turbineList.powerCurves[0], 10, 3.5f, 0.03f, "Linear"); MetCollection metList = new MetCollection(); metList.metItem = new Met[1]; metList.metItem[0] = new Met(); // Load sectorwise wind speed distribution string Sect_WS_file = testingFolder + "\\CalcWakeLosses\\Sect_WS.txt"; sr = new StreamReader(Sect_WS_file); double[,] sectorWS = new double[16, 31]; for (int i = 0; i <= 15; i++) { string This_WS_Array = sr.ReadLine(); string[] This_Array_Split = This_WS_Array.Split('\t'); for (int j = 0; j <= 30; j++) { sectorWS[i, j] = Convert.ToSingle(This_Array_Split[j]); } } string WR_file = testingFolder + "\\CalcWakeLosses\\Wind_Rose.txt"; sr = new StreamReader(WR_file); double[] windRose = new double[16]; for (int i = 0; i <= 15; i++) { windRose[i] = Convert.ToSingle(sr.ReadLine()) / 100; } string Sect_AEP_file = testingFolder + "\\CalcWakeLosses\\Sect_AEP.txt"; sr = new StreamReader(Sect_AEP_file); double[] Sect_AEP = new double[16]; for (int i = 0; i <= 15; i++) { Sect_AEP[i] = Convert.ToSingle(sr.ReadLine()); } double[] R_RD = new double[21]; for (int i = 0; i <= 20; i++) { R_RD[i] = i * 0.025f; } WakeCollection.WakeLossCoeffs[] These_Coeffs = new WakeCollection.WakeLossCoeffs[140]; // 5 (DW_RDs) x 28 (WS > 3) int Ind_Count = 0; for (double DW_RD = 5.5f; DW_RD <= 5.9; DW_RD = DW_RD + 0.1f) { int DW_ind = (int)Math.Round((DW_RD - 2) / 0.1, 0); for (int i = 3; i <= 30; i++) { double[] Vel_Def_Rad = new double[21]; // Velocity Deficit profile at X_Length_RD double[,] WS_Def_EV_Grid = WakeModList.CalcWS_DeficitEddyViscosityGrid(2f, 6f, 0.1f, 0.025f, i, WakeModList.wakeModels[0], metList); for (int radiusInd = 0; radiusInd <= 19; radiusInd++) { Vel_Def_Rad[radiusInd] = WS_Def_EV_Grid[DW_ind, radiusInd]; // index = 37 corresponds to DW dist = 5.7 (i.e. 2 + 0.1 * 37 = 5.7) } Vel_Def_Rad[20] = 0; double[] Coeffs = WakeModList.CalcWakeProfileFit(Vel_Def_Rad, R_RD); These_Coeffs[Ind_Count].freeStream = i; These_Coeffs[Ind_Count].X_LengthRD = DW_RD; These_Coeffs[Ind_Count].linRegInt = Coeffs[0]; These_Coeffs[Ind_Count].linCoeff4 = Coeffs[1]; These_Coeffs[Ind_Count].linCoeff3 = Coeffs[2]; These_Coeffs[Ind_Count].linCoeff2 = Coeffs[3]; These_Coeffs[Ind_Count].linCoeff1 = Coeffs[4]; Ind_Count++; } } turbineList.AddTurbine("Target Site", 280050, 4552500, 1); turbineList.AddTurbine("UW Site", 280000, 4553000, 1); Continuum thisInst = new Continuum(""); thisInst.turbineList = turbineList; thisInst.metList.WS_FirstInt = 0.5; thisInst.metList.WS_IntSize = 1; thisInst.metList.numWS = 30; thisInst.metList.AddMetTAB("dummy", 0, 0, 0, windRose, sectorWS, 0.5, 1, thisInst); // Need to define exceed model thisInst.turbineList.exceed = new Exceedance(); thisInst.turbineList.exceed.compositeLoss = new Exceedance.Monte_Carlo(); thisInst.turbineList.exceed.compositeLoss.pVals1yr = new double[100]; for (int i = 0; i < 100; i++) { thisInst.turbineList.exceed.compositeLoss.pVals1yr[i] = 1.0; } WakeCollection.WakeCalcResults WakeResults = WakeModList.CalcWakeLosses(These_Coeffs, 280050, 4552500, sectorWS, 4130, Sect_AEP, thisInst, WakeModList.wakeModels[0], windRose); Assert.AreEqual(WakeResults.sectorNetEnergy[0], 79.1604, 0.1, "Wrong net AEP"); Assert.AreEqual(WakeResults.sectorWakedWS[0], 4.2851, 0.1, "Wrong waked wind speed"); Assert.AreEqual(WakeResults.sectorWakeLoss[0], 0.2278, 0.1, "Wrong wake loss"); }
/// <summary> Combines all wind speed estimates formed by each predictor met and each wind flow model to form average wind speed estimate at map node. </summary> public void GenerateAvgWS_AtOneMapNode(ref MapNode thisMapNode, Continuum thisInst) { double avgWS = 0; double avgWeight = 0; MetCollection metList = thisInst.metList; ModelCollection modelList = thisInst.modelList; InvestCollection radiiList = thisInst.radiiList; int numRadii = thisInst.radiiList.ThisCount; int numWD = thisInst.metList.numWD; thisMapNode.sectorWS = new double[numWD]; double[] sectorWS = new double[numWD]; int numMetsUsed = metsUsed.Length; Met[] predMets = new Met[numMetsUsed]; for (int i = 0; i < numMetsUsed; i++) { for (int j = 0; j < metList.ThisCount; j++) { if (metsUsed[i] == metList.metItem[j].name) { predMets[i] = metList.metItem[j]; break; } } } Model[] models = modelList.GetModels(thisInst, metList.GetMetsUsed(), Met.TOD.All, Met.Season.All, thisInst.modeledHeight, false); NodeCollection nodeList = new NodeCollection(); Nodes MapNode = nodeList.GetMapAsNode(thisMapNode); ModelCollection.ModelWeights[] indivMetWeights = modelList.GetWS_EstWeights(predMets, MapNode, models, metList.GetAvgWindRose(thisInst.modeledHeight, Met.TOD.All, Met.Season.All), thisInst.radiiList); for (int r = 0; r < numRadii; r++) { for (int j = 0; j < thisMapNode.WS_Estimates.Length; j++) { bool isMetUsed = false; for (int k = 0; k < metsUsed.Length; k++) { if (metsUsed[k] == thisMapNode.WS_Estimates[j].predictorMetName) { isMetUsed = true; break; } } if (isMetUsed == true && thisMapNode.WS_Estimates[j].radius == radiiList.investItem[r].radius && thisMapNode.WS_Estimates[j].WS != 0) { Met thisMet = thisInst.metList.GetMet(thisMapNode.WS_Estimates[j].predictorMetName); double weight = thisInst.modelList.GetWeightForMetAndModel(indivMetWeights, thisMet, models[r]); avgWS = avgWS + thisMapNode.WS_Estimates[j].WS * weight; thisMapNode.WS_Estimates[j].WS_weight = weight; avgWeight = avgWeight + weight; for (int WD = 0; WD < numWD; WD++) { sectorWS[WD] = sectorWS[WD] + thisMapNode.WS_Estimates[j].sectorWS[WD] * weight; } } } } thisMapNode.avgWS_Est = 0; if (avgWeight != 0) { thisMapNode.avgWS_Est = avgWS / avgWeight; for (int WD = 0; WD < numWD; WD++) { thisMapNode.sectorWS[WD] = thisMapNode.sectorWS[WD] + sectorWS[WD] / avgWeight; } } }