示例#1
0
        public void Dispose()
        {
            if (PositionsBuffer != null)
            {
                PositionsBuffer.Release();
                PositionsBuffer = null;
            }

            if (DensitiesBuffer != null)
            {
                DensitiesBuffer.Release();
                DensitiesBuffer = null;
            }

            if (PressuresBuffer != null)
            {
                PressuresBuffer.Release();
                PressuresBuffer = null;
            }

            FusionUtilities.Release(PredictedBuffer);
            FusionUtilities.Release(VelocitiesBuffer);
            FusionUtilities.Release(ref m_argsBuffer);
        }
        //
        // Funkcja wywoływana przez wątek do rysowania wykresów - tutaj plotujemy model
        //
        void worker_DoWork2(object sender, DoWorkEventArgs e)
        {
            plotBusy = true; // wątek rysowania jest zajęty

            // Tymczasowe równanie - jest nadpisywane w różnych miejscach kodu
            eq = new org.mariuszgromada.math.mxparser.Expression(equationString);

            // Lista tokenów (argumentów) dodawana do listy łańcuchów znaków argumentów
            List <Token> tokensList = eq.getCopyOfInitialTokens();

            foreach (Token t in tokensList)
            {
                if (t.tokenTypeId == Token.NOT_MATCHED)
                {
                    if (!argumentsString.Contains(t.tokenStr))
                    {
                        argumentsString.Add(t.tokenStr);
                    }
                }
            }

            // Rozdzielenie argumentów przecinkami
            commaSeparatedArguments = string.Join(", ", argumentsString);

            // Utworzenie funkcji na podstawie argumentów i równania
            f = new Function("f(" + commaSeparatedArguments + ") = " + equationString);

            // Wyłapywanie błędów równania
            if (argumentsString.ToArray().Length < 1)
            {
                argumentsString.Clear();
                argumentsString = new List <string>();
                equationString  = "";
                eq = new org.mariuszgromada.math.mxparser.Expression();
                System.GC.Collect(); // <- Garbage Collector
                algorithm.ClearAlgorithm();
                return;
            }
            if (!eq.checkLexSyntax())
            {
                argumentsString.Clear();
                argumentsString = new List <string>();
                equationString  = "";
                eq = new org.mariuszgromada.math.mxparser.Expression();
                System.GC.Collect(); // <- Garbage Collector
                algorithm.ClearAlgorithm();
                return;
            }
            if (eq.checkSyntax())
            {
                argumentsString.Clear();
                argumentsString = new List <string>();
                equationString  = "";
                eq = new org.mariuszgromada.math.mxparser.Expression();
                System.GC.Collect(); // <- Garbage Collector
                algorithm.ClearAlgorithm();
                return;
            }
            foreach (var arg in argumentsString)
            {
                if (arg.Length < 2 || !arg.Contains("x"))
                {
                    argumentsString.Clear();
                    argumentsString = new List <string>();
                    equationString  = "";
                    eq = new org.mariuszgromada.math.mxparser.Expression();
                    System.GC.Collect(); // <- Garbage Collector
                    algorithm.ClearAlgorithm();
                    return;
                }
            }

            // Jeśli liczba argumentów > 1 to rysujemy warstwice
            if (arguments.ToArray().Length > 1)
            {
                model.Title = "Warstwice: ";                // tytuł modelu to warstwice
                List <double[]> xy = new List <double[]>(); // lista tablic zmiennych double przechowująca minimum i maximum konkretnych argumentów

                // Zapisywanie tych zmiennych jest potrzebne do określenia granic wykresów
                foreach (var arg in arguments)
                {
                    xy.Add(ArrayBuilder.CreateVector(arg.Minimum, arg.Maximum, p));
                }

                // Pomocnicza tablica łańcuchów znaków argumentów funkcji (trochę czarów się tutaj dzieje)
                // Finalnie infunc powinien zawierać łańcuchy znaków postaci:
                //      Przykład dla 2 argumentów: 0.125, 1.216
                //      Przykład dla 3 argumentów: 0.125, 1.216, 0
                //      Przykład dla 4 argumentów: 0.125, 1.216, 0, 0
                // Zera na końcu są wstawiane dlatego, że spłaszczamy wielowymiarowy wykres do postaci warstwic
                var infunc = new string[p, p];
                for (int i = 0; i < p; ++i)
                {
                    for (int j = 0; j < p; ++j)
                    {
                        for (int k = 0; k < xy.ToArray().Length; ++k)
                        {
                            // Jeśli jest to pierwszy argument to dodajemy go po prostu do łańcucha znaków
                            if (k == 0)
                            {
                                infunc[i, j] += xy[k][i].ToString().Replace(',', '.');
                            }
                            // Jeżeli jest to drugi argument to dodajemy go do łańcucha znaków z przecinkiem przed wartością
                            if (k == 1)
                            {
                                infunc[i, j] += "," + xy[k][j].ToString().Replace(',', '.');
                            }
                            // Jeżeli jest to każdy kolejny argument to dodajemy 0 do łańcucha znaków z przecinkiem przed
                            if (k > 1)
                            {
                                infunc[i, j] += ", 0";
                            }
                        }
                    }
                }

                // Tablica zawierająca wyrażenia do obliczenia - korzysta z poprzedniej tablicy pomocniczej do określenia tych wyrażeń
                var data = new double[p, p];
                for (int i = 0; i < p; ++i)
                {
                    for (int j = 0; j < p; ++j)
                    {
                        int progressPercentage = Convert.ToInt32(((double)i / p) * 100);
                        org.mariuszgromada.math.mxparser.Expression equa = new org.mariuszgromada.math.mxparser.Expression("f(" + infunc[i, j] + ")", f);
                        data[i, j] = equa.calculate();
                        (sender as BackgroundWorker).ReportProgress(progressPercentage);
                    }
                }

                buffer = new PositionsBuffer();
                sigma  = data;

                // Tworzenie zmiennej kontur - wykorzystywana do rysowania warstwic
                var cs = new ContourSeries
                {
                    Color             = OxyColors.Red,
                    LabelBackground   = OxyColors.White,
                    ColumnCoordinates = xy[0],
                    RowCoordinates    = xy[1],
                    Data = data
                };
                // Dodanie kontur do modelu
                model.Series.Add(cs);
            }
            // Jeśli liczba argumentów = 1 to rysujemy wykres
            else
            {
                p           = p * 30;                            // zmieniamy dokładność na 30-krotnie większą od ustalonej ze względu na mniejszą złożoność obliczeniową
                model.Title = "Wykres: ";                        // tytuł modelu to wykres
                LineSeries      series1 = new LineSeries();      // zmienna lineseries używana do rysowania wykresów
                List <double[]> xy      = new List <double[]>(); // lista tablic tak jak w poprzednim przypadku - tutaj przechowuje tylko jeden argument, ale zachowanie konwencji ułatwiło dalsze zadania
                foreach (var arg in arguments)
                {
                    xy.Add(ArrayBuilder.CreateVector(arg.Minimum, arg.Maximum, p));
                }

                // Tak samo jak powyżej
                var infunc = new string[p];
                for (int i = 0; i < p; ++i)
                {
                    infunc[i] = xy[0][i].ToString().Replace(',', '.');
                }

                // Tak samo jak powyżej
                var data = new double[p];
                for (int i = 0; i < p; ++i)
                {
                    int progressPercentage = Convert.ToInt32(((double)i / p) * 100);
                    org.mariuszgromada.math.mxparser.Expression equa = new org.mariuszgromada.math.mxparser.Expression("f(" + infunc[i] + ")", f);
                    data[i] = equa.calculate();
                    (sender as BackgroundWorker).ReportProgress(progressPercentage);
                }

                // Lista wygenerowanych punktów dodawana do zmiennej typu lineseries w celu wygenerowania wykresu
                List <DataPoint> pnts = new List <DataPoint>();
                for (int i = 0; i < p; ++i)
                {
                    series1.Points.Add(new DataPoint(xy[0][i], data[i]));
                }
                // Kolor wykresu ustalamy na czerwony - tak żeby wykresy i warstwice były tego samego koloru
                series1.Color = OxyColors.Red;
                model.Series.Add(series1);
                p = p / 30; // przywracamy domyślną wartość zmiennej odpowiadającej za dokładność wykresu
            }

            // Czyścimy listę argumentów w postaci łańcuchów znaków
            argumentsString.Clear();
            // Czyścimy wyrażenie
            eq = new org.mariuszgromada.math.mxparser.Expression();
            // Zapisujemy utworzony model w wyniku wątku rysowania
            e.Result = model;
        }