/// <summary> /// 读入项目小层文件,包括4列,井号,小层名,顶深,底深,这个文件小层与系统小层层序一致且完整,小层断失标识是定底深相等 /// </summary> /// <param name="_sJH"></param> /// <returns></returns> public static List <ItemDicLayerDepth> readLayerDepth2Struct(string _sJH) { string filePath = Path.Combine(cProjectManager.dirPathWellDir, _sJH, cProjectManager.fileNameWellLayerDepth); List <ItemDicLayerDepth> listLayerDepth = new List <ItemDicLayerDepth>(); if (File.Exists(filePath)) { List <string> ltLines = cIOGeoEarthText.getDataLineListStringFromGeoText(filePath); foreach (string line in ltLines) { if (line.TrimEnd() != "") { ItemDicLayerDepth sttLayerDepth = new ItemDicLayerDepth(); string[] split = line.Trim().Split(new char[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries); sttLayerDepth.sJH = split[0]; sttLayerDepth.sXCM = split[1]; sttLayerDepth.fDS1 = float.Parse(split[2]); sttLayerDepth.fDS2 = float.Parse(split[3]); listLayerDepth.Add(sttLayerDepth); } } } return(listLayerDepth); }
//垂向非均质计算 public void calHeterogeneityInterLayer() { StreamWriter sw = new StreamWriter(cProjectManager.filePathInterLayerHeterogeneity, false, Encoding.UTF8); List <string> ltStrHeadColoum = new List <string>(); //中文表头 ltStrHeadColoum.Add("井名"); ltStrHeadColoum.Add("层名"); ltStrHeadColoum.Add("顶深(md)"); ltStrHeadColoum.Add("底深(md)"); ltStrHeadColoum.Add("层厚(m)"); ltStrHeadColoum.Add("砂岩厚度(m)"); ltStrHeadColoum.Add("有效厚度(m)"); ltStrHeadColoum.Add("砂地比"); ltStrHeadColoum.Add("解释砂层个数"); ltStrHeadColoum.Add("解释油层个数"); ltStrHeadColoum.Add("加权孔隙度(%)"); ltStrHeadColoum.Add("孔隙度(max)%"); ltStrHeadColoum.Add("孔隙度(min)%"); ltStrHeadColoum.Add("孔隙度(average)%"); ltStrHeadColoum.Add("加权渗透率(md)"); ltStrHeadColoum.Add("渗透率(max)"); ltStrHeadColoum.Add("渗透率(min)"); ltStrHeadColoum.Add("渗透率(average)"); ltStrHeadColoum.Add("突进系数Tk"); ltStrHeadColoum.Add("渗透率级差Jk"); ltStrHeadColoum.Add("变异系数Vk"); sw.WriteLine(string.Join("\t", ltStrHeadColoum.ToArray())); if (cProjectData.ltStrProjectJH.Count > 0 && cProjectData.ltStrProjectXCM.Count > 0) { for (int i = 0; i < cProjectData.ltStrProjectJH.Count; i++) { for (int j = 0; j < cProjectData.ltStrProjectXCM.Count; j++) { string sCurrentJH = cProjectData.ltStrProjectJH[i].ToString(); string sCurrentXCM = cProjectData.ltStrProjectXCM[j].ToString(); List <ItemDicLayerDepth> listLayerDepth = cIOinputLayerDepth.readLayerDepth2Struct(sCurrentJH); List <ItemJSJL> listJSJL = cIOinputJSJL.readJSJL2Struct(sCurrentJH); float fCurrentLayerDS1 = 0; //当前层位的顶面测深 float fCurrentLayerDS2 = 0; //当前层位的底面测深 float fCurrentLayerDCHD = 0; //当前层位的地层测深 需要测算 float fCurrentLayerSandThickness = 0; //当前层位的砂岩厚度 float fCurrentLayerYXHD = 0; //当前层位的有效厚度 int iCurrentLayerNumberOfSand = 0; //当前层位的砂层个数 int iCurrentLayerNumberOfOilSand = 0; //当前层位的有效砂层个数 float fCurrentLayerKXD = 0; //当前层位的厚度加权孔隙度 float fCurrentLayerSTL = 0; //当前层位的厚度加权渗透率 float fCurrentLayerKXD_mean = 0; //当前层位的算术平均孔隙度 float fCurrentLayerKXD_max = 0; //当前层位的最大孔隙度 float fCurrentLayerKXD_min = 0; //当前层位的最小孔隙度 float fCurrentLayerSTL_mean = 0; //当前层位的算术平均渗透率 float fCurrentLayerSTL_max = 0; //当前层位的最大渗透率 float fCurrentLayerSTL_min = 0; //当前层位的最小渗透率 float fCurrentLayerSTL_Tk = 0; //当前层位的渗透率突进系数 float fCurrentLayerSTL_Jk = 0; //当前层位的渗透率级差 float fCurrentLayerSTL_Vk = 0; //当前层位的渗透率级差 ////读取层位顶底深,获取fCurrentLayerDS1,fCurrentLayerDS2 bool bFoundInLayerDepth = false; ItemDicLayerDepth currentLayerDepth = listLayerDepth.FirstOrDefault(p => p.sXCM == sCurrentXCM); if (currentLayerDepth.sJH != null) { fCurrentLayerDS1 = currentLayerDepth.fDS1; fCurrentLayerDS2 = currentLayerDepth.fDS2; bFoundInLayerDepth = true; } //读取JSJL结果链表,获取fCurrentLayerKXD,fCurrentLayerSTL,fCurrentLayerBHD if (bFoundInLayerDepth == true) //找到小层顶底深,才处理,否则直接跳过 { List <float> fListSH_temp = new List <float>(); List <float> fListYXHD_temp = new List <float>(); List <float> fListKXD_temp = new List <float>(); List <float> fListSTL_temp = new List <float>(); List <float> fListBHD_temp = new List <float>(); foreach (ItemJSJL jsjlItem in listJSJL) { if (sCurrentJH == jsjlItem.sJH && fCurrentLayerDS1 <= jsjlItem.fDS1 && fCurrentLayerDS2 >= jsjlItem.fDS2) { fListSH_temp.Add(jsjlItem.fSandThickness); fListYXHD_temp.Add(jsjlItem.fNetPaySand); fListKXD_temp.Add(jsjlItem.fKXD); fListSTL_temp.Add(jsjlItem.fSTL); } } { fCurrentLayerDCHD = fCurrentLayerDS2 - fCurrentLayerDS1; //地层厚度 fCurrentLayerSandThickness = fListSH_temp.Sum(); //当前层位的砂岩厚度 fCurrentLayerYXHD = fListYXHD_temp.Sum(); //当前层位的有效厚度 iCurrentLayerNumberOfSand = fListSH_temp.Count; //当前层位的砂层个数 iCurrentLayerNumberOfOilSand = fListYXHD_temp.Count; //当前层位的有效砂层厚度 if (fListSH_temp.Count > 0) { fCurrentLayerKXD = weightedBYThickNessWithourInvalidValue(fListKXD_temp, fListSH_temp); //当前层位的厚度加权孔隙度 fCurrentLayerSTL = weightedBYThickNessWithourInvalidValue(fListSTL_temp, fListSH_temp); //当前层位的厚度加权渗透率 } fCurrentLayerKXD_max = maxWithourInvalidValue(fListKXD_temp, fMaxValid_Pore, fMinValid_Pore); fCurrentLayerKXD_min = minWithourInvalidValue(fListKXD_temp, fMaxValid_Pore, fMinValid_Pore); fCurrentLayerKXD_mean = meanWithourInvalidValue(fListKXD_temp, fMaxValid_Pore, fMinValid_Pore); fCurrentLayerSTL_max = maxWithourInvalidValue(fListSTL_temp); fCurrentLayerSTL_min = minWithourInvalidValue(fListSTL_temp); fCurrentLayerSTL_mean = meanWithourInvalidValue(fListSTL_temp); fCurrentLayerSTL_Tk = calTk(fListSTL_temp); fCurrentLayerSTL_Jk = calJk(fListSTL_temp); fCurrentLayerSTL_Vk = calVk(fListSTL_temp); } } List <string> ltStrWrited = new List <string>(); ltStrWrited.Add(sCurrentJH); ltStrWrited.Add(sCurrentXCM); //未在深度表中找到数据 代表本井本层位缺失 if (bFoundInLayerDepth == true) { ltStrWrited.Add(fCurrentLayerDS1.ToString("0.0")); //顶深MD ltStrWrited.Add(fCurrentLayerDS2.ToString("0.0")); //底深MD ltStrWrited.Add(fCurrentLayerDCHD.ToString("0.0")); //地层厚度 ltStrWrited.Add(fCurrentLayerSandThickness.ToString("0.0")); ltStrWrited.Add(fCurrentLayerYXHD.ToString("0.0")); ltStrWrited.Add((fCurrentLayerSandThickness / fCurrentLayerDCHD).ToString("0.00")); //砂底比 ltStrWrited.Add(iCurrentLayerNumberOfSand.ToString()); //砂层个数 ltStrWrited.Add(iCurrentLayerNumberOfOilSand.ToString()); //油层个数 ltStrWrited.Add(fCurrentLayerKXD.ToString("0.00")); ltStrWrited.Add(fCurrentLayerKXD_max.ToString("0.00")); ltStrWrited.Add(fCurrentLayerKXD_min.ToString("0.00")); ltStrWrited.Add(fCurrentLayerKXD_mean.ToString("0.00")); ltStrWrited.Add(fCurrentLayerSTL.ToString("0.00")); ltStrWrited.Add(fCurrentLayerSTL_max.ToString("0.00")); ltStrWrited.Add(fCurrentLayerSTL_min.ToString("0.00")); ltStrWrited.Add(fCurrentLayerSTL_mean.ToString("0.00")); ltStrWrited.Add(fCurrentLayerSTL_Tk.ToString("0.00")); ltStrWrited.Add(fCurrentLayerSTL_Jk.ToString("0.00")); ltStrWrited.Add(fCurrentLayerSTL_Vk.ToString("0.00")); } else { ltStrWrited.Add("Mssing"); } sw.WriteLine(string.Join("\t", ltStrWrited.ToArray())); } } } sw.Close(); MessageBox.Show("层间垂向非均质计算完毕"); }
public void generateLayerData() { //更新算法,保证计算后的数据字典完善: //如果这口井有有效厚度而没有孔隙度,渗透率,饱和度,那么找临近的几口井,根据厚度相近的原则,取孔隙度,渗透率 //数据缺失的先用地层厚度为-999填充标记,然后正着扫一遍,再反着扫一遍 把所有的值填充合理 List <ItemDicLayerDataStatic> listLayerDataDic = new List <ItemDicLayerDataStatic>(); if (cProjectData.ltStrProjectJH.Count > 0 && cProjectData.ltStrProjectXCM.Count > 0) { for (int i = 0; i < cProjectData.ltStrProjectJH.Count; i++) { for (int j = 0; j < cProjectData.ltStrProjectXCM.Count; j++) { string sCurrentJH = cProjectData.ltStrProjectJH[i].ToString(); string sCurrentXCM = cProjectData.ltStrProjectXCM[j].ToString(); ItemWellHead currentWellHead = cIOinputWellHead.getWellHeadByJH(sCurrentJH); List <ItemDicLayerDepth> listLayerDepth = cIOinputLayerDepth.readLayerDepth2Struct(sCurrentJH); List <ItemJSJL> listJSJL = cIOinputJSJL.readJSJL2Struct(sCurrentJH); double dfCurrentLayerX = 0; double dfCurrentLayerY = 0; double dfCurrentLayerZ = 0; float fCurrentLayerDS1 = 0; //当前层位的顶面测深 float fCurrentLayerDS2 = 0; //当前层位的底面测深 float fCurrentLayerTVD = 0; //顶面TVD float fCurrentLayerDCHD = -999; //当前层位的地层测深 需要测算 -999代表缺失 float fCurrentLayerSandThickness = -999; //当前层位的砂岩厚度 float fCurrentLayerYXHD = 0; //当前层位的有效厚度 float fCurrentLayerKXD = 0; //当前层位的厚度加权孔隙度 float fCurrentLayerSTL = 0; //当前层位的厚度加权渗透率 float fCurrentLayerBHD = 0; //当前层位的厚度加权饱和度 //读取层位顶底深,获取fCurrentLayerDS1,fCurrentLayerDS2 //没找到的情况要重新考虑下! bool bFoundInLayerDepth = false; ItemDicLayerDepth currentLayerDepth = listLayerDepth.Find(p => p.sJH == sCurrentJH && p.sXCM == sCurrentXCM); if (currentLayerDepth.sJH != null && currentLayerDepth.fDS1 <= currentLayerDepth.fDS2) { fCurrentLayerDS1 = currentLayerDepth.fDS1; ItemDicWellPath currentDS1WellPathItem = cIOinputWellPath.getWellPathItemByJHAndMD(sCurrentJH, fCurrentLayerDS1); ItemDicWellPath currentDS2WellPathItem = cIOinputWellPath.getWellPathItemByJHAndMD(sCurrentJH, fCurrentLayerDS2); fCurrentLayerDS2 = currentLayerDepth.fDS2; dfCurrentLayerX = currentDS1WellPathItem.dbX; dfCurrentLayerY = currentDS1WellPathItem.dbY; dfCurrentLayerZ = currentDS1WellPathItem.dfZ; fCurrentLayerTVD = currentDS1WellPathItem.f_TVD; fCurrentLayerDCHD = currentDS2WellPathItem.f_TVD - currentDS1WellPathItem.f_TVD; bFoundInLayerDepth = true; } //读取JSJL结果链表,获取fCurrentLayerKXD,fCurrentLayerSTL,fCurrentLayerBHD if (bFoundInLayerDepth == true) //找到小层顶底深,才处理,否则直接跳过 { List <ItemJSJL> listCurrentWellJSJL = listJSJL.Where(p => p.sJH == sCurrentJH && p.fDS1 >= fCurrentLayerDS1 && p.fDS2 <= fCurrentLayerDS2).ToList(); List <float> fListSH_temp = new List <float>(); List <float> fListYXHD_temp = new List <float>(); List <float> fListKXD_temp = new List <float>(); List <float> fListSTL_temp = new List <float>(); List <float> fListBHD_temp = new List <float>(); foreach (ItemJSJL item in listCurrentWellJSJL) { fListSH_temp.Add(item.fSandThickness); fListYXHD_temp.Add(item.fNetPaySand); fListKXD_temp.Add(item.fKXD); fListSTL_temp.Add(item.fSTL); fListBHD_temp.Add(item.fBHD); } { fCurrentLayerDCHD = fCurrentLayerDS2 - fCurrentLayerDS1; //地层厚度 fCurrentLayerSandThickness = fListSH_temp.Sum(); //当前层位的砂岩厚度 fCurrentLayerYXHD = fListYXHD_temp.Sum(); //当前层位的有效厚度 fCurrentLayerKXD = weightedBYThickNessWithourInvalidValue(fListKXD_temp, fListSH_temp); //当前层位的厚度加权孔隙度 fCurrentLayerSTL = weightedBYThickNessWithourInvalidValue(fListSTL_temp, fListSH_temp); //当前层位的厚度加权渗透率 fCurrentLayerBHD = weightedBYThickNessWithourInvalidValue(fListBHD_temp, fListSH_temp); //当前层位的厚度加权饱和度 } } //写小层数据表 ItemDicLayerDataStatic itemLayerData = new ItemDicLayerDataStatic(); itemLayerData.sJH = sCurrentJH; itemLayerData.sXCM = sCurrentXCM; //在LayerDepth表中找到数据层段的顶底 if (bFoundInLayerDepth == true) { itemLayerData.dbX = dfCurrentLayerX; itemLayerData.dbY = dfCurrentLayerY; itemLayerData.dbZ = dfCurrentLayerZ; itemLayerData.fDCHD = fCurrentLayerDCHD; itemLayerData.fSH = fCurrentLayerSandThickness; itemLayerData.fYXHD = fCurrentLayerYXHD; itemLayerData.fKXD = fCurrentLayerKXD; itemLayerData.fSTL = fCurrentLayerSTL; itemLayerData.fBHD = fCurrentLayerBHD; itemLayerData.fDS1_md = fCurrentLayerDS1; itemLayerData.fDS2_md = fCurrentLayerDS2; itemLayerData.fDS1_TVD = fCurrentLayerTVD; } else //未在LayerDepth表中找到数据 代表本井本层位缺失 { itemLayerData.dbX = 0.0; itemLayerData.dbY = 0.0; itemLayerData.dbZ = 0.0; itemLayerData.fDCHD = -999; itemLayerData.fSH = -999; itemLayerData.fYXHD = 0; itemLayerData.fKXD = -999; itemLayerData.fSTL = -999; itemLayerData.fBHD = -999; itemLayerData.fDS1_md = -999; itemLayerData.fDS2_md = -999; itemLayerData.fDS1_TVD = -999; } listLayerDataDic.Add(itemLayerData); } } } //正一遍 倒一遍,完善小层数据表 for (int i = 0; i < listLayerDataDic.Count - 1; i++) { ItemDicLayerDataStatic currentItem = listLayerDataDic[i]; if (currentItem.fDCHD < 0 && currentItem.sJH == listLayerDataDic[i + 1].sJH) { ItemDicLayerDataStatic nextItem = listLayerDataDic[i + 1]; currentItem.dbX = nextItem.dbX; currentItem.dbY = nextItem.dbY; currentItem.dbZ = nextItem.dbZ + nextItem.fDCHD; currentItem.fDS1_md = nextItem.fDS1_md; currentItem.fDS2_md = nextItem.fDS2_md; currentItem.fDS1_TVD = nextItem.fDS1_TVD; currentItem.fDCHD = 0; currentItem.fSH = 0; } listLayerDataDic[i] = currentItem; } //完善 小层 孔渗为无效值的情况 for (int i = 0; i < listLayerDataDic.Count - 1; i++) { ItemDicLayerDataStatic currentItem = listLayerDataDic[i]; if (currentItem.fDCHD < 0 && currentItem.sJH == listLayerDataDic[i + 1].sJH) { ItemDicLayerDataStatic nextItem = listLayerDataDic[i + 1]; currentItem.dbX = nextItem.dbX; currentItem.dbY = nextItem.dbY; currentItem.dbZ = nextItem.dbZ + nextItem.fDCHD; currentItem.fDS1_md = nextItem.fDS1_md; currentItem.fDS2_md = nextItem.fDS2_md; currentItem.fDS1_TVD = nextItem.fDS1_TVD; currentItem.fDCHD = 0; currentItem.fSH = 0; } listLayerDataDic[i] = currentItem; } for (int i = listLayerDataDic.Count - 1; i > 0; i--) { ItemDicLayerDataStatic currentItem = listLayerDataDic[i]; if (currentItem.fSH > 0 && (currentItem.fKXD <= 0 || currentItem.fSTL <= 0)) //有砂厚,砂厚大于0的必须有孔隙度和渗透率,用于产量劈分,储量计算 { //从 listLayerDataDic中选择,无值的取层段平均值 List <ItemDicLayerDataStatic> listCurrentLayer = listLayerDataDic.FindAll(p => p.sXCM == currentItem.sXCM).ToList(); if (listCurrentLayer.Count > 0) { if (currentItem.fKXD <= 0 && listCurrentLayer.FindAll(p => p.fKXD > 0).Count > 0) { currentItem.fKXD = listCurrentLayer.FindAll(p => p.fKXD > 0).Select(p => p.fKXD).Average(); } if (currentItem.fSTL <= 0 && listCurrentLayer.FindAll(p => p.fSTL > 0).Count > 0) { currentItem.fSTL = listCurrentLayer.FindAll(p => p.fSTL > 0).Select(p => p.fSTL).Average(); } } } listLayerDataDic[i] = currentItem; } write2File(cProjectManager.filePathLayerDataDic, listLayerDataDic); // Format and display the TimeSpan value. }
public static void creatWellGeoFile(string _sJH) { List <ItemLayerDepthInput> ltLayerDepthInput = readInputFile(_sJH); creatWellGeoHeadFile(_sJH); if (ltLayerDepthInput.Count == 0) { return; } //增加layer循环 List <ItemDicLayerDepth> ltLayerDepthWrite = new List <ItemDicLayerDepth>(); int iCount = cProjectData.ltStrProjectXCM.Count; for (int i = 0; i < iCount; i++) { //先按每个井号、层位附上0值 ItemDicLayerDepth _item = new ItemDicLayerDepth(); _item.sJH = _sJH; _item.sXCM = cProjectData.ltStrProjectXCM[i]; _item.fDS1 = 0.0f; _item.fDS2 = 0.0f; //在输入的列表中查找,找到小层名的,把顶深和底深赋值,底深付下个顶深 int _iFind = -1; //设置没找到的标识 for (int k = 0; k < ltLayerDepthInput.Count; k++) { if (_item.sXCM == ltLayerDepthInput[k].sXCM) { _item.fDS1 = ltLayerDepthInput[k].fTop; if (k < ltLayerDepthInput.Count - 1) { _item.fDS2 = ltLayerDepthInput[k + 1].fTop; } if (k == ltLayerDepthInput.Count - 1) { _item.fDS2 = cProjectData.ltProjectWell.Find(p => p.sJH == _sJH).fWellBase; if (_item.fDS2 <= _item.fDS1) { _item.fDS2 = _item.fDS1; //如果找到了 最后一行的处理, } } _iFind = 1; //找到了 break; } } if (_iFind < 0) //如何没找到 { if (i == 0) { _item.fDS1 = ltLayerDepthInput[0].fTop; _item.fDS2 = _item.fDS1; } if (i > 0) { _item.fDS1 = ltLayerDepthWrite[ltLayerDepthWrite.Count - 1].fDS1; _item.fDS2 = _item.fDS1; } } ltLayerDepthWrite.Add(_item); } string filePath = Path.Combine(cProjectManager.dirPathWellDir, _sJH, cProjectManager.fileNameWellLayerDepth); List <string> ltStrLine = new List <string>(); foreach (ItemDicLayerDepth _item in ltLayerDepthWrite) { ltStrLine.Add(ItemDicLayerDepth.item2string(_item)); } cIOGeoEarthText.addDataLines2GeoEarTxt(filePath, ltStrLine); }