package com.ruoyi.caltools.controller;

import com.ruoyi.caltools.model.GasProps;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.solvers.BracketingNthOrderBrentSolver;
import org.apache.commons.math3.exception.TooManyEvaluationsException;

/**
 * GB/T 22634-2008 天然气水含量与水露点工业级换算
 * 注：需配合气体性质计算模块GasController使用
 */

public class GBT22634WaterContentCalc {



        // 安托因方程常数（GB/T 22634规定）
        private static final double ANTOINE_A = 8.07131;
        private static final double ANTOINE_B = 1730.63;
        private static final double ANTOINE_C = 233.426;
        private static final double MMHG_TO_KPA = 0.1333223684;

        /**
         * 工业级水含量计算（含真实气体修正）
         * @param dewPointTemp 水露点温度（℃）
         * @param pressure 绝对压力（kPa）
         * @param gasProps 气体组分属性
         * @return 水含量（mg/Sm³）
         */
        public  double calculateWaterContent(double dewPointTemp,
                                                   double pressure,
                                                   GasProps gasProps) {
            // 1. 计算饱和水蒸气压
            double pWater = calculateWaterVaporPressure(dewPointTemp);
            // 2. 获取压缩因子
            GasController.Crit(gasProps,0); // 调用实际压缩因子计算模块
            // 3. 计算真实摩尔体积
            double molarVolume = calculateMolarVolume(dewPointTemp, pressure, gasProps.getdZf());
            // 4. 计算水含量
            return (pWater / (pressure - pWater)) * (18.01528 * 1e6) / molarVolume;
        }

        /**
         * 逆向计算水露点温度（工业级精度）
         * @param waterContent 水含量（mg/Sm³）
         * @param pressure 绝对压力（kPa）
         * @param gasProps 气体组分属性
         * @return 水露点温度（℃），精度±0.01℃
         */
        public   double calculateDewPoint(final double waterContent,
                                               final double pressure,
                                               final GasProps gasProps) {
//            NewtonRaphsonSolver solver = new NewtonRaphsonSolver(1e-4);

            // 使用5阶布伦特法求解器（无需导数）
            BracketingNthOrderBrentSolver solver = new BracketingNthOrderBrentSolver(
                    1e-4,   // 相对精度
                    1e-6,   // 绝对精度
                    1e-10,  // 函数值精度
                    5       // 多项式阶数
            );

            UnivariateFunction function = new UnivariateFunction() {
                @Override
                public double value(double tempC) {
                    try {
                        // 创建临时气体属性副本
                        GasProps tempProps = gasProps.clone();
                        tempProps.setdTf(tempC + 273.15); // 更新温度
                        tempProps.setdPf(pressure);

                        double calc = calculateWaterContent(tempC, pressure, tempProps);
                        return calc - waterContent;
                    } catch (Exception e) {
                        return Double.NaN;
                    }
                }
            };

            try {
                return solver.solve(100, function, -50.0, 100.0, 20.0); // 初始猜测20℃
            } catch (TooManyEvaluationsException e) {
                throw new ArithmeticException("露点计算未收敛，请检查输入参数");
            }
        }

        // 饱和水蒸气压计算（GB/T 22634规定方法）
        private   double calculateWaterVaporPressure(double tempC) {
            if(tempC < 0 || tempC > 100) {
                throw new IllegalArgumentException("温度超出GB/T 22634适用范围");
            }
            return Math.pow(10, ANTOINE_A - ANTOINE_B / (tempC + ANTOINE_C)) * MMHG_TO_KPA;
        }

        // 真实气体摩尔体积计算
        private static double calculateMolarVolume(double tempC, double pressure, double Z) {
            return Z * 8.3144621 * (tempC + 273.15) / pressure;
        }

//        // 气体属性类（示例结构）
//        public static class GasProps implements Cloneable {
//            private double temperature; // K
//            private double pressure;   // kPa
//            private double[] composition; // 组分摩尔分数
//
//            // 克隆方法用于迭代计算
//            @Override
//            public GasProps clone() {
//                GasProps clone = new GasProps();
//                clone.temperature = this.temperature;
//                clone.pressure = this.pressure;
//                clone.composition = this.composition.clone();
//                return clone;
//            }
//
//            // Getter/Setter
//            public double getTemperature() { return temperature; }
//            public void setTemperature(double temperature) { this.temperature = temperature; }
//            public double getPressure() { return pressure; }
//            public void setPressure(double pressure) { this.pressure = pressure; }
//            public double[] getComposition() { return composition; }
//            public void setComposition(double[] composition) { this.composition = composition; }
//        }
//
//        // 示例调用
//        public static void main(String[] args) {
//            // 初始化气体属性
//            GasProps gas = new GasProps();
//            gas.setPressure(5000.0); // 5 MPa
//            gas.setTemperature(293.15); // 20℃
//            gas.setComposition(new double[]{0.95, 0.03, 0.02}); // 示例组分
//
//            // 正向计算
//            double wc = calculateWaterContent(10.0, 5000.0, gas);
//            System.out.printf("5MPa下10℃露点对应水含量：%.2f mg/Sm³\n", wc);
//
//            // 逆向计算
//            double dewPoint = calculateDewPoint(1000.0, 5000.0, gas);
//            System.out.printf("5MPa下1000mg/Sm³对应露点：%.2f℃\n", dewPoint);
//        }


}
