Пример #1
0
        //平衡正切法计算井斜 输入必须是角度格式flist 和petrel对过 最后一个值 狗腿度没有计算。
        public static List <ItemDicWellPath> phzqf2Struct(string sJH, double dbX, double dbY, float fKB, List <float> fListMD, List <float> fListInc, List <float> fListAzimuth)
        {
            List <ItemDicWellPath> returnListWellPathItem = new List <ItemDicWellPath>();

            if (fListMD.Count > 0)
            {
                double _tvd = fListMD[0]; //海拔向下为正 第一个点md=tvd
                double _y   = 0;          //偏移Y
                double _x   = 0;          //偏移X
                float  _dls = 0;          //狗腿度
                for (int i = 0; i < fListMD.Count; i++)
                {
                    if (i > 0)
                    {
                        float fLength = fListMD[i] - fListMD[i - 1];
                        float i1      = Convert.ToSingle(fListInc[i - 1] * Math.PI / 180.0);
                        float a1      = Convert.ToSingle(fListAzimuth[i - 1] * Math.PI / 180.0);
                        float i2      = Convert.ToSingle(fListInc[i] * Math.PI / 180.0);
                        float a2      = Convert.ToSingle(fListAzimuth[i] * Math.PI / 180.0);

                        //        ## a1 上测点井斜 b1 上测点方位
                        _tvd = _tvd + 0.5 * fLength * (Math.Cos(i2) + Math.Cos(i1));
                        _y   = _y + 0.5 * fLength * (Math.Sin(i1) * Math.Cos(a1) + Math.Sin(i2) * Math.Cos(a2));
                        _x   = _x + 0.5 * fLength * (Math.Sin(i1) * Math.Sin(a1) + Math.Sin(i2) * Math.Sin(a2));
                        //注释为中国算法
                        //if (fLength != 0)
                        //    _dls = 30 / fLength * (float)
                        //            (180/Math.PI*Math.Pow(
                        //                     Math.Pow(( i1-i2),2) + Math.Pow( Math.Sin((i1+i2)/2) * (a2 - a1),2) ,0.5
                        //            )
                        //        );
                        if (fLength != 0)
                        {
                            _dls = 30 / fLength * (float)
                                   (180 / Math.PI *
                                    Math.Acos(
                                        (Math.Cos(i1) * Math.Cos(i2) + Math.Sin(i1) * Math.Sin(i2) * Math.Cos(a2 - a1))
                                        )
                                   );
                        }
                    }
                    ItemDicWellPath sttWellPathItem = new ItemDicWellPath();
                    sttWellPathItem.sJH       = sJH;
                    sttWellPathItem.dbX       = dbX + _x;
                    sttWellPathItem.dbY       = dbY + _y;
                    sttWellPathItem.dfZ       = fKB - _tvd;
                    sttWellPathItem.f_md      = fListMD[i];
                    sttWellPathItem.f_incl    = fListInc[i];
                    sttWellPathItem.f_azim    = fListAzimuth[i];
                    sttWellPathItem.f_dx      = Convert.ToSingle(_x);
                    sttWellPathItem.f_dy      = Convert.ToSingle(_y);
                    sttWellPathItem.f_TVD     = Convert.ToSingle(_tvd);
                    sttWellPathItem.f_CalcDLS = _dls;
                    returnListWellPathItem.Add(sttWellPathItem);
                }
            }

            return(returnListWellPathItem);
        }
