Пример #1
0
        public static bool SOLUTION(int NI, int NJ, int NK)
        {
            //Check for numerical problems using overall massdivergence
            if (Program.MASSOURCE[Program.IDIV] > 1000) // 13.4.2017 Ku Check if Divergence increased to a very high value
            {
                Program.Divergence_Min = Math.Min(Program.Divergence_Min, Program.MASSOURCE[Program.IDIV]);
            }

            if ((Program.MASSOURCE[Program.IDIV] * 0.001 >= 500000) || (Program.MASSOURCE[Program.IDIV] > Program.Divergence_Min * 50))
            {
                if (Program.computation_retry >= 3) // try 4 times
                {
                    try
                    {
                        string err = "Numerical instabilities detected for flow field: " + Program.IWETTER.ToString();
                        ProgramWriters.LogfileProblemreportWrite(err);
                    }
                    catch { }

                    Program.REALTIME = Program.TLIMIT; // exit this situation
                }
                for (int i = 0; i < 11; i++)
                {
                    Program.MASSOURCE[i] = 0;
                }
                return(false); // error
            }

            //Calculation of several terms for the implicit scheme according to Patankar, 1980
            //Note that the wind speeds and the non-hydrostatic pressure are calculated using half-cells,
            //while pot. temperature, humidity, turbulent-kinetic energy and dissipation are modelled based on the full-cell
            if (Program.REALTIME < Program.DTI)
            {
                TERMIVterms(NI, NJ, NK);

                TERMIPSterms(NI, NJ, NK);

                TERMIPterms(NI, NJ, NK);

                //Prandtl-layer quantities
                if (Program.ICPR)
                {
                    Prandtl_calculate(NI, NJ, NK);
                }

                //Soil temperature (as the last 5 cells near the borders are not calculated, the routine just makes sense if model domains have more than 10 grid cells in the horizontal directions
                if ((NI > 10) && (NJ > 10) && (Program.ICTB))
                {
                    Calctb_calculate(NI, NJ, NK);
                }

                //Solve momentum equations
                if (Program.pOptions.MaxDegreeOfParallelism > 3) // more cores - divide the work -> try to avoid false sharing
                {
                    //                  int cores = Program.pOptions.MaxDegreeOfParallelism;
                    //                  Program.pOptions.MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling(cores / 3.0f));

                    Parallel.Invoke(Program.pOptions,
                                    () => UIMPcalculate(NI, NJ, NK),
                                    () => VIMPcalculate(NI, NJ, NK),
                                    () => WVELcalculate(NI, NJ, NK));

                    //                  Program.pOptions.MaxDegreeOfParallelism = cores; // reset core-count
                }
                else
                {
                    UIMPcalculate(NI, NJ, NK);
                    VIMPcalculate(NI, NJ, NK);
                    WVELcalculate(NI, NJ, NK);
                }

                //Boundary conditions
                Bords_calculate(NI, NJ, NK);

                //Solve the non-hydrostatic pressure equation
                if (Program.ICPN == true)
                {
                    CALCPR_calculate(NI, NJ, NK);
                }

                //save initial mass-divergence to check for numerical instabilities at the end of the simulation
                if (Program.REALTIME <= (1.5 * Program.DT))
                {
                    Program.MASSOURCE_FIRST = Program.SUMG;
                }


                if (Program.ICT == true && Program.ICQU == true)
                {
                    Parallel.Invoke(Program.pOptions,
                                    () => Timp_calculate(NI, NJ, NK),
                                    () => Fimp_calculate(NI, NJ, NK));
                    //computation of water vapour content
                    if (Program.ICQU == true && Program.ISTAT != 0)
                    {
                        WatVap_calculate(NI, NJ, NK);
                    }
                }
                else
                {
                    //computation of pot. temperature
                    if (Program.ICT == true)
                    {
                        Timp_calculate(NI, NJ, NK);
                    }
                    //computation of humidity
                    if (Program.ICQU == true)
                    {
                        Fimp_calculate(NI, NJ, NK);
                    }
                    //computation of water vapour content
                    if (Program.ICQU == true && Program.ISTAT != 0)
                    {
                        WatVap_calculate(NI, NJ, NK);
                    }
                }

                //computation of thermal pressure
                //if (Program.ICPSI == true) THERMPRESScalculate(NI, NJ, NK);

                //computation of turbulent kinetic energy and dissipation rate
                if (Program.ICTE == true)
                {
                    Parallel.Invoke(Program.pOptions,
                                    () => Tkeimp_calculate(NI, NJ, NK),
                                    () => Epsimp_calculate(NI, NJ, NK));
                }

                //time-step adjustion
                if (Program.ISTAT == 0)
                {
                    Program.IDIV_LockDown2--;
                    if (Program.IDIV_LockDown > 0) // 5.4.2017 Ku avoid increase of time step after a decrease
                    {
                        Program.IDIV_LockDown--;
                    }
                    else
                    {
                        Program.STEIGUNG = Math.Round(Program.STEIGUNG, 2);
                        if ((Program.IDIV == 10) && (Program.STEIGUNG <= 0))
                        {
                            if (REALTIME <= DTI * 0.75)                                             // do not adjust time step if steady state criterion is measured
                            {
                                Program.DT             = Math.Min(Program.DT + 0.5, Program.DTMAX); //3.4.2017 Ku
                                Program.IDIV_LockUp    = 0;
                                Program.IDIV_LockDown2 = 40;
                            }
                        }
                    }

                    //5.4.2017 Ku
                    if (((Program.MASSOURCE_Old * 1.01 < Program.MASSOURCE_Act) || ((Program.MASSOURCE_Old + 500) < Program.MASSOURCE_Act)) && IDIV_LockUp <= 3 && IDIV_LockDown == 0 && IDIV_LockDown2 < 0)
                    {
                        Program.DT             = Math.Max(Program.DT * 0.80, 1.5); //5.4.2017 Ku
                        RELAXV                 = Math.Max(RELAXV * 0.80, 0.05);
                        RELAXT                 = Math.Max(RELAXT * 0.80, 0.05);
                        Program.IDIV_LockDown  = 11;
                        Program.IDIV_LockDown2 = 20;
                        Program.IDIV_LockUp++;
                        Program.IDIV_PingPong++;

                        if (Program.IDIV_PingPong > 6 * Math.Pow(Program.Relaxv_ori / Program.RELAXV, 2) && Program.IDIV_LockRelax < 6)
                        {                                                  // Set relax factors down and increase lockDown value if downsteps occur periodically
                            Program.DT = Math.Max(Program.DT * 0.80, 1.5); //5.4.2017 Ku
                            RELAXV     = Math.Max(RELAXV * 0.80, 0.05);
                            RELAXT     = Math.Max(RELAXT * 0.80, 0.05);
                            Program.IDIV_LockRelax++;
                            Program.IDIV_PingPong = 0;
                            Program.IDIV_LockDown = 20;
                        }
                        else if (IDIV_LockUp > 2 && IDIV_LockRelax < 6)
                        {
                            RELAXV = Math.Max(RELAXV * 0.80, 0.05);
                            RELAXT = Math.Max(RELAXT * 0.80, 0.05);
                            Program.IDIV_LockRelax++;
                        }
                    }
                }
                //5.4.2017 Ku


                //2.9.2019 Öt
                //dynamic time step and relaxation factor adjustments for GRAMM full transient simulations
                if (Program.ISTAT != 0)
                {
                    //Console.WriteLine(Program.IDIV.ToString() + "," + Program.MASSOURCE[Program.IDIV].ToString() + "," + Program.MASSOURCE[1].ToString() + "," + Program.MASSOURCE_FIRST.ToString());

                    /*
                     * if ((Program.IDIV == 5) && (Program.MASSOURCE[Program.IDIV] > Program.MASSOURCE[1]) && (Program.MASSOURCE_FIRST < Program.MASSOURCE[Program.IDIV]))
                     * {
                     *  Program.DT = Math.Max(Program.DT * 0.70, 1.5); //5.4.2017 Ku
                     *  RELAXV = Math.Max(RELAXV * 0.70, 0.05);
                     *  RELAXT = Math.Max(RELAXT * 0.70, 0.05);
                     *  Program.IDIV = 0;
                     * }
                     * else if ((Program.IDIV == 5) && (Program.MASSOURCE[Program.IDIV] <= Program.MASSOURCE[1]))
                     * {
                     *
                     *  Program.DT = Math.Min(Program.DT + 0.5, Program.DTMAX);
                     *  RELAXV = Math.Min(RELAXV * 1.01, 0.15);
                     *  RELAXT = Math.Min(RELAXT * 1.01, 0.15);
                     *  Program.IDIV = 0;
                     * }
                     */
                    Program.DT = Program.DTMAX;
                }
                //2.9.2019 Öt



                Program.TerminalOut++;
                if (Program.TerminalOut >= TerminalThreshold) // if Counter is even
                {
                    writeProbes();

                    //output to screen
                    string LOGT = "-";
                    string LOGH = "-";
                    string LOGU = "-";
                    string LOGV = "-";
                    string LOGW = "-";
                    if (Program.ICT)
                    {
                        LOGT = "+";
                    }
                    if (Program.ICQU)
                    {
                        LOGH = "+";
                    }
                    if (Program.ICU)
                    {
                        LOGU = "+";
                    }
                    if (Program.ICV)
                    {
                        LOGV = "+";
                    }
                    if (Program.ICW)
                    {
                        LOGW = "+";
                    }
                    Console.WriteLine("-------------------------------------------------------------------------------------");
                    Console.WriteLine("WEATHER-SIT. TIME[s]  TIMESTEP[s]  ENDTIME[s]  PRESS-ITERATIONS  DIVERGENCE U V W T H");
                    Console.WriteLine(Program.IWETTER.ToString().PadLeft(10) + "/" + (1 + computation_retry).ToString().PadLeft(1) + " " + Program.REALTIME.ToString("0.0").PadLeft(7) + "  " +
                                      Program.DT.ToString("0.0").PadLeft(11) + "  " + Program.DTI.ToString("0").PadLeft(10) + "               " +
                                      (Program.INUMS - 1).ToString("0").PadLeft(3) + "  " + (Program.SUMG * 0.001).ToString("0.000").PadLeft(10) + " " +
                                      LOGU + " " + LOGV + " " + LOGW + " " + LOGT + " " + LOGH);
                }
            }

            return(true); // computation OK
        }
