Beispiel #1
0
        /// <summary>
        /// 吸収係数
        /// </summary>
        /// <param name="elements"></param>
        /// <param name="index"></param>
        /// <param name="incidentEnergy"></param>
        /// <param name="theta"></param>
        /// <returns></returns>
        public static double AbsorptionCorrectionFunction(Element[] elements, int index, double incidentEnergy, double theta)
        {
            int z = elements[index].Z;

            XrayLine     line = elements[index].Line;
            XrayLineEdge edge;

            if (elements[index].Line == XrayLine.Ka || elements[index].Line == XrayLine.Ka1 || elements[index].Line == XrayLine.Ka2)
            {
                edge = XrayLineEdge.K;
            }
            else
            {
                edge = XrayLineEdge.L3;
            }

            double mu_rho = 0;
            double h      = 0;

            for (int i = 0; i < elements.Length; i++)
            {
                mu_rho += elements[i].WeightRatio * AtomConstants.MassAbsorption(AtomConstants.CharacteristicXrayEnergy(z, line), elements[i].Z);
                h      += elements[i].WeightRatio * 1.2 * AtomConstants.AtomicWeight(elements[i].Z) / elements[i].Z / elements[i].Z;
            }

            double chi   = mu_rho / Math.Sin(theta);
            double ec    = AtomConstants.CharacteristicXrayEnergy(z, edge);
            double sigma = 4.5E5 / (Math.Pow(incidentEnergy, 1.65) - Math.Pow(ec, 1.65));

            return((1 + h) / (1 + chi / sigma) / (1 + h * (1 + chi / sigma)));;
        }
Beispiel #2
0
 public Element(int atomicNumber, double valence, double molarAbundance = 1, XrayLine line = XrayLine.Ka, double count = 0, double countTime = 1)
 {
     Z              = atomicNumber;
     AtomicName     = AtomConstants.AtomicName(Z);
     MolarAbundance = molarAbundance;
     Valence        = valence;
     // Isotopes = AtomConstants.IsotopeAbundance[Z];
     MolarWeight = AtomConstants.AtomicWeight(Z);
 }
Beispiel #3
0
 /// <summary>
 /// 単原子分子のコンストラクタ
 /// </summary>
 /// <param name="z">原子番号</param>
 /// <param name="valence">価数</param>
 /// <param name="weightRatio">重量比</param>
 public Molecule(int z, double valence = 0, double weightRatio = 0, double molarAbundance = 0)
 {
     if (z != 0)
     {
         Element e = new Element(z, 0);
         Elements = new List <Element>();
         Elements.Add(e);
         e.MolarAbundance = 1;
         MolarWeight      = e.MolarWeight;
         Valence          = valence;
         WeightRatio      = weightRatio;
         MolarAbundance   = molarAbundance;
         Formula          = AtomConstants.AtomicName(z);
     }
 }
Beispiel #4
0
        static Bonds()
        {
            var anionNum = new List <int> {
                8, 9, 16, 17, 34, 35, 52, 53
            };

            Anions = anionNum.Select(n => $"{n}: {AtomConstants.AtomicName(n)}").ToList();

            var cationNum = new List <int>();

            cationNum.AddRange(Enumerable.Range(3, 5));
            cationNum.AddRange(Enumerable.Range(11, 5));
            cationNum.AddRange(Enumerable.Range(19, 15));
            cationNum.AddRange(Enumerable.Range(37, 15));
            cationNum.AddRange(Enumerable.Range(55, 20));
            Cations = cationNum.Select(n => $"{n}: {AtomConstants.AtomicName(n)}").ToList();
        }
