Example #1
0
        public void UnboundLine(MyLine tempLine)
        {
            int currentModel           = this.parent.GetCurrentModelIndex();
            MyFiniteElementModel model = this.parent.currentFullModel.FiniteElementModels[currentModel];

            List <MyNode> nodes = new List <MyNode>();

            if (tempLine is MyStraightLine)
            {
                nodes = model.Nodes.FindAll(node => Mathematics.pointOnLine(node.X, node.Y, (MyStraightLine)tempLine) && model.INOUT[node.Id] != 0);
            }
            else
            {
                double precision = (model.baseType == MyFiniteElementModel.GridType.Delauney || model.type == MyFiniteElementModel.GridType.FrontalMethod) ? 0.01 : -1;
                nodes = model.Nodes.FindAll(node => Mathematics.pointFitsArc(node, (MyArc)tempLine, precision) && model.INOUT[node.Id] != 0);
            }

            foreach (MyNode node in nodes)
            {
                UnboundNode(node);
            }
            // сохраняем закрепления в массив NFIX
            renewNfixNB(currentModel);
            this.parent.DrawFEBounds(Color.Brown);

            this.txtLine.Text = "";
            this.txtLine.Select();
        }
        public void BoundLine(MyLine tempLine)
        {
            int currentModel           = this.parent.GetCurrentModelIndex();
            MyFiniteElementModel model = this.parent.currentFullModel.FiniteElementModels[currentModel];

            this.errorNoLine.Visible = false;

            tempLine.BoundType = GetBoundType();

            List <MyNode> nodes = new List <MyNode>();

            if (tempLine is MyStraightLine)
            {
                nodes = model.Nodes.FindAll(node => Mathematics.pointOnLine(node.X, node.Y, (MyStraightLine)tempLine) && model.INOUT[node.Id] != 0);
            }
            else
            {
                MyArc  a         = tempLine as MyArc;
                double r         = Mathematics.FindDist(a.CenterPoint, a.StartPoint);
                double precision = NewMethod(model);
                nodes = model.Nodes.FindAll(node => Mathematics.pointFitsArc(node, (MyArc)tempLine, precision) && model.INOUT[node.Id] != 0);
            }

            foreach (MyNode node in nodes)
            {
                BoundNode(node, tempLine.BoundType);
            }
            // сохраняем закрепления в массив NFIX
            renewNfixNB(currentModel);
            this.parent.DrawFEBounds(Color.Brown);

            this.txtLine.Text = "";
            this.txtLine.Select();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == string.Empty)
            {
                return;
            }

            this.parent.precision          = this.parent.DefinePrecision();
            this.parent.showForces.Checked = true;
            int number;
            int currentModel           = this.parent.GetCurrentModelIndex();
            MyFiniteElementModel model = this.parent.currentFullModel.FiniteElementModels[currentModel];

            MyLine lineToForces;
            bool   error = false;

            if (!int.TryParse(this.textBox1.Text, out number))
            {
                error = true;
            }
            lineToForces = parent.currentFullModel.geometryModel.Lines.Find(l => l.Id == number);
            if (lineToForces == null)
            {
                error = true;
            }
            if (error)
            {
                return;
            }
            UnboundLine(lineToForces);
            parent.ReDrawAll();
        }
Example #4
0
        private void okButton_Click(object sender, EventArgs e)
        {
            List <string> lineNumbers = new List <string>(this.notMoveLines.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList <string>());
            List <MyLine> fixedLines  = new List <MyLine>();

            if (gridName.Text == string.Empty)
            {
                MessageBox.Show("Имя сетки не может быть пустым!");
                return;
            }
            foreach (string str in lineNumbers)
            {
                int idx;
                if (!int.TryParse(str, out idx))
                {
                    MessageBox.Show("Неверно заданы линии!");
                    return;
                }
                MyLine line = parent.currentFullModel.geometryModel.Lines.Find(l => l.Id == idx);
                if (line == null)
                {
                    MessageBox.Show("Не найдена линия с номером " + idx.ToString());
                    return;
                }
                fixedLines.Add(line);
            }
            parent.precision = parent.DefinePrecision();
            if (parent.currentFullModel.geometryModel.Areas.Count != 0)
            {
                errorMessage1.Visible    = false;
                errorBadGridName.Visible = false;

                // создаем новый объект "конечно-элементная модель" и добавляем его в список конечно-элементных моделей.
                foreach (MyFiniteElementModel model in parent.currentFullModel.FiniteElementModels) // проверяем, нет ли модели с таким именем
                {
                    if (model.ModelName == gridName.Text)
                    {
                        errorBadGridName.Visible = true;
                        return;
                    }
                }

                // создаем для новой КЭ модели id
                int id = parent.currentFullModel.IdCandidate;
                currentModel           = (MyFiniteElementModel)Util.getObjectCopy(currentModel);
                currentModel.ModelName = gridName.Text;
                currentModel.Id        = id;
                currentModel.type      = MyFiniteElementModel.GridType.Ruppert;
                currentModel.restoreArraysForOldMethods(parent.currentFullModel.geometryModel);
                parent.clearSelection();
                parent.ReDrawAll();
                this.Hide();
                Optimize(fixedLines);
            }
            else
            {
                errorMessage1.Visible = true;
            }
        }
 public void DrawFE(MyFiniteElementModel model, Color color, bool showFEnumbers = true, bool showFEnodeNumbers = true, bool showMaterials = false)
 {
     DrawElements(model.FiniteElements.ToArray(), color, showFEnumbers, showMaterials);
     if (showFEnodeNumbers)
     {
         Gl.glColor3dv(colorArray(Color.Green));
         model.Nodes.ForEach(n => DrawString(n.Id.ToString(), (float)n.X, (float)n.Y));
         FlushText(Color.Green);
     }
 }
        public Regularization(ProjectForm parent)
        {
            InitializeComponent();
            this.parent = parent;

            currentModel      = parent.currentFullModel.FiniteElementModels[this.parent.GetCurrentModelIndex()];
            currentModelIndex = parent.currentFullModel.FiniteElementModels.Count;

            gridName.Text = "Сетка №" + (currentModelIndex + 1).ToString();
            TopMost       = true;
        }
Example #7
0
 public Delauney(ProjectForm parent)
 {
     InitializeComponent();
     this.parent   = parent;
     currentModel  = parent.currentFullModel.FiniteElementModels.Find(m => m.ModelName == parent.currentFullModel.currentGridName);
     gridName.Text = "Сетка №" + (parent.currentFullModel.IdCandidate).ToString();
     ddlTriangulationMethod.SelectedIndex = ddlGenerationMethod.SelectedIndex = 0;
     if (parent.currentFullModel.FiniteElementModels.Count == 0)
     {
         ddlGenerationMethod.Items.RemoveAt(4);
     }
     settingsForm              = new DelauneySettings(parent);
     settingsForm.FormClosing += new FormClosingEventHandler(settingsForm_FormClosing);
 }
Example #8
0
        private void fillObjectsFromArrays(MyFiniteElementModel model, List <double> CORDD, List <int> NOP, int MAXNP, int NEL, int zonesCount)
        {
            model.FiniteElements.Clear();
            model.Nodes.Clear();
            for (int i = 1; i <= MAXNP; i++) // MAXNP - число узлов
            {
                model.Nodes.Add(new MyNode(CORDD[2 * (i - 1) + 1], CORDD[2 * (i - 1) + 2], i));
            }

            model.IMAT.Clear();
            for (int i = 0; i <= NEL; i++)
            {
                model.IMAT.Add(0);
            }

            int           numOfFe      = 0;
            List <MyNode> tempNodes    = new List <MyNode>();
            int           elemsPerZone = NEL / zonesCount;

            for (int temp = 1; temp <= NEL; temp++)
            {
                double X1 = CORDD[2 * (NOP[3 * (temp - 1) + 1] - 1) + 1];
                double Y1 = CORDD[2 * (NOP[3 * (temp - 1) + 1] - 1) + 2];
                double X2 = CORDD[2 * (NOP[3 * (temp - 1) + 2] - 1) + 1];
                double Y2 = CORDD[2 * (NOP[3 * (temp - 1) + 2] - 1) + 2];
                double X3 = CORDD[2 * (NOP[3 * (temp - 1) + 3] - 1) + 1];
                double Y3 = CORDD[2 * (NOP[3 * (temp - 1) + 3] - 1) + 2];
                tempNodes.AddRange(model.Nodes.FindAll(node =>
                                                       Math.Abs(node.X - X1) <= 0.001 && Math.Abs(node.Y - Y1) <= 0.001 ||
                                                       Math.Abs(node.X - X2) <= 0.001 && Math.Abs(node.Y - Y2) <= 0.001 ||
                                                       Math.Abs(node.X - X3) <= 0.001 && Math.Abs(node.Y - Y3) <= 0.001));
                model.FiniteElements.Add(new MyFiniteElement(++numOfFe, 0, tempNodes, (temp - 1) / elemsPerZone));
                tempNodes.Clear();
            }

            // сохраняем число КЭ
            model.NE = NEL;

            // сохраняем NP
            model.NP = MAXNP;

            // сохраняем массив CORD
            model.CORD = new List <double>(CORDD);

            // сохраняем массив NOP
            model.NOP = new List <int>(NOP);
        }