Пример #2
0
        public static void OUTPUT(int NI, int NJ, int NK, bool intermediate)
        {
            // force a garbage collection on the Large Object heap to clean up the envrionment
            //GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
            GC.Collect();

            //Check for quasi-steady-state requirement (VDI 3783-7) -> the lateral region where topography is smoothed is not considered
            if (Program.REALTIME > 0.8 * Program.DTI)
            {
                StreamWriter writesteadystate = null; // create streamwriter-container


                if (Program.WriteSteadyState) // write data for steady state criterion to a file
                {
                    string filename = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + "_steady_state.txt");
                    try
                    {
                        writesteadystate = new StreamWriter(filename);
                        writesteadystate.WriteLine("ncols         " + Convert.ToString(NI - 2 * Program.nr_cell_smooth));
                        writesteadystate.WriteLine("nrows         " + Convert.ToString(NJ - 2 * Program.nr_cell_smooth));
                        writesteadystate.WriteLine("xllcorner     " + Convert.ToString(Program.IKOOA + Program.nr_cell_smooth * Program.DDX[1])); // TODO: Fix for horizontal mesh grading
                        writesteadystate.WriteLine("yllcorner     " + Convert.ToString(Program.JKOOA + Program.nr_cell_smooth * Program.DDX[1])); // TODO: Fix for horizontal mesh grading
                        writesteadystate.WriteLine("cellsize      " + Convert.ToString(Program.DDX[1]));
                        writesteadystate.WriteLine("NODATA_value  " + "-9999");
                    }
                    catch { }
                }

                double UTREFFER = 0;
                double VTREFFER = 0;
                double WTREFFER = 0;
                for (int j = NJ - Program.nr_cell_smooth; j >= 1 + Program.nr_cell_smooth; j--)
                {
                    string steadystateline = "";
                    for (int i = 1 + Program.nr_cell_smooth; i <= NI - Program.nr_cell_smooth; i++)
                    {
                        Byte steadystatevalue = 0;
                        if ((Math.Abs(Program.U_TEMP[i][j] - Program.U[i][j][1]) <= 0.35) || (Math.Abs((Program.U_TEMP[i][j] - Program.U[i][j][1]) / (Math.Max(Math.Abs(Program.U[i][j][1]), 0.001))) <= 0.1))
                        {
                            UTREFFER++;
                            steadystatevalue = 1;
                        }
                        if ((Math.Abs(Program.V_TEMP[i][j] - Program.V[i][j][1]) <= 0.35) || (Math.Abs((Program.V_TEMP[i][j] - Program.V[i][j][1]) / (Math.Max(Math.Abs(Program.V[i][j][1]), 0.001))) <= 0.1))
                        {
                            VTREFFER++;
                            steadystatevalue += 2;
                        }
                        if ((Math.Abs(Program.W_TEMP[i][j] - Program.W[i][j][1]) <= 0.35) || (Math.Abs((Program.W_TEMP[i][j] - Program.W[i][j][1]) / (Math.Max(Math.Abs(Program.W[i][j][1]), 0.001))) <= 0.1))
                        {
                            WTREFFER++;
                            steadystatevalue += 4;
                        }

                        if (writesteadystate != null)                                               // write file!
                        {
                            if (j == 1 + Program.nr_cell_smooth && i == 1 + Program.nr_cell_smooth) // Avoid blank raster data set for GUI
                            {
                                steadystateline += Convert.ToString((double)steadystatevalue + 0.01).Replace(Program.decsep, ".") + " ";
                            }
                            else
                            {
                                steadystateline += Convert.ToString(steadystatevalue) + " ";
                            }
                        }
                    }

                    if (writesteadystate != null)
                    {
                        writesteadystate.WriteLine(steadystateline);
                    }
                }

                if (writesteadystate != null)
                {
                    try
                    {
                        writesteadystate.Close();
                        writesteadystate.Dispose();
                    }
                    catch { }
                }



                UTREFFER /= ((NI - 2 * Program.nr_cell_smooth) * (NJ - 2 * Program.nr_cell_smooth));
                VTREFFER /= ((NI - 2 * Program.nr_cell_smooth) * (NJ - 2 * Program.nr_cell_smooth));
                WTREFFER /= ((NI - 2 * Program.nr_cell_smooth) * (NJ - 2 * Program.nr_cell_smooth));
            }

            //Check for possible numerical instabilities
            if (Program.MASSOURCE_FIRST < Program.SUMG)
            {
                //compute maximum wind speeds
                float UMAX = 0;
                float VMAX = 0;
                float WMAX = 0;
                for (int i = 2; i <= NI - 1; i++)
                {
                    for (int j = 2; j <= NJ - 1; j++)
                    {
                        for (int k = 1; k <= NK - 1; k++)
                        {
                            UMAX = (float)Math.Max(Math.Abs(Program.U[i][j][k]), UMAX);
                            VMAX = (float)Math.Max(Math.Abs(Program.V[i][j][k]), VMAX);
                            WMAX = (float)Math.Max(Math.Abs(Program.W[i][j][k]), WMAX);
                        }
                    }
                }

                try
                {
                    if ((UMAX > 50) || (VMAX > 50) || (WMAX > 20))
                    {
                        try
                        {
                            string err = "Final mass divergence is larger than initial mass divergence." + "  Possible numerical instabilities detected for flow field: " +
                                         Program.IWETTER.ToString();
                            ProgramWriters.LogfileProblemreportWrite(err);
                            err = "Maximum wind speeds in east/west/vertical direction: " + UMAX.ToString("0000.0") + ";" + VMAX.ToString("0000.0") + ";" + WMAX.ToString("0000.0");
                            ProgramWriters.LogfileProblemreportWrite(err);
                        }
                        catch { }
                    }
                }
                catch { }
            }

            //differentiating between intermediate output and final output in case of meteopgt.all input
            string wndfilename;
            string wndExtrafilename;

            if (intermediate == false)
            {
                wndfilename      = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".wnd");
                wndExtrafilename = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".ewnd");
            }
            else
            {
                wndfilename      = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".wnd");
                wndExtrafilename = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".ewnd");
                //intermediate output in case of meteopgt.all
                if (((METEO == "Y") || (METEO == "y")) && (Program.ISTAT == 0))
                {
                    //compute fictious weather number
                    int    FILENUMBER = 0;
                    double time_real  = Program.REALTIME;
                    if (time_real < Program.IOUTPUT) // 1st situation should be stored after 1800 s
                    {
                        time_real = Program.IOUTPUT + 2;
                    }
                    Meteopgtall.meteopgtall_calculate(Program.meteopgt_nr, Program.IWETTER, Program.DTI, time_real, Program.IOUTPUT, Program.TLIMIT2, ref FILENUMBER);
                    wndfilename      = (Convert.ToString(FILENUMBER).PadLeft(5, '0') + ".wnd");
                    wndExtrafilename = (Convert.ToString(FILENUMBER).PadLeft(5, '0') + ".ewnd");
                }
            }

            Console.Write(wndfilename + "  "); // write windfile name to the console

            bool writeExtra = true;

            BinaryWriter writer = new BinaryWriter(File.Open(wndfilename, FileMode.Create));
            int          header = -1;
            Int16        dummy;
            Int32        dummy2;
            float        GRAMMhorgridsize = (float)Program.DDX[1];

            // TODO: Not possible with horizontal mesh grading
            if (writeExtra)
            {
                Console.Write(wndExtrafilename + "  "); // write windfile name to the console
                BinaryWriter ewriter = new BinaryWriter(File.Open(wndExtrafilename, FileMode.Create));
                ewriter.Write(header);
                ewriter.Write(NI);
                ewriter.Write(NJ);
                ewriter.Write(NK);
                ewriter.Write(GRAMMhorgridsize);
                for (int i = 1; i <= NI; i++)
                {
                    for (int j = 1; j <= NJ; j++)
                    {
                        for (int k = 1; k <= NK; k++)
                        {
                            try
                            {
                                dummy = Convert.ToInt16(Program.TE[i][j][k] * 10000.0);
                            }
                            catch
                            {
                                dummy = Int16.MaxValue;
                            }
                            ewriter.Write(dummy);

                            try
                            {
                                dummy = Convert.ToInt16(Program.DISS[i][j][k] * 1000000.0);
                            }
                            catch
                            {
                                dummy = Int16.MaxValue;
                            }
                            ewriter.Write(dummy);
                            try
                            {
                                dummy = Convert.ToInt16(Program.DP[i][j][k] * 100.0);
                            }
                            catch
                            {
                                dummy = Int16.MaxValue;
                            }
                            ewriter.Write(dummy);
                            try
                            {
                                dummy = Convert.ToInt16((Program.TABS[i][j][k] - 273.15) * 100.0);
                            }
                            catch
                            {
                                dummy = Int16.MaxValue;
                            }
                            ewriter.Write(dummy);
                        }
                    }
                }
                ewriter.Close();
                ewriter.Dispose();
            }

            //there are two different formats: IOUTPUT = 0 (standard output for GRAL-GUI users) and IOUTPUT = 3 for SOUNDPLAN USERS
            if (Program.IOUT == 0)
            {
                writer.Write(header);
                writer.Write(NI);
                writer.Write(NJ);
                writer.Write(NK);
                writer.Write(GRAMMhorgridsize);
                for (int i = 1; i <= NI; i++)
                {
                    for (int j = 1; j <= NJ; j++)
                    {
                        for (int k = 1; k <= NK; k++)
                        {
                            try
                            {
                                dummy = Convert.ToInt16(Program.U[i][j][k] * 100);
                            }
                            catch
                            {
                                //Console.WriteLine("U " + e.Message.ToString() + Program.U[i][j][k].ToString());
                                dummy = Int16.MaxValue;
                            }
                            writer.Write(dummy);

                            try
                            {
                                dummy = Convert.ToInt16(Program.V[i][j][k] * 100);
                            }
                            catch
                            {
                                //Console.WriteLine("V " + e.Message.ToString() + Program.V[i][j][k].ToString());
                                dummy = Int16.MaxValue;
                            }
                            writer.Write(dummy);
                            try
                            {
                                dummy = Convert.ToInt16(Program.W[i][j][k] * 100);
                            }
                            catch
                            {
                                //Console.WriteLine("W " + e.Message.ToString() + Program.W[i][j][k].ToString());
                                dummy = Int16.MaxValue;
                            }
                            writer.Write(dummy);
                        }
                    }
                }
            }
            if (Program.IOUT == 3)
            {
                for (int i = 1; i <= NI; i++)
                {
                    for (int j = 1; j <= NJ; j++)
                    {
                        for (int k = 1; k <= NK; k++)
                        {
                            writer.Write((float)Program.U[i][j][k]);
                            writer.Write((float)Program.V[i][j][k]);
                            writer.Write((float)Program.W[i][j][k]);
                        }
                    }
                }
            }

            writer.Close();
            writer.Dispose();

            //output for friction velocity and Obukhov length
            // write a Zip file
            string stabclassfilename = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".scl");

            if (intermediate == false)
            {
                stabclassfilename = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".scl");
            }
            else
            {
                stabclassfilename = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".scl");
                //intermediate output in case of meteopgt.all
                if (((METEO == "Y") || (METEO == "y")) && (Program.ISTAT == 0))
                {
                    //compute fictious weather number
                    int    FILENUMBER = 0;
                    double time_real  = Program.REALTIME;
                    if (time_real < Program.IOUTPUT) // 1st situation should be stored after 1800 s
                    {
                        time_real = Program.IOUTPUT + 2;
                    }
                    Meteopgtall.meteopgtall_calculate(Program.meteopgt_nr, Program.IWETTER, Program.DTI, time_real, Program.IOUTPUT, Program.TLIMIT2, ref FILENUMBER);
                    stabclassfilename = (Convert.ToString(FILENUMBER).PadLeft(5, '0') + ".scl");
                }
            }

            try
            {
                Console.Write(stabclassfilename + "  "); // write windfile name to the console

                using (FileStream zipToOpen = new FileStream(stabclassfilename, FileMode.Create))
                {
                    using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
                    {
                        string          ustarfilename = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".ust");
                        ZipArchiveEntry write_entry1  = archive.CreateEntry(ustarfilename);
                        using (writer = new BinaryWriter(write_entry1.Open()))
                        {
                            writer.Write(header);
                            writer.Write(NI);
                            writer.Write(NJ);
                            writer.Write(NK);
                            writer.Write(GRAMMhorgridsize);
                            for (int i = 1; i <= NI; i++)
                            {
                                for (int j = 1; j <= NJ; j++)
                                {
                                    dummy = Convert.ToInt16(Program.UST[i][j] * 1000);
                                    writer.Write(dummy);
                                }
                            }
                        }

                        string          obukhovfilename = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".obl");
                        ZipArchiveEntry write_entry2    = archive.CreateEntry(obukhovfilename);
                        using (writer = new BinaryWriter(write_entry2.Open()))
                        {
                            writer.Write(header);
                            writer.Write(NI);
                            writer.Write(NJ);
                            writer.Write(NK);
                            writer.Write(GRAMMhorgridsize);
                            for (int i = 1; i <= NI; i++)
                            {
                                for (int j = 1; j <= NJ; j++)
                                {
                                    dummy = Convert.ToInt16(Program.OL[i][j] * 10);
                                    writer.Write(dummy);
                                }
                            }
                        }

                        //computation and ouput of stability classes
                        string          stabilityfile = (Convert.ToString(Program.IWETTER).PadLeft(5, '0') + ".scl");
                        ZipArchiveEntry write_entry3  = archive.CreateEntry(stabilityfile);
                        using (writer = new BinaryWriter(write_entry3.Open()))
                        {
                            writer.Write(header);
                            writer.Write(NI);
                            writer.Write(NJ);
                            writer.Write(NK);
                            writer.Write(GRAMMhorgridsize);
                            for (int i = 1; i <= NI; i++)
                            {
                                for (int j = 1; j <= NJ; j++)
                                {
                                    writer.Write(Program.stabilityclass[i][j]);
                                }
                            }
                        }
                    } // archive
                }     // Zip File
            }         // catch
            catch { }

            Program.Max_Proc_File_Read();                       // read number of max. Processors

            if (recexist == true && IWetter_Console_First == 0) // write receptor wind fields; not if multi-instances are used
            {
                try
                {
                    using (StreamWriter wr = new StreamWriter("GRAMM.dat", true))
                    {
                        for (int ianz = 0; ianz < Urec.Count(); ianz++)
                        {
                            double angle = winkel(Urec[ianz], Vrec[ianz]);
                            wr.Write(Math.Sqrt(Math.Pow(Urec[ianz], 2) + Math.Pow(Vrec[ianz], 2)).ToString("0.00").Replace(decsep, ".") +
                                     "," + angle.ToString("0").Replace(decsep, ".") + "," + Trec[ianz].ToString("0.0").Replace(decsep, ".") + "," + Globradrec[ianz].ToString("0").Replace(decsep, ".")
                                     + "," + Longradrec[ianz].ToString("0").Replace(decsep, ".") + "," + Soilheatfluxrec[ianz].ToString("0").Replace(decsep, ".")
                                     + "," + Sensheatfluxrec[ianz].ToString("0").Replace(decsep, ".") + "," + Latheatfluxrec[ianz].ToString("0").Replace(decsep, ".") + ",");
                            Urec[ianz]            = 0;
                            Vrec[ianz]            = 0;
                            Trec[ianz]            = 0;
                            Globradrec[ianz]      = 0;
                            Longradrec[ianz]      = 0;
                            Soilheatfluxrec[ianz] = 0;
                            Sensheatfluxrec[ianz] = 0;
                            Latheatfluxrec[ianz]  = 0;
                        }
                        wr.WriteLine();
                    }
                }
                catch { }
            }
        }