Esempio n. 1
0
        public static Dictionary <int, double>?ReadNXYIntDouble(string content, int ny)
        {
            var nxy = NnAgent.ReadNXY(content, ny) ??
                      throw new Exception();

            if (nxy == null)
            {
                return(null);
            }

            var result = new Dictionary <int, double>();

            foreach (var(id, value) in nxy)
            {
                result[int.Parse(id)] = Double.Parse(value);
            }

            return(result);
        }
Esempio n. 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]));