15 int &nnz,
int* &
id,
int* &ik,
double* &sk)
18 int nnode = *max_element(ia, ia + ndof_e * nelem);
20 assert(*min_element(ia, ia + ndof_e * nelem) == 0);
23 vector< list<int> > cc(nnode);
24 for (
int i = 0; i < nelem; ++i)
27 const int idx = ndof_e * i;
28 for (
int k = 0; k < ndof_e; ++k)
30 list<int> &cck = cc.at(ia[idx + k]);
31 cck.insert( cck.end(), ia + idx, ia + idx + ndof_e );
45 id =
new int [nnode + 1];
50 for (
size_t i = 0; i < cc.size(); ++i)
53 const list<int> &ci = cc.at(i);
54 const auto nci =
static_cast<int>(ci.size());
55 id[i + 1] =
id[i] + nci;
56 copy(ci.begin(), ci.end(), ik +
id[i] );
59 assert(nnz ==
id[nnode]);
60 sk =
new double [nnz];
68 void CalcElem(
int const ial[3],
double const xc[],
double ske[3][3],
double fe[3])
71 const int i1 = 2 * ial[0], i2 = 2 * ial[1], i3 = 2 * ial[2];
72 const double x13 = xc[i3 + 0] - xc[i1 + 0], y13 = xc[i3 + 1] - xc[i1 + 1],
73 x21 = xc[i1 + 0] - xc[i2 + 0], y21 = xc[i1 + 1] - xc[i2 + 1],
74 x32 = xc[i2 + 0] - xc[i3 + 0], y32 = xc[i2 + 1] - xc[i3 + 1];
75 const double jac = fabs(x21 * y13 - x13 * y21);
77 ske[0][0] = 0.5 / jac * (y32 * y32 + x32 * x32);
78 ske[0][1] = 0.5 / jac * (y13 * y32 + x13 * x32);
79 ske[0][2] = 0.5 / jac * (y21 * y32 + x21 * x32);
80 ske[1][0] = ske[0][1];
81 ske[1][1] = 0.5 / jac * (y13 * y13 + x13 * x13);
82 ske[1][2] = 0.5 / jac * (y21 * y13 + x21 * x13);
83 ske[2][0] = ske[0][2];
84 ske[2][1] = ske[1][2];
85 ske[2][2] = 0.5 / jac * (y21 * y21 + x21 * x21);
87 const double xm = (xc[i1 + 0] + xc[i2 + 0] + xc[i3 + 0]) / 3.0,
88 ym = (xc[i1 + 1] + xc[i2 + 1] + xc[i3 + 1]) / 3.0;
89 fe[0] = fe[1] = fe[2] = 0.5 * jac *
FunctF(xm, ym) / 3.0;
97 void AddElem(
int const ial[3],
double const ske[3][3],
double const fe[3],
98 int const id[],
int const ik[],
double sk[],
double f[])
100 for (
int i = 0; i < 3; ++i)
102 const int ii = ial[i],
106 for (
int j = 0; j < 3; ++j)
108 const int jj = ial[j];
109 bool not_found =
true;
112 not_found = (ik[ip] != jj);
115 while (not_found && ip < id2);
117 #ifndef NDEBUG // compiler option -DNDEBUG switches off the check
120 cout <<
"Error in AddElem: (" << ii <<
"," << jj <<
") ["
121 << ial[0] <<
"," << ial[1] <<
"," << ial[2] <<
"]\n";
125 sk[ip - 1] += ske[i][j];
132 void DebugMatrix(
int const nnode,
int const id[],
int const ik[],
double const sk[])
136 cout <<
"\nMatrix (nnz = " <<
id[nnode] <<
")\n";
138 for (
int row = 0; row < nnode; ++row)
140 cout <<
"Row " << row <<
" : ";
143 for (
int j = id1; j < id2; ++j)
145 cout.setf(ios::right, ios::adjustfield);
146 cout <<
"[" << setw(2) << ik[j] <<
"] " << setw(4) << sk[j] <<
" ";
156 cout <<
"\nVector (nnode = " << nnode <<
")\n";
157 for (
int j = 0; j < nnode; ++j)
159 cout.setf(ios::right, ios::adjustfield);
170 int fetch(
int const row,
int const col,
int const id[],
int const ik[])
172 int const id2 =
id[row + 1];
175 while (ip < id2 && ik[ip] != col)
179 #ifndef NDEBUG // compiler option -DNDEBUG switches off the check
182 cout <<
"No column " << col <<
" in row " << row << endl;
191 void Defect(
double w[],
double const f[],
double const u[],
192 int const nnode,
int const id[],
int const ik[],
double const sk[])
194 for (
int row = 0; row < nnode; ++row)
197 for (
int ij =
id[row]; ij <
id[row + 1]; ++ij)
199 wi -= sk[ij] * u[ ik[ij] ];
206 void CrsMult(
double w[],
double const u[],
int const nnode,
207 int const id[],
int const ik[],
double const sk[])
209 for (
int row = 0; row < nnode; ++row)
212 for (
int ij =
id[row]; ij <
id[row + 1]; ++ij)
214 wi += sk[ij] * u[ ik[ij] ];
223 void GetDiag(
int const nnode,
int const id[],
int const ik[],
double const sk[],
double d[])
225 for (
int row = 0; row < nnode; ++row)
227 const int ia =
fetch(row, row,
id, ik);
243 void GetMatrix (
int const nelem,
int const ndof_e,
int const ia[],
int const nnode,
double const xc[],
244 int const nnz,
int const id[],
int const ik[],
double sk[],
double f[])
247 assert(nnz ==
id[nnode]);
249 for (
int k = 0; k <
id[nnode]; ++k)
253 for (
int k = 0; k < nnode; ++k)
258 double ske[3][3], fe[3];
260 for (
int i = 0; i < nelem; ++i)
263 AddElem(ia + 3 * i, ske, fe,
id, ik, sk, f);
276 double const u[],
int const id[],
int const ik[] ,
double sk[],
double f[])
278 const double PENALTY = 1e6;
284 tr = (ny + 1) * (nx + 1) - 1;
285 const int start[4] = { bl, br, tl, bl},
286 end[4] = { br, tr, tr, tl},
287 step[4] = { dx, dy, dx, dy};
289 for (
int j = 0; j < 4; j++)
293 for (
int i = start[j]; i <= end[j]; i += step[j])
295 const int id1 =
fetch(i, i,
id, ik);
300 f[i] += PENALTY * u[i];