Пример #2
0
        private void cbxAddHorizonWell_CheckedChanged(object sender, EventArgs e)
        {
            if (cbxAddHorizonWell.Checked == true)
            {
                List <string> llistHorizinalJH = new List <string>();
                foreach (object selecteditem in lbxJHSeclected.Items)
                {
                    string strItem = selecteditem as String;
                    llistHorizinalJH.Add(strItem);
                }
                //add svg文件中水平井段
                if (File.Exists(filePathOperate))
                {
                    cXMLLayerMapHorizonalWell.delHorizonalWellIntervalNode(this.filePathOperate);
                    List <string> _ltStrData = new List <string>();
                    foreach (string _sjh in llistHorizinalJH)
                    {
                        List <ItemDicWellPath> currentWellPath = cIOinputWellPath.readWellPath2Struct(_sjh);
                        //井必须在project井范围内
                        if (cProjectData.ltStrProjectJH.IndexOf(_sjh) >= 0)
                        {
                            ItemDicWellPath top  = currentWellPath.Find(x => x.f_incl > 80);
                            ItemDicWellPath tail = currentWellPath.FindLast(x => x.f_incl > 80);
                            // 井号+ 井型 + 井口view坐标 + head view 坐标 + tail view 坐标

                            //      ItemWellMapPosition item = this.listWellsStatic.Find(x => x.sJH == _sjh);
                            ItemWellMapPosition item = new ItemWellMapPosition();
                            if (item != null && top.sJH != null && tail.sJH != null)
                            {
                                _ltStrData.Add(_sjh);
                                _ltStrData.Add(item.iWellType.ToString());

                                _ltStrData.Add(item.dbX.ToString());
                                _ltStrData.Add(item.dbY.ToString());


                                _ltStrData.Add(top.dbX.ToString());
                                _ltStrData.Add(top.dbY.ToString());

                                _ltStrData.Add(tail.dbX.ToString());
                                _ltStrData.Add(tail.dbY.ToString());
                            }
                        }
                    }//end foreach

                    string _data = string.Join(" ", _ltStrData);
                    cXMLLayerMapHorizonalWell.addLayerWellHorizonalInterval2XML(this.filePathOperate, "horizonalWellInterval", _data);
                }
                else
                {
                    MessageBox.Show("请先创建原始图件。");
                }
            }
            else
            {   //删除水平井段
                cXMLLayerMapHorizonalWell.delHorizonalWellIntervalNode(this.filePathOperate);
            }
        }
Пример #3
0
        public static List <ItemDicWellPath> getWellPathItemListByJHAndMDList(string sJH, List <float> fListMD)
        {
            List <ItemDicWellPath> listReturnWellPath = new List <ItemDicWellPath>();

            List <ItemDicWellPath> listWellPath = readWellPath2Struct(sJH);

            foreach (float _fMD in fListMD)
            {
                ItemDicWellPath currentWellPath = getWellPathItemByJHAndMD(listWellPath, _fMD);
                listReturnWellPath.Add(currentWellPath);
            }
            return(listReturnWellPath);
        }
Пример #4
0
        public static void creatWellGeoFile(string sJH, List <ItemDicWellPath> listWellPath)
        {
            ItemWellHead wellHead   = cIOinputWellHead.getWellHeadByJH(sJH);
            string       filePath   = Path.Combine(cProjectManager.dirPathWellDir, wellHead.sJH, cProjectManager.fileNameWellPath);
            string       sFirstLine = cProjectManager.fileNameWellPath + wellHead.sJH + " " + wellHead.dbX.ToString() + " " + wellHead.dbY.ToString() + " " + wellHead.fKB.ToString();

            creatWellGeoHeadFile(wellHead.sJH, filePath, sFirstLine);
            List <string> ltStrLine = new List <string>();

            foreach (ItemDicWellPath _item in listWellPath)
            {
                ltStrLine.Add(ItemDicWellPath.item2string(_item));
            }
            cIOGeoEarthText.addDataLines2GeoEarTxt(filePath, ltStrLine);
        }
Пример #5
0
        public static void creatVerticalWellPathGeoFile(string sJH)
        {
            ItemWellHead    wellHead       = cIOinputWellHead.getWellHeadByJH(sJH);
            ItemDicWellPath wellPathTop    = new ItemDicWellPath(wellHead);
            ItemDicWellPath wellPathBottom = new ItemDicWellPath(wellHead);

            wellPathBottom.dfZ   = wellPathTop.dfZ - wellHead.fWellBase;
            wellPathBottom.f_md  = wellHead.fWellBase;
            wellPathBottom.f_TVD = wellHead.fWellBase;
            List <ItemDicWellPath> listItem = new List <ItemDicWellPath>();

            listItem.Add(wellPathTop);
            listItem.Add(wellPathBottom);
            creatWellGeoFile(sJH, listItem);
        }
