Exemple #1
0
        public bool StartProc()
        {
            if (tmp == null)
            {
                return(false);
            }
            uint MemRequested, MemLockRequested;

            t = new Thread(new ThreadStart(tmp.ForeWork));
            t.Start();
            t.Join();
            if (!tmp.ForeWorkResult)
            {
                return(false);
            }
            MemRequested     = tmp.MemRequested();
            MemLockRequested = tmp.MemLockRequested();

            MemMan.Compact();
            MemMan.MEMORYSTATUSEX MS;
            MS = MemMan.MemoryStatus();
            try
            {
                MemMan.curProc.MaxWorkingSet = (IntPtr)MS.TotalPhys;
                MemMan.curProc.MinWorkingSet = (IntPtr)(MemLockRequested + 0x800000);
            }
            catch (Exception e)
            {
                Console.WriteLine("\n>>>>>>> " + e.Message);
                Console.WriteLine(">>>>>>> Can't take the ownership on " + ((MemLockRequested + 0x800000) / (1024 * 1024)).ToString("####0.0") + "Mb RAM");
                Console.WriteLine(">>>>>>> Probably the progamm is running not under an administrative account,\n>>>>>>> or too many other applications are running");
                Console.WriteLine(">>>>>>> or too many other applications are running.");
                Console.WriteLine(">>>>>>> Calculations will continue, but may slow down.");
            }


            if (!MM.Allocate(MemRequested))
            {
                Console.WriteLine(ExI + " ----> virtual allocation failed for " + MemRequested.ToString() + " bytes");
                return(false);
            }

            // optionally lock the memory
            if (!MM.Lock(0, MemLockRequested))
            {
                Console.WriteLine(">>>>>>> Unable to lock the memory.");
                Console.WriteLine(">>>>>>> Calculations will continue, but will slow down.");
            }
            unsafe
            {
                tmp.data = (double *)MM.BaseAddress;
            }
            t = new Thread(new ThreadStart(tmp.StartCalculations));
            t.Start();
            t.Join();
            MM.Free();
            return(true);
        }
Exemple #2
0
 public ProjectStarter()
 {
     //
     // TODO: Add constructor logic here
     //
     MM     = new MemMan();
     result = true;
     ExI    = ++ExN;
 }
Exemple #3
0
 public MSUseOnceCalculator()
 {
     //
     // TODO: Add constructor logic here
     //
     nn             = 1;
     mm             = 1;
     buf            = null;
     K              = 0;
     atSFT_forward  = null;
     atSFT_backward = null;
     atM            = null;
 }
Exemple #4
0
        static void Main(string[] args)
        {
#if DEBUG
            Console.WriteLine("DEBUG build " + MemMan.GetCurrentVersion());
#else
            Console.WriteLine("Release build " + MemMan.GetCurrentVersion());
#endif
#if  !_WIN32
            Console.WriteLine(" x64 ");
#else
            Console.WriteLine("DEBUG win32 ");
            //Console.WriteLine(Path.GetDirectoryName(Application.ExecutablePath));
            // Console.WriteLine("GetExecutingAssembly=" + Assembly.GetExecutingAssembly().FullName);

            Console.WriteLine("DEBUG win32 ");
#endif
            projectstarter(args);

            if (!IsContinue)
            {
                Console.Read();
            }
        }
