# Medium测量模型
**本文档引用的文件**
- [Medium.cpp](file://cpp\ProblemZone\Medium.cpp)
- [MediumA.cpp](file://cpp\ProblemZone\MediumA.cpp)
- [MediumB.cpp](file://cpp\ProblemZone\MediumB.cpp)
- [MediumC.cpp](file://cpp\ProblemZone\MediumC.cpp)
- [MediumD.cpp](file://cpp\ProblemZone\MediumD.cpp)
- [MediumCrossHoleGeomative.cpp](file://cpp\ProblemZone\MediumCrossHoleGeomative.cpp)
- [MediumCustom2D.cpp](file://cpp\ProblemZone\MediumCustom2D.cpp)
- [MediumZ.cpp](file://cpp\ProblemZone\MediumZ.cpp)
- [MediumY.cpp](file://cpp\ProblemZone\MediumY.cpp)
- [MediumX.cpp](file://cpp\ProblemZone\MediumX.cpp)
- [CCrossHoleConfig2DMainDlg.cpp](file://cpp\crossHole\CCrossHoleConfig2DMainDlg.cpp)
## 目录
1. [引言](#引言)
2. [核心Medium类架构](#核心medium类架构)
3. [标准电极排列模型](#标准电极排列模型)
- [温纳α装置 (MediumA)](#温纳α装置-mediuma)
- [温纳β装置 (MediumB)](#温纳β装置-mediumb)
- [温纳γ装置 (MediumC)](#温纳γ装置-mediumc)
- [施伦贝谢装置 (MediumD)](#施伦贝谢装置-mediumd)
4. [特殊测量模型](#特殊测量模型)
- [跨孔测量模型 (MediumCrossHoleGeomative)](#跨孔测量模型-mediumcrossholegeomative)
- [自定义2D模型 (MediumCustom2D)](#自定义2d模型-mediumcustom2d)
5. [高级与遗留模型](#高级与遗留模型)
- [通用脚本模型 (MediumX, MediumY, MediumZ)](#通用脚本模型-mediumx-mediumy-mediumz)
6. [用户界面与配置](#用户界面与配置)
7. [模型选择决策树](#模型选择决策树)
8. [结论](#结论)
## 引言
Medium系列类是Geomative Studio软件中实现地球物理电阻率测量模型的核心组件。这些类通过继承自基类`CMedium`,为各种电极排列方式和测量方法提供了具体的实现。本文档系统地介绍了从`MediumA`到`MediumZ`的系列类,详细说明了它们所对应的电极排列方式,如`MediumA`代表温纳α装置,`MediumB`代表温纳β装置,`MediumCrossHoleGeomative`支持跨孔测量等。文档将深入分析各模型在电极间距计算、供电-测量电极组合逻辑、数据采集序列生成等方面的实现差异,并结合配置界面说明用户如何选择和参数化特定的测量模型。
## 核心Medium类架构
`CMedium`是所有测量模型的抽象基类,定义了测量脚本生成、测点定位和数据管理的通用接口。所有具体的测量模型,如`CMediumA`、`CMediumB`等,都继承自此类,并重写其核心方法以实现特定的测量逻辑。
```mermaid
classDiagram
class CMedium {
+int m_iAR
+int m_iStartPole
+int m_iEndPole
+float m_fEOffsetR
+float m_fLOffsetR
+map m_mapUniversalLayer
+CalculateTdPtLoc()
+SetValidPoleInfo()
+GeneralUniSptInfo()
+ReSortPoint()
+AddSptToUniLayer()
+QuerySptLayerFromUni()
+GetUniSptXPos()
}
class CMediumA {
+GenerateSptRecElecVal()
+CalculateSptKVal()
+CalculateSptLevel()
+CalculateSptPtLoc()
}
class CMediumB {
+GenerateSptRecElecVal()
+CalculateSptKVal()
+CalculateSptLevel()
+CalculateSptPtLoc()
}
class CMediumC {
+GenerateSptRecElecVal()
+CalculateSptKVal()
+CalculateSptLevel()
+CalculateSptPtLoc()
}
class CMediumD {
+int m_iParamIma
+int m_iParamImn
+SetParamVal()
+GenerateSptRecElecVal()
+CalculateSptKVal()
+CalculateSptLevel()
+CalculateSptPtLoc()
}
class CMediumCrossHoleGeomative {
+float m_fSeprate
+GenerateSptRecElecVal()
+CalculateCESptKVal()
+CalculateSptPtLoc()
+GenSptRecLevel()
}
class CMediumCustom2D {
+GenerateSptRecElecVal()
}
CMedium <|-- CMediumA
CMedium <|-- CMediumB
CMedium <|-- CMediumC
CMedium <|-- CMediumD
CMedium <|-- CMediumCrossHoleGeomative
CMedium <|-- CMediumCustom2D
```
**图源**
- [Medium.cpp](file://cpp\ProblemZone\Medium.cpp#L11-L657)
- [MediumA.cpp](file://cpp\ProblemZone\MediumA.cpp#L19-L239)
- [MediumB.cpp](file://cpp\ProblemZone\MediumB.cpp#L19-L237)
- [MediumC.cpp](file://cpp\ProblemZone\MediumC.cpp#L19-L240)
- [MediumD.cpp](file://cpp\ProblemZone\MediumD.cpp#L19-L362)
- [MediumCrossHoleGeomative.cpp](file://cpp\ProblemZone\MediumCrossHoleGeomative.cpp#L19-L148)
- [MediumCustom2D.cpp](file://cpp\ProblemZone\MediumCustom2D.cpp#L19-L228)
**节源**
- [Medium.cpp](file://cpp\ProblemZone\Medium.cpp#L11-L657)
## 标准电极排列模型
标准电极排列模型是地球物理勘探中最常用的几种方法,它们在`MediumA`到`MediumD`类中实现。
### 温纳α装置 (MediumA)
`CMediumA`类实现了温纳α(Wenner Alpha)装置,这是一种对称四极排列,其中供电电极(A, B)和测量电极(M, N)等间距排列,且M、N位于A、B的中点。
在`GenerateSptRecElecVal`方法中,该类通过一个双重循环生成测点序列。外层循环遍历测量电极M的位置,内层循环则通过移动供电电极A来生成同一层内的所有测点。其电极间距计算遵循公式:`AB = 3 * MN`,且MN间距随层数增加而增大。
```mermaid
flowchart TD
Start["开始生成温纳α测点"] --> Init["初始化参数 iEAmount, iMaxSpace"]
Init --> OuterLoop["外层循环: iMMVal = 2 to iEAmount-2"]
OuterLoop --> CalcSpace["计算当前间距 iSpace"]
CalcSpace --> InnerLoop["内层循环: 移动A电极"]
InnerLoop --> CreatePoint["创建CSptRecord: A, B, M, N"]
CreatePoint --> SetK["计算K值: k = 2π * (N-M)"]
SetK --> SetLevel["计算层数: Level = N - M"]
SetLevel --> AddToArray["将测点加入pSptRecArray"]
AddToArray --> CheckInner["内层循环结束?"]
CheckInner --> |否| InnerLoop
CheckInner --> |是| CheckOuter["外层循环结束?"]
CheckOuter --> |否| OuterLoop
CheckOuter --> |是| End["返回测点总数和最大层数"]
```
**图源**
- [MediumA.cpp](file://cpp\ProblemZone\MediumA.cpp#L30-L167)
**节源**
- [MediumA.cpp](file://cpp\ProblemZone\MediumA.cpp#L30-L167)
### 温纳β装置 (MediumB)
`CMediumB`类实现了温纳β(Wenner Beta)装置。与α装置不同,β装置的供电电极B和测量电极M是相邻的。
其`GenerateSptRecElecVal`方法的逻辑与`MediumA`非常相似,主要区别在于电极的赋值顺序和K值的计算。在β装置中,K值的计算公式为 `k = 6π * (N-M)`,这反映了其不同的几何因子。
**节源**
- [MediumB.cpp](file://cpp\ProblemZone\MediumB.cpp#L30-L167)
### 温纳γ装置 (MediumC)
`CMediumC`类实现了温纳γ(Wenner Gamma)装置。在这种排列中,两个测量电极M和N位于一个供电电极A的同一侧。
该类的`GenerateSptRecElecVal`方法同样采用双重循环结构,但其电极组合逻辑和K值计算(`k = 3π * (M-A)`)与α和β装置有显著不同,体现了γ装置的独特性。
**节源**
- [MediumC.cpp](file://cpp\ProblemZone\MediumC.cpp#L30-L168)
### 施伦贝谢装置 (MediumD)
`CMediumD`类实现了施伦贝谢(Schlumberger)装置,这是一种非对称排列,其中测量电极MN间距固定,而供电电极AB间距随测量深度增加而扩大。
该模型的实现更为复杂,因为它引入了可配置的参数`m_iParamIma`和`m_iParamImn`,分别代表AM和MN的最大间距倍数。`SetParamVal`方法允许从外部设置这些参数。`GenerateSptRecElecVal`方法中的三重循环结构(`for (a = 1; a <= m_iParamIma; a++)`)用于生成不同MN间距的测点,这与标准温纳装置的单一间距不同。
**节源**
- [MediumD.cpp](file://cpp\ProblemZone\MediumD.cpp#L32-L279)
## 特殊测量模型
除了标准的地面测量模型,系统还支持更复杂的特殊测量场景。
### 跨孔测量模型 (MediumCrossHoleGeomative)
`CMediumCrossHoleGeomative`类专门用于跨孔(Cross-Hole)电阻率成像。这种模型涉及两个或多个钻孔中的电极,极大地增加了测量的复杂性。
该类的`GenerateSptRecElecVal`方法实现了一种特定的跨孔测量方案:电极按特定顺序排列(1-12从下到上,13-24从上到下),并遵循“C1P1 = C2P2”的规则。其核心逻辑是一个`while(TRUE)`循环,通过逐层增加测量深度(`iLayer++`)并控制C1/P1和C2/P2的移动来生成所有测点。K值的计算使用了更复杂的公式 `k = π / (1/AM - 1/sqrt(AM² + AB²))`,考虑了电极间的垂直和水平距离。
**节源**
- [MediumCrossHoleGeomative.cpp](file://cpp\ProblemZone\MediumCrossHoleGeomative.cpp#L47-L111)
### 自定义2D模型 (MediumCustom2D)
`CMediumCustom2D`类为用户提供了最大的灵活性,允许用户手动输入任意的电极组合(A, B, M, N)、K值、叠加次数(N)和层数。
该类的`GenerateSptRecElecVal`方法会弹出一个对话框`CDialCustomSptInput`,让用户输入所有测点的详细信息。程序会逐行读取用户输入,并创建`CSptRecord`对象。此外,它还支持多通道模式,会根据A、B、M的值对测点进行排序,以避免重复。
**节源**
- [MediumCustom2D.cpp](file://cpp\ProblemZone\MediumCustom2D.cpp#L28-L228)
## 高级与遗留模型
系统中还包含一些更高级或为兼容性而保留的模型。
### 通用脚本模型 (MediumX, MediumY, MediumZ)
`MediumX`、`MediumY`和`MediumZ`这三个类代表了基于外部脚本引擎的通用测量模型。它们不直接在C++代码中生成测点,而是通过调用底层的`scr_*`函数(如`scr_create`, `scr_generate`)来操作一个脚本引擎。
这些类的`GenerateSptRecElecVal`方法非常简单,主要是遍历由脚本引擎生成的测点列表(`scr_get_points`),并将每个点的A、B、M、N、K值复制到`CSptRecord`对象中。`MediumZ`、`MediumY`、`MediumX`分别对应“WennerAlfa”、“Schlumberger”和“Dipole-Dipole”等不同的脚本名称,这表明它们是通过配置不同的脚本来实现不同测量方法的。
**节源**
- [MediumZ.cpp](file://cpp\ProblemZone\MediumZ.cpp#L28-L61)
- [MediumY.cpp](file://cpp\ProblemZone\MediumY.cpp#L29-L62)
- [MediumX.cpp](file://cpp\ProblemZone\MediumX.cpp#L27-L60)
## 用户界面与配置
用户通过`CCrossHoleConfig2DMainDlg`等配置对话框来选择和参数化测量模型。例如,在跨孔配置界面中,用户可以在“参数”选项卡中选择测量类型(`GetMediumType`),并输入脚本名称、时间间隔等信息。
当用户点击“创建”按钮时,`OnBnClickedBtnCreate`方法会被调用。该方法首先获取用户选择的测量类型和参数,然后调用`TwoBoreholeGenerateScript`等函数来生成具体的测量脚本。最终,`SaveTestPointToDB`方法会将生成的测点信息(A, B, M, N, K值等)写入数据库的`script2d`表中,完成整个配置流程。
**节源**
- [CCrossHoleConfig2DMainDlg.cpp](file://cpp\crossHole\CCrossHoleConfig2DMainDlg.cpp#L734-L780)
## 模型选择决策树
为了帮助用户根据地质条件和勘探目标选择合适的Medium类型,以下提供一个决策树:
```mermaid
flowchart TD
Start["开始选择测量模型"] --> Q1["勘探目标是二维剖面吗?"]
Q1 --> |是| Q2["需要标准对称排列吗?"]
Q1 --> |否| Q3["是跨孔测量吗?"]
Q2 --> |是| Q4["需要最大探测深度?"]
Q2 --> |否| Q5["需要高横向分辨率?"]
Q3 --> |是| Recommend["推荐: MediumCrossHoleGeomative"]
Q3 --> |否| Q6["需要完全自定义电极组合?"]
Q4 --> |是| RecommendA["推荐: MediumA (温纳α)"]
Q4 --> |否| Q7["需要快速测量?"]
Q5 --> |是| RecommendD["推荐: MediumD (施伦贝谢)"]
Q5 --> |否| RecommendB["推荐: MediumB (温纳β)"]
Q6 --> |是| RecommendCustom["推荐: MediumCustom2D"]
Q6 --> |否| RecommendLegacy["考虑: MediumX/Y/Z (通用脚本)"]
Q7 --> |是| RecommendC["推荐: MediumC (温纳γ)"]
Q7 --> |否| RecommendA
Recommend --> End
RecommendA --> End
RecommendB --> End
RecommendC --> End
RecommendD --> End
RecommendCustom --> End
RecommendLegacy --> End
End["完成选择"]
```
**图源**
- [MediumA.cpp](file://cpp\ProblemZone\MediumA.cpp)
- [MediumB.cpp](file://cpp\ProblemZone\MediumB.cpp)
- [MediumC.cpp](file://cpp\ProblemZone\MediumC.cpp)
- [MediumD.cpp](file://cpp\ProblemZone\MediumD.cpp)
- [MediumCrossHoleGeomative.cpp](file://cpp\ProblemZone\MediumCrossHoleGeomative.cpp)
- [MediumCustom2D.cpp](file://cpp\ProblemZone\MediumCustom2D.cpp)
## 结论
Medium系列类构成了Geomative Studio软件的核心测量引擎,通过面向对象的设计,为多种地球物理测量方法提供了清晰、可扩展的实现。从标准的温纳和施伦贝谢装置到复杂的跨孔测量和完全自定义的方案,这些类满足了不同勘探场景的需求。模型的参数(如电极间距、K值计算)直接影响最终的反演结果,因此用户应根据具体的地质条件和勘探目标谨慎选择合适的模型。未来的工作可以进一步优化这些模型的性能,并增加更多先进的测量方法。