Пример #6
0
        public static List <ItemDicWellPath> readWellPath2Struct(string sJH)
        {
            List <ItemDicWellPath> returnListWellPathItem = new List <ItemDicWellPath>();

            string filePath = Path.Combine(cProjectManager.dirPathWellDir, sJH, cProjectManager.fileNameWellPath);

            if (File.Exists(filePath))
            {
                using (StreamReader sr = new StreamReader(filePath))
                {
                    String          line;
                    ItemDicWellPath sttWellPathItem = new ItemDicWellPath();
                    int             iStartLine      = 4;
                    int             _indexLine      = 0;
                    while ((line = sr.ReadLine()) != null) //delete the line whose legth is 0
                    {
                        _indexLine++;
                        string[] split = line.Trim().Split(new char[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries);
                        if (_indexLine == 1)
                        {
                            continue;
                        }
                        else if (_indexLine == 2)
                        {
                            iStartLine = 2 + int.Parse(split[0]);
                        }
                        else if (_indexLine > iStartLine)
                        {
                            sttWellPathItem.sJH       = split[0];
                            sttWellPathItem.dbX       = double.Parse(split[1]);
                            sttWellPathItem.dbY       = double.Parse(split[2]);
                            sttWellPathItem.dfZ       = double.Parse(split[3]);
                            sttWellPathItem.f_md      = float.Parse(split[4]);
                            sttWellPathItem.f_incl    = float.Parse(split[5]);
                            sttWellPathItem.f_azim    = float.Parse(split[6]);
                            sttWellPathItem.f_dx      = float.Parse(split[7]);
                            sttWellPathItem.f_dy      = float.Parse(split[8]);
                            sttWellPathItem.f_TVD     = float.Parse(split[9]);
                            sttWellPathItem.f_CalcDLS = float.Parse(split[10]);
                            returnListWellPathItem.Add(sttWellPathItem);
                        }
                    }
                }
            }


            return(returnListWellPathItem);
        }
Пример #7
0
        public static string item2string(ItemDicWellPath _item)
        {
            List <string> _ltStr = new List <string>();

            _ltStr.Add(_item.sJH);
            _ltStr.Add(_item.dbX.ToString("0.00"));
            _ltStr.Add(_item.dbY.ToString("0.00"));
            _ltStr.Add(_item.dfZ.ToString("0.00"));
            _ltStr.Add(_item.f_md.ToString("0.00"));
            _ltStr.Add(_item.f_incl.ToString("0.00"));
            _ltStr.Add(_item.f_azim.ToString("0.00"));
            _ltStr.Add(_item.f_dx.ToString("0.00"));
            _ltStr.Add(_item.f_dy.ToString("0.00"));
            _ltStr.Add(_item.f_TVD.ToString("0.00"));
            _ltStr.Add(_item.f_CalcDLS.ToString("0.00"));
            return(string.Join(" ", _ltStr));
        }
Пример #8
0
        public static ItemDicWellPath getWellPathItemByJHAndMD(List <ItemDicWellPath> listWellPathItem, float fMD)
        {
            List <float> ltFloatMd = listWellPathItem.Select(p => p.f_md).ToList();
            int          _iUp      = 1;
            int          _iDown    = 0;

            if (fMD >= ltFloatMd[ltFloatMd.Count - 1])
            {
                _iUp   = ltFloatMd.Count - 1;
                _iDown = _iUp - 1;
            }
            else if (fMD <= ltFloatMd[0])
            {
            }
            else
            {
                for (int i = 1; i < ltFloatMd.Count; i++)
                {
                    if (ltFloatMd[i] >= fMD && ltFloatMd[i - 1] <= fMD)
                    {
                        _iDown = i - 1;
                        _iUp   = i;
                    }
                }
            }
            ItemDicWellPath itemDown = listWellPathItem[_iDown];
            ItemDicWellPath itemUp   = listWellPathItem[_iUp];

            ItemDicWellPath returnWellPathItem = new ItemDicWellPath();

            returnWellPathItem.dbX       = cInterpolation.linear(fMD, itemUp.f_md, itemUp.dbX, itemDown.f_md, itemDown.dbX);
            returnWellPathItem.dbY       = cInterpolation.linear(fMD, itemUp.f_md, itemUp.dbY, itemDown.f_md, itemDown.dbY);
            returnWellPathItem.dfZ       = cInterpolation.linear(fMD, itemUp.f_md, itemUp.dfZ, itemDown.f_md, itemDown.dfZ);
            returnWellPathItem.f_incl    = cInterpolation.linear(fMD, itemUp.f_md, itemUp.f_incl, itemDown.f_md, itemDown.f_incl);
            returnWellPathItem.f_azim    = cInterpolation.linear(fMD, itemUp.f_md, itemUp.f_azim, itemDown.f_md, itemDown.f_azim);
            returnWellPathItem.f_dx      = cInterpolation.linear(fMD, itemUp.f_md, itemUp.f_dx, itemDown.f_md, itemDown.f_dx);
            returnWellPathItem.f_dy      = cInterpolation.linear(fMD, itemUp.f_md, itemUp.f_dy, itemDown.f_md, itemDown.f_dy);
            returnWellPathItem.f_CalcDLS = cInterpolation.linear(fMD, itemUp.f_md, itemUp.f_CalcDLS, itemDown.f_md, itemDown.f_CalcDLS);
            returnWellPathItem.f_TVD     = cInterpolation.linear(fMD, itemUp.f_md, itemUp.f_TVD, itemDown.f_md, itemDown.f_TVD);

            return(returnWellPathItem);
        }
Пример #9
0
        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.
        }