Beispiel #5
0
        /// <summary>
        /// 連続X線による蛍光励起補正
        /// </summary>
        /// <param name="elements"></param>
        /// <param name="index"></param>
        /// <param name="E0"></param>
        /// <param name="TakeoffAngle"></param>
        /// <returns></returns>
        public static double ChontinuousFluorescenceFactor(Element[] elements, int index, double E0, double TakeoffAngle)
        {
            int          zA    = elements[index].Z;
            XrayLineEdge edgeA = XrayLineEdge.K;
            XrayLine     lineA = XrayLine.Ka;

            if (elements[index].Line == XrayLine.La1 || elements[index].Line == XrayLine.La2 || elements[index].Line == XrayLine.Lb1 || elements[index].Line == XrayLine.Lb2)
            {
                edgeA = XrayLineEdge.L3;
                lineA = XrayLine.La1;
            }
            double EcA = AtomConstants.CharacteristicXrayEnergy(zA, edgeA);
            double E   = AtomConstants.CharacteristicXrayEnergy(zA, elements[index].Line);

            double c = lineA == XrayLine.Ka ? 4.34E-6 : 3.13E-6;

            double mu_rhoAAe   = AtomConstants.MassAbsorption(EcA, zA);
            double mu_rhoUnkAe = 0;
            double mu_rhoUnkA  = 0;
            double zAve        = 0;

            for (int i = 0; i < elements.Length; i++)
            {
                mu_rhoUnkAe += elements[i].WeightRatio * AtomConstants.MassAbsorption(EcA, elements[i].Z);
                mu_rhoUnkA  += elements[i].WeightRatio * AtomConstants.MassAbsorption(E, elements[i].Z);
                zAve        += elements[i].WeightRatio * elements[i].Z;
            }
            double gamma = AtomConstants.AbsorptionJumpRatio(zA, edgeA);
            double gammaMinusOnePerGamma = (gamma - 1) / gamma;

            if (lineA == XrayLine.La1)
            {
                gammaMinusOnePerGamma = (gamma - 1) / gamma / AtomConstants.AbsorptionJumpRatio(zA, XrayLineEdge.L2) / AtomConstants.AbsorptionJumpRatio(zA, XrayLineEdge.L1);
            }

            double chi = mu_rhoUnkA / Math.Sin(TakeoffAngle);
            double g   = chi / mu_rhoUnkAe;
            double U0A = E0 / EcA;

            return(c * elements[index].MolarWeight * zAve * EcA * mu_rhoAAe / mu_rhoUnkAe * gammaMinusOnePerGamma * Math.Log(1 + g * U0A) / g / U0A);
        }
Beispiel #6
0
        /// <summary>
        /// 後方散乱係数
        /// </summary>
        /// <param name="elements"></param>
        /// <param name="index"></param>
        /// <param name="incidentEnergy"></param>
        /// <returns></returns>
        public static double BackscatteredFactor(Element[] elements, int index, double incidentEnergy)
        {
            int          z    = elements[index].Z;
            XrayLine     line = elements[index].Line;
            XrayLineEdge edge;

            if (line == XrayLine.Ka || line == XrayLine.Ka1 || line == XrayLine.Ka2)
            {
                edge = XrayLineEdge.K;
            }
            else
            {
                edge = XrayLineEdge.L3;
            }
            double r = 0;

            for (int i = 0; i < elements.Length; i++)
            {
                r += elements[i].WeightRatio * AtomConstants.BackScatteredFactor(AtomConstants.CharacteristicXrayEnergy(z, edge), incidentEnergy, elements[i].Z);
            }
            return(r);
        }
Beispiel #7
0
 /// <summary>
 /// Vesta標準のボンドを生成. 入力形式は、原子番号の配列
 /// </summary>
 /// <param name="atomicNumbers"></param>
 /// <returns></returns>
 public static Bonds[] GetVestaBonds(IEnumerable <int> atomicNumbers) => GetVestaBonds(atomicNumbers.Select(n => $"{n}: {AtomConstants.AtomicName(n)}"));
Beispiel #8
0
 public WaveProperty(int xrayElementNumber, XrayLine xrayLine)
 {
     Source     = WaveSource.Xray;
     WaveLength = AtomConstants.CharacteristicXrayWavelength(xrayElementNumber, xrayLine);
     Energy     = AtomConstants.CharacteristicXrayWavelength(xrayElementNumber, xrayLine);
 }