Example #9
0
        public RuppertForm(ProjectForm parent)
        {
            InitializeComponent();
            this.parent = parent;

            if (this.parent.currentFullModel.FiniteElementModels.Count == 0)
            {
                MessageBox.Show("Нельзя экспортировать модель в систему Рапперта, пока она не разбита на КЭ!");
                Close();
            }

            currentModel      = parent.currentFullModel.FiniteElementModels[parent.GetCurrentModelIndex()];
            currentModelIndex = parent.currentFullModel.FiniteElementModels.Count;

            gridName.Text = "Рапперт_Сетка №" + (currentModelIndex + 1).ToString();
            TopMost       = true;
        }
        public int[] Get_Star(int IND, MyFiniteElementModel model)
        {
            //C Содержит подпрограмму GET_STAR
            //C =============================================================
            //C формирование массива КЭ, сост-щих звезду оптимизируемого КЭ
            //C Вызывается из REGULARIZATION, вызываемых модулей нет
            //C =============================================================
            //C  входные параметры:
            //C    IND  - номер рассматриваемого узла
            //C    NOPT - массив номеров узлов, сост-щих элементы
            //C    NUMOFELT - число элементов
            //C  выходные параметры:
            //C    ITSTAR - массив номеров узлов, сост-щих элементы звезды
            //C    NSTAREL  - число элементов звезды
            //C =============================================================
            //C =============== начало кода GET_STAR =========================
            //C =============================================================

            int        NODELS, JGT;
            int        NSTAREL    = 0;
            List <int> nodePoints = model.NOP;

            NODELS = 3;

            JGT = 1;
            List <int> Indexes = new List <int>();
            int        index   = -1;

            while ((index = nodePoints.IndexOf(IND, index + 1)) != -1)
            {
                Indexes.Add(index - 1);
            }

            int[] ITSTAR = new int[Indexes.Count * 3 + 1];

            foreach (int elemIndex in Indexes)
            {
                int elemNumber = (elemIndex / NODELS);
                ITSTAR[NODELS * (JGT - 1) + 1] = nodePoints[NODELS * (elemNumber) + 1];
                ITSTAR[NODELS * (JGT - 1) + 2] = nodePoints[NODELS * (elemNumber) + 2];
                ITSTAR[NODELS * (JGT - 1) + 3] = nodePoints[NODELS * (elemNumber) + 3];
                JGT++;
            }
            //* запоминаем число элементов звезды
            return(ITSTAR);
        }
Example #11
0
        private void renewNfixNB(int modelIndex)
        {
            parent.showBounds.Checked = true;
            MyFiniteElementModel currentModel = parent.currentFullModel.FiniteElementModels[modelIndex];

            currentModel.NBC.Clear();
            currentModel.NFIX.Clear();
            currentModel.NBC.Add(0);
            currentModel.NFIX.Add(0);
            List <MyNode> boundedNodes = currentModel.Nodes.FindAll(n => n.BoundType != 0);

            foreach (MyNode node in boundedNodes)
            {
                currentModel.NFIX.Add(node.BoundType);
                currentModel.NBC.Add(node.Id);
            }
            currentModel.NB = boundedNodes.Count;
        }
        private void okButton_Click(object sender, EventArgs e)
        {
            List <string> lineStrings = new List <string>(this.notMoveLines.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList <string>());
            List <MyLine> fixedLines  = new List <MyLine>();

            if (gridName.Text == string.Empty)
            {
                MessageBox.Show("Имя сетки не может быть пустым!");
                return;
            }
            foreach (string str in lineStrings)
            {
                int idx;
                if (!int.TryParse(str, out idx))
                {
                    MessageBox.Show("Неверно заданы линии!");
                    return;
                }
                MyLine line = parent.currentFullModel.geometryModel.Lines.Find(l => l.Id == idx);
                if (line == null)
                {
                    MessageBox.Show("Не найдена линия с номером " + idx.ToString());
                    return;
                }
                fixedLines.Add(line);
            }
            parent.precision = parent.DefinePrecision();
            if (parent.currentFullModel.geometryModel.Areas.Count != 0)
            {
                errorMessage1.Visible    = false;
                errorBadGridName.Visible = false;

                // создаем новый объект "конечно-элементная модель" и добавляем его в список конечно-элементных моделей.
                foreach (MyFiniteElementModel model in parent.currentFullModel.FiniteElementModels) // проверяем, нет ли модели с таким именем
                {
                    if (model.ModelName == gridName.Text)
                    {
                        errorBadGridName.Visible = true;
                        return;
                    }
                }

                // создаем для новой КЭ модели id
                int id = parent.currentFullModel.IdCandidate;
                currentModel           = (MyFiniteElementModel)Util.getObjectCopy(currentModel);
                currentModel.ModelName = gridName.Text;
                currentModel.Id        = id;
                currentModel.restoreArraysForOldMethods(parent.currentFullModel.geometryModel);
                List <MyNode> dontMove = new List <MyNode>();
                for (int i = 1; i < currentModel.INOUT.Count; i++)
                {
                    if (currentModel.INOUT[i] == 0)
                    {
                        continue;
                    }
                    MyNode node = currentModel.Nodes.Find(n => n.Id == i);
                    if (node != null)
                    {
                        dontMove.Add(node);
                    }
                }
                foreach (MyLine line in fixedLines)
                {
                    if (line is MyStraightLine)
                    {
                        dontMove.AddRange(findNodesAtStraightLine(line as MyStraightLine));
                    }
                    else
                    {
                        dontMove.AddRange(findNodesAtArc(line as MyArc));
                    }
                }

                Regularize(dontMove);
                parent.clearSelection();
                parent.ModelCreated(currentModel);
                Close();
            }
            else
            {
                errorMessage1.Visible = true;
            }
        }
 private static double NewMethod(MyFiniteElementModel model)
 {
     return((model.baseType == MyFiniteElementModel.GridType.Delauney || model.type == MyFiniteElementModel.GridType.FrontalMethod) ? 0.01 : -1);
 }