Exemple #5
0
        void PG_rs_pullZ()
        {
            int     offsx, offsy;
            uint    N2 = N * 2;
            int     i, j, k;
            double *ddata, bbuf;
            double *curk;
            double  xx, yy;
            double  dxa = a / N;
            double  dyb = b / M;
            double  aa = dxa * nn, bb = dyb * mm;
            float   progress;

            for (k = 0; k < NAtoms; k++)
            {
                if (PotType == MSProject.PotTypes.PG_curve_DW_pullZ)
                {
                    xx = x[k] * a;
                    yy = y[k] * b;
                }
                else
                {
                    xx = x[k];
                    yy = y[k];
                }

                offsx = (int)(N * xx / a - nn / 2);
                offsy = (int)(M * yy / b - mm / 2);
                xx    = (xx - a / N * offsx) / aa;
                yy    = (yy - b / M * offsy) / bb;
                offsx = (int)(offsx * 2);
                offsy = (int)(offsy + M);
                curk  = (CurveHolder + type_[k] * CurveLength);

                for (j = 0; j < mm; j++)
                {
                    bbuf  = buf + j * nn * 2;
                    ddata = data + (int)(((offsy + j) % M) * N2);
                    if (offsx < 0)
                    {
                        MemMan.CopyData(ddata + N2 + offsx, bbuf, (uint)(-offsx));
                        MemMan.CopyData(ddata, bbuf - offsx, (uint)(nn * 2 + offsx));
                    }
                    else
                    if (offsx + nn * 2 >= N2)
                    {
                        MemMan.CopyData(ddata + offsx, bbuf, (uint)(N2 - offsx));
                        MemMan.CopyData(ddata, bbuf + N2 - offsx, (uint)(nn * 2 - (N2 - offsx)));
                    }
                    else
                    {
                        MemMan.CopyData(ddata + offsx, bbuf, nn * 2);
                    }
                }
                if (Math.Abs(z[k]) > 0.001)
                {
                    // Hanning window
                    for (j = 0; j < mm; j++)
                    {
                        bbuf  = buf + j * nn * 2;
                        ddata = buf + j * nn * 2 + nn * 2 - 1;
                        for (i = 0; i < hanwidth * 2; i++)
                        {
                            *(bbuf + i)  *= (1 - hanning[i / 2]);
                            *(ddata - i) *= (hanning[hanwidth - 1 - i / 2]);
                        }
                    }
                    for (j = 0; j < hanwidth; j++)
                    {
                        bbuf  = buf + j * nn * 2;
                        ddata = buf + (mm - j - 1) * nn * 2;
                        for (i = 0; i < nn * 2; i++)
                        {
                            *(bbuf + i)  *= (1 - hanning[j]);
                            *(ddata + i) *= (hanning[hanwidth - 1 - j]);
                        }
                    }
                    atSFT_forward.MakeSFT(buf);
                    ApplyPropagator(aa, bb, gam, z[k], E, X_tilt_crystal, Y_tilt_crystal, nn, mm, buf, &progress);
                    atSFT_backward.MakeSFT(buf);
                }

                PG_rs_curve_DW_cutpot_oneatom(aa, bb, gam, K, atrad, nn, mm, xx, yy, ads[k], occ[k], curk, CurveLength, dela, buf);

                if (Math.Abs(z[k]) > 0.001)
                {
                    atSFT_forward.MakeSFT(buf);
                    ApplyPropagator(aa, bb, gam, -z[k], E, X_tilt_crystal, Y_tilt_crystal, nn, mm, buf, &progress);
                    atSFT_backward.MakeSFT(buf);
                }
                // glue back only the center
                offsx += offix;
                offsy += offiy;
                for (j = 0; j < mminner; j++)
                {
                    bbuf  = buf + (j + offiy) * nn * 2 + offix;
                    ddata = data + (int)(((offsy + j) % M) * N2);
                    if (offsx < 0)
                    {
                        MemMan.CopyData(bbuf, ddata + N2 + offsx, (uint)(-offsx));
                        MemMan.CopyData(bbuf - offsx, ddata, (uint)(nninner * 2 + offsx));
                    }
                    else
                    if (offsx + nninner * 2 >= N2)
                    {
                        MemMan.CopyData(bbuf, ddata + offsx, (uint)(N2 - offsx));
                        MemMan.CopyData(bbuf + N2 - offsx, ddata, (uint)(nninner * 2 - (N2 - offsx)));
                    }
                    else
                    {
                        MemMan.CopyData(bbuf, ddata + offsx, nninner * 2);
                    }
                }
//				else
//				{
//					for(j=0;j<mm;j++)
//					{
//						bbuf=buf+j*nn*2 ;
//						ddata=data+(int)(((offsy+j)%M)*N2) ;
//						if(offsx<0)
//						{
//							MemMan.CopyData(bbuf,ddata+N2+offsx,(uint)(-offsx)) ;
//							MemMan.CopyData(bbuf-offsx,ddata,(uint)(nn*2+offsx)) ;
//
//						}
//						else
//							if(offsx+nn*2>=N2)
//						{
//							MemMan.CopyData(bbuf,ddata+offsx,(uint)(N2-offsx)) ;
//							MemMan.CopyData(bbuf+N2-offsx,ddata,(uint)(nn*2-(N2-offsx))) ;
//
//						}
//						else
//							MemMan.CopyData(bbuf,ddata+offsx,nn*2) ;
//					}
//				}
            }
        }
