Sign in

    moonbit_extractor

    Extraction process calculation toolkit for liquid-liquid extraction and solid-liquid leaching

    chemical-engineering
    extraction
    equilibrium
    ternary-diagram
    cli
    Download zip
    Version
    0.1.2
    License
    Apache-2.0
    Last updated
    2 months ago
    Downloads
    47

    #moonbit-extractor

    CI

    moonbit-extractor 是一个用 MoonBit 编写的液液萃取、固液浸取与三元相平衡计算工具箱。项目面向化工教学、实验数据整理和工艺方案初算,将常用的物料衡算、相平衡插值、级数计算、方案比较与结果审计组织为可复用库,同时提供可脚本化的 native CLI。

    项目使用理想平衡级和显式输入约束构建可核对的计算流程,不替代严格热力学模拟或工程放大设计。使用实测相平衡数据时,结果的适用性取决于数据范围、物性基准和实验质量。

    项目仓库:GitHub · GitLink

    #核心能力

    • 分配系数、选择性、萃取因子、回收率和物料衡算残差
    • 恒定分配系数或表格相平衡下的单级液液萃取
    • 任意溶剂分配和等量溶剂分配的错流多级萃取
    • 恒流、恒定分配系数的逆流多级物料衡算
    • 固液浸取的单级洗涤、错流多级洗涤和目标洗液量反算
    • 一维相平衡表的校验、插值、反插值、斜率和积分
    • 三元组成归一化、三角形坐标变换、混合点、杠杆规则和两相分割
    • 联络线表插值、邻近联络线选择、两相区多边形与边界投影
    • McCabe–Thiele 风格级数计算,支持非线性表格相平衡和末级分数级
    • 非理想级效率分布、实际接触级估算和工艺窗口校验
    • 溶剂量反算、单级/错流/逆流方案比较、灵敏度分析和 Pareto 筛选
    • 批量情景、统计汇总、衡算审计、区间包络和实验设计
    • 加权多项式回归、留一法验证、级效率校准和相平衡筛查
    • 显式质量、时间、流量单位,以及三角形几何输出和无依赖 SVG 导出
    • CSV 相平衡数据与联络线数据读取

    #快速开始

    项目按 MoonBit stable 工具链验证。查看本机版本并准备依赖:

    moon version --all moon update

    执行严格检查:

    moon fmt --check moon check --target all --deny-warn moon test --deny-warn

    构建并运行 CLI 需要 native 后端和本机 C 编译器:

    moon build cmd/extractor --target native moon run --target native cmd/extractor -- --help

    #CLI

    CLI 支持以下命令:

    命令用途
    distribution <x> <y>计算分配系数
    single <L> <xF> <V> <K> [yS]单级液液萃取
    countercurrent <L> <xF> <V> <K> <N> [yS]逆流多级萃取
    leach <B> <M0> <x0> <W> <R> [xW]单级固液浸取/洗涤
    stages-linear <L> <V> <xF> <xR> <K> [yS]线性平衡关系下的级数计算
    solvent-design <L> <xF> <K> <xR> <N>溶剂量与流程方案比较
    sensitivity <L> <xF> <V> <K> [step]局部灵敏度与情景审计

    示例:

    moon run --target native cmd/extractor -- distribution 0.10 0.40 # distribution_coefficient=4 moon run --target native cmd/extractor -- single 100 0.10 50 2 # raffinate_concentration=0.05 # extract_concentration=0.1 # recovery=0.5 # balance_residual=0

    更多输入约束和模型假设见 docs/ALGORITHMS.md。

    #库 API

    根包提供常用计算的门面 API:

    test {
    let result = @moonbit_extractor.single_stage_constant_k(
    feed_flow=100.0,
    feed_concentration=0.1,
    solvent_flow=50.0,
    distribution=2.0,
    )
    assert_true(result.recovery.is_close(0.5))
    }

    需要更清晰领域边界时,可以直接使用子包:

    • domain:组成、平衡点、联络线和错误类型
    • interpolation、data:相平衡表、线性表和 CSV 数据
    • liquid、leaching:液液萃取与固液浸取
    • ternary、geometry、export:三元相图几何和 SVG 导出
    • stages、process:级数计算、级效率和操作窗口
    • design、optimization:方案设计、搜索和 Pareto 筛选
    • analysis、sampling、calibration、reporting:情景分析、统计、回归校准和审计报告
    • units、thermo:单位量与热力学辅助模型

    表格相平衡示例:

    test {
    let points = [
    @domain.EquilibriumPoint::new(x=0.0, y=0.0),
    @domain.EquilibriumPoint::new(x=0.1, y=0.2),
    @domain.EquilibriumPoint::new(x=0.2, y=0.3),
    ]
    let equilibrium = @interpolation.EquilibriumTable::new(points)
    let result = @liquid.single_stage_table(
    feed_flow=100.0,
    feed_concentration=0.1,
    solvent_flow=50.0,
    equilibrium~,
    )
    assert_true(result.balance_residual.abs() < 1.0e-8)
    }

    CSV 示例见 examples/equilibrium-linear.csv 和 examples/tie-lines-synthetic.csv。示例数据是用于测试和演示的无量纲数据,不代表具体物系。

    #架构

    cmd/extractor 命令行入口与参数校验 cmd/benchmark 可复现基准入口 │ ├── facade 根包门面 API ├── domain 领域类型、错误和输入约束 ├── liquid 液液萃取物料衡算 ├── leaching 固液浸取与洗涤 ├── stages 级数与级效率 ├── ternary 三元相平衡和几何 ├── data CSV 数据读取 ├── design 方案设计和灵敏度 ├── analysis 情景、统计和衡算审计 └── supporting 插值、单位、校准、优化、报告和导出

    液液萃取 API 默认使用一致的无溶质基准:L 为载体相流量,V 为溶剂相流量,x、y 为单位无溶质相中的溶质量。平衡级假定两相充分接触并达到给定的 y*(x),不自动计入互溶、夹带、体积变化和传质效率。固液浸取模型、三元组成顺序和输入边界见 docs/ALGORITHMS.md。

    #基准

    基准入口使用 20 个可复现工程输入,输出回收率均值和最大衡算残差:

    moon run --target native cmd/benchmark

    当前记录的输出为:

    cases=20 average_recovery=0.3796434209968044 maximum_balance_residual=8.881784197001252e-16

    在 Windows 本地连续运行 5 次时,包含 CLI 启动和缓存检查开销的总耗时为 295.53–333.92 ms,中位数为 309.83 ms。该数据用于复现工程流程,不等同于纯算法吞吐量;完整记录和复现命令见 docs/BENCHMARKS.md。

    #测试

    当前版本包含 733 个通过测试,其中包括 650 个边界矩阵案例和覆盖工程集成路径的测试。边界案例调用实际单级计算并要求衡算残差小于 1e-8。

    项目按领域拆分为可复用的计算包、数据包、流程分析包、设计优化包和报告导出包;测试代码与生产包分离,生成接口文件和构建缓存不参与源码发布。

    复现测试时,建议使用:

    moon test --deny-warn moon check --target all --deny-warn moon info

    #CI

    GitHub Actions 工作流位于 .github/workflows/ci.yml,使用 MoonBit stable 安装器,在 Ubuntu、macOS 和 Windows 上执行:

    • 格式检查、全后端类型检查和严格测试
    • 生成接口文件一致性检查
    • native CLI 构建与多个 CLI 冒烟算例
    • 可复现基准程序
    • Ubuntu 覆盖率摘要

    #许可证

    本项目以 Apache License 2.0 发布。实现来源、公式依据和示例数据说明见 docs/SOURCES.md。

    ActivityModel

    Lightweight activity-coefficient relations for screening non-ideal data.

    BalanceAudit

    Batch scenarios, statistics, balance audits and uncertainty envelopes.

    BenchmarkCase

    A reproducible engineering casebook. Values are dimensionless on the same basis as the liquid package and are intentionally kept in source control.

    BinodalCurve

    Ternary diagram geometry and phase splitting.

    BoundaryIntersection

    Ternary diagram geometry and phase splitting.

    BoundaryProjection

    Ternary diagram geometry and phase splitting.

    CartesianPoint

    Ternary diagram geometry and phase splitting.

    ContactPattern

    Process sizing and sensitivity calculations.

    CountercurrentResult

    Liquid-liquid extraction balances.

    CountercurrentStage

    Liquid-liquid extraction balances.

    CrossValidation

    Measurement calibration and engineering unit helpers.

    CrosscurrentLeachingResult

    Solid-liquid leaching and washing balances.

    CrosscurrentResult

    Liquid-liquid extraction balances.

    CrosscurrentStage

    Liquid-liquid extraction balances.

    CsvOptions

    Text data ingestion.

    DesignPoint

    Screening models, deterministic experiment design and geometric reports.

    EfficiencyCalibration

    Measurement calibration and engineering unit helpers.

    EfficiencyStageResult

    Graphical stage calculation.

    EfficiencyStep

    Graphical stage calculation.

    EquilibriumPoint

    Core domain types and validated constructors.

    EquilibriumTable

    Table interpolation and equilibrium relations.

    ExtractionError

    Core domain types and validated constructors.

    ExtractionStep

    Graphical stage calculation.

    Extrapolation

    Table interpolation and equilibrium relations.

    LeachingStage

    Solid-liquid leaching and washing balances.

    LeachingStageResult

    Solid-liquid leaching and washing balances.

    LeverResult

    Ternary diagram geometry and phase splitting.

    LinearTable

    Table interpolation and equilibrium relations.

    MassUnit

    Explicit engineering quantities prevent accidental mixing of kg/h and kg/s.

    NumericSummary

    Batch scenarios, statistics, balance audits and uncertainty envelopes.

    Observation

    Measurement calibration and engineering unit helpers.

    OperatingWindow

    Operating-window validation keeps a calculation inside a declared process envelope.

    PhaseSplit

    Core domain types and validated constructors.

    Point

    Polygon helpers used by ternary phase-envelope exporters.

    Range

    Reproducible design-of-experiments and robust statistics for process studies.

    RecoveryEnvelope

    Batch scenarios, statistics, balance audits and uncertainty envelopes.

    RegressionModel

    Measurement calibration and engineering unit helpers.

    ScenarioResult

    Batch scenarios, statistics, balance audits and uncertainty envelopes.

    ScenarioSummary

    Batch scenarios, statistics, balance audits and uncertainty envelopes.

    SearchResult

    Screening models, deterministic experiment design and geometric reports.

    SensitivityPoint

    Process sizing and sensitivity calculations.

    Severity

    Human- and machine-readable audit summaries for process studies.

    SingleStageResult

    Liquid-liquid extraction balances.

    SingleStageScenario

    Batch scenarios, statistics, balance audits and uncertainty envelopes.

    SolventDesign

    Process sizing and sensitivity calculations.

    StageCountResult

    Graphical stage calculation.

    SvgCanvas

    Dependency-free SVG output for ternary diagrams and audit plots.

    TernaryComposition

    Core domain types and validated constructors.

    TieLine

    Core domain types and validated constructors.

    TieLineTable

    Ternary diagram geometry and phase splitting.

    analysis_balance_report

    Build a report from the analysis package's aggregate balance audit.

    approximately_equal

    fn approximately_equal(left : Double, right : Double, tolerance? : Double) -> Bool

    average_recovery

    balance_report

    bounded_minimize

    fn bounded_minimize(objective : (Double) -> Double raise
    ExtractionError
    , lower~ : Double, upper~ : Double, tolerance? : Double, maximum_iterations? : Int) ->
    SearchResult
    raise
    ExtractionError

    calibrate_efficiency

    Calibrate stage efficiency from measured ideal/actual stage pairs. Efficiencies are physically constrained to (0, 1] after prediction.

    compare_contact_patterns

    fn compare_contact_patterns(carrier_flow~ : Double, feed_concentration~ : Double, distribution~ : Double, target_raffinate~ : Double, maximum_stages? : Int) -> Array[
    SolventDesign
    ] raise
    ExtractionError

    Compare feasible ideal contact patterns at the same target.

    countercurrent_constant_k

    fn countercurrent_constant_k(carrier_flow~ : Double, feed_concentration~ : Double, solvent_flow~ : Double, solvent_inlet_concentration? : Double, distribution~ : Double, stage_count~ : Int) ->
    CountercurrentResult
    raise
    ExtractionError

    Solve an ideal countercurrent cascade with constant flows and constant K. Stage one is adjacent to the feed; stage N is adjacent to fresh solvent.

    crosscurrent_constant_k

    fn crosscurrent_constant_k(feed_flow~ : Double, feed_concentration~ : Double, solvent_flows : ArrayView[Double], solvent_concentrations? : Array[Double], distribution~ : Double) ->
    CrosscurrentResult
    raise
    ExtractionError

    Calculate ideal crosscurrent stages with fresh or preloaded solvent.

    solvent_flows and solvent_concentrations contain one value per stage.

    crosscurrent_equal_solvent

    fn crosscurrent_equal_solvent(feed_flow~ : Double, feed_concentration~ : Double, total_solvent~ : Double, stage_count~ : Int, distribution~ : Double) ->
    CrosscurrentResult
    raise
    ExtractionError

    Equal-solvent allocation convenience wrapper.

    crosscurrent_equal_wash

    fn crosscurrent_equal_wash(dry_solid_mass~ : Double, initial_solution_mass~ : Double, initial_solute_fraction~ : Double, total_wash_mass~ : Double, stage_count~ : Int, retention_ratio~ : Double) ->
    CrosscurrentLeachingResult
    raise
    ExtractionError

    crosscurrent_leach

    fn crosscurrent_leach(dry_solid_mass~ : Double, initial_solution_mass~ : Double, initial_solute_fraction~ : Double, wash_masses : ArrayView[Double], wash_solute_fractions? : Array[Double], retention_ratio~ : Double) ->
    CrosscurrentLeachingResult
    raise
    ExtractionError

    Repeatedly wash a retained solution with fresh or specified wash streams.

    distribution_coefficient

    fn distribution_coefficient(raffinate_concentration : Double, extract_concentration : Double) -> Double raise
    ExtractionError

    Calculate the distribution coefficient K_D = y / x.

    extraction_factor

    fn extraction_factor(distribution~ : Double, solvent_flow~ : Double, carrier_flow~ : Double) -> Double raise
    ExtractionError

    is_finite

    fn is_finite(value : Double) -> Bool

    ledger_entry

    fn ledger_entry(name~ : String, inlet~ : Double, outlet~ : Double, generated? : Double, consumed? : Double) ->
    LedgerEntry
    raise
    ExtractionError

    ledger_passes

    fn ledger_passes(entries : ArrayView[
    LedgerEntry
    ], tolerance~ : Double) -> Bool

    lever_rule

    Apply the lever rule by projecting an overall composition onto the line between two phase endpoints. A small residual confirms collinearity.

    maximum_residual

    mccabe_thiele_stages

    fn mccabe_thiele_stages(equilibrium~ :
    EquilibriumTable
    , carrier_flow~ : Double, solvent_flow~ : Double, feed_concentration~ : Double, target_raffinate~ : Double, solvent_inlet_concentration? : Double, maximum_stages? : Int, tolerance? : Double) ->
    StageCountResult
    raise
    ExtractionError

    McCabe-Thiele style stepping for countercurrent liquid extraction.

    Starting at the raffinate product end, each step first reaches the equilibrium curve and then follows a stage material-balance line toward the feed. A fractional final stage is reported by linear interpolation of the last horizontal concentration span.

    minimum_countercurrent_stages

    fn minimum_countercurrent_stages(carrier_flow~ : Double, feed_concentration~ : Double, solvent_flow~ : Double, solvent_inlet_concentration? : Double, distribution~ : Double, target_raffinate~ : Double, maximum_stages? : Int) ->
    CountercurrentResult
    raise
    ExtractionError

    Find the smallest integer stage count that meets a raffinate target.

    operating_line

    fn operating_line(carrier_flow~ : Double, solvent_flow~ : Double, raffinate_product~ : Double, solvent_inlet~ : Double, xs : ArrayView[Double]) -> Array[
    EquilibriumPoint
    ] raise
    ExtractionError

    Build points on the overall operating line for plotting or tabulation.

    parse_tie_lines_csv

    Parse tie lines with columns r_carrier,r_solute,r_solvent,e_carrier,e_solute,e_solvent.

    quantile

    fn quantile(values : ArrayView[Double], probability : Double) -> Double raise
    ExtractionError

    fn recommended_safety_factor(uncertainty_fraction : Double, minimum? : Double) -> Double raise
    ExtractionError

    recovery_fraction

    fn recovery_fraction(inlet_solute : Double, raffinate_solute : Double) -> Double raise
    ExtractionError

    selectivity

    fn selectivity(solute_a_raffinate~ : Double, solute_a_extract~ : Double, solute_b_raffinate~ : Double, solute_b_extract~ : Double) -> Double raise
    ExtractionError

    Calculate separation selectivity (y_a/x_a) / (y_b/x_b).

    shortcut_actual_stages

    fn shortcut_actual_stages(theoretical_stages : Double, overall_efficiency : Double) -> Double raise
    ExtractionError

    Convert ideal theoretical stages to a shortcut actual-stage estimate.

    single_stage_constant_k

    fn single_stage_constant_k(feed_flow~ : Double, feed_concentration~ : Double, solvent_flow~ : Double, solvent_concentration? : Double, distribution~ : Double) ->
    SingleStageResult
    raise
    ExtractionError

    Solve one ideal equilibrium stage with constant distribution coefficient. Concentrations and flow rates must use a consistent solute-free basis.

    single_stage_leach

    fn single_stage_leach(dry_solid_mass~ : Double, initial_solution_mass~ : Double, initial_solute_fraction~ : Double, wash_solution_mass~ : Double, wash_solute_fraction? : Double, retention_ratio~ : Double) ->
    LeachingStageResult
    raise
    ExtractionError

    Solve one ideal solid-liquid washing/leaching contact.

    retention_ratio is kg solution retained per kg insoluble dry solid.

    single_stage_recovery_envelope

    fn single_stage_recovery_envelope(feed_flow~ : Double, feed_concentration~ : Double, nominal_solvent_flow~ : Double, solvent_flow_lower~ : Double, solvent_flow_upper~ : Double, nominal_distribution~ : Double, distribution_lower~ : Double, distribution_upper~ : Double) ->
    RecoveryEnvelope
    raise
    ExtractionError

    Evaluate the corner cases of bounded solvent-flow and distribution ranges. Monotonicity is not assumed by the implementation even though the ideal constant-K model is monotone in both inputs.

    single_stage_sensitivity

    fn single_stage_sensitivity(carrier_flow~ : Double, feed_concentration~ : Double, solvent_flow~ : Double, distribution~ : Double, relative_step? : Double) -> Array[
    SensitivityPoint
    ] raise
    ExtractionError

    Central finite-difference sensitivity of single-stage recovery.

    single_stage_table

    fn single_stage_table(feed_flow~ : Double, feed_concentration~ : Double, solvent_flow~ : Double, solvent_concentration? : Double, equilibrium~ :
    EquilibriumTable
    , tolerance? : Double, max_iterations? : Int) ->
    SingleStageResult
    raise
    ExtractionError

    Solve one stage against a tabulated equilibrium relation using bisection.

    solvent_for_countercurrent

    fn solvent_for_countercurrent(carrier_flow~ : Double, feed_concentration~ : Double, distribution~ : Double, target_raffinate~ : Double, stage_count~ : Int, solvent_inlet_concentration? : Double, tolerance? : Double) ->
    SolventDesign
    raise
    ExtractionError

    solvent_for_crosscurrent

    fn solvent_for_crosscurrent(carrier_flow~ : Double, feed_concentration~ : Double, distribution~ : Double, target_raffinate~ : Double, stage_count~ : Int, tolerance? : Double) ->
    SolventDesign
    raise
    ExtractionError

    solvent_for_single_stage

    fn solvent_for_single_stage(carrier_flow~ : Double, feed_concentration~ : Double, distribution~ : Double, target_raffinate~ : Double) ->
    SolventDesign
    raise
    ExtractionError

    Closed-form fresh-solvent requirement for one ideal stage.

    stages_with_efficiency_profile

    fn stages_with_efficiency_profile(equilibrium~ :
    EquilibriumTable
    , carrier_flow~ : Double, solvent_flow~ : Double, feed_concentration~ : Double, target_raffinate~ : Double, efficiencies : ArrayView[Double], solvent_inlet_concentration? : Double, tolerance? : Double) ->
    EfficiencyStageResult
    raise
    ExtractionError

    Step through a countercurrent extractor with per-stage Murphree-style extract-phase efficiencies.

    For each contact, y_actual = y_in + eta (y_equilibrium - y_in). The resulting solute transfer determines the raffinate concentration entering the next contact toward the feed end.

    stages_with_uniform_efficiency

    fn stages_with_uniform_efficiency(equilibrium~ :
    EquilibriumTable
    , carrier_flow~ : Double, solvent_flow~ : Double, feed_concentration~ : Double, target_raffinate~ : Double, efficiency~ : Double, solvent_inlet_concentration? : Double, maximum_stages? : Int, tolerance? : Double) ->
    EfficiencyStageResult
    raise
    ExtractionError

    Uniform-efficiency wrapper that allocates at most maximum_stages steps.

    sweep_distribution

    fn sweep_distribution(feed_flow~ : Double, feed_concentration~ : Double, solvent_flow~ : Double, distributions : ArrayView[Double]) -> Array[
    ScenarioResult
    ] raise
    ExtractionError

    sweep_solvent_flow

    fn sweep_solvent_flow(feed_flow~ : Double, feed_concentration~ : Double, solvent_flows : ArrayView[Double], distribution~ : Double) -> Array[
    ScenarioResult
    ] raise
    ExtractionError

    to_cartesian

    Convert normalized ternary fractions to an equilateral triangle with carrier=(0,0), solvent=(1,0), solute=(1/2,sqrt(3)/2).

    wash_for_target

    fn wash_for_target(dry_solid_mass~ : Double, initial_solution_mass~ : Double, initial_solute_fraction~ : Double, stage_count~ : Int, retention_ratio~ : Double, target_remaining_fraction~ : Double, tolerance? : Double, max_wash_mass? : Double) ->
    CrosscurrentLeachingResult
    raise
    ExtractionError

    Evaluate a grid of stage counts and select the least wash meeting a target.

    Source Files