Beispiel #9
0
        /// <summary>
        /// 特性X線による蛍光励起補正
        /// </summary>
        /// <param name="elements"></param>
        /// <param name="index"></param>
        /// <param name="E0"></param>
        /// <param name="takeoff"></param>
        /// <returns></returns>
        public static double CharacteristicFluorescenceFactor(Element[] elements, int index, double E0, double takeoff)
        {
            //まず、被励起X線 A[] と励起X線 B[] の組み合わせを選択

            int          zA      = elements[index].Z;
            XrayLineEdge edgeA   = XrayLineEdge.K;
            XrayLine     lineA   = XrayLine.Ka;
            double       energyA = AtomConstants.CharacteristicXrayEnergy(zA, elements[index].Line);

            if (elements[index].Line == XrayLine.La1 || elements[index].Line == XrayLine.La2 || elements[index].Line == XrayLine.Lb1 || elements[index].Line == XrayLine.Lb2)
            {
                edgeA = XrayLineEdge.L3;
                lineA = XrayLine.La1;
            }
            double EcA = AtomConstants.CharacteristicXrayEnergy(zA, edgeA);

            double fchGamma = 0;
            double U0A      = E0 / EcA;
            double gamma    = AtomConstants.AbsorptionJumpRatio(zA, edgeA);
            double gammaMinusOnePerGamma = (gamma - 1) / gamma;

            if (lineA == XrayLine.La1)
            {
                gammaMinusOnePerGamma = (gamma - 1) / gamma / AtomConstants.AbsorptionJumpRatio(zA, XrayLineEdge.L2) / AtomConstants.AbsorptionJumpRatio(zA, XrayLineEdge.L1);
            }

            double mu_rhoUnkA = 0;

            for (int k = 0; k < elements.Length; k++)
            {
                mu_rhoUnkA += elements[k].WeightRatio * AtomConstants.MassAbsorption(energyA, elements[k].Z);
            }

            double sigmaA = 4.5E5 / (Math.Pow(E0, 1.65) - Math.Pow(EcA, 1.65));

            for (int i = 0; i < elements.Length; i++)
            {
                if (i != index)
                {
                    int    zB         = elements[i].Z;
                    double omega      = AtomConstantsSub.FluorescentYieldK[zB];
                    double JAwithoutP = 0.5 * gammaMinusOnePerGamma * omega * AtomConstants.AtomicWeight(zA) / AtomConstants.AtomicWeight(zB);

                    //"Kab": beta = 1.1;  "Kb": beta = 0.1; "Lab": beta = 1.4;  "Lb": beta = 0.4; 計算効率を上げるため、一度計算したbetaは再利用する.
                    double[] beta = new double[0];
                    if (betaArray[zB] != null && betaArray[zB].ContainsKey(EcA))
                    {
                        beta = betaArray[zB][EcA];
                    }
                    else
                    {
                        if (EcA < AtomConstants.CharacteristicXrayEnergy(zB, XrayLine.La1))
                        {
                            beta = new[] { 1.1, 1.4 }
                        }
                        ;
                        else if (EcA < AtomConstants.CharacteristicXrayEnergy(zB, XrayLine.Lb1))
                        {
                            beta = new[] { 1.1, 0.4 }
                        }
                        ;
                        else if (EcA < AtomConstants.CharacteristicXrayEnergy(zB, XrayLine.Ka1))
                        {
                            beta = new[] { 1.1 }
                        }
                        ;
                        else if (EcA < AtomConstants.CharacteristicXrayEnergy(zB, XrayLine.Kb1))
                        {
                            beta = new[] { 0.1 }
                        }
                        ;
                        if (betaArray[zB] == null)
                        {
                            betaArray[zB] = new Dictionary <double, double[]>();
                        }
                        lock (lockObJforBetaArray)
                            betaArray[zB].Add(EcA, beta);
                    }

                    for (int j = 0; j < beta.Length; j++)//j==0ならK系列, j==1ならL系列
                    {
                        XrayLineEdge edgeB = j == 0 ? XrayLineEdge.K : XrayLineEdge.L3;
                        double       EcB   = AtomConstants.CharacteristicXrayEnergy(zB, edgeB);
                        double       U0B   = E0 / EcB;
                        if (E0 > EcB)
                        {
                            double fchCb = elements[i].WeightRatio * beta[j];

                            double P = 1;
                            if (lineA == XrayLine.Ka && j == 1)
                            {
                                P = 4.2;
                            }
                            else if (lineA == XrayLine.La1 && j == 1)
                            {
                                P = 0.24;
                            }

                            double JA = JAwithoutP * P;

                            double D = Math.Pow((U0B - 1) / (U0A - 1), 1.67);

                            double energyB = j == 0 ? AtomConstants.CharacteristicXrayEnergy(zB, XrayLine.Ka) : AtomConstants.CharacteristicXrayEnergy(zB, XrayLine.La1);

                            double mu_rhoAB   = AtomConstants.MassAbsorption(energyB, zA);
                            double mu_rhoUnkB = 0;
                            for (int k = 0; k < elements.Length; k++)
                            {
                                mu_rhoUnkB += elements[k].WeightRatio * AtomConstants.MassAbsorption(energyB, elements[k].Z);
                            }

                            double x  = mu_rhoUnkA / mu_rhoUnkB / Math.Sin(takeoff);
                            double gx = Math.Log(1 + x) / x;

                            double y  = sigmaA / mu_rhoUnkB;
                            double gy = Math.Log(1 + y) / y;

                            fchGamma += 0.5 * fchCb * JA * D * mu_rhoAB / mu_rhoUnkB * (gx + gy);
                        }
                    }
                }
            }
            return(fchGamma);
        }
