-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
135 lines (119 loc) · 3.12 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <iostream>
#include "Tools.h"
#include <Eigen/Eigen>
#include <iomanip>
using namespace Eigen;
using namespace std;
int main()
{
// Define the physical problem
// u_xxxx + ll = 0; x in (0,L)
// u is displacement
// u(L) = 0;
// u_x(L) = 0;
// EI u_xx(0) = M;
// EI u_xxx(0) = Q;
const double EI = 1.0;
const double M = 0.0/EI;
const double Q = 0.0/EI;
const double omega_l = 0.0;
const double omega_r = 1.0;
// exact solution can be solved
const int nElem = 10;
const int nLocBas = 4;
const int nFunc = 4 + 2 * (nElem - 1);
const double hh = (omega_r - omega_l) / nElem;
double x_coor[nElem+1];
for (int ii = 0; ii < nElem+1; ii++)
{
x_coor[ii] = hh * double(ii);
}
int IEN[nLocBas][nElem];
for (int ee = 0; ee < nElem; ee++)
{
for (int aa = 0; aa < nLocBas; aa++)
{
IEN[aa][ee] = 2 * ee + aa;
}
}
int ID[nFunc];
for (int ii = 0; ii < nFunc; ii++)
{
ID[ii] = ii;
}
// assign the ID for the Dirichlet node to be -1
ID[nFunc-1] = -1;
ID[nFunc-2] = -1;
SparseMatrix <double,RowMajor> K(nFunc,nFunc);
VectorXd F(nFunc);
VectorXd uu(nFunc);
for (int ee = 0; ee < nElem; ee++)
{
double k_ele[nLocBas][nLocBas];
double f_ele[nLocBas];
double x_ele[nLocBas];
for (int ii = 0; ii < nLocBas; ii++)
{
for (int jj = 0; jj < nLocBas; jj++)
{
k_ele[ii][jj] = 0.0;
}
f_ele[ii] = 0.0;
x_ele[ii] = 0.0;
}
const double x1 = x_coor[ee];
const double x2 = x_coor[ee+1];
// quadrature rule
const int nqp = 10;
double * qp = new double[nqp];
double * wq = new double[nqp];
Gauss(nqp, x1, x2, qp, wq);
for (int qua = 0; qua < nqp; qua++)
{
for (int aa = 0; aa < nLocBas; aa++)
{
const double Na = HermiteBasis(x1, x2, aa+1, 0, qp[qua]);
const double Na_xx = HermiteBasis(x1, x2, aa+1, 2, qp[qua]);
f_ele[aa] += wq[qua] * Func_source(qp[qua]) * Na * EI;
for (int bb = 0; bb < nLocBas; bb++)
{
const double Nb_xx = HermiteBasis(x1, x2, bb+1, 2, qp[qua]);
k_ele[aa][bb] += wq[qua] * Na_xx * Nb_xx * EI;
}
}
}
// k_ele goes into K and f_ele goes into F, which is called global assembly
for (int aa = 0; aa < nLocBas; aa++)
{
const int AA = ID[IEN[aa][ee]];
if (AA >= 0)
{
F(AA) += f_ele[aa];
for (int bb = 0; bb < nLocBas; bb++)
{
const int BB = IEN[bb][ee];
K.coeffRef(AA,BB) += k_ele[aa][bb];
}
}
else
{ K.coeffRef(IEN[aa][ee],IEN[aa][ee]) = 1.0;
F(IEN[aa][ee]) = 0.0;
}
}
}
F(0) += Q;
F(1) -= M;
SparseLU< SparseMatrix<double> > solver;
solver.compute(K);
uu = solver.solve(F);
cout << "The number of elements = " << nElem << endl;
cout << "The number of nodes = " << nElem+1 << endl;
cout << "The degree of Hermite-shape function = " << 2 << endl;
cout << "Displacement Slope" << endl;
for (int ii = 0; ii < nElem+1; ii++)
{
cout << "u = ";
cout << fixed <<setprecision(6) << uu(2*ii);
cout << " u_x = " << uu(2*ii+1) << endl;
}
}