/// <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)));; }
/// <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); }
/// <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); }