• Приложение Б. Исходный код некоторых алгоритмов системы. Триангуляция фронтальным методом: функции Mesh() и AddElem()
  • Процедура регуляризации



  • страница32/32
    Дата11.07.2018
    Размер4.51 Mb.

    Описание препроцессора


    1   ...   24   25   26   27   28   29   30   31   32


    1. Прикладываем нагрузки: при открытой форме нагрузок щелкаем по линиям 9 и 10. Указываем функцию нагрузки, остальные параметры пока не меняем. Нажимаем «добавить нагрузку»:








    1. Прикладываем нагрузки к другим линиям. Для вертикальной линии поставим «Сортировка» : «по Y», «Тип сортировки» : «<» (по убыванию). Для горизонтальной оставим сортировку по Х, но поставим тип сортировки «<». Вместе с закреплениями после этого пластина будет выглядеть так:



    1. Осталось назначить материалы. Перейдем в модуль «назначение материалов», нажмем «выбрать все зоны» и кнопку «сохранить»:




    1. Импортируем пластину: нажимаем кнопку импорта и выбираем «импортировать модель целиком». Выбираем путь и нажимаем сохранить. В целевой папке должны появиться 6 файлов:



    1. Создаем проект Sigma в указанной папке. В конфигурации проекта указываем путь к файлу с формой, созданном в препроцессоре. При компиляции и расчете проекта, будут подтянуты данные импортированные из препроцессора. Результат расчет выглядит так:

    А максимальное эквивалентное напряжение равно 15953.8, что почти на 10% больше значения, полученного при расчете на «родной» для Sigma сетке. Это ещё раз показывает, как сильно влияет конфигурация сетки на расчеты МКЭ.


    Приложение Б. Исходный код некоторых алгоритмов системы.

    1. Триангуляция фронтальным методом: функции Mesh() и AddElem()

    private void Mesh() // Формирование и построение сетки КЭ

    {

    feNumber = 1;



    ExternalFront = new List();

    this.Paint -= MethodForm_Paint;

    DisableControls();

    for (int i = 0; i < Front.Count; i++)

    {

    Front[i].finiteElems.Clear();



    ExternalFront.Add(MyFrontSegment.createCopy(Front[i]));

    }

    meshProgress.Show();



    meshProgress.progressBar1.Value = 0;

    totalNodes = Front.Sum(s => s.Nodes.Count);

    currentNodes = totalNodes;

    for (int j = 0; j < cZoneCount; j++) // Выполняем цикл для каждой зоны

    {

    currentSegAngles = null;



    while (ExternalFront[j].Nodes.Count > 3) // Если длина фронта ещё может быть разбита

    {

    if (!AddElem(j)) return;



    meshProgress.progressBar1.Value = (int)(100.0 * (1.0 - (double)currentNodes / totalNodes));

    meshProgress.Refresh();

    Application.DoEvents();

    }

    // Добавляем последний треугольник к списку треугольников



    Front[j].finiteElems.Add(new MyFiniteElement(feNumber++, 0, ExternalFront[j].Nodes, j));

    currentNodes -= 3;

    meshProgress.progressBar1.Value = (int)(100.0 * (1.0 - (double)currentNodes / totalNodes));

    meshProgress.Refresh();

    Application.DoEvents();

    }

    endMesh();



    this.Paint += MethodForm_Paint;

    meshProgress.Hide();

    }
    private bool AddElem(int frontNum)

    {

    int IndexMinAngle;



    if (currentSegAngles == null)

    {

    currentSegAngles = new Dictionary();



    for (int k = 0; k < ExternalFront[frontNum].Nodes.Count; k++)

    {

    double angle = FindAngle(k, frontNum);



    currentSegAngles.Add(ExternalFront[frontNum].Nodes[k], angle);

    }

    }



    currentSegAngles = (from entry in currentSegAngles orderby entry.Value ascending select entry).ToDictionary(pair => pair.Key, pair => pair.Value);

    IndexMinAngle = ExternalFront[frontNum].Nodes.IndexOf(currentSegAngles.First().Key);

    MinAngle = currentSegAngles.First().Value;

    if ((MinAngle <= fMiterAngle) || Math.Abs(MinAngle - fMiterAngle) < 0.1)

    {

    int iLeftPoint = -1, iRightPoint = -1;



    FindLeftRightIndex2(IndexMinAngle, out iLeftPoint, out iRightPoint, frontNum);

    MyNode[] Triangle = new MyNode[3]; // Добавление треугольника к списку

    Triangle[0] = ExternalFront[frontNum].Nodes[iLeftPoint];

    Triangle[1] = ExternalFront[frontNum].Nodes[iRightPoint];

    Triangle[2] = ExternalFront[frontNum].Nodes[IndexMinAngle];

    MyFiniteElement fe = new MyFiniteElement(feNumber++, 0, Triangle, frontNum);

    Front[frontNum].finiteElems.Add(fe);

    currentSegAngles.Remove(ExternalFront[frontNum].Nodes[IndexMinAngle]);

    ExternalFront[frontNum].Nodes.RemoveAt(IndexMinAngle);

    currentSegAngles[Triangle[0]] = FindAngle(ExternalFront[frontNum].Nodes.IndexOf(Triangle[0]), frontNum);

    currentSegAngles[Triangle[1]] = FindAngle(ExternalFront[frontNum].Nodes.IndexOf(Triangle[1]), frontNum);

    currentNodes--;

    }

    else


    {

    int iLeftPoint = -1, iRightPoint = -1;

    FindLeftRightIndex2(IndexMinAngle, out iLeftPoint, out iRightPoint, frontNum);

    MyNode oldPoint = ExternalFront[frontNum].Nodes[IndexMinAngle];

    MyNode newPoint = AddPoint(IndexMinAngle, MinAngle, frontNum);

    if (newPoint == null)

    return false;

    MyNode[] Triangle = new MyNode[3];

    Triangle[0] = ExternalFront[frontNum].Nodes[iLeftPoint];

    Triangle[1] = oldPoint; // Формируем координаты треугольника для добавления к списку

    Triangle[2] = newPoint;

    Front[frontNum].finiteElems.Add(new MyFiniteElement(feNumber++, 0, Triangle, frontNum));

    Triangle[0] = ExternalFront[frontNum].Nodes[iRightPoint];

    Triangle[1] = oldPoint; // Формируем координаты треугольника для добавления к списку

    Triangle[2] = newPoint;

    Front[frontNum].finiteElems.Add(new MyFiniteElement(feNumber++, 0, Triangle, frontNum));

    currentSegAngles.Remove(oldPoint);

    currentSegAngles[ExternalFront[frontNum].Nodes[iRightPoint]] = FindAngle(iRightPoint, frontNum);

    currentSegAngles[ExternalFront[frontNum].Nodes[iLeftPoint]] = FindAngle(iLeftPoint, frontNum);

    currentSegAngles[ExternalFront[frontNum].Nodes[IndexMinAngle]] = FindAngle(IndexMinAngle, frontNum);

    }

    return true;



    }


    1. Процедура регуляризации

    private void Regularize(List dontMove) // Регуляризация

    {

    MyNode p = new MyNode(); // новая точка



    double delta;

    this.Hide();

    parent.StartProgress("Выполняется регуляризация");

    int maxCycles = 500;

    Dictionary> nodeStars = new Dictionary>();

    foreach (MyNode node in currentModel.Nodes)

    {

    List nearestNodes = new List();



    List nearestElems = currentModel.FiniteElements.FindAll(fe => fe.Nodes.Contains(node));

    foreach (MyFiniteElement fe in nearestElems)

    foreach (MyNode nearestNode in fe.Nodes) if (!nearestNodes.Contains(nearestNode) && nearestNode != node) nearestNodes.Add(nearestNode);

    nodeStars.Add(node, nearestNodes);

    Application.DoEvents();

    }

    do



    {

    delta = -1;

    foreach (MyNode node in currentModel.Nodes)

    {

    if (dontMove.Contains(node)) continue;



    List starNodes = nodeStars[node];
    // Вычисляем новые координаты точки

    double X = 0, Y = 0; // новые координаты точки

    for (int k = 0; k < starNodes.Count; k++)

    {

    X += starNodes[k].X;



    Y += starNodes[k].Y;

    }

    X = X / starNodes.Count;



    Y = Y / starNodes.Count;

    double newDelta = Math.Max(Math.Abs(X - node.X), Math.Abs(Y - node.Y));

    if (delta < 0)

    delta = newDelta;

    else

    delta = Math.Max(delta, newDelta);


    node.X = X;

    node.Y = Y;


    }

    } while (delta > 0.01 && maxCycles-- > 0);

    parent.EndProgress();

    }
    35




    1   ...   24   25   26   27   28   29   30   31   32

    Коьрта
    Контакты

        Главная страница


    Описание препроцессора