Exemple #6
0
        override public bool RunCalculation()
        {
            float    progress;
            DateTime start;
            TimeSpan period;
            double   StartThickness = CurThickness;

            int i, iSlice = 0, iWave = 0;

            if ((ThWaves == null) || (ThWaves.Length == 0))
            {
                return(true);
            }
            if ((double)ThWaves[iWave] <= CurThickness)
            {
                bool result = ((LastSavedWave = SaveWav(CurThickness)) != null);
                iWave++;
                Console.WriteLine("\rWave at " + CurThickness.ToString("######0.00") + "A unloaded " + result + "                             ");
            }
            if ((PotType == MSProject.PotTypes.PG_curve_TV_pullZ) || (PotType == MSProject.PotTypes.PG_curve_DW_pullZ))
            {
                hanwidth       = 8;
                hanning        = new double[hanwidth];
                nn             = Math.Min(N, (uint)Math.Pow(2, Math.Ceiling(Math.Log(((atrad + 0.5) / a * N + hanwidth) / (1.0 - 2.0 / hanwidth), 2)) + 1));
                mm             = Math.Min(M, (uint)Math.Pow(2, Math.Ceiling(Math.Log(((atrad + 0.5) / b * M + hanwidth) / (1.0 - 2.0 / hanwidth), 2)) + 1));
                atSFT_forward  = new SFT();
                atSFT_backward = new SFT();
                atM            = new MemMan();
                if (!atM.Allocate(nn * mm * 2 * sizeof(double)))
                {
                    return(false);
                }
                if (!atM.Lock(0, nn * mm * 2 * sizeof(double)))
                {
                    return(false);
                }
                buf = (double *)atM.LockAddress;
                atSFT_forward.MakePlan(buf, nn, mm, 1);
                atSFT_backward.MakePlan(buf, nn, mm, -1);
                lambda  = 0.387818 / Math.Sqrt(E / 1000.0 * (1.0 + 0.978459e-3 * E / 1000));   // E in V
                K       = lambda * Math.Sqrt(1.0 + Math.Pow((0.0242621 / lambda), 2));
                nninner = (uint)Math.Min(nn, (uint)(atrad) / a * N * 2 + Math.Max(1, nn / 2 - hanwidth - (uint)(atrad) / a * N));
                mminner = (uint)Math.Min(mm, (uint)(atrad) / b * M * 2 + Math.Max(1, mm / 2 - hanwidth - (uint)(atrad) / b * M));
//				nninner=(uint)Math.Min(nn,(uint)(atrad)/a*N*2) ;
//				mminner=(uint)Math.Min(mm,(uint)(atrad)/b*M*2) ;
                offix = (int)(nn - nninner);
                offiy = (int)(mm - mminner) / 2;
                for (i = 0; i < hanwidth; i++)
                {
                    hanning[i] = (Math.Cos(i * Math.PI / hanwidth) + 1) * 0.5;
                }
            }

            start = DateTime.Now;
            while (iWave < ThWaves.Length)
            {
                iSlice = (int)(iSlice % NSlices) + 1;


                // Load Slice
                if (!LoadSlice(iSlice))
                {
                    return(false);
                }
                // apply Phase Gratting
                if (NAtoms > 0)
                {
                    if ((PotType == MSProject.PotTypes.PG_DT_TV_periodic) ||
                        (PotType == MSProject.PotTypes.PG_DT_TV_cut) ||
                        (PotType == MSProject.PotTypes.PG_curve_TV_periodic) ||
                        (PotType == MSProject.PotTypes.PG_curve_TV_cut) ||
                        (PotType == MSProject.PotTypes.PG_curve_TV_pullZ))
                    {                           // некорректно работает с gam!=90
                        MusliRandom vibr = new MusliRandom();
                        for (i = 0; i < NAtoms; i++)
                        {
                            x[i]       *= a; y[i] *= b;
                            vibr.StDevX = vibr.StDevY = Math.Sqrt(DW[i] * 0.5) / (2.0 * Math.PI);
                            vibr.Vobble(ref x[i], ref y[i]);
                            if (PotType == MSProject.PotTypes.PG_curve_TV_pullZ)
                            {
                                z[i] += vibr.NextGauss();
                            }
                            if (x[i] < 0)
                            {
                                x[i] += a;
                            }
                            if (x[i] >= a)
                            {
                                x[i] -= a;
                            }
                            if (y[i] < 0)
                            {
                                y[i] += b;
                            }
                            if (y[i] >= b)
                            {
                                y[i] -= b;
                            }
                        }
                    }

                    fixed(double *_x = x, _y = y, _dw = DW, _ads = ads, _occ = occ)
                    {
                        fixed(int *_type_ = type_, _type = type)
                        {
                            switch (PotType)
                            {
                            case MSProject.PotTypes.PG_DT_DW_periodic:
                                PG_rs_DT_DW_periodic(a, b, gam, E, atrad, N, M, NAtoms, _x, _y, _dw, _ads, _occ, _type, data, &progress);
                                break;

                            case MSProject.PotTypes.PG_DT_DW_cut:
                                PG_rs_DT_DW_cutpot(a, b, gam, E, atrad, N, M, NAtoms, _x, _y, _dw, _ads, _occ, _type, data, &progress);
                                break;

                            case MSProject.PotTypes.PG_curve_DW_periodic:
                                PG_rs_curve_DW_periodic(a, b, gam, E, atrad, N, M, NAtoms, _x, _y, _ads, _occ, _type_, CurveHolder, CurveLength, dela, data, &progress);
                                break;

                            case MSProject.PotTypes.PG_curve_DW_cut:
                                PG_rs_curve_DW_cutpot(a, b, gam, E, atrad, N, M, NAtoms, _x, _y, _ads, _occ, _type_, CurveHolder, CurveLength, dela, data, &progress);
                                break;

                            case MSProject.PotTypes.PG_DT_TV_periodic:
                                PG_rs_DT_TV_periodic(a, b, gam, E, atrad, N, M, NAtoms, _x, _y, _ads, _occ, _type, data, &progress);
                                break;

                            case MSProject.PotTypes.PG_DT_TV_cut:
                                PG_rs_DT_TV_cutpot(a, b, gam, E, atrad, N, M, NAtoms, _x, _y, _ads, _occ, _type, data, &progress);
                                break;

                            case MSProject.PotTypes.PG_curve_TV_periodic:
                                PG_rs_curve_TV_periodic(a, b, gam, E, atrad, N, M, NAtoms, _x, _y, _ads, _occ, _type_, CurveHolder, CurveLength, dela, data, &progress);
                                break;

                            case MSProject.PotTypes.PG_curve_TV_cut:
                                PG_rs_curve_TV_cutpot(a, b, gam, E, atrad, N, M, NAtoms, _x, _y, _ads, _occ, _type_, CurveHolder, CurveLength, dela, data, &progress);
                                break;

                            case MSProject.PotTypes.PG_curve_DW_pullZ:
                                PG_rs_pullZ();
                                break;

                            case MSProject.PotTypes.PG_curve_TV_pullZ:
                                PG_rs_pullZ();
                                break;

                            default:
                                Console.WriteLine("Phase Gratting " + PotType.ToString() + " is not supported in " + this.ToString());
                                break;
                            }
                        }
                    }
                }

                //Apply Propagator
                SFT_direct.MakeSFT(data);
                ApplyPropagator(a, b, gam, CurSliThickness, E, X_tilt_crystal, Y_tilt_crystal, N, M, data, &progress);
                CurThickness += CurSliThickness;
                if ((double)ThWaves[iWave] <= CurThickness)
                {
                    if (IsSaveSTEM)
                    {
                        SaveSTEM(iWave);
                    }

                    if (IsSaveDiffractions)
                    {
                        Console.WriteLine("\rDiffraction at " + CurThickness.ToString("######0.00") + "A unloaded " + (SaveDiffraction(CurThickness) != null) + "                                   ");
                    }
                }
                SFT_backward.MakeSFT(data);
                period = DateTime.Now - start;
                if (!IsSaveSTEM)
                {
                    Console.Write("\rPropagated " + NAtoms + " atoms, at total " + CurThickness.ToString("######0.00") + "A at a speed of " + ((double)((CurThickness - StartThickness) * TimeSpan.TicksPerSecond / period.Ticks * 3600)).ToString("###0.0") + "A/h     ");
                }
                if ((double)ThWaves[iWave] <= CurThickness)
                {
                    iWave++;
                    if (IsSaveWaves)
                    {
                        Console.WriteLine("\rWave at " + CurThickness.ToString("######0.00") + "A unloaded " + ((LastSavedWave = SaveWav(CurThickness)) != null) + "                                   ");
                    }
                }
            }             // calculation cycle
            return(true);
        }