Example #14
0
        private void btnOk_Click(object sender, EventArgs e)
        {
            string modelName = gridName.Text;
            int    elemId    = 0;

            errorBadGridName.Visible = false;

            if (gridName.Text == string.Empty)
            {
                MessageBox.Show("Имя сетки не может быть пустым!");
                return;
            }
            if (parent.currentFullModel.FiniteElementModels.Find(m => m.ModelName == modelName) != null)
            {
                errorBadGridName.Visible = true;
                return;
            }
            if (ddlGenerationMethod.SelectedIndex == -1)
            {
                MessageBox.Show("Не задан метод генерации точек!");
                return;
            }
            this.Hide();
            parent.StartProgress("Построение сетки");
            List <MyFrontSegment> segments = new List <MyFrontSegment>();

            nodesCount = 0;
            MyFiniteElementModel newModel = new MyFiniteElementModel(parent.currentFullModel.IdCandidate, gridName.Text, MyFiniteElementModel.GridType.Normal);

            // если выбрана триангуляция на основе существующих узлов
            if (ddlGenerationMethod.SelectedIndex == 4)
            {
                List <MyFiniteElement> elems = GetTriangulation(currentModel.Nodes);
                newModel.Nodes.AddRange(currentModel.Nodes);
                newModel.Nodes.ForEach(n => n.finiteElements.Clear());
                foreach (MyFiniteElement elem in elems)
                {
                    double cx = elem.Nodes.Sum(s => s.X) / 3;
                    double cy = elem.Nodes.Sum(s => s.Y) / 3;
                    foreach (MyArea area in parent.currentFullModel.geometryModel.Areas)
                    {
                        //if (Mathematics.ContainsPoint(area.Nodes, cx, cy))
                        if (PointFits(area, new List <MyNode>(), new MyPoint(cx, cy), double.MinValue))
                        {
                            elem.Id     = ++elemId;
                            elem.areaId = area.Id;
                            elem.LinkNodes();
                            newModel.FiniteElements.Add(elem);
                            break;
                        }
                    }
                }
            }
            // любая другая триангуляция
            else
            {
                foreach (MyArea area in parent.currentFullModel.geometryModel.Areas)
                {
                    List <MyNode> result = new List <MyNode>();
                    for (int j = 0; j < 4; j++)
                    {
                        int neighbor = parent.currentFullModel.geometryModel.joinTable[area.Id - 1, j] - 1;
                        if (neighbor != -1)
                        {
                            if (neighbor < area.Id - 1)
                            {
                                List <MyLine> lines = area.Lines.FindAll(l => l.Areas.Contains(area.Id) && l.Areas.Contains(neighbor + 1));
                                foreach (MyLine line in lines)
                                {
                                    if (line is MyStraightLine)
                                    {
                                        result.AddRange(findNodesAtStraightLine(segments[neighbor].Nodes, line as MyStraightLine));
                                    }
                                    else
                                    {
                                        result.AddRange(findNodesAtArc(segments[neighbor].Nodes, line as MyArc));
                                    }
                                }
                            }
                        }
                    }
                    result = result.Distinct().ToList();
                    double h = (double)nudMinDistance.Value;
                    foreach (MyPoint p in area.Nodes)
                    {
                        if (result.Find(n => Mathematics.sameNode(n, p)) == null)
                        {
                            result.Add(new MyNode(p.X, p.Y, ++nodesCount));
                        }
                    }
                    GeneratePoints(area, result);
                    MyFrontSegment seg = new MyFrontSegment(area);
                    seg.Nodes = result;
                    segments.Add(seg);
                    AddNodesFromCommonLine(seg, segments);
                }

                elemId = 0;
                if (ddlGenerationMethod.SelectedIndex == 1)
                {
                    GenerateNodesInDensitySectors(segments);
                }

                foreach (MyFrontSegment seg in segments)
                {
                    foreach (MyNode node in seg.Nodes)
                    {
                        if (!newModel.Nodes.Contains(node))
                        {
                            newModel.Nodes.Add(node);
                        }
                    }
                }
                if (ddlGenerationMethod.SelectedIndex == 1)
                {
                    foreach (MyFiniteElement elem in GetTriangulation(newModel.Nodes))
                    {
                        double cx = elem.Nodes.Sum(s => s.X) / 3;
                        double cy = elem.Nodes.Sum(s => s.Y) / 3;
                        foreach (MyArea area in parent.currentFullModel.geometryModel.Areas)
                        {
                            //if (Mathematics.ContainsPoint(area.Nodes, cx, cy))
                            if (PointFits(area, new List <MyNode>(), new MyPoint(cx, cy), 0.001))
                            {
                                elem.Id = ++elemId;
                                elem.LinkNodes();
                                newModel.FiniteElements.Add(elem);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    foreach (MyFrontSegment seg in segments)
                    {
                        foreach (MyFiniteElement elem in GetTriangulation(seg.Nodes, seg.CorrespondingArea.Id))
                        {
                            double cx   = elem.Nodes.Sum(s => s.X) / 3;
                            double cy   = elem.Nodes.Sum(s => s.Y) / 3;
                            MyArea area = parent.currentFullModel.geometryModel.Areas[segments.IndexOf(seg)];
                            //if (PointFits(Mathematics.ContainsPoint(area.Nodes, cx, cy))
                            if (PointFits(area, new List <MyNode>(), new MyPoint(cx, cy), 0.001))
                            {
                                elem.Id = ++elemId;
                                elem.LinkNodes();
                                seg.finiteElems.Add(elem);
                            }
                        }
                        newModel.FiniteElements.AddRange(seg.finiteElems);
                    }
                }
            }
            newModel.baseType = newModel.type = MyFiniteElementModel.GridType.Delauney;
            parent.currentFullModel.densityPoints.Clear();
            parent.EndProgress();
            parent.ModelCreated(newModel);
            Close();
            // создаем для новой КЭ модели id
        }
        public void DrawForces(MyFiniteElementModel model, double scale, Color color, bool showValues = true)
        {
            MyNode[] forcedNodes = model.Nodes.FindAll(n => n.ForceX != 0.0 || n.ForceY != 0.0).ToArray();
            int      nodesCount  = forcedNodes.Length;

            if (nodesCount == 0)
            {
                return;
            }
            int count = 6 * nodesCount;

            float[] pts = new float[count * 2];
            Gl.glColor3dv(colorArray(color));

            for (int i = 0; i < nodesCount; i++)
            {
                MyNode node = forcedNodes[i];
                // силу будем рисовать, как линию со стрелочкой на конце. Если сила > 0, то она идет вверх или вправо ( зависит от нагрузки - по X или по Y)
                // плюс, надо еще масштабировать длину стрелки
                // координаты начальной и конечной точки в пикселях

                float forceLengthX = (float)node.ForceX;
                float forceLengthY = (float)node.ForceY;
                float x1           = (float)node.X;
                float y1           = (float)node.Y;
                float x2           = x1 + forceLengthX * (float)scale; // масштабируем длину стрелки
                float y2           = y1 + forceLengthY * (float)scale; // масштабируем длину стрелки

                pts[(i * 12)]     = x1;
                pts[(i * 12) + 1] = y1;
                pts[(i * 12) + 2] = x2;
                pts[(i * 12) + 3] = y2;

                // вычисляем угол нагрузки
                float alfa = (float)Math.Atan2(y2 - y1, x2 - x1);
                // длина стрелочки
                float aSize = (float)Math.Pow(((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)), 0.5) / 10.0f;

                float px1 = x2;
                float py1 = y2;
                float px2 = (float)(x2 - aSize * Math.Cos(alfa + 15.0 * (Math.PI / 180.0)));
                float py2 = (float)(y2 - aSize * Math.Sin(alfa + 15.0 * (Math.PI / 180.0)));
                float px3 = (float)(x2 - aSize * Math.Cos(alfa - 15.0 * (Math.PI / 180.0)));
                float py3 = (float)(y2 - aSize * Math.Sin(alfa - 15.0 * (Math.PI / 180.0)));

                pts[(i * 12) + 4] = px1;
                pts[(i * 12) + 5] = py1;
                pts[(i * 12) + 6] = px2;
                pts[(i * 12) + 7] = py2;

                pts[(i * 12) + 8]  = px1;
                pts[(i * 12) + 9]  = py1;
                pts[(i * 12) + 10] = px3;
                pts[(i * 12) + 11] = py3;

                if (showValues)
                {
                    float  f      = (float)Math.Pow((Math.Pow(node.ForceX, 2) + Math.Pow(node.ForceY, 2)), 0.5);
                    double fRound = Mathematics.floor(f, Mathematics.accuracy_medium);
                    DrawString(fRound.ToString(), x2, y2, true);
                }
            }
            int list;

            list = Gl.glGenLists(1);
            Gl.glNewList(list, Gl.GL_COMPILE);
            Gl.glColor3dv(colorArray(color));
            Gl.glLineWidth(1.0f);
            Gl.glEndList();
            drawBuffer.Add(new DrawingOperation(Gl.GL_LINES, pts, list));
            if (showValues)
            {
                FlushText(color);
            }
        }
        private void btnStatistics_Click(object sender, EventArgs e)
        {
            MyFiniteElementModel currentModel = parent.currentFullModel.FiniteElementModels.Find(m => m.ModelName == parent.currentFullModel.currentGridName);
            StringBuilder        stats        = new StringBuilder();

            stats.AppendLine("Статистика по сетке: " + currentModel.ModelName + ".");
            stats.AppendLine();
            stats.AppendLine("Заданные параметры:");
            stats.AppendLine("Минимально допустимый угол: " + MinAllowAngle);
            stats.AppendLine("Максимально допустимый угол: " + MaxAllowAngle);
            stats.AppendLine("Минимально допустимая площадь: " + MinAllowSquare);
            stats.AppendLine();
            stats.AppendLine("Всего конечных элементов: " + currentModel.Nodes.Count);

            int    badMinAngle = 0, badMaxAngle = 0, badSquare = 0, badAngles = 0;
            double minAngle = double.MaxValue, maxAngle = double.MinValue, minSquare = double.MaxValue, maxSquare = double.MinValue;;
            int    minAngleElem = 0, maxAngleElem = 0, minSquareElem = 0, maxSquareElem = 0;

            foreach (MyFiniteElement elem in currentModel.FiniteElements)
            {
                double[] angles = Mathematics.getFEangles(elem);
                double   max    = angles.Max();
                double   min    = angles.Min();
                if (max > MaxAllowAngle || min < MinAllowAngle)
                {
                    badAngles++;
                    if (max > MaxAllowAngle)
                    {
                        badMaxAngle++;
                    }
                    else
                    {
                        badMinAngle++;
                    }
                }
                if (max > maxAngle)
                {
                    maxAngle     = max;
                    maxAngleElem = elem.Id;
                }
                if (min < minAngle)
                {
                    minAngle     = min;
                    minAngleElem = elem.Id;
                }
                double sqr = Mathematics.GeronLaw(elem.Nodes);
                if (sqr < MinAllowSquare)
                {
                    badSquare++;
                    if (sqr < minSquare)
                    {
                        minSquare     = sqr;
                        minSquareElem = elem.Id;
                    }
                }
                if (sqr > maxSquare)
                {
                    maxSquare     = sqr;
                    maxSquareElem = elem.Id;
                }
            }
            int    elemCount           = currentModel.FiniteElements.Count;
            string percentBadAngles    = String.Format(" ({0:##0.##}% от общего числа).", (1.0 * badAngles / elemCount) * 100);
            string percentBadMinAngles = String.Format(" ({0:##0.##}% от общего числа).", (1.0 * badMinAngle / elemCount) * 100);
            string percentBadMaxAngles = String.Format(" ({0:##0.##}% от общего числа).", (1.0 * badMaxAngle / elemCount) * 100);
            string percentBadSquare    = String.Format(" ({0:##0.##}% от общего числа).", (1.0 * badSquare / elemCount) * 100);

            stats.AppendLine("Из них содержат недопустимых углов: " + badAngles + percentBadAngles);
            stats.AppendLine("Элементов с углом меньше допустимого: " + badMinAngle + percentBadMinAngles);
            stats.AppendLine("Элементов с углом больше допустимого: " + badMaxAngle + percentBadMaxAngles);
            stats.AppendLine("Минимальный угол: " + minAngle.ToString("##0.##") + ", в элементе: " + minAngleElem + ".");
            stats.AppendLine("Максимальный угол: " + maxAngle.ToString("##0.##") + ", в элементе: " + maxAngleElem + ".");
            stats.AppendLine();
            stats.AppendLine("Элементов с площадью меньше допустимой: " + badSquare + percentBadSquare);
            stats.AppendLine("Минимальная площадь: " + minSquare.ToString("##0.00") + ", у элемента: " + minSquareElem);
            stats.AppendLine("Максимальная площадь: " + maxSquare.ToString("##0.00") + ", у элемента: " + maxSquareElem);

            GridAnalysisStatistics statForm = new GridAnalysisStatistics();

            statForm.StatText = stats.ToString();
            statForm.ShowDialog();
        }
Example #17
0
        public int Griddm(int NRC, int boundaryPointsCount, int zonesCount, int NMAT, int NCN, MyFiniteElementModel newModel)
        {
            // Эти массивы используются при обходе зон для извлечения координат узлов, образующих каждую из зон
            double[] areaNodesX = new double[10];
            double[] areaNodesY = new double[10];
            // функции формы для квадратичного четырехугольника
            double[] formFunctions = new double[9];
            // номера узлов, определяющих зону
            int[] definingNodesNumbers = new int[9];
            // ?
            int[]    LB    = new int[4];
            double[] CORD  = new double[4];
            double[] CORD1 = new double[4];
            // номера узлов зоны
            int[,] nodeNumbers = new int[53, 53];
            // видимо, номера элементов
            int[]    NE    = new int[601];
            double[] xElem = new double[601];
            double[] yElem = new double[601];

            int[] NR = new int[5];
            // координаты X и Y узлов зоны
            double[,] xCord = new double[53, 53];
            double[,] yCord = new double[53, 53];
            // трехмерный массив номеров узлов, находящихся на границе. По индексам: 1 - зона, 2 - сторона, 3 - номер узла
            int[, ,] boundaryNodesNumbers = new int[101, 5, 53];

            // Матрица данных о соединениях зон. Строка i = номер зоны, столбец j = номер стороны, элемент на пересечении - граничащая с зоной i зона по стороне j
            int[,] joinTable = new int[101, 5];

            // ооох.
            int[,] ICOMP =
            {
                { 0,  0,  0,  0,  0 },
                { 0, -1,  1,  1, -1 },
                { 0,  1, -1, -1,  1 },
                { 0,  1, -1, -1,  1 },
                { 0, -1,  1,  1, -1 }
            };
            double[] GLOB = { 0.0, 0.0, -1.0, 3.0, 0.0, -5.0, -1.0, 0.0, 3.0, 0.0 };

            List <double> CORDD = new List <double>();
            List <int>    NOP   = new List <int>();
            //List<int> INOUT = new List<int>();

            int NUMOFELEM;

            int NBW = 0;
            int NB  = 0;
            int NEL = 0;

            int    TR;
            double DETA, DSI, ETA, SI, DIAG1, DIAG2;
            int    KN1, KN2, KS1, KS2, neighborArea, JL, JK, K, L, NELBW;
            int    neighborAreaSide = 0;
            int    J1 = 0;
            int    J2 = 0;
            int    J3 = 0;

            /*формируем массив joinTable*/
            for (int i = 1; i <= 100; i++)
            {
                for (int j = 1; j <= 4; j++)
                {
                    joinTable[i, j] = this.parent.currentFullModel.geometryModel.joinTable[i - 1, j - 1];
                }
            }

            /*формируем массив areaDefiningNodes*/
            int p = 1;

            foreach (MyArea area in this.parent.currentFullModel.geometryModel.Areas)
            {
                for (int i = 1; i <= 8; i++)
                {
                    newModel.areaDefiningNodes[i, p] = area.Nodes[i - 1].Id;
                }
                p++;
            }

            /*формируем массив XP и YP. Массивы глобальных координат точек, образующих зоны */
            List <MyPoint> nodes = new List <MyPoint>();

            foreach (MyArea area in this.parent.currentFullModel.geometryModel.Areas)
            {
                for (int i = 1; i <= 8; i++)
                {
                    if (nodes.IndexOf(area.Nodes[i - 1]) == -1)
                    {
                        nodes.Add(area.Nodes[i - 1]);
                    }
                }
            }

            newModel.XP.Add(0);
            newModel.YP.Add(0);
            for (int i = 1; i <= nodes.Count; i++)
            {
                newModel.XP.Add(nodes[i - 1].X);
                newModel.YP.Add(nodes[i - 1].Y);
            }
            // подсчет количества элементов.
            NUMOFELEM = NRC * NRC * zonesCount - NRC * (zonesCount - 1);

            for (int i = 0; i <= NUMOFELEM; i++)
            {
                newModel.INOUT.Add(1);
            }

            int MAXNP = 1;

            int nodeRowsCount, nodeColsCount;

            for (int i = 0; i <= NUMOFELEM * NCN * 2; i++)
            {
                CORDD.Add(0.0);
                NOP.Add(0);
            }

            for (int zoneNumber = 1; zoneNumber <= zonesCount; zoneNumber++)
            {
                Application.DoEvents();
                // рассматриваемая зона - zoneNumber

                // количество рядов и строк в будущей сетке
                nodeRowsCount = NRC;
                nodeColsCount = NRC;
                // выбираем точки, образующие текущую зону

                for (int i = 1; i <= 8; i++)
                {
                    definingNodesNumbers[i] = newModel.areaDefiningNodes[i, zoneNumber];
                }

                // генерация сетки КЭ
                // записываем координаты граничных узлов зоны в массивы areaNodes
                for (int i = 1; i <= 8; i++)
                {
                    int nodeNumber = definingNodesNumbers[i];
                    areaNodesX[i] = newModel.XP[nodeNumber];
                    areaNodesY[i] = newModel.YP[nodeNumber];
                }

                areaNodesX[9] = areaNodesX[1];
                areaNodesY[9] = areaNodesY[1];

                // вычисления шага сетки

                TR = nodeRowsCount - 1; // по сути nrc-1
                // буквы D в названии переменных обозначают шаг (по аналогии с dx и т.п.), т.е. DETA - это величина, на которую изменяется ETA
                DETA = 2.0 / TR;        // видимо, этот коэффициент определяет расстояние между узлами на сторонах зоны
                // Зона состоит из 8 узлов и за исходное расстояние принимается расстояние между двумя соседними узлами (не путать с узлами сетки!)
                // При умножении этого расстояния на коэффициенты DETA и DSI, получим реальный шаг распределения узлов.
                // например, для NRC = 5 получим DETA = DSI = 2.0/4 = 1/2, тоесть необходимо расставить узлы сетки
                // на стороне зоны с шагом 0.5 от исходного расстояния между узлами зоны
                TR  = nodeColsCount - 1; // то же
                DSI = 2.0 / TR;

                for (int i = 1; i <= nodeRowsCount; i++)
                {
                    // Дальше используются хитрые коэффициенты ETA и SI. Смысл в следующем: разбивая четырехугольник на 4 части, примем координаты пересечения
                    // его центральных линий за (0; 0), координаты его граничных узлов за (-1, -1), (1, -1), (1, 1), (-1, 1).
                    // Тогда Координаты каждого из узлов будут отличаться друг от друга на величину {±DSI, ±DETA} и получится равномерная сетка в пределах четырехгранника.
                    // Суть дальнейших махинаций - в преобразовании координат каждого узла из системы координат нашего четырехугольника
                    // к глобальным координатам
                    TR  = i - 1;
                    ETA = 1.0 - TR * DETA; // координата y текущего узла в системе координат четырехугольника
                    for (int j = 1; j <= nodeColsCount; j++)
                    {
                        TR = j - 1;
                        SI = -1.0 + TR * DSI;// координата x текущего узла в системе координат четырехугольника
                        // Функции формы квадратичного четырехугольника. Будут использоватсья для получения угловых координат элементов
                        // Комментарии по поводу того, откуда это все берется, заняли бы больше, чем сама подпрограмма.
                        // Жаждущие знаний могут обратиться к циклу статей http://www.exponenta.ru/soft/mathemat/pinega/a1/a1.asp
                        formFunctions[1] = -0.25 * (1.0 - SI) * (1.0 - ETA) * (SI + ETA + 1.0);
                        formFunctions[2] = 0.50 * (1.0 - SI * SI) * (1.0 - ETA);
                        formFunctions[3] = 0.25 * (1.0 + SI) * (1.0 - ETA) * (SI - ETA - 1.0);
                        formFunctions[4] = 0.50 * (1.0 + SI) * (1.0 - ETA * ETA);
                        formFunctions[5] = 0.25 * (1.0 + SI) * (1.0 + ETA) * (SI + ETA - 1.0);
                        formFunctions[6] = 0.50 * (1.0 - SI * SI) * (1.0 + ETA);
                        formFunctions[7] = .25 * (1.0 - SI) * (1.0 + ETA) * (ETA - SI - 1.0);
                        formFunctions[8] = 0.50 * (1.0 - SI) * (1.0 - ETA * ETA);
                        // обнуление начальных координат определяемого узла
                        xCord[i, j] = 0.0;
                        yCord[i, j] = 0.0;

                        // вычисляются координаты узлов сетки
                        // в формировании координаты нового узла участвуют все восемь
                        // базовых (образующих зону) узлов, координаты каждого из которых
                        // умножаются на коэффицент, соответсвующий номеру узла в зоне
                        // по сути - афинное преобразование координат.
                        for (int k = 1; k <= 8; k++)
                        {
                            xCord[i, j] = xCord[i, j] + areaNodesX[k] * formFunctions[k];
                            yCord[i, j] = yCord[i, j] + areaNodesY[k] * formFunctions[k];
                        }
                        Application.DoEvents();
                    }
                }

                KN1 = 1;
                KS1 = 1;
                KN2 = nodeRowsCount;
                KS2 = nodeColsCount;

                for (int i = 1; i <= 4; i++)
                {
                    // перебор связей текущей зоны с другими
                    neighborArea = joinTable[zoneNumber, i];

                    // На каждом этапе нас интересуют только те зоны, граничащие с данной, которые уже разбиты на КЭ
                    // Отсюда условие: если со стороны i зона не граничит с другими зонами (neighborArea = 0)
                    // или номер смежной зоны больше чем рассматриваемой, переходим к следующей стороне
                    if (neighborArea == 0 || neighborArea > zoneNumber)
                    {
                        continue;
                    }
                    else
                    {
                        for (int j = 1; j <= 4; j++)
                        {
                            // запоминаем номер стороны соседней зоны, по которой она граничит с нашей
                            if (joinTable[neighborArea, j] == zoneNumber)
                            {
                                neighborAreaSide = j;
                            }
                        }
                        K = nodeColsCount;
                        if (i == 2 || i == 4)
                        {
                            K = nodeRowsCount;
                        }
                        JL = 1;
                        // I - номер смежной стороны рассм зоны,
                        // neighborAreaSide - номер смежной стороны текущей зоны
                        JK = ICOMP[i, neighborAreaSide];
                        if (JK == -1)
                        {
                            JL = K;
                        }

                        for (int j = 1; j <= K; j++)
                        {
                            switch (i)
                            {
                            case 1:
                                nodeNumbers[nodeRowsCount, j] = boundaryNodesNumbers[neighborArea, neighborAreaSide, JL];
                                // узлы на стыке двух зон - внутренние
                                if (j != 1 && j != nodeColsCount)
                                {
                                    newModel.INOUT[nodeNumbers[nodeRowsCount, j]] = 0;
                                }
                                KN2 = nodeRowsCount - 1;
                                break;

                            case 2:
                                nodeNumbers[j, nodeColsCount] = boundaryNodesNumbers[neighborArea, neighborAreaSide, JL];
                                // узлы на стыке двух зон - внутренние
                                if (j != 1 && j != nodeRowsCount)
                                {
                                    newModel.INOUT[nodeNumbers[j, nodeColsCount]] = 0;
                                }
                                KS2 = nodeColsCount - 1;
                                break;

                            case 3:
                                nodeNumbers[1, j] = boundaryNodesNumbers[neighborArea, neighborAreaSide, JL];
                                // узлы на стыке двух зон - внутренние
                                if (j != 1 && j != nodeColsCount)
                                {
                                    newModel.INOUT[nodeNumbers[1, j]] = 0;
                                }
                                KN1 = 2;
                                break;

                            case 4:
                                nodeNumbers[j, 1] = boundaryNodesNumbers[neighborArea, neighborAreaSide, JL];
                                // узлы на стыке двух зон - внутренние
                                if (j != 1 && j != nodeRowsCount)
                                {
                                    newModel.INOUT[nodeNumbers[j, 1]] = 0;
                                }
                                KS1 = 2;
                                break;
                            }
                            JL = JL + JK;
                        }
                    }
                }

                if (KN1 > KN2)
                {
                }
                else if (KS1 > KS2)
                {
                }
                else
                {
                    for (int i = KN1; i <= KN2; i++)
                    {
                        int j;
                        for (j = KS1; j <= KS2; j++)
                        {
                            NB = NB + 1;
                            nodeNumbers[i, j] = NB;
                        }
                    }

                    for (int i = 1; i <= nodeColsCount; i++)
                    {
                        boundaryNodesNumbers[zoneNumber, 1, i] = nodeNumbers[nodeRowsCount, i];
                        boundaryNodesNumbers[zoneNumber, 3, i] = nodeNumbers[1, i];
                    }

                    for (int i = 1; i <= nodeRowsCount; i++)
                    {
                        boundaryNodesNumbers[zoneNumber, 2, i] = nodeNumbers[i, nodeColsCount];
                        boundaryNodesNumbers[zoneNumber, 4, i] = nodeNumbers[i, 1];
                    }
                }

                /* < Определение внешних и внутренних узлов
                 * формируется массив INOUT: если узел внутренний, то соответсвующий
                 * элемент INOUT равен 0, если внешний - 1.
                 * все неграничные узлы внутренние;
                 * если сторона зоны смежна с другой зоной, узлы на этой стороне,
                 * кроме угловых, тоже внутренние.
                 * узлы не на границе зоны - внутренние */

                try
                {
                    for (int INODE = 2; INODE <= nodeRowsCount - 1; INODE++)
                    {
                        for (int JNODE = 2; JNODE <= nodeColsCount - 1; JNODE++)
                        {
                            newModel.INOUT[nodeNumbers[INODE, JNODE]] = 0;
                        }
                    }
                }
                catch
                {
                    return(-1);
                }
                // > Определение внешних и внутренних узлов
                // > завершена генерация сетки конечных элементов

                // < определение конечных элементов (группировка узлов)

                K = 1;
                for (int i = 1; i <= nodeRowsCount; i++)
                {
                    for (int j = 1; j <= nodeColsCount; j++)
                    {
                        xElem[K] = xCord[i, j];
                        yElem[K] = yCord[i, j];
                        //ZE[K] = ZC[i,j];
                        NE[K] = nodeNumbers[i, j];

                        if (NE[K] > MAXNP)
                        {
                            MAXNP = NE[K];
                        }
                        CORDD[(2 * (NE[K] - 1) + 1)] = xElem[K];
                        CORDD[(2 * (NE[K] - 1) + 2)] = yElem[K];
                        CORD[1] = xElem[K];
                        CORD[2] = yElem[K];
                        K       = K + 1;
                    }
                }

                L = nodeRowsCount - 1;
                for (int i = 1; i <= L; i++)
                {
                    for (int j = 2; j <= nodeColsCount; j++)
                    {
                        DIAG1 = Math.Pow((Math.Pow((xCord[i, j] - xCord[i + 1, j - 1]), 2) + Math.Pow((yCord[i, j] - yCord[i + 1, j - 1]), 2)), 0.5);
                        DIAG2 = Math.Pow((Math.Pow((xCord[i + 1, j] - xCord[i, j - 1]), 2) + Math.Pow((yCord[i + 1, j] - yCord[i, j - 1]), 2)), 0.5);

                        //DIAG1 = Math.Pow((Math.Pow((xCord[i, j] - xCord[i + 1, j - 1]), 2) + Math.Pow((yCord[i, j] - yCord[i + 1, j - 1]), 2) + Math.Pow((ZC[i, j] - ZC[i + 1, j - 1]), 2)), 0.5);
                        //DIAG2 = Math.Pow((Math.Pow((xCord[i + 1, j] - xCord[i, j - 1]), 2) + Math.Pow((yCord[i + 1, j] - yCord[i, j - 1]), 2) + Math.Pow((ZC[i + 1, j] - ZC[i, j - 1]), 2)), 0.5);

                        NR[1] = nodeColsCount * i + j - 1;
                        NR[2] = nodeColsCount * i + j;
                        NR[3] = nodeColsCount * (i - 1) + j;
                        NR[4] = nodeColsCount * (i - 1) + j - 1;
                        for (int ij = 1; ij <= 2; ij++)
                        {
                            NEL = NEL + 1;
                            if ((DIAG1 / DIAG2) > 1.01)
                            {
                                J1 = NR[ij];
                                J2 = NR[ij + 1];
                                J3 = NR[4];
                            }
                            else if ((DIAG1 / DIAG2) < 1.01)
                            {
                                J1 = NR[1];
                                J2 = NR[ij + 1];
                                J3 = NR[ij + 2];
                            }
                            else if ((i + j) % 2 == 1)
                            {
                                J1 = NR[ij];
                                J2 = NR[ij + 1];
                                J3 = NR[4];
                            }

                            LB[1] = Math.Abs(NE[J1] - NE[J2]) + 1;
                            LB[2] = Math.Abs(NE[J2] - NE[J3]) + 1;
                            LB[3] = Math.Abs(NE[J1] - NE[J3]) + 1;

                            for (int ik = 1; ik <= 3; ik++)
                            {
                                if (LB[ik] <= NBW)
                                {
                                }
                                else
                                {
                                    NBW   = LB[ik];
                                    NELBW = NEL;
                                }
                            }
                            NOP[(NCN * (NEL - 1) + 1)] = NE[J1];
                            NOP[(NCN * (NEL - 1) + 2)] = NE[J2];
                            NOP[(NCN * (NEL - 1) + 3)] = NE[J3];
                            // > завершено определение конечных элементов (группировка узлов)
                        }
                    }
                }
            }
            fillObjectsFromArrays(newModel, CORDD, NOP, MAXNP, NEL, zonesCount);
            return(0);
        }
Example #18
0
        private void okButton_Click(object sender, EventArgs e)
        {
            this.parent.precision = this.parent.DefinePrecision();
            if (this.parent.currentFullModel.geometryModel.Areas.Count != 0)
            {
                this.errorMessage1.Visible    = false;
                this.errorBadGridName.Visible = false;
                if (gridName.Text == string.Empty)
                {
                    MessageBox.Show("Имя сетки не может быть пустым!");
                    return;
                }

                List <MyPoint> nodes = new List <MyPoint>();
                foreach (MyArea area in this.parent.currentFullModel.geometryModel.Areas)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        if (nodes.IndexOf(area.Nodes[i]) == -1)
                        {
                            nodes.Add(area.Nodes[i]);
                        }
                    }
                }

                // создаем новый объект "конечно-элементная модель" и добавляем его в список конечно-элементных моделей.
                foreach (MyFiniteElementModel model in this.parent.currentFullModel.FiniteElementModels) // проверяем, нет ли модели с таким именем
                {
                    if (model.ModelName == this.gridName.Text)
                    {
                        this.errorBadGridName.Visible = true;
                        return;
                    }
                }

                // создаем для новой КЭ модели id
                int id = this.parent.currentFullModel.IdCandidate;
                MyFiniteElementModel newModel = new MyFiniteElementModel(id, this.gridName.Text, Convert.ToInt32(this.NRC.Text), MyFiniteElementModel.GridType.Normal);
                newModel.baseType = newModel.type;

                this.parent.currentFullModel.geometryModel.boundaryPointsCount = nodes.Count;

                int NRC = Convert.ToInt32(this.NRC.Text);

                if (NRC < 3 || NRC > 15)
                {
                    MessageBox.Show("Нельзя задать такое NRC!");
                    return;
                }
                parent.StartProgress("Формируется сетка");
                this.Hide();
                int result = Griddm(NRC, this.parent.currentFullModel.geometryModel.boundaryPointsCount, this.parent.currentFullModel.geometryModel.Areas.Count, 1, 3, newModel); // последний парамер - номер рассматриваемой модели, расчитаный по числу моделей в списке

                if (result == -1)
                {
                    MessageBox.Show("Невозможно построить сетку КЭ, зоны были заданы непоследовательно!");
                    return;
                }
                parent.EndProgress();
                parent.clearSelection();
                parent.ModelCreated(newModel);
                this.Close();
            }
            else
            {
                this.errorMessage1.Visible = true;
            }
        }
        private void constructionArea_MouseMove(object sender, MouseEventArgs e)
        {
            mouseAboveArea = true;
            MyPoint clickPoint = visualizer.getClickPoint(e.X, e.Y);

            if (mouseXcord.Equal(clickPoint.X) && mouseYcord.Equal(clickPoint.Y))
            {
                return;
            }
            mouseXcord = clickPoint.X;
            mouseYcord = clickPoint.Y;

            if (e.Button == MouseButtons.Left)
            {
                // кусочек, который отвечает за перетаскивание области построения
                if (!this.mouseAboveEditedPoint && !this.mouseAboveEditedNode && this.currentFullModel.geometryModel.editedPoint == null)
                {
                    this.mouseMoved = true;
                    visualizer.MoveBy((e.X - mouseX), (e.Y - mouseY), showGrid.Checked);
                    mouseX = e.X;
                    mouseY = e.Y;
                }

                // кусочек, который отвечает за перетаскивание точки в режиме редактирования точки
                if (this.editPointsControl != null && this.editPointsControl.IsHandleCreated && this.mouseAboveEditedPoint)
                {
                    if (this.currentFullModel.geometryModel.editedPoint != null)
                    {
                        if (currentFullModel.geometryModel.editedPoint.IsCenterOfArc)
                        {
                            MessageBox.Show("Изменение центра дуги невозможно!");
                            this.mouseAboveEditedPoint = false;
                        }
                        else
                        {
                            MyPoint ePoint = currentFullModel.geometryModel.editedPoint;
                            if (currentFullModel.geometryModel.editedPoint.IsStartOfArc || currentFullModel.geometryModel.editedPoint.IsEndOfArc)
                            {
                                MyArc[] incidentArcs = currentFullModel.geometryModel.Arcs.Where(a => a.StartPoint == currentFullModel.geometryModel.editedPoint || a.EndPoint == currentFullModel.geometryModel.editedPoint).ToArray();
                                if (incidentArcs.Length > 0)
                                {
                                    MyPoint commonCenter;
                                    commonCenter = incidentArcs[0].CenterPoint;

                                    double R = Mathematics.FindDist(currentFullModel.geometryModel.editedPoint, commonCenter);
                                    double x;
                                    double y;
                                    double angle = Math.Atan2(clickPoint.Y - commonCenter.Y, clickPoint.X - commonCenter.X);
                                    x = commonCenter.X + R * Math.Cos(angle);
                                    y = commonCenter.Y + R * Math.Sin(angle);

                                    bool PointFits = true;
                                    foreach (MyArc arc in incidentArcs)
                                    {
                                        MyArc testArc;
                                        if (arc.EndPoint == currentFullModel.geometryModel.editedPoint)
                                        {
                                            testArc = new MyArc(0, arc.Clockwise, arc.StartPoint, new MyPoint(x, y, MyPoint.PointType.IsGeometryPoint), arc.CenterPoint);
                                        }
                                        else
                                        {
                                            testArc = new MyArc(0, arc.Clockwise, new MyPoint(x, y, MyPoint.PointType.IsGeometryPoint), arc.EndPoint, arc.CenterPoint);
                                        }

                                        if (!TestArc(testArc))
                                        {
                                            PointFits = false;
                                            break;
                                        }
                                    }
                                    if (PointFits)
                                    {
                                        currentFullModel.geometryModel.editedPoint.X = x;
                                        currentFullModel.geometryModel.editedPoint.Y = y;
                                    }
                                }
                                else
                                {
                                    currentFullModel.geometryModel.editedPoint.X = clickPoint.Y;
                                    currentFullModel.geometryModel.editedPoint.Y = clickPoint.Y;
                                }
                            }

                            else
                            {
                                currentFullModel.geometryModel.editedPoint.X = clickPoint.X;
                                currentFullModel.geometryModel.editedPoint.Y = clickPoint.Y;
                            }
                            if (currentFullModel.geometryModel.editedPoint.NodeReference != null) // точка может и не иметь ссылки на узел - если это центральная точка дуги, например
                            {
                                currentFullModel.geometryModel.editedPoint.NodeReference.X = this.currentFullModel.geometryModel.editedPoint.X;
                                currentFullModel.geometryModel.editedPoint.NodeReference.Y = this.currentFullModel.geometryModel.editedPoint.Y;
                            }
                            // отображаем id, x и y точки
                            this.editPointsControl.number.Text = this.currentFullModel.geometryModel.editedPoint.Id.ToString();
                            this.editPointsControl.x.Text      = Mathematics.floor(this.currentFullModel.geometryModel.editedPoint.X, Mathematics.accuracy_medium).ToString();
                            this.editPointsControl.y.Text      = Mathematics.floor(this.currentFullModel.geometryModel.editedPoint.Y, Mathematics.accuracy_medium).ToString();
                            ReDrawAll(true);
                        }
                    }
                }

                // кусочек, который отвечает за перетаскивание узла зоны в режиме редактирования узлов зоны
                if (this.editNodesControl != null && this.editNodesControl.IsHandleCreated && this.mouseAboveEditedNode)
                {
                    if (this.currentFullModel.geometryModel.editedNode != null)
                    {
                        this.currentFullModel.geometryModel.editedNode.X = clickPoint.X;
                        this.currentFullModel.geometryModel.editedNode.Y = clickPoint.Y;
                        if (currentFullModel.geometryModel.editedNode.PointReference != null) // точка может и не иметь ссылки на узел - если это центральная точка дуги, например
                        {
                            if (!(currentFullModel.geometryModel.editedNode.PointReference.IsCenterOfArc || currentFullModel.geometryModel.editedNode.PointReference.IsStartOfArc || currentFullModel.geometryModel.editedNode.PointReference.IsEndOfArc))
                            {
                                currentFullModel.geometryModel.editedNode.PointReference.X = this.currentFullModel.geometryModel.editedNode.X;
                                currentFullModel.geometryModel.editedNode.PointReference.Y = this.currentFullModel.geometryModel.editedNode.Y;
                            }
                        }

                        // отображаем id, x и y точки
                        this.editNodesControl.number.Text = this.currentFullModel.geometryModel.editedNode.Id.ToString();
                        this.editNodesControl.x.Text      = Mathematics.floor(this.currentFullModel.geometryModel.editedNode.X, Mathematics.accuracy_medium).ToString();
                        this.editNodesControl.y.Text      = Mathematics.floor(this.currentFullModel.geometryModel.editedNode.Y, Mathematics.accuracy_medium).ToString();
                        ReDrawAll(true);
                    }
                }
            }
            else
            {
                // подсвечиваем точки и линии

                MyPoint nearestPoint;
                if ((nearestPoint = currentFullModel.geometryModel.Points.Find(p => Math.Abs(clickPoint.X - p.X) < (double)visualizer.pointLocality && Math.Abs(clickPoint.Y - p.Y) < (double)visualizer.pointLocality)) != null)
                {
                    hoveredPoint = nearestPoint;
                    mouseXcord   = nearestPoint.X;
                    mouseYcord   = nearestPoint.Y;
                    ReDrawAll(true);
                }
                else
                {
                    if (hoveredPoint != null)
                    {
                        hoveredPoint = null;
                        ReDrawAll(true);
                    }
                }

                if (creatingCircle) // если мы в режиме рисования окружности
                {
                    if (this.currentFullModel.geometryModel.centerOfCircle != null)
                    {
                        double x1, y1;
                        if (hoveredPoint == null)
                        {
                            x1 = clickPoint.X; y1 = clickPoint.Y;
                        }
                        else
                        {
                            x1 = hoveredPoint.X; y1 = hoveredPoint.Y;
                        }

                        double radius = Mathematics.FindDist(x1, y1, currentFullModel.geometryModel.centerOfCircle.X, currentFullModel.geometryModel.centerOfCircle.Y);
                        if (this.addCirclesControl != null)
                        {
                            this.addCirclesControl.radius.Text = Mathematics.floor(radius, Mathematics.accuracy_medium).ToString();
                        }
                        currentFullModel.geometryModel.tempCircle = new MyCircle(this.currentFullModel.geometryModel.NumOfCircles + 1, this.currentFullModel.geometryModel.centerOfCircle, radius);
                        ReDrawAll(true);
                    }
                }
                if (activeControl is GridAnalysis)
                {
                    MyFiniteElementModel model = currentFullModel.FiniteElementModels.Find(m => m.ModelName == currentFullModel.currentGridName);
                    MyFiniteElement      elem  = model.FiniteElements.Find(el => Mathematics.ContainsPoint(el.Nodes.ToArray(), clickPoint));
                    if (elem != null)
                    {
                        elemInfoTooltip.ToolTipTitle = "Элемент №" + elem.Id.ToString();
                        StringBuilder tooltipText = new StringBuilder();
                        tooltipText.AppendLine("Площадь: " + Mathematics.floor(Mathematics.GeronLaw(elem.Nodes), 0.01));
                        double[] angles = Mathematics.getFEangles(elem);
                        for (int i = 0; i < 3; i++)
                        {
                            tooltipText.AppendLine("Угол " + (i + 1).ToString() + ": " + angles[i].ToString("###.##"));
                        }

                        elemInfoTooltip.Show(tooltipText.ToString(), constructionArea, new Point(e.X, e.Y));
                    }
                    else
                    {
                        elemInfoTooltip.Hide(constructionArea);
                    }
                }
            }
            this.textBox1.Text = Mathematics.floor(mouseXcord, Mathematics.accuracy_medium).ToString();
            this.textBox2.Text = Mathematics.floor(mouseYcord, Mathematics.accuracy_medium).ToString();
        }
Example #20
0
        // чтение вариантов сетки из файла (Рапперт)
        public void ReadRuppertVariants(string file)
        {
            string[] lines = File.ReadAllLines(file, Encoding.Default);

            int NRC               = Convert.ToInt32(lines[0]);
            int countOfZones      = Convert.ToInt32(lines[1]);
            int CountOfBasePoints = Convert.ToInt32(lines[2]);

            int j = 3;
            // создаем для новой сетки id
            MyFiniteElementModel model = new MyFiniteElementModel(currentModel.Id, currentModel.ModelName, MyFiniteElementModel.GridType.Ruppert);
            int cur = parent.GetCurrentModelIndex();

            model.INOUT = parent.currentFullModel.FiniteElementModels[cur].INOUT;

            model.NP = Convert.ToInt32(lines[j++]); // число узлов в варианте сетки

            model.CORD.Add(0.0);
            for (int n = 1; n <= model.NP; n++)
            {
                int    Number = Convert.ToInt32(lines[j++]);
                double X      = Convert.ToDouble(lines[j++].Replace(".", ","));
                double Y      = Convert.ToDouble(lines[j++].Replace(".", ","));
                //int SeNum = Convert.ToInt32(slines[j++]);
                //int ZoneNum = Convert.ToInt32(slines[j++]);
                //string s = slines[j++];
                //s = slines[j++];
                j += 9;

                model.Nodes.Add(new MyNode(X, Y, Number));
                model.CORD.Add(X);
                model.CORD.Add(Y);
            }

            model.NE = Convert.ToInt32(lines[j++]); // число КЭ в варианте сетки

            for (int e = 1; e <= model.NE; e++)
            {
                int Number   = Convert.ToInt32(lines[j++]);
                int Node1    = Convert.ToInt32(lines[j++]);
                int Node2    = Convert.ToInt32(lines[j++]);
                int Node3    = Convert.ToInt32(lines[j++]);
                int Material = Convert.ToInt32(lines[j++]);

                List <MyNode> nodes = new List <MyNode>();
                nodes = model.Nodes.FindAll(n => n.Id == Node1 || n.Id == Node2 || n.Id == Node3);
                MyFiniteElement elem = new MyFiniteElement(Number, Material, nodes);
                elem.DefineArea(parent.currentFullModel.geometryModel.Areas);
                model.FiniteElements.Add(elem);
                nodes.Clear();
            }

            model.NOP.Add(0);
            for (int i = 0; i < model.NE; i++)
            {
                int n1 = model.FiniteElements[i].Nodes[0].Id;
                int n2 = model.FiniteElements[i].Nodes[1].Id;
                int n3 = model.FiniteElements[i].Nodes[2].Id;
                model.NOP.Add(n1);
                model.NOP.Add(n2);
                model.NOP.Add(n3);
            }

            File.Delete(Path.GetDirectoryName(this.parent.FullProjectFileName) + "\\grid.Ralg");
            parent.ModelCreated(model);
        }
Example #21
0
        private void btnOk_Click(object sender, EventArgs e)
        {
            if (txtLine.Text == string.Empty && txtNode.Text == string.Empty)
            {
                return;
            }

            this.parent.precision          = this.parent.DefinePrecision();
            this.parent.showBounds.Checked = true;
            int number;
            int currentModel           = this.parent.GetCurrentModelIndex();
            MyFiniteElementModel model = this.parent.currentFullModel.FiniteElementModels[currentModel];

            if (rbnOnLine.Checked)
            {
                MyLine lineToBound;
                bool   error = false;
                if (!int.TryParse(this.txtLine.Text, out number))
                {
                    error = true;
                }
                lineToBound = parent.currentFullModel.geometryModel.Lines.Find(l => l.Id == number);
                if (lineToBound == null)
                {
                    error = true;
                }
                if (error)
                {
                    errorNoLine.Visible = true;
                    return;
                }
                UnboundLine(lineToBound);
            }
            else
            {
                MyNode nodeToBound;

                bool error = false;
                if (!int.TryParse(this.txtNode.Text, out number))
                {
                    error = true;
                }
                nodeToBound = model.Nodes.Find(n => n.Id == number);
                if (nodeToBound == null)
                {
                    error = true;
                }
                if (error)
                {
                    lblNoNode.Visible = true;
                    return;
                }
                UnboundNode(nodeToBound);
                renewNfixNB(currentModel);
                this.parent.DrawFEBounds(Color.Brown);

                this.txtNode.Text = "";
                this.txtNode.Select();
            }
            parent.ReDrawAll();
        }
        public void Regularization(int NRC, int zonesCount, MyFiniteElementModel model, int[] notMove)
        {
            //C ===================================================================
            //C REGULARIZATION - процедура оптимизации конечных элементов по углам
            //C вызывается из GRIDDM,
            //C вызывает модули FINDNODD, GET_STAR, FIND_MIN_ANG
            //C ===================================================================
            //C  входные параметры:
            //C    NRC  - параметр разбиения
            //C    zonesCount - число зон
            //C    NOPR - массив номеров узлов, сост-щих элементы
            //C    nodeRowsCount - число строк узлов в зоне ( равно NRC)
            //C    nodeColsCount - число столбцов узлов в зоне ( равно NRC)
            //C    CORDDR  - массив координат узлов
            //C    INOUTR - массив признаков узлов (узел граничный или внутренний)
            //C    NP - число узлов
            //C    NUMOFEL - число элементов
            //C  выходные параметры отсутствуют
            //C =================================================================
            //C ================ начало кода REGULARIZATION ======================


            int[]         EX    = { 0, 1, 0, -1, 0 };
            int[]         EY    = { 0, 0, 1, -0, -1 };
            double[]      CDNT  = new double[7];
            int[]         ISTAR = new int[101];
            List <double> CORD  = model.CORD;


            List <double> CORDDR_NO_OPT = new List <double>();
            List <int>    NOTMOVE       = new List <int>();

            int NOUTPNT,
            //IND,
                NSTEL, L, K, INDSTAR, JNDSTAR, KTIMES, MAXTIMES;
            double MINANG, NEWMINANG, NEWMINSIDE, STEP, COORX, COORY, MAXDELTA, CURDELTA, MANG, MODMANG, NEWMODMANG;
            double CURMINANG  = 0;
            double CURMINSIDE = 0;
            double MINSIDE    = 0;
            int    i;

            // NOTMOVE - массив для хранения номеров узлов, которые лежат на границе материалов
            // J - колличество элементов в массиве NOTMOVE

            //double X1,Y1;
            int MAXL = 3;

            int NP = model.NP;


            KTIMES   = 0;
            MAXTIMES = 100;

            NOUTPNT = (3 * NRC - 4) * zonesCount + NRC - (zonesCount - 1) * NRC;

            for (i = 0; i <= 2 * NP; i++)
            {
                CORDDR_NO_OPT.Add(0.0);
            }

            for (i = 1; i <= NP; i++)
            {
                CORDDR_NO_OPT[2 * (i - 1) + 1] = CORD[2 * (i - 1) + 1];
                CORDDR_NO_OPT[2 * (i - 1) + 2] = CORD[2 * (i - 1) + 2];
            }

            List <int> nullIndexes = new List <int>();
            int        index       = -1;

            while ((index = model.INOUT.IndexOf(0, index + 1)) != -1)
            {
                if (notMove[index] == 0)
                {
                    nullIndexes.Add(index);
                }
            }

            // Ищем соседние узлы для всех изменяемых узлов
            Dictionary <int, int[]> stars = new Dictionary <int, int[]>();

            foreach (int IND in nullIndexes)
            {
                stars.Add(IND, Get_Star(IND, model));
            }
            // -- число прогонов процедуры оптимизации
            do
            {
                KTIMES     = KTIMES + 1;
                MANG       = 1.0472;
                MODMANG    = 1.0472;
                NEWMODMANG = 1.0472;
                MAXDELTA   = 0.0;
                // -- цикл по узлам
                foreach (int IND in nullIndexes)
                {
                    // если текущий узел не принадлежит границе области и не относится к узлам,
                    // которые лежат на границе материалов
                    //IF ((INOUTR(IND).EQ.0).AND.(NTM(IND,NOTMOVE,J).EQ.0)) THEN

                    //* -- принадлежит ли узел границе области
                    //C ==============================================================
                    //C -- определяем звезду, соотв-ю данному узлу
                    //C =================================================================

                    ISTAR = stars[IND];
                    NSTEL = ISTAR.Count() / 3;
                    // -- найти более хорошее положение узла
                    // вычисление мин. угла при исходных коор-тах
                    // перебор эл-тов звезды
                    MINANG = 1.0472;
                    for (INDSTAR = 1; INDSTAR <= NSTEL; INDSTAR++)
                    {
                        // перебор узлов текущего эл-та
                        for (JNDSTAR = 1; JNDSTAR <= 3; JNDSTAR++)
                        {
                            // опр-ние коор-т узлов тек. эл-та для вычисл. мин. угла
                            CDNT[2 * (JNDSTAR - 1) + 1] = CORD[2 * (ISTAR[3 * (INDSTAR - 1) + JNDSTAR] - 1) + 1];
                            CDNT[2 * (JNDSTAR - 1) + 2] = CORD[2 * (ISTAR[3 * (INDSTAR - 1) + JNDSTAR] - 1) + 2];
                        }
                        // ==============================================================
                        //     Определение мин. угла в эл-те
                        // =================================================================
                        Find_Min_Ang(CDNT);

                        CURMINANG  = GLOBAL_MINANG;
                        CURMINSIDE = GLOBAL_MINSIDE;

                        // определение минимального угла звезды
                        if (MINANG > CURMINANG)
                        {
                            MINANG  = CURMINANG;
                            MINSIDE = CURMINSIDE;
                        }
                    }

                    // осуществляем оптимизацию положения узла
                    STEP = MINSIDE / 3.0;

                    for (L = 1; L <= MAXL; L++)
                    {
                        STEP = STEP / 2.0;

                        for (K = 1; K <= 4; K++)
                        {
                            COORX = CORD[2 * (IND - 1) + 1] + STEP * EX[K];
                            COORY = CORD[2 * (IND - 1) + 2] + STEP * EY[K];

                            // вычисление минимального звезды угла при новом положении узла
                            NEWMINANG = 1.0472;
                            for (INDSTAR = 1; INDSTAR <= NSTEL; INDSTAR++)
                            {
                                // перебор узлов текущего эл-та
                                for (JNDSTAR = 1; JNDSTAR <= 3; JNDSTAR++)
                                {
                                    // опр-ние коор-т узлов тек. эл-та для вычисл. мин. угла
                                    // если это оптимизируемый узел, принять новые координаты
                                    if (ISTAR[3 * (INDSTAR - 1) + JNDSTAR] == IND)
                                    {
                                        CDNT[2 * (JNDSTAR - 1) + 1] = COORX;
                                        CDNT[2 * (JNDSTAR - 1) + 2] = COORY;
                                    }
                                    else
                                    {
                                        CDNT[2 * (JNDSTAR - 1) + 1] = CORD[2 * (ISTAR[3 * (INDSTAR - 1) + JNDSTAR] - 1) + 1];
                                        CDNT[2 * (JNDSTAR - 1) + 2] = CORD[2 * (ISTAR[3 * (INDSTAR - 1) + JNDSTAR] - 1) + 2];
                                    }
                                }
                                // ==============================================================
                                // вычисление мин. угла и стороны тек. эл-та звезды
                                // =================================================================

                                Find_Min_Ang(CDNT);

                                CURMINANG  = GLOBAL_MINANG;
                                CURMINSIDE = GLOBAL_MINSIDE;

                                //* определение минимального угла звезды
                                if (NEWMINANG > CURMINANG)
                                {
                                    NEWMINANG  = CURMINANG;
                                    NEWMINSIDE = CURMINSIDE;
                                }
                            }

                            // Определение минимального угла из всех
                            // нужно лишь для проверки
                            if (MINANG <= MANG)
                            {
                                MANG = MINANG;
                            }

                            // выяснить, лучше ли нов. коор. узла, т.е. увеличился ли мин. угол
                            if (NEWMINANG > MINANG)
                            {
                                CURDELTA = NEWMINANG - MINANG;
                                if (CURDELTA > MAXDELTA)
                                {
                                    MAXDELTA = CURDELTA;
                                }
                                //* Определение минимального измененного угла из всех
                                //* нужно лишь для проверки
                                if (MODMANG >= MINANG)
                                {
                                    MODMANG = MINANG;
                                }
                                if (NEWMODMANG >= NEWMINANG)
                                {
                                    NEWMODMANG = NEWMINANG;
                                }
                                CORD[2 * (IND - 1) + 1] = COORX;
                                CORD[2 * (IND - 1) + 2] = COORY;
                                MINANG = NEWMINANG;
                                continue;
                            }
                        }
                        Application.DoEvents();
                    }
                }
            } while (MAXDELTA > (0.001) && KTIMES < MAXTIMES);
        }
        private void okButton_Click(object sender, EventArgs e)
        {
            List <string> lineStrings = new List <string>(this.notMoveLines.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList <string>());
            List <MyLine> fixedLines  = new List <MyLine>();

            foreach (string str in lineStrings)
            {
                int idx;
                if (!int.TryParse(str, out idx))
                {
                    MessageBox.Show("Неверно заданы линии!");
                    return;
                }

                MyLine line = (MyLine)parent.currentFullModel.geometryModel.StraightLines.Find(l => l.Id == idx) ?? (MyLine)parent.currentFullModel.geometryModel.Arcs.Find(a => a.Id == idx);
                if (line == null)
                {
                    MessageBox.Show("Не найдена линия с номером " + idx.ToString());
                    return;
                }
                fixedLines.Add(line);
            }
            parent.precision = parent.DefinePrecision();
            if (parent.currentFullModel.geometryModel.Areas.Count != 0)
            {
                errorMessage1.Visible    = false;
                errorBadGridName.Visible = false;

                // создаем новый объект "конечно-элементная модель" и добавляем его в список конечно-элементных моделей.
                foreach (MyFiniteElementModel model in parent.currentFullModel.FiniteElementModels) // проверяем, нет ли модели с таким именем
                {
                    if (model.ModelName == gridName.Text)
                    {
                        errorBadGridName.Visible = true;
                        return;
                    }
                }
                this.Hide();
                parent.StartProgress("Выполняется оптимизация");
                // создаем для новой КЭ модели id
                int id = parent.currentFullModel.IdCandidate;
                currentModel           = (MyFiniteElementModel)Util.getObjectCopy(currentModel);
                currentModel.ModelName = gridName.Text;
                currentModel.Id        = id;
                currentModel.restoreArraysForOldMethods(parent.currentFullModel.geometryModel);

                int[] notMove = new int[currentModel.INOUT.Count];
                notMove.Initialize();
                if (notMoveLines.TextLength != 0)
                {
                    foreach (MyLine fixedLine in fixedLines)
                    {
                        List <MyNode> tempNodes = new List <MyNode>();
                        if (fixedLine is MyStraightLine)
                        {
                            findNodesAtStraightLine(tempNodes, (MyStraightLine)fixedLine);
                            foreach (MyNode node in tempNodes)
                            {
                                node.Type        = NodeType.Fixed;
                                notMove[node.Id] = 1;
                            }
                        }
                        else
                        {
                            findNodesAtArc(tempNodes, (MyArc)fixedLine);
                            foreach (MyNode node in tempNodes)
                            {
                                node.Type        = NodeType.Fixed;
                                notMove[node.Id] = 1;
                                //currentModel.INOUT[node.Id] = 1;
                            }
                        }
                    }
                }

                Regularization(currentModel.NRC, parent.currentFullModel.geometryModel.Areas.Count, currentModel, notMove);
                currentModel.FiniteElements.Clear();
                currentModel.Nodes.Clear();

                for (int i = 1; i <= currentModel.NP; i++) // MAXNP - число узлов
                {
                    currentModel.Nodes.Add(new MyNode(currentModel.CORD[2 * (i - 1) + 1], currentModel.CORD[2 * (i - 1) + 2], i));
                }

                for (int temp = 1; temp <= currentModel.NE; temp++)
                {
                    int           numOfFE    = currentModel.FiniteElements.Count;
                    int           numOfNodes = currentModel.Nodes.Count;
                    List <MyNode> tempNodes  = new List <MyNode>();

                    double X1 = currentModel.CORD[2 * (currentModel.NOP[3 * (temp - 1) + 1] - 1) + 1];
                    double Y1 = currentModel.CORD[2 * (currentModel.NOP[3 * (temp - 1) + 1] - 1) + 2];
                    double X2 = currentModel.CORD[2 * (currentModel.NOP[3 * (temp - 1) + 2] - 1) + 1];
                    double Y2 = currentModel.CORD[2 * (currentModel.NOP[3 * (temp - 1) + 2] - 1) + 2];
                    double X3 = currentModel.CORD[2 * (currentModel.NOP[3 * (temp - 1) + 3] - 1) + 1];
                    double Y3 = currentModel.CORD[2 * (currentModel.NOP[3 * (temp - 1) + 3] - 1) + 2];

                    foreach (MyNode node in currentModel.Nodes)
                    {
                        if (Math.Abs(node.X - X1) <= 0.001 && Math.Abs(node.Y - Y1) <= 0.001)
                        {
                            tempNodes.Add(node);
                        }
                        if (Math.Abs(node.X - X2) <= 0.001 && Math.Abs(node.Y - Y2) <= 0.001)
                        {
                            tempNodes.Add(node);
                        }
                        if (Math.Abs(node.X - X3) <= 0.001 && Math.Abs(node.Y - Y3) <= 0.001)
                        {
                            tempNodes.Add(node);
                        }
                    }
                    MyFiniteElement elem = new MyFiniteElement(numOfFE + 1, 0, tempNodes);
                    elem.DefineArea(parent.currentFullModel.geometryModel.Areas);
                    currentModel.FiniteElements.Add(elem);
                    tempNodes.Clear();
                }
                parent.EndProgress();
                parent.ModelCreated(currentModel);
                Close();
            }
            else
            {
                errorMessage1.Visible = true;
            }
        }
Example #24
0
        public static void restoreArraysForOldMethods(this MyFiniteElementModel model, MyGeometryModel geomModel)
        {
            // Восстанавливаем закрепленные узлы
            List <MyNode> boundedNodes = model.Nodes.FindAll(n => n.BoundType != 0);

            // Восстанавливаем закрепленные узлы
            model.NBC.Clear();
            model.NB  = boundedNodes.Count;
            model.NBC = boundedNodes.ConvertAll(n => n.Id);
            model.NBC.Insert(0, 0);

            // Типы закреплений
            model.NFIX.Clear();
            model.NFIX = boundedNodes.ConvertAll(n => n.BoundType);
            model.NFIX.Insert(0, 0);

            // Нагрузки
            model.R.Clear();
            model.Nodes.ConvertAll(n => new double[] { n.ForceX, n.ForceY }).ForEach(pair => model.R.AddRange(pair));
            model.R.Insert(0, 0.0);

            // Сами узлы
            model.NP = model.Nodes.Count;
            model.Nodes.Sort((n, m) => n.Id.CompareTo(m.Id));
            model.CORD.Clear();
            model.Nodes.ConvertAll(n => new double[] { n.X, n.Y }).ForEach(pair => model.CORD.AddRange(pair));
            model.CORD.Insert(0, 0.0);

            // Конечные элементы
            model.NE = model.FiniteElements.Count;
            model.NOP.Clear();
            model.NOP.Insert(0, 0);
            if (model.IMAT.Count == 0)
            {
                model.IMAT = new List <int>();
            }
            for (int i = 0; i <= model.NE; i++)
            {
                model.IMAT.Add(0);
            }
            foreach (MyFiniteElement elem in model.FiniteElements)
            {
                List <MyNode> nodes = new List <MyNode>(elem.Nodes);
                // сортировка узлов КЭ против часовой стрелке //
                double[] angle = new double[3];
                for (int i = 1; i < 3; i++)
                {
                    angle[i] = Math.Atan2(nodes[i].Y - nodes[0].Y, nodes[i].X - nodes[0].X);
                    if (angle[i] < 0)
                    {
                        angle[i] += Math.PI * 2;
                    }
                }
                model.NOP.Add(nodes[0].Id);
                if (angle[1] > angle[2])
                {
                    if (angle[1] - angle[2] < Math.PI)
                    {
                        model.NOP.Add(nodes[2].Id);
                        model.NOP.Add(nodes[1].Id);
                    }
                    else
                    {
                        model.NOP.Add(nodes[1].Id);
                        model.NOP.Add(nodes[2].Id);
                    }
                }
                else
                {
                    if (angle[2] - angle[1] < Math.PI)
                    {
                        model.NOP.Add(nodes[2].Id);
                        model.NOP.Add(nodes[1].Id);
                    }
                    else
                    {
                        model.NOP.Add(nodes[2].Id);
                        model.NOP.Add(nodes[1].Id);
                    }
                }
            }

            // восстанавливаем принадлежность к зонам
            foreach (MyFiniteElement elem in model.FiniteElements)
            {
                elem.DefineArea(geomModel.Areas);
            }

            model.INOUT.Clear();
            model.INOUT.Add(1);
            foreach (MyNode node in model.Nodes)
            {
                int nodeCount = model.INOUT.Count;
                foreach (MyFiniteElement elem in node.finiteElements)
                {
                    MyArea inspectArea = geomModel.Areas.Find(area => area.Id == elem.areaId + 1);
                    double precision   = (model.baseType == MyFiniteElementModel.GridType.Delauney || model.type == MyFiniteElementModel.GridType.FrontalMethod) ? 0.01 : -1;
                    if (inspectArea.StraightLines.Find(line => Mathematics.pointOnLine(node, line) && line.Areas.Count == 1) != null)
                    {
                        model.INOUT.Add(1);
                    }
                    else if (inspectArea.Arcs.Find(arc => Mathematics.pointFitsArc(node, arc, precision) && arc.Areas.Count == 1) != null)
                    {
                        model.INOUT.Add(1);
                    }
                    if (model.INOUT.Count != nodeCount)
                    {
                        break;
                    }
                }
                if (nodeCount == model.INOUT.Count)
                {
                    model.INOUT.Add(0);
                }
            }
        }