Beispiel #10
0
        /// <summary>
        /// 文字列を分解して、化学組成を返す。戻り値は、Dictionary<Key, Value> で、Keyには原子番号、Valueにはモル比
        /// </summary>
        /// <param name="compound"></param>
        /// <returns></returns>
        public static Dictionary <int, double> GetFormula(string str)
        {
            Dictionary <int, double> formula = new Dictionary <int, double>();

            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] >= 'A' && str[i] <= 'Z')//一文字目が大文字のとき
                {
                    int z = 0;
                    if (i + 1 < str.Length && str[i + 1] >= 'a' && str[i + 1] <= 'z')//二文字目が小文字のとき
                    {
                        z = AtomConstants.AtomicNumber(str.Substring(i++, 2));
                    }
                    else//二文字目が小文字ではないとき
                    {
                        z = AtomConstants.AtomicNumber(str.Substring(i, 1));
                    }

                    string numStr = "";
                    while (i + 1 < str.Length && str[i + 1] >= '0' && str[i + 1] <= '9')//次に続く文字が数字の時
                    {
                        numStr += str[i++ + 1];
                    }
                    int num = numStr == "" ? 1 : Convert.ToInt32(numStr);

                    if (formula.ContainsKey(z))
                    {
                        formula[z] += num;
                    }
                    else
                    {
                        formula.Add(z, num);
                    }
                }

                if (str[i] == '(')  //かっこの始まりが現れたら
                {
                    int count = 1;
                    for (int j = i + 1; j < str.Length; j++)//対応するかっこの終りをみつける
                    {
                        if (str[j] == '(')
                        {
                            count++;
                        }
                        else if (str[j] == ')')
                        {
                            count--;
                        }
                        if (count == 0)//見つかったら
                        {
                            Dictionary <int, double> temp = GetFormula(str.Substring(i + 1, j - i - 1));
                            string numStr = "";
                            while (j + 1 < str.Length && str[j + 1] >= '0' && str[j + 1] <= '9')// ")"のあとが数値だったら
                            {
                                numStr += str[j++ + 1];
                            }
                            int num = numStr == "" ? 1 : Convert.ToInt32(numStr);

                            foreach (int n in temp.Keys)
                            {
                                if (formula.ContainsKey(n))
                                {
                                    formula[n] += num * temp[n];
                                }
                                else
                                {
                                    formula.Add(n, num * temp[n]);
                                }
                            }
                            i = j;
                            break;
                        }
                    }
                }
            }
            return(formula);
        }