Exemple #7
0
        override public void StartCalculations()
        {
            DateTime start;
            string   ostr;
            int      iSTEMline, iSTEMpoint;
            TimeSpan period;

            start = DateTime.Now;
            Console.WriteLine("\n****************** MS with reused potentials started ********************");

            // Создание планов FFT
            Console.WriteLine("\nCreating FFT plans for " + N + "*" + M + " transformations");
            SFT_backward.MakePlan(data, N, M, -1);
            SFT_direct.MakePlan(data, N, M, 1);

            Calc.a                  = a;
            Calc.b                  = b;
            Calc.gam                = gam;
            Calc.N                  = N;
            Calc.M                  = M;
            Calc.E                  = E;
            Calc.data               = data;
            Calc.NSlices            = NSlices;
            Calc.ThSlices           = ThSlices;
            Calc.IsSaveWaves        = IsSaveWaves;
            Calc.IsSaveDiffractions = IsSaveDiffractions;
            Calc.IsSaveSTEM         = (IniWaveType == MSProject.IniWaveTypes.STEMshift);
            Calc.SFT_direct         = SFT_direct;
            Calc.SFT_backward       = SFT_backward;

            Console.WriteLine("\nInitial wave is " + IniWaveType.ToString());

//			int iE, iBT, iBS, iCA, iDf, iCs, iCT ; // moved to MyProject class definition
            for (iE = 0; iE < Emat.Length; iE++)
            {
                Calc.E = E = Emat[iE];
                // Расчет и сохранение слоев
                if (!GeneratePG())
                {
                    Console.WriteLine("Can't create slices, exiting");
                    return;
                }
                for (iCT = 0; iCT < Math.Max(CrystalTilt.Length, 1); iCT++)
                {
                    try
                    {
                        X_tilt_crystal = CrystalTilt[iCT][0] / 1000.0;
                        Y_tilt_crystal = CrystalTilt[iCT][1] / 1000.0;
                    }
                    catch
                    {
                        Y_tilt_crystal = 0.0;
                    }

                    // создание пропагаторов
                    GenerateProps();
                    Calc.SliList  = SliList;
                    Calc.PropList = PropList;


                    for (iBT = 0; iBT < Math.Max(BeamTilt.Length, 1); iBT++)
                    {
                        X_beamtilt = Y_beamtilt = 0;
                        if ((IniWaveType == MSProject.IniWaveTypes.Converged) || (IniWaveType == MSProject.IniWaveTypes.STEMshift))
                        {
                            try
                            {
                                X_beamtilt = BeamTilt[iBT][0] / 1000.0;
                                Y_beamtilt = BeamTilt[iBT][1] / 1000.0;
                            }
                            catch
                            {
                            }
                        }
                        if (IniWaveType == MSProject.IniWaveTypes.PlaneWave)
                        {
                            try
                            {
                                X_beamtilt = BeamTilt[iBT][0];
                                Y_beamtilt = BeamTilt[iBT][1];
                            }
                            catch
                            {
                            }
                        }
                        for (iBS = 0; iBS < (((IniWaveType == MSProject.IniWaveTypes.Converged) || (IniWaveType == MSProject.IniWaveTypes.STEMshift))?Math.Max(BeamShift.Length, 1):1); iBS++)
                        {
                            if ((IniWaveType == MSProject.IniWaveTypes.Converged) || (IniWaveType == MSProject.IniWaveTypes.STEMshift))
                            {
                                try
                                {
                                    X_beamshift = BeamShift[iBS][0];
                                    Y_beamshift = BeamShift[iBS][1];
                                }
                                catch
                                {
                                    X_beamshift = Y_beamshift = 0.5;
                                }
                            }
                            for (iCA = 0; iCA < (((IniWaveType == MSProject.IniWaveTypes.Converged) || (IniWaveType == MSProject.IniWaveTypes.STEMshift))?Math.Max(ConvAngles.Length, 1):1); iCA++)
                            {
                                if ((IniWaveType == MSProject.IniWaveTypes.Converged) || (IniWaveType == MSProject.IniWaveTypes.STEMshift))
                                {
                                    try
                                    {
                                        ConvAngle      = ConvAngles[iCA][0];
                                        ConvAngleInner = ConvAngles[iCA][1];
                                    }
                                    catch
                                    {
                                        ConvAngle      = 0.3;
                                        ConvAngleInner = 0;
                                    }
                                }
                                for (iCs = 0; iCs < (((IniWaveType == MSProject.IniWaveTypes.Converged) || (IniWaveType == MSProject.IniWaveTypes.STEMshift))?Math.Max(Csmat.Length, 1):1); iCs++)
                                {
                                    if ((IniWaveType == MSProject.IniWaveTypes.Converged) || (IniWaveType == MSProject.IniWaveTypes.STEMshift))
                                    {
                                        try
                                        {
                                            Cs = Csmat[iCs];
                                        }
                                        catch
                                        {
                                            Cs = 0;
                                        }
                                    }
                                    for (iDf = 0; iDf < (((IniWaveType == MSProject.IniWaveTypes.Converged) || (IniWaveType == MSProject.IniWaveTypes.STEMshift))?Math.Max(Dfmat.Length, 1):1); iDf++)
                                    {
                                        if ((IniWaveType == MSProject.IniWaveTypes.Converged) || (IniWaveType == MSProject.IniWaveTypes.STEMshift))
                                        {
                                            try
                                            {
                                                Df = Dfmat[iDf];
                                            }
                                            catch
                                            {
                                                Df = 0;
                                            }
                                        }


                                        if ((IniWaveType == MSProject.IniWaveTypes.STEMshift))
                                        {
                                            iSTEMline  = (int)Math.Floor((double)iBS / STEM_N);
                                            iSTEMpoint = iBS % STEM_N;
                                            if ((iSTEMpoint == 0) && (iCA == 0) && (iCs == 0) && (iDf == 0) && (iCT == 0))
                                            {
                                                ostr = "\nLine " + iSTEMline + " (" + STEM_M + ")\n#";
                                            }
                                            else
                                            {
                                                ostr = "#";
                                            }
                                        }
                                        else
                                        {
                                            ostr  = "\n*** " + (E / 1000.0).ToString("###0.0") + "kV";
                                            ostr += ", CT(" + X_tilt_crystal.ToString("0.0###") + "," + Y_tilt_crystal.ToString("0.0###") + ")";
                                            ostr += ", BT(" + X_beamtilt.ToString("0.0###") + "," + Y_beamtilt.ToString("0.0###") + ")";
                                            ostr += "\n*** BS(" + X_beamshift.ToString("0.0###") + "," + Y_beamshift.ToString("0.0###") + ")";
                                            ostr += ", CA(" + ConvAngle.ToString("0.0###") + "," + ConvAngleInner.ToString("0.0###") + ")";
                                            ostr += ", Df" + Df.ToString("###0.0") + "A";
                                            ostr += ", Cs" + (Cs / 1e7).ToString("###0.0") + "mm\n";
                                        }
                                        Console.Write(ostr);

                                        // Создание начальной волны
                                        if (!CreateInitialWave())
                                        {
                                            Console.WriteLine("Can't create initial wave, exiting");
                                            return;
                                        }
                                        Calc.CurThickness = StartThickness;
                                        if (IsCalcAll)
                                        {
                                            this.ThWaves = new double[] { c + StartThickness - 0.00001 }
                                        }
                                        ;
                                        Calc.ThWaves = ThWaves;

                                        // Начало мултислайса

                                        Calc.RunCalculation();
                                    } // Df cycle
                                }     // Cs cycle
                            }         // Convergence angle cycle
                        }             // beam shift cycle
                    }                 // beam tilt cycle
                }                     // crystal tilt cycle
            }                         // E cycle


            if (IsContinue)
            {
                System.IO.File.Copy(Calc.LastSavedWave,
                                    Path.Combine(this.WorkingDirectoryName, "last.wav"), true);
            }
            if (IniWaveType == IniWaveTypes.STEMshift)
            {
                FlushSTEMfile();
            }

            period = DateTime.Now - start;
            Console.WriteLine("\n****** MS finished, total time " + period.ToString() + " ********************");
        }

        bool GeneratePG()
        {
            int    i, j, k;
            MemMan iM;
            uint   NMMs;
            float  progress;

            int[] PropSliTable = new int[NSlices];
            Props    = new ArrayList();
            SliList  = new double *[NSlices];
            PropList = new double *[NSlices];
            for (i = 0; i < NSlices; i++)
            {
                for (j = 0; j < Props.Count; j++)
                {
                    if (Math.Abs((double)Props[j] - (double)ThSlices[i]) < 0.000001)
                    {
                        break;
                    }
                }
                if (j == Props.Count)
                {
                    j = Props.Add(ThSlices[i]);
                }
                PropSliTable[i] = j;
            }

            PropsP = new double *[Props.Count];

            MMList = new ArrayList((int)(NSlices + Props.Count));
            for (i = 0; i < NSlices + Props.Count; i++)
            {
                iM = new MemMan();
                if (iM.Allocate(MemRequested()))
                {
                    MMList.Add(iM);
                }
                else
                {
                    break;
                }
            }
            NMMs = (uint)MMList.Count;
            if (NMMs < NSlices + Props.Count)
            {
                Console.WriteLine("Can't allocate all data in memory, only " + NMMs + " pages are available, " + (NSlices + Props.Count) + " requested,\nuse inline calculation");
                return(false);
            }
            for (i = 0; i < NSlices; i++)
            {
                Console.WriteLine("Creating slice number " + i.ToString("0000") + " from " + (uint)NASlices[i] + " atoms using " + PotType.ToString());
                //((MemMan)MMList[i]).Lock(0,MemRequested()) ;
                SliList[i] = (double *)((MemMan)MMList[i]).BaseAddress;
                if ((uint)NASlices[i] > 0)
                {
                    ExtractSlice(i);
                    fixed(double *_x = x, _y = y, _dw = DW, _ads = ads, _occ = occ)
                    {
                        fixed(int *_type_ = type_, _type = type)
                        {
                            switch (PotType)
                            {
                            case PotTypes.rs_DT_DW_periodic:
                                Potential_rs_DT_DW_periodic(a, b, gam, atrad, N, M, (uint)NASlices[i], _x, _y, _dw, _ads, _occ, _type, SliList[i], &progress);
                                break;

                            case PotTypes.rs_DT_DW_cut:
                                Potential_rs_DT_DW_cutpot(a, b, gam, atrad, N, M, (uint)NASlices[i], _x, _y, _dw, _ads, _occ, _type, SliList[i], &progress);
                                break;

                            case PotTypes.rs_curve_DW_periodic:
                                Potential_rs_curve_DW_periodic(a, b, gam, atrad, N, M, (uint)NASlices[i], _x, _y, _ads, _occ, _type_, (double *)PotCurve.BaseAddress, CurveLength, dela, SliList[i], &progress);
                                break;

                            case PotTypes.rs_curve_DW_cut:
                                Potential_rs_curve_DW_cutpot(a, b, gam, atrad, N, M, (uint)NASlices[i], _x, _y, _ads, _occ, _type_, (double *)PotCurve.BaseAddress, CurveLength, dela, SliList[i], &progress);
                                break;

                            case PotTypes.rec_DT_DW:
                                Potential_rec_DT_DW(a, b, gam, Nmult, Mmult, N, M, (uint)NASlices[i], 0, M, _x, _y, _dw, _ads, _occ, _type, SliList[i], &progress);
                                SFT_backward.MakeSFT(SliList[i]);
                                break;

                            case PotTypes.rec_curve_DW:
                                Potential_rec_curve_DW(a, b, gam, Nmult, Mmult, N, M, (uint)NASlices[i], 0, M, _x, _y, _ads, _occ, _type_, (double *)PotCurve.BaseAddress, CurveLength, ds, SliList[i], &progress);
                                SFT_backward.MakeSFT(SliList[i]);
                                break;

                            default:
                                Console.WriteLine("Potential " + PotType.ToString() + " is not supported");
                                return(false);
                            }
                        }
                    }
                }
                if (IsSaveSlices)
                {
                    SaveSlice(i);
                }
            }
            if (IsPotRec)
            {
                a *= Nmult; b *= Mmult;
            }

            //Создание PG из слайсов
            double lambda = 0.387818 / Math.Sqrt(E / 1000.0 * (1.0 + 0.978459e-3 * E / 1000)); // E in V
            double K      = lambda * Math.Sqrt(1.0 + Math.Pow((0.0242621 / lambda), 2));

            if (IsPotRec)
            {
                K *= (N * M);
            }
            for (i = 0; i < NSlices; i++)
            {
                double *pbuf = SliList[i];
                double  aR, aI;
                for (j = 0; j < M; j++)
                {
                    for (k = 0; k < N; k++)
                    {
                        aR = K * *pbuf;
                        aI = Math.Exp(-*(pbuf + 1) * K);
                        *pbuf = Math.Cos(aR) * aI;
                        *(++pbuf) = -Math.Sin(aR) * aI;
                        pbuf++;
                    }
                }                 // y-cycle
            }

            Atoms = null;            // free a memory occupied by the model
            GC.Collect();

            for (i = 0; i < Props.Count; i++)
            {
                PropsP[i] = (double *)((MemMan)MMList[(int)(i + NSlices)]).BaseAddress;
            }
            for (i = 0; i < NSlices; i++)
            {
                PropList[i] = PropsP[PropSliTable[i]];
            }

            return(true);
        }

        bool GenerateProps()
        {
            int   i;
            float progress;

            for (i = 0; i < Props.Count; i++)
            {
                Console.WriteLine("Creating propagator for " + ((double)Props[i]).ToString("##0.000000") + " A");
                CreatePropagator(a, b, gam, (double)Props[i], E, X_tilt_crystal, Y_tilt_crystal, N, M, PropsP[i], &progress);
            }
            return(true);
        }

        void ExtractSlice(int i)
        {
            uint nas = (uint)NASlices[i];

            x     = new double[(int)nas];
            y     = new double[(int)nas];
            DW    = new double[(int)nas];
            ads   = new double[(int)nas];
            occ   = new double[(int)nas];
            type  = new int[(int)nas];
            type_ = new int[(int)nas];
            int j = 0;

            foreach (AtomRec at in Atoms)
            {
                if (at.sn == i)
                {
                    x[j]     = at.x;
                    y[j]     = at.y;
                    DW[j]    = at.DW;
                    ads[j]   = at.ads;
                    occ[j]   = at.occ;
                    type[j]  = at.type;
                    type_[j] = at.type_;
                    j++;
                }
            }
        }

        /// <summary>
        /// Saves slices in real space
        /// </summary>
        /// <returns></returns>
        bool SaveSlice(int iSlice)         // save slices in real space
        {
            // a*Nmult, b*Mmult
            FileRW fN;
            string lwd, SavedFilename;

            lwd = Path.Combine(WorkingDirectoryName, "Slice stack");
            if (!Directory.Exists(lwd))
            {
                try
                {
                    Directory.CreateDirectory(lwd);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Can't create working directory:\n" + e.ToString());
                    return(false);
                }
            }
            SavedFilename = Path.Combine(lwd, "Slice_" + iSlice.ToString("0000") + ".slice");
            if ((fN = FileRW.Open(SavedFilename, FileRW.Action.CreateAlways, FileRW.Access.Write)) != null)
            {
                byte[] sout = new byte[160];
                string Sout;
                uint   nw;
                nw = fN.Write(SliList[iSlice], N * M * (uint)2);
                if (nw != N * M * (uint)2 * sizeof(double))
                {                 // add code to find and display the reason
                    Console.WriteLine("Only " + nw + " bytes out of " + N * M * (uint)2 * sizeof(double) + " are written to\n" + SavedFilename);
                    fN.Close();
                    SavedFilename = null;
                    return(false);
                }
                Sout = String.Format("___ {0,12:g10} {1,12:g10} {2,12:g10} {3,10:g5} {4,10:g5} {5,10:g8} {6,10:g} {7,00000} {8,00000} {9,10:g} {10,5:n0} ",
                                     a * Nmult, b * Mmult, ThSlices[iSlice], Math.PI / 2.0, Math.PI / 2.0, gam, -1.0, N, M, iSlice, NSlices);
                for (int i = 0; i < 160; i++)
                {
                    sout[i] = (i < Sout.Length)?System.Convert.ToByte(Sout[i]):(byte)0;
                }
                fN.Write(sout, 160);
                fN.Close();
                return(true);
            }
            else
            {
                SavedFilename = null;
                return(false);
            }
        }
    }