예제 #1
0
        bool NnMainNonSCExecute(CancellationToken ct, ImmutableDictionary <string, string> options)
        {
            options.TryGetValue("x0", out string?x0s);
            options.TryGetValue("x1", out string?x1s);
            options.TryGetValue("y0", out string?y0s);
            options.TryGetValue("y1", out string?y1s);
            options.TryGetValue("z0", out string?z0s);
            options.TryGetValue("z1", out string?z1s);

            double?x0 = x0s != "-" ? Convert.ToDouble(x0s) : (double?)null;
            double?x1 = x1s != "-" ? Convert.ToDouble(x1s) : (double?)null;
            double?y0 = y0s != "-" ? Convert.ToDouble(y0s) : (double?)null;
            double?y1 = y1s != "-" ? Convert.ToDouble(y1s) : (double?)null;
            double?z0 = z0s != "-" ? Convert.ToDouble(z0s) : (double?)null;
            double?z1 = z1s != "-" ? Convert.ToDouble(z1s) : (double?)null;

            // Extract potential and bound charge from NnMain.
            var potentialFile = NnAgent.GetCoordAndDat(
                FSPath, NnAgent.NnPotentialFileEntry());
            var potential = ScalarField.FromNnDatAndCoord(
                potentialFile.data.Content, potentialFile.coord.Content
                ); // Unit: eV

            var densityFile = NnAgent.GetCoordAndDat(
                FSPath, NnAgent.NnDensityFileEntry());
            var density = ScalarField.FromNnDatAndCoord(
                densityFile.data.Content, densityFile.coord.Content
                ); // Unit: 1E18/cm3 = 1E-3/nm3
            var boundChargeDensity = 0.001 * density.TruncateAndKeep((x0, y0, z0), (x1, y1, z1));

            // Evalute corrected potential.

            var boundChargePotential =
                ScalarField.CoulombPotential_ByConvolutionWithKernel(
                    boundChargeDensity,
                    NnAgent.CoulombKernel(boundChargeDensity)
                    );

            var correctedPotential = potential + boundChargePotential;

            // Copy correceted potential to NonSC folder

            foreach ((RPath src, string extName) in new [] {
예제 #2
0
        bool NnDQDReportExecute(CancellationToken ct, ImmutableDictionary <string, string> options)
        {
            options.TryGetValue("non_SC", out string?non_SC);
            RPath?NNPath;

            if (non_SC == "yes")
            {
                NNPath = NnMainNonSCPath;
                File.Create(NnMainNonSCToken);
            }
            else
            {
                NNPath = FSPath;
                if (File.Exists(NnMainNonSCToken))
                {
                    File.Delete(NnMainNonSCToken);
                }
            }

            //==========Clearing old outputs==========
            if (NnDQDReportPath.Exists())
            {
                foreach (var file in Directory.GetFiles(NnDQDReportPath))
                {
                    File.Delete(file);
                }
            }



            //==========Remove data of other bands==========
            // FIXME: What would happen if there's multiple quantum region ?
            options.TryGetValue("band", out string?band);
            if (band == "X1")
            {
                foreach (var file in Directory.GetFiles(NNPath, "*_X2*"))
                {
                    File.Delete(file);
                }
                foreach (var file in Directory.GetFiles(NNPath, "*_X3*"))
                {
                    File.Delete(file);
                }
            }
            else
            {
                // FIXME: Bands other than X1 is not implemented yet!
                return(false);
            }


            //==========Categorize 1d & 2d data (1d & 2d are not needed)==========
            string[] subDirs = { "1d", "2d" };
            foreach (string subDir in subDirs)
            {
                var path = NNPath.SubPath(subDir);
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                foreach (var file in Directory.GetFiles(NNPath, $"*_{subDir}_*"))
                {
                    var dest = path.SubPath(Path.GetFileName(file), false);
                    if (dest.Exists())
                    {
                        File.Delete(dest);
                    }
                    File.Move(file, dest);
                }
            }



            //==========Read energy & occupation from spectrum==========
            // TODO: Bands other than X1 is not implemented yet!
            RPath?spectrumFile = NNPath.SubPath("wf_spectrum_quantum_region_X1.dat");

            if (spectrumFile?.Content == null)
            {
                return(false);
            }

            Dictionary <int, double>?energy =
                NnAgent.ReadNXY(spectrumFile.Content, 0).ToDictionary(
                    p => int.Parse(p.Item1),
                    p => Double.Parse(p.Item2, System.Globalization.NumberStyles.Float)
                    );

            if (energy == null)
            {
                return(false);
            }

            Dictionary <int, double>?occup =
                NnAgent.ReadNXY(spectrumFile.Content, 1).ToDictionary(
                    p => int.Parse(p.Item1),
                    p => Double.Parse(p.Item2, System.Globalization.NumberStyles.Float)
                    );

            if (occup == null)
            {
                return(false);
            }


            options.TryGetValue("portion", out string?portions);
            options.TryGetValue("L_x0", out string?L_x0s);
            options.TryGetValue("L_x1", out string?L_x1s);
            options.TryGetValue("L_y0", out string?L_y0s);
            options.TryGetValue("L_y1", out string?L_y1s);
            options.TryGetValue("L_z0", out string?L_z0s);
            options.TryGetValue("L_z1", out string?L_z1s);
            options.TryGetValue("R_x0", out string?R_x0s);
            options.TryGetValue("R_x1", out string?R_x1s);
            options.TryGetValue("R_y0", out string?R_y0s);
            options.TryGetValue("R_y1", out string?R_y1s);
            options.TryGetValue("R_z0", out string?R_z0s);
            options.TryGetValue("R_z1", out string?R_z1s);

            double?portion = portions != "-" ? Convert.ToDouble(portions) : (double?)null;
            double?L_x0    = L_x0s != "-" ? Convert.ToDouble(L_x0s)    : (double?)null;
            double?L_x1    = L_x1s != "-" ? Convert.ToDouble(L_x1s)    : (double?)null;
            double?L_y0    = L_y0s != "-" ? Convert.ToDouble(L_y0s)    : (double?)null;
            double?L_y1    = L_y1s != "-" ? Convert.ToDouble(L_y1s)    : (double?)null;
            double?L_z0    = L_z0s != "-" ? Convert.ToDouble(L_z0s)    : (double?)null;
            double?L_z1    = L_z1s != "-" ? Convert.ToDouble(L_z1s)    : (double?)null;
            double?R_x0    = R_x0s != "-" ? Convert.ToDouble(R_x0s)    : (double?)null;
            double?R_x1    = R_x1s != "-" ? Convert.ToDouble(R_x1s)    : (double?)null;
            double?R_y0    = R_y0s != "-" ? Convert.ToDouble(R_y0s)    : (double?)null;
            double?R_y1    = R_y1s != "-" ? Convert.ToDouble(R_y1s)    : (double?)null;
            double?R_z0    = R_z0s != "-" ? Convert.ToDouble(R_z0s)    : (double?)null;
            double?R_z1    = R_z1s != "-" ? Convert.ToDouble(R_z1s)    : (double?)null;


            //==========Calculate dot-region occupation from e- density==========
            (var eDData, var eDCoord, _, _) = NnAgent.GetCoordAndDat(
                NNPath, "density_electron");
            if ((eDData?.Content == null) || (eDCoord?.Content == null))
            {
                return(false);
            }
            ScalarField eD = ScalarField.FromNnDatAndCoord(eDData.Content, eDCoord.Content);

            var occupL = 0.001 * eD.IntegrateInRange((L_x0, L_y0, L_z0), (L_x1, L_y1, L_z1)).Real;
            var occupR = 0.001 * eD.IntegrateInRange((R_x0, R_y0, R_z0), (R_x1, R_y1, R_z1)).Real;



            //==========Calculate dot-region occupation from wave function (probabilities)==========
            var portionSpin = CalculateSpinPortion(NNPath);
            var portionL    = CalculatePortions((L_x0, L_y0, L_z0), (L_x1, L_y1, L_z1), NNPath);
            var portionR    = CalculatePortions((R_x0, R_y0, R_z0), (R_x1, R_y1, R_z1), NNPath);

            if (occup.Keys.Except(portionL.Keys).Count() != 0)
            {
                return(false);
            }
            if (occup.Keys.Except(portionR.Keys).Count() != 0)
            {
                return(false);
            }



            //==========Identify bound states and write spectrum reports==========
            string reportAll = "";

            reportAll += "no. occupation[electrons] portion-left portion-right energy(eV)\n";

            var specLU = new List <(int Id, double Energy)>();
            var specRU = new List <(int Id, double Energy)>();
            var specLD = new List <(int Id, double Energy)>();
            var specRD = new List <(int Id, double Energy)>();

            int lUSpecCount = 0,
                rUSpecCount = 0,
                lDSpecCount = 0,
                rDSpecCount = 0;

            foreach (var id in occup.Keys.OrderBy(k => k))
            {
                reportAll += $"{id} {occup[id]} {portionL[id]} {portionR[id]} {energy[id]}\n";


                // Move bound state prob.s to output directory for reference.
                (RPath? data, RPath? coord, RPath? fld, RPath? v) =
                    NnAgent.GetCoordAndDat(NNPath, NnAgent.NnProbFileEntry(NnAgent.BandType.X1, id));

                (RPath? dataNew, RPath? coordNew, _, RPath? vNew) =
                    NnAgent.GetCoordAndDat(NnDQDReportPath, NnAgent.NnProbFileEntry(NnAgent.BandType.X1, id), true);
                (_, _, RPath? fldLUNew, _) = NnAgent.GetCoordAndDat(NnDQDReportPath, $"LU_" + NnAgent.NnProbFileEntry(NnAgent.BandType.X1, lUSpecCount), true);
                (_, _, RPath? fldRUNew, _) = NnAgent.GetCoordAndDat(NnDQDReportPath, $"RU_" + NnAgent.NnProbFileEntry(NnAgent.BandType.X1, rUSpecCount), true);
                (_, _, RPath? fldLDNew, _) = NnAgent.GetCoordAndDat(NnDQDReportPath, $"LD_" + NnAgent.NnProbFileEntry(NnAgent.BandType.X1, lDSpecCount), true);
                (_, _, RPath? fldRDNew, _) = NnAgent.GetCoordAndDat(NnDQDReportPath, $"RD_" + NnAgent.NnProbFileEntry(NnAgent.BandType.X1, rDSpecCount), true);

                if (data == null || coord == null || fld == null || v == null ||
                    dataNew == null || coordNew == null || vNew == null ||
                    fldLUNew == null || fldRUNew == null || fldLDNew == null || fldRDNew == null)
                {
                    continue;
                }


                // Categorize bound states according to their side and spin
                if (portionL[id] > portion)
                {
                    File.Copy(data, dataNew);
                    File.Copy(coord, coordNew);
                    File.Copy(v, vNew);

                    if (portionSpin[id] > 0.5)
                    {
                        specLU.Add((id, energy[id]));