Пример #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)));;
        }
Пример #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);
 }
Пример #3
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);
        }