Для запуска программы следует запустить файл WindowsFormApplication1\bin\Debug\WindowsFormsApplication1.exe или WindowsFormsApplication1.sln (если установлен Microsoft Visual C#2008 или выше) и в запустившейся программе нажать функциональную клавишу F5.
В появившемся окне ввести необходимые размеры деталей, точность и нагрузку. Нагрузку можно задать 2-умя способами:
. Задать нагрузку с боков гайки (Рисунок 9).
Рисунок 9 - Задание нагрузки с боков гайки
2. Задать нагрузку фронтально (Рисунок 10).
Рисунок 10 - Задание нагрузки фронтально
Затем можно начать вычисления, нажав на кнопку «Вычислить».
В случае если длины болта хватило, то будет выведено сообщение с ответом:
«Расчет закончен. Для восприятия нагрузки болт должен иметь N витков.»
Где N - искомое число витков.
Иначе, будет выведено сообщение: «Длина болта слишком мала. Что бы болт мог выдержать нагрузку измените размеры болта.»
В случае если число витков найдено - появятся две кнопки «Исходная
резьба» и «Резьба после деформации» (Рисунок 11).
Рисунок 11 - Кнопки, появившиеся после успешного завершения расчетов
По нажатию на одну из этих кнопок появится форма, по нажатию на которую, появится изображение резьбы.
математический трапецеидальный верификация пользователь
3.3 Верификация
Для проверки соответствия полученных в программе данных использовался конечно-элементный пакет ANSYS.
Алгоритм проведения верификации в данной работе следующий:
. Нанесение сетки в программе.
. Расчет смещений узлов вследствие приложения нагрузки.
. Перенос координат узлов в ANSYS.
. Создание модели в ANSYS по найденным точкам.
. Решение полученной модели (Рисунок 12).
. Вывод результатов в файл.
. Визуализация полученных данных.
. Сравнение.
Рисунок 12 - Решение полученной модели в ANSYS
.4 Вычислительный эксперимент
Для эксперимента возьмем следующие данные:
|
Параметр |
Значение |
|
Ширина шляпки |
1 |
|
Диаметр шляпки |
10 |
|
Длина конца болта |
10 |
|
Диаметр резьбы |
6 |
|
Шаг резьбы |
1 |
|
Толщина гайки |
5 |
|
Точность |
1 |
|
Нагрузка |
100 |
Рисунок 13 - Заполнение исходных данных
Далее необходимо нажать кнопку «Вычислить».
После завершения расчетов выводится ответ (Рисунок 14).
Рисунок 14 - Ответ
Резьба после деформации будет выглядеть, как показано на рисунках 15, 16.
Рисунок 15 - Резьба после деформации при нагрузке заданной фронтально
Рисунок 16 - Резьба после деформации при нагрузке заданной с боков
Визуализация в программе, считывающей решение из ANSYS, и представляя их графически (Рисунок 17).
Рисунок 16 - Резьба после деформации при нагрузке заданной фронтально,
реализация в ANSYS.
Заключение
В ходе выполнения курсовой работы были получены необходимые теоретические знания о методах математического моделирования, возможностях их реализации в программах.
В результате выполнения курсовой работы была построена математическая модель резьбового соединения, с трапецеидальной резьбой, а так же разработана программа, выполняющая вычисление количества витков необходимого для восприятия осевой сжимающей нагрузки.
Был изучен метод аппроксимации физической модели математической, с использованием метода конечных элементов.
Данный метод является универсальным для большого типа задач.
На базе метода конечных элементов создано много конечно-элементных
пакетов, таких как ANSYS, ABAQUS, Impact и т.д.
Список использованных источников
1. Введение в метод конечных элементов, Норри Д., Фриз Ж. - 74 с.
. Зенкевич О. - Метод конечных элементов в технике. -17 c.
. Теория метода конечных элементов, Стренг Г., Фикс Дж. -90 c.
. Турчак Л.И. П.В. Плотников. - Основы численных методов. -52 с.
. С.Ф. Клованич. - Метод конечных элементов в нелинейных задачах инженерной механики. -9,10 с.
. А.
О. Шимановский, А. В. Путято. - Применение метода конечных элементов в решении
задач прикладной механики. -66 с.
Приложение. Текст программы
Form1.cs
using System;System.Collections.Generic;System.ComponentModel;System.Data;System.Drawing;System.Text;System.Windows.Forms;System.Threading;System.IO;WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//
}
void Form1_DoubleClick(object sender, EventArgs e)
{
int n=coord_do.Count;
int []mass=new int[coord_do.Count];
StreamWriter stream_wr = new StreamWriter("variables.txt",false);
stream_wr.WriteLine("/PREP7");
string str = "";
for (int i = 0; i < n; i++)
{
if (coord_do[i].c != Color.Black)
{
if (mass[listGI[i].ind[0]] == 0)
{
stream_wr.Write("K," + (listGI[i].ind[0] + 1) + ",");
str = coord_do[i].x1.ToString();
stream_wr.Write("" + str.Replace(",", ".") + ",");
str = coord_do[i].y1.ToString();
stream_wr.WriteLine("" + str.Replace(",", ".") + ",,");
mass[listGI[i].ind[0]] = 1;
}
if (mass[listGI[i].ind[1]] == 0)
{
stream_wr.Write("K," + (listGI[i].ind[1] + 1) + ",");
str = coord_do[i].x2.ToString();
stream_wr.Write("" + str.Replace(",", ".") + ",");
str = coord_do[i].y2.ToString();
stream_wr.WriteLine("" + str.Replace(",", ".") + ",,");
mass[listGI[i].ind[1]] = 1;
}
if (mass[listGI[i].ind[2]] == 0)
{
stream_wr.Write("K," + (listGI[i].ind[2] + 1) + ",");
str = coord_do[i].x3.ToString();
stream_wr.Write("" + str.Replace(",", ".") + ",");
str = coord_do[i].y3.ToString();
stream_wr.WriteLine("" + str.Replace(",", ".") + ",,");
mass[listGI[i].ind[2]] = 1;
}
}
}
stream_wr.WriteLine("FINISH");
stream_wr.Close();
MessageBox.Show("Координаты узлов записаны в файл.");
}
#region AznamenA(double x1, double x2, double x3, double y1, double y2, double y3)
{
return x1 * y2 - x2 * y1 - x1 * y3 + x3 * y1 + x2 * y3 - x3 * y2;
}
double elemA(double e1, double e2, double e3, double e4, double zn)
{
return (e1 * e2 + e3 * e4) / zn;
}
double[,] matrA(double x1, double x2, double x3, double y1, double y2, double y3)
{
double[,] matr = new double[6, 6];
double znamenatel = znamenA(x1, x2, x3, y1, y2, y3);
matr[0, 0] = elemA(x2, y3, (-1) * x3, y2, znamenatel);
matr[0, 1] = elemA(1, y2, (-1), y3, znamenatel);
matr[0, 2] = -elemA(x2, 1, (-1) * x3, 1, znamenatel);
matr[1, 3] = matr[0, 0];
matr[1, 4] = matr[0, 1];
matr[1, 5] = matr[0, 2];
matr[2, 0] = -elemA(x1, y3, (-1) * x3, y1, znamenatel);
matr[2, 1] = -elemA(1, y1, (-1), y3, znamenatel);
matr[2, 2] = elemA(x1, 1, (-1) * x3, 1, znamenatel);
matr[3, 3] = matr[2, 0];
matr[3, 4] = matr[2, 1];
matr[3, 5] = matr[2, 2];
matr[4, 0] = elemA(x1, y2, (-1) * x2, y1, znamenatel);
matr[4, 1] = elemA(1, y1, (-1), y2, znamenatel);
matr[4, 2] = -elemA(x1, 1, (-1) * x2, 1, znamenatel);
matr[5, 3] = matr[4, 0];
matr[5, 4] = matr[4, 1];
matr[5, 5] = matr[4, 2];
return matr;
}
#endregion
#region Edouble[,] matrE(double muy, double G)
{
double[,] E = new double[3, 3];
double c = G / (1 - muy * muy);
E[0, 0] = c;
E[0, 1] = muy * c;
E[1, 1] = c;
E[1, 0] = muy * c;
E[2, 2] = (1 - muy) * c / 2;
return E;
}
#endregion
#region Qdouble[,] matrQ()
{
double[,] Q = new double[3, 6];
Q[0, 1] = 1;
Q[1, 5] = 1;
Q[2, 2] = 1;
Q[2, 4] = 1;
return Q;
}
#endregion
#region Multiplication[,] Multiplication(double[,] a, double[,] b)
{
if (a.GetLength(1) != b.GetLength(0)) throw new Exception("Матрицы нельзя перемножить");
double[,] r = new double[a.GetLength(0), b.GetLength(1)];
for (int i = 0; i < a.GetLength(0); i++)
{
for (int j = 0; j < b.GetLength(1); j++)
{
for (int k = 0; k < b.GetLength(0); k++)
{
r[i, j] += a[i, k] * b[k, j];
}
}
}
return r;
}
#endregion
static bool Conver(double[] xx, double[] xp, double epsi)
{
for (int i = 0; i < xx.Length; i++)
if (Math.Abs(xx[i] - xp[i]) >= epsi) return false;
return true;
}
static void MethodGZ(double[,] A, double[] b, ref double[] x, double eps)
{
double[] p = new double[b.Length];
double var = 0;
do
{
for (int i = 0; i < b.Length; i++)
{
var = 0;
for (int j = 0; j < b.Length; j++)
{
if (i != j) var += A[i, j] * x[j];
}
p[i] = x[i];
Console.WriteLine("" + x[0] + " " + x[1] + " " + x[2]);
Console.ReadKey();
x[i] = (b[i] - var) / A[i, i];
}
}
while (!Conver(x, p, eps));
}
private void button1_Click(object sender, EventArgs e)
{
this.DoubleClick-= new EventHandler(Form1_DoubleClick);
list_coord.Clear();
listAt.Clear();
Rezba.b = double.Parse(textBox1.Text);
Rezba.D = double.Parse(textBox2.Text);
Rezba.l = double.Parse(textBox4.Text);
Rezba.d1 = double.Parse(textBox5.Text);
Rezba.p = double.Parse(textBox6.Text);
Rezba.bg = double.Parse(textBox3.Text);
Rezba.eps = double.Parse(textBox7.Text);
//Rezba.lg = int.Parse(textBox8.Text);
Rezba.H = Rezba.p / 2;
Rezba.d3 = Rezba.d1 - Rezba.p;
Rezba.d2 = Rezba.d1 - Rezba.H;
this.DoubleClick += new EventHandler(Form1_DoubleClick);
}
List<Uzl_Coord> coord_do = new List<Uzl_Coord>();
List<Uzl_Coord> list_coord = new List<Uzl_Coord>();
List<Uzl_Coord> list_coord_invert = new List<Uzl_Coord>();
List<Uzl_Coord> list_coord_rez = new List<Uzl_Coord>();
List<matrAclass> listAt = new List<matrAclass>();
List<matrKLOCclass> listKLOC = new List<matrKLOCclass>();
List<globindexes> listGI = new List<globindexes>();
List<globindexes> listGIBuf = new List<globindexes>();
Uzl_Coord vozvr_uzl(double x1, double x2, double x3, double y1, double y2, double y3)
{
Uzl_Coord p=new Uzl_Coord();
p.x1 = x1;
p.x2 = x2;
p.x3 = x3;
p.y1 = y1;
p.y2 = y2;
p.y3 = y3;
return p;
}
private double max(double[] m)
{
double max = 0;
double x=0, y=0;
for (int i = 0; i < listGI.Count;i++ )
{
if (list_coord_rez[i].c == Color.Gray)
{
if (max < Math.Sqrt(m[listGI[i].ind[0] * 2] * m[listGI[i].ind[0] * 2] + m[listGI[i].ind[0] * 2+1] * m[listGI[i].ind[0] * 2+1]))
{
max = Math.Sqrt(m[listGI[i].ind[0] * 2] * m[listGI[i].ind[0] * 2] + m[listGI[i].ind[0] * 2 + 1] * m[listGI[i].ind[0] * 2 + 1]);
x = m[listGI[i].ind[0] * 2]; y = m[listGI[i].ind[0] * 2+1];
}
if (max < Math.Sqrt(m[listGI[i].ind[1] * 2] * m[listGI[i].ind[1] * 2] + m[listGI[i].ind[1] * 2 + 1] * m[listGI[i].ind[1] * 2 + 1]))
{
max = Math.Sqrt(m[listGI[i].ind[1] * 2] * m[listGI[i].ind[1] * 2] + m[listGI[i].ind[1] * 2 + 1] * m[listGI[i].ind[1] * 2 + 1]);
x = m[listGI[i].ind[1] * 2]; y = m[listGI[i].ind[1] * 2 + 1];
}
if (max < Math.Sqrt(m[listGI[i].ind[2] * 2] * m[listGI[i].ind[2] * 2] + m[listGI[i].ind[2] * 2 + 1] * m[listGI[i].ind[2] * 2 + 1]))
{
max = Math.Sqrt(m[listGI[i].ind[2] * 2] * m[listGI[i].ind[2] * 2] + m[listGI[i].ind[2] * 2 + 1] * m[listGI[i].ind[2] * 2 + 1]);
x = m[listGI[i].ind[2] * 2]; y = m[listGI[i].ind[2] * 2 + 1];
}
}
}
return max;
}
private double max2(double[] m)
{
double max = 0;
double x = 0, y = 0;
for (int i = 0; i < listGI.Count; i++)
{
if (list_coord_rez[i].c != Color.Black)
{
if (max < Math.Sqrt(m[listGI[i].ind[0] * 2] * m[listGI[i].ind[0] * 2] + m[listGI[i].ind[0] * 2 + 1] * m[listGI[i].ind[0] * 2 + 1]))
{
max = Math.Sqrt(m[listGI[i].ind[0] * 2] * m[listGI[i].ind[0] * 2] + m[listGI[i].ind[0] * 2 + 1] * m[listGI[i].ind[0] * 2 + 1]);
x = m[listGI[i].ind[0] * 2]; y = m[listGI[i].ind[0] * 2 + 1];
}
if (max < Math.Sqrt(m[listGI[i].ind[1] * 2] * m[listGI[i].ind[1] * 2] + m[listGI[i].ind[1] * 2 + 1] * m[listGI[i].ind[1] * 2 + 1]))
{
max = Math.Sqrt(m[listGI[i].ind[1] * 2] * m[listGI[i].ind[1] * 2] + m[listGI[i].ind[1] * 2 + 1] * m[listGI[i].ind[1] * 2 + 1]);
x = m[listGI[i].ind[1] * 2]; y = m[listGI[i].ind[1] * 2 + 1];
}
if (max < Math.Sqrt(m[listGI[i].ind[2] * 2] * m[listGI[i].ind[2] * 2] + m[listGI[i].ind[2] * 2 + 1] * m[listGI[i].ind[2] * 2 + 1]))
{
max = Math.Sqrt(m[listGI[i].ind[2] * 2] * m[listGI[i].ind[2] * 2] + m[listGI[i].ind[2] * 2 + 1] * m[listGI[i].ind[2] * 2 + 1]);
x = m[listGI[i].ind[2] * 2]; y = m[listGI[i].ind[2] * 2 + 1];
}
}
}
return max;
}
private double max_in_all(double[] m)
{
double max = 0;
double x = 0, y = 0;
for (int i = 0; i < listGI.Count; i++)
{
if (list_coord_rez[i].c != Color.Black)
{
if (Math.Abs(x) < Math.Abs(m[listGI[i].ind[0] * 2]))
{
x = m[listGI[i].ind[0] * 2];
}
if (Math.Abs(x) <Math.Abs(m[listGI[i].ind[1] * 2]))
{
x = m[listGI[i].ind[1] * 2];
}
if (Math.Abs(x) <Math.Abs(m[listGI[i].ind[2] * 2]))
{
x = m[listGI[i].ind[2] * 2];
}
if (Math.Abs(y) <Math.Abs( m[listGI[i].ind[0] * 2 + 1]))
{
y = m[listGI[i].ind[0] * 2 + 1];
}
if (Math.Abs(y) <Math.Abs( m[listGI[i].ind[1] * 2 + 1]))
{
y = m[listGI[i].ind[1] * 2 + 1];
}
if (Math.Abs(y) < Math.Abs(m[listGI[i].ind[2] * 2 + 1]))
{
y = m[listGI[i].ind[2] * 2 + 1];
}
}
}
return max;
}
private void find_coord()
{
double sm =double.MaxValue;
Rezba.count_v=1;
GausMethod Solution = new GausMethod(1); ;
while(sm>Rezba.eps&& Rezba.count_v*Rezba.p<Rezba.l)
{
coord_do.Clear();
list_coord.Clear();
list_coord_invert.Clear();
list_coord_rez.Clear();
listAt.Clear();
listGI.Clear();
listGIBuf.Clear();
listKLOC.Clear();<int> uzk = new List<int>();
uzk.Clear();
double[,] A = new double[6, 6];
double[,] E = new double[3, 3];
double dy1 = Rezba.d3 / 2;
double dy2 = Rezba.H;
double dy3 = (Rezba.D - Rezba.d3) / 2 - dy2;
double dy4 = (Rezba.bg - dy2 - dy3) / 5;
double dx1 = Rezba.b;
double dx2 = (Rezba.l - Rezba.p * Rezba.count_v) / 10;
double dx3 = Rezba.H * Math.Sin(15 * Math.PI / 180) / Math.Sin(75 * Math.PI / 180);
double dx4 = (Rezba.p - 2 * dx3) / 2;
double dx5 = Rezba.p - dx4;
double[,] Q= matrQ();
Form3 fff;
double x1 = 0, x2, x3 = 0, y1 = 0, y2, y3 = 0;
double dx, dy;
int k = 0;
int flag = 0;
int line = 0;
#region фигура вращения
#region 1c_in1 = 0;
if (line == 0)
{
Color c = Color.Gray;
x1 = 0;
dx = dx1;
dy = dy1;
x2 = x1; y2 = y1 + dy;
x3 = x1 + dx; y3 = y2;
Uzl_Coord p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c;
list_coord.Add(p); //uzpor.Insert(0,p);
x2 = x1 + dx; y2 = y1 + dy;
x3 = x2; y3 = y1;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c;
list_coord.Add(p); //uzpor.Insert(0, p);
x1 = x1 + dx;
c_in1++; c_in1++;
dx = dx2;
flag = 0;
while (flag < 10)
{
x2 = x1; y2 = y1 + dy;
x3 = x1 + dx; y3 = y2;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c;
list_coord.Add(p); //uzpor.Insert(0, p);
x2 = x1 + dx; y2 = y1 + dy;
x3 = x2; y3 = y1;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c;
list_coord.Add(p);// uzpor.Insert(0, p);
flag++;
x1 = x1 + dx;
c_in1++;
}
flag = 0;
k = Rezba.count_v * 2;
dx = dx4;
int fl = 0;
while (flag < k)
{
if(fl==0)
{
x2 = x1; y2 = y1 + dy;
x3 = x1 + dx5; y3 = y2;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c;
list_coord.Add(p); //uzpor.Insert(0, p);
x2 = x1 + dx5; y2 = y1 + dy;
x3 = x2; y3 = y1;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c;
list_coord.Add(p); //uzpor.Insert(0, p);
flag++;
x1 = x1 + dx5;
fl = 1;
c_in1++;
}
else
{
x2 = x1; y2 = y1 + dy;
x3 = x1 + dx4; y3 = y2;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c;
list_coord.Add(p); //uzpor.Insert(0, p);
x2 = x1 + dx4; y2 = y1 + dy;
x3 = x2; y3 = y1;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c;
list_coord.Add(p); //uzpor.Insert(0, p);
flag++;
x1 = x1 + dx4;
fl = 0;
c_in1++;
}
}
line++;
}
uzk.Add(c_in1);
#endregion
#region Нумерация узлов для первого ряда элементов
globindexes gi1;
globindexes gi2;
int ind = 0;
for (int i = 0; i < c_in1-1; i++)
{
gi1 = new globindexes();
gi2 = new globindexes();
gi1.ind = new int[3];
gi2.ind = new int[3];
gi1.ind[0] = ind;
gi2.ind[1] = ind + c_in1+1;
gi1.ind[1] = ind + c_in1;
gi2.ind[2] = ind + 1;
gi1.ind[2] = ind + c_in1+1;
gi2.ind[0] = ind;
listGI.Add(gi1);
listGI.Add(gi2);
ind++;
}
ind++;
#endregion
#region 2
int c_in2 = 0;
if (line == 1)
{
Color c1=Color.Gray;
Color c2 = Color.Black;
Color c3 = Color.Red;
y1 = dy1;
x1 = 0;
dx = dx1;
dy = dy2;
x2 = x1; y2 = y1 + dy;
x3 = x1 + dx; y3 = y2;
Uzl_Coord p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c1;
list_coord.Add(p); //uzpor.Insert(jer, p);
x2 = x1 + dx; y2 = y1 + dy;
x3 = x2; y3 = y1;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c1;
list_coord.Add(p);// uzpor.Insert(jer, p);
x1 = x1 + dx;
c_in2++;
c_in2++;
dx = dx2;
flag = 0;
while (flag < 10)
{
x2 = x1; y2 = y1 + dy;
x3 = x1 + dx; y3 = y2;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c2;
list_coord.Add(p);// uzpor.Insert(jer, p);
x2 = x1 + dx; y2 = y1 + dy;
x3 = x2; y3 = y1;
p = new Uzl_Coord();
p = vozvr_uzl(x1, x2, x3, y1, y2, y3);
p.c = c2;
list_coord.Add(p);// uzpor.Insert(jer, p);
flag++;
x1 = x1 + dx;
c_in2++;
}
x2 = x1; y2 = y1 + dy;
x3 = x1 + dx3; y3 = y2;