/// <summary> Adds exposure to expo() list. </summary> public void AddExposure(int radius, double exponent, int numSectors, int numWD) { int expCount = ExposureCount; int insertInd = 0; if (expCount > 0) { if (radius > expo[expCount - 1].radius) // Larger radius than largest in list { insertInd = expCount - 1; } else { for (int i = 0; i <= expCount - 2; i++) { if (expo[i].radius < radius && expo[i + 1].radius >= radius) { insertInd = i; break; } } } Exposure[] existingExpos = expo; expo = new Exposure[expCount + 1]; for (int j = 0; j <= insertInd; j++) { expo[j] = existingExpos[j]; } expo[insertInd + 1] = new Exposure(); expo[insertInd + 1].radius = radius; expo[insertInd + 1].exponent = exponent; expo[insertInd + 1].numSectors = numSectors; expo[insertInd + 1].expo = new double[numWD]; for (int j = insertInd + 2; j <= expCount; j++) { expo[j] = existingExpos[j - 1]; } } else { expo = new Exposure[1]; expo[0] = new Exposure(); expo[0].radius = radius; expo[0].exponent = exponent; expo[0].numSectors = numSectors; expo[0].expo = new double[numWD]; } }
/// <summary> Calculates P10 UW and P10 DW exposure in each WD sector for specified radius. List of nodes pulled from database (nodesFromDB) are passed to function /// and are used when possible. If a grid point is not in nodesFromDB, the exposure is calculated and is added to the referenced list of nodes allNodesForDB.</summary> public void CalcGridStats(int radiusInd, ref TopoInfo.TopoGrid[] gridArray, ref Node_table[] allNodesForDB, Nodes[] nodesFromDB, Continuum thisInst, bool isTest, string outFilename) { Grid_Avg_SD thisStats = new Grid_Avg_SD(); int gridCount = gridArray.Length; int numWD = thisInst.metList.numWD; double[] thisGridUW = new double[gridCount]; // UW exposure at each grid point for specific WD sector double[] thisGridDW = new double[gridCount]; Exposure[] gridExpos = new Exposure[gridCount]; int numDB = 0; int radius = thisInst.radiiList.investItem[radiusInd].radius; double[,] gridUW = new double[gridCount, numWD]; // UW exposure at each grid point for each WD sector double[,] gridDW = new double[gridCount, numWD]; BinaryFormatter bin = new BinaryFormatter(); for (int j = 0; j < gridCount; j++) { if (gridArray[j].elev == 0) { gridArray[j].elev = thisInst.topo.CalcElevs(gridArray[j].UTMX, gridArray[j].UTMY); } gridExpos[j] = new Exposure(); if (nodesFromDB != null) { for (int i = 0; i < nodesFromDB.Length; i++) { if (nodesFromDB[i].UTMX == gridArray[j].UTMX && nodesFromDB[i].UTMY == gridArray[j].UTMY) { gridExpos[j] = nodesFromDB[i].expo.ElementAt(radiusInd); break; } } } if (gridExpos[j].expo == null) { // Calculate exposure for each radius // Save calculated node to list Array.Resize(ref allNodesForDB, numDB + 1); allNodesForDB[numDB] = new Node_table(); allNodesForDB[numDB].UTMX = gridArray[j].UTMX; allNodesForDB[numDB].UTMY = gridArray[j].UTMY; allNodesForDB[numDB].elev = gridArray[j].elev; for (int i = 0; i < thisInst.radiiList.ThisCount; i++) { int thisRadius = thisInst.radiiList.investItem[i].radius; double thisExponent = thisInst.radiiList.investItem[i].exponent; if (gridArray[j].smallerR_Exposure == null) { gridExpos[j] = thisInst.topo.CalcExposures(gridArray[j].UTMX, gridArray[j].UTMY, gridArray[j].elev, thisRadius, thisExponent, 1, thisInst.topo, numWD); } else { int smallerRadius = gridArray[j].smallerRadius; Exposure smallerExposure = gridArray[j].smallerR_Exposure; gridExpos[j] = thisInst.topo.CalcExposuresWithSmallerRadius(gridArray[j].UTMX, gridArray[j].UTMY, gridArray[j].elev, thisRadius, thisExponent, 1, smallerRadius, smallerExposure, numWD); } if (thisRadius == radius) { for (int WD = 0; WD < numWD; WD++) { gridUW[j, WD] = gridExpos[j].expo[WD]; gridDW[j, WD] = gridExpos[j].GetDW_Param(WD, "Expo"); } } MemoryStream MS1 = new MemoryStream(); bin.Serialize(MS1, gridExpos[j].expo); Expo_table expoTable = new Expo_table(); allNodesForDB[numDB].expo.Add(expoTable); allNodesForDB[numDB].expo.ElementAt(i).exponent = thisExponent; allNodesForDB[numDB].expo.ElementAt(i).radius = thisRadius; allNodesForDB[numDB].expo.ElementAt(i).Expo_Array = MS1.ToArray(); MemoryStream MS2 = new MemoryStream(); bin.Serialize(MS2, gridExpos[j].expoDist); allNodesForDB[numDB].expo.ElementAt(i).ExpoDist_Array = MS2.ToArray(); gridArray[j].smallerRadius = thisRadius; gridArray[j].smallerR_Exposure = gridExpos[j]; } numDB = numDB + 1; } else { for (int WD = 0; WD < numWD; WD++) { gridUW[j, WD] = gridExpos[j].expo[WD]; gridDW[j, WD] = gridExpos[j].GetDW_Param(WD, "Expo"); } } } // Calc grid stats thisStats.P10_UW = new double[numWD]; thisStats.P10_DW = new double[numWD]; StreamWriter wrUW = null; StreamWriter wrDW = null; if (isTest) { wrUW = new StreamWriter(outFilename + " Grid UW Expo.csv"); wrDW = new StreamWriter(outFilename + " Grid DW Expo.csv"); } for (int WD = 0; WD < numWD; WD++) { for (int j = 0; j < gridCount; j++) { thisGridUW[j] = gridUW[j, WD]; thisGridDW[j] = gridDW[j, WD]; if (isTest) { wrUW.Write(gridUW[j, WD] + ","); wrDW.Write(gridDW[j, WD] + ","); } } if (isTest) { wrUW.WriteLine(); wrDW.WriteLine(); } Array.Sort(thisGridUW); Array.Sort(thisGridDW); thisStats.radius = radius; thisStats.P10_UW[WD] = thisGridUW[Convert.ToInt16(gridCount * 0.9)]; thisStats.P10_DW[WD] = thisGridDW[Convert.ToInt16(gridCount * 0.9)]; if (thisStats.P10_UW[WD] > 100) { WD = WD; } } Array.Resize(ref stats, radiusInd + 1); stats[radiusInd] = thisStats; if (isTest) { wrUW.Close(); wrDW.Close(); } }
/// <summary> Calculates the grid stats (i.e. P10 exposure), exposure, surface roughness and disp. height at node for each radius of investigation. </summary> public void CalcGridStatsAndExposures(Continuum thisInst) { int numWD = thisInst.metList.numWD; int smallerRadius = 0; Exposure smallerExposure = new Exposure(); if (ExposureCount == 0) { // Calculate exposures and grid stats at all radii for (int i = 0; i < thisInst.radiiList.ThisCount; i++) { int thisRadius = thisInst.radiiList.investItem[i].radius; double thisExponent = thisInst.radiiList.investItem[i].exponent; AddExposure(thisRadius, thisExponent, 1, numWD); int expInd = 0; for (expInd = 0; expInd <= ExposureCount - 1; expInd++) { if (expo[expInd].radius == thisRadius && expo[expInd].exponent == thisExponent) { //Found exposure that was just added break; } } if (smallerRadius == 0 || smallerExposure.radius >= thisRadius) { expo[expInd] = thisInst.topo.CalcExposures(UTMX, UTMY, elev, thisRadius, thisExponent, 1, thisInst.topo, numWD); if (thisInst.topo.gotSR == true) { thisInst.topo.CalcSRDH(ref expo[expInd], UTMX, UTMY, thisRadius, thisExponent, numWD); } } else { expo[expInd] = thisInst.topo.CalcExposuresWithSmallerRadius(UTMX, UTMY, elev, thisRadius, thisExponent, 1, smallerRadius, smallerExposure, numWD); if (thisInst.topo.gotSR == true) { thisInst.topo.CalcSRDHwithSmallerRadius(ref expo[expInd], UTMX, UTMY, thisRadius, thisExponent, 1, smallerRadius, smallerExposure, numWD); } } smallerExposure = expo[expInd]; smallerRadius = smallerExposure.radius; } } if (gridStats.stats == null) { gridStats.GetGridArrayAndCalcStats(UTMX, UTMY, thisInst); } // Calc P10 UW Crosswind and Parallel Grade for (int expInd = 0; expInd < thisInst.radiiList.ThisCount; expInd++) { expo[expInd].UW_P10CrossGrade = new double[numWD]; expo[expInd].UW_ParallelGrade = new double[numWD]; } for (int WD_sec = 0; WD_sec < numWD; WD_sec++) { double UW_CW_Grade = thisInst.topo.CalcP10_UW_CrosswindGrade(UTMX, UTMY, WD_sec, numWD); double UW_PL_Grade = thisInst.topo.CalcP10_UW_ParallelGrade(UTMX, UTMY, WD_sec, numWD); for (int expInd = 0; expInd <= thisInst.radiiList.ThisCount - 1; expInd++) { expo[expInd].UW_P10CrossGrade[WD_sec] = UW_CW_Grade; expo[expInd].UW_ParallelGrade[WD_sec] = UW_PL_Grade; } } }
/// <summary> Adds another exposure to the list (sorted by radius). </summary> public void AddExposure(ref MapNode thisMapNode, int radius, double exponent, int numSectors, int numWD) { int expoCount = 0; int insertInd = 0; if (thisMapNode.expo != null) { expoCount = thisMapNode.expo.Length; } else { expoCount = 0; } if (expoCount > 0) { if (radius > thisMapNode.expo[expoCount - 1].radius) // Larger radius than largest in list { insertInd = expoCount; } else if (radius < thisMapNode.expo[0].radius) // Smaller than smallest in list { insertInd = 0; } else { for (int i = 0; i <= expoCount - 2; i++) { if (thisMapNode.expo[i].radius < radius && thisMapNode.expo[i + 1].radius >= radius) { insertInd = i + 1; break; } } } Exposure[] existingExpos = new Exposure[expoCount]; for (int j = 0; j < expoCount; j++) { existingExpos[j] = thisMapNode.expo[j]; } thisMapNode.expo = new Exposure[expoCount + 1]; for (int j = 0; j < insertInd; j++) { thisMapNode.expo[j] = existingExpos[j]; } thisMapNode.expo[insertInd] = new Exposure(); thisMapNode.expo[insertInd].radius = radius; thisMapNode.expo[insertInd].exponent = exponent; thisMapNode.expo[insertInd].numSectors = numSectors; thisMapNode.expo[insertInd].expo = new double[numWD]; for (int j = insertInd + 1; j <= expoCount; j++) { thisMapNode.expo[j] = existingExpos[j - 1]; } } else { thisMapNode.expo = new Exposure[1]; thisMapNode.expo[0] = new Exposure(); thisMapNode.expo[0].radius = radius; thisMapNode.expo[0].exponent = exponent; thisMapNode.expo[0].numSectors = numSectors; thisMapNode.expo[0].expo = new double[numWD]; } }