18 : _nrows(nrows), _ncols(ncols), _dd(0)
43 :
Matrix(0,0), _nnz(0), _id(0), _ik(0), _sk(0)
51 assert(
_ncols==
static_cast<int>(
u.size()) );
52 assert(
_nrows==
static_cast<int>(w.size()) );
54 for (
int row = 0; row <
_nrows; ++row)
57 for (
int ij =
_id[row]; ij <
_id[row + 1]; ++ij)
67 vector<double>
const &f, vector<double>
const &
u)
const
69 assert(
_ncols==
static_cast<int>(
u.size()) );
70 assert(
_nrows==
static_cast<int>(w.size()) );
71 assert( w.size()==f.size() );
73 #pragma omp parallel for
74 for (
int row = 0; row <
_nrows; ++row)
77 for (
int ij =
_id[row]; ij <
_id[row + 1]; ++ij)
91 assert( nm==
static_cast<int>(d.size()) );
93 for (
int row = 0; row < nm; ++row)
105 int const id2 =
_id[row + 1];
108 while (ip < id2 &&
_ik[ip] != col)
115 #ifndef NDEBUG // compiler option -DNDEBUG switches off the check
116 cout <<
"No column " << col <<
" in row " << row << endl;
129 for (
int row = 0; row <
_nrows; ++row)
131 cout <<
"Row " << row <<
" : ";
132 int const id1 =
_id[row];
133 int const id2 =
_id[row + 1];
134 for (
int j = id1; j < id2; ++j)
136 cout.setf(ios::right, ios::adjustfield);
137 cout <<
"[" << setw(2) <<
_ik[j] <<
"] " << setw(4) <<
_sk[j] <<
" ";
151 cout <<
"######### Error: " <<
"number of rows" << endl;
157 cout <<
"######### Error: " <<
"number of non zero elements" << endl;
160 bool bd = equal(
id,
id+
nnode+1,
_id.cbegin());
163 cout <<
"######### Error: " <<
"row starts" << endl;
166 bool bk = equal(ik,ik+
id[
nnode],
_ik.cbegin());
169 cout <<
"######### Error: " <<
"column indices" << endl;
172 bool bv = equal(sk,sk+
id[
nnode],
_sk.cbegin());
175 cout <<
"######### Error: " <<
"values" << endl;
178 return bn && bz && bd && bk && bv;
196 cout <<
"\n############ FEM_Matrix::Derive_Matrix_Pattern ";
197 double tstart = clock();
204 assert(*min_element(
ia.cbegin(),
ia.cbegin() + ndof_e *
nelem) == 0);
212 for (
size_t v = 0;
v<v2v.size(); ++
v )
215 _nnz += v2v[
v].size();
224 for (
size_t v = 0;
v<v2v.size(); ++
v )
226 for (
size_t vi=0; vi<v2v[
v].size(); ++vi)
228 _ik[kk] = v2v[
v][vi];
237 double duration = (clock() - tstart) / CLOCKS_PER_SEC;
238 cout <<
"finished in " << duration <<
" sec. ########\n";
246 cout <<
"\n############ FEM_Matrix::Derive_Matrix_Pattern slow ";
247 double tstart = clock();
254 assert(*min_element(
ia.cbegin(),
ia.cbegin() + ndof_e *
nelem) == 0);
258 vector< list<int> > cc(
_nrows);
259 for (
int i = 0; i <
nelem; ++i)
261 int const idx = ndof_e * i;
262 for (
int k = 0; k < ndof_e; ++k)
264 list<int> &cck = cc[
ia[idx + k]];
265 cck.insert( cck.end(),
ia.cbegin() + idx,
ia.cbegin() + idx + ndof_e );
284 for (
size_t i = 0; i < cc.size(); ++i)
287 const list<int> &ci = cc[i];
288 const auto nci =
static_cast<int>(ci.size());
289 _id[i + 1] =
_id[i] + nci;
290 copy(ci.begin(), ci.end(),
_ik.begin() +
_id[i] );
301 double duration = (clock() - tstart) / CLOCKS_PER_SEC;
302 cout <<
"finished in " << duration <<
" sec. ########\n";
310 cout <<
"\n############ FEM_Matrix::CalculateLaplace ";
312 double tstart = omp_get_wtime();
317 for (
int k = 0; k <
_nrows; ++k)
321 for (
int k = 0; k <
_nrows; ++k)
326 double ske[3][3], fe[3];
332 #pragma omp parallel for private(ske,fe)
333 for (
int i = 0; i <
nelem; ++i)
341 double duration = omp_get_wtime() - tstart;
342 cout <<
"finished in " << duration <<
" sec. ########\n";
369 int const nidx = idx.size();
371 for (
int i=0; i<nidx; ++i)
373 int const row = idx[i];
374 for (
int ij=
_id[row]; ij<
_id[row+1]; ++ij)
376 int const col=
_ik[ij];
384 int const id1 =
fetch(col, row);
386 f[col] -=
_sk[id1]*
u[row];
400 for (
int i = 0; i < 3; ++i)
402 const int ii = ial[i];
403 for (
int j = 0; j < 3; ++j)
405 const int jj = ial[j];
406 const int ip =
fetch(ii,jj);
407 #ifndef NDEBUG // compiler option -DNDEBUG switches off the check
410 cout <<
"Error in AddElem: (" << ii <<
"," << jj <<
") ["
411 << ial[0] <<
"," << ial[1] <<
"," << ial[2] <<
"]\n";
416 _sk[ip] += ske[i][j];
445 void CalcElem(
int const ial[3],
double const xc[],
double ske[3][3],
double fe[3])
448 const int i1 = 2 * ial[0], i2 = 2 * ial[1], i3 = 2 * ial[2];
449 const double x13 =
xc[i3 + 0] -
xc[i1 + 0], y13 =
xc[i3 + 1] -
xc[i1 + 1],
450 x21 =
xc[i1 + 0] -
xc[i2 + 0], y21 =
xc[i1 + 1] -
xc[i2 + 1],
451 x32 =
xc[i2 + 0] -
xc[i3 + 0], y32 =
xc[i2 + 1] -
xc[i3 + 1];
452 const double jac = fabs(x21 * y13 - x13 * y21);
454 ske[0][0] = 0.5 / jac * (y32 * y32 + x32 * x32);
455 ske[0][1] = 0.5 / jac * (y13 * y32 + x13 * x32);
456 ske[0][2] = 0.5 / jac * (y21 * y32 + x21 * x32);
457 ske[1][0] = ske[0][1];
458 ske[1][1] = 0.5 / jac * (y13 * y13 + x13 * x13);
459 ske[1][2] = 0.5 / jac * (y21 * y13 + x21 * x13);
460 ske[2][0] = ske[0][2];
461 ske[2][1] = ske[1][2];
462 ske[2][2] = 0.5 / jac * (y21 * y21 + x21 * x21);
464 const double xm = (
xc[i1 + 0] +
xc[i2 + 0] +
xc[i3 + 0]) / 3.0,
465 ym = (
xc[i1 + 1] +
xc[i2 + 1] +
xc[i3 + 1]) / 3.0;
467 fe[0] = fe[1] = fe[2] = 0.5 * jac *
fNice(xm, ym) / 3.0;
470 void CalcElem_Masse(
int const ial[3],
double const xc[],
double const cm,
double ske[3][3])
472 const int i1 = 2 * ial[0], i2 = 2 * ial[1], i3 = 2 * ial[2];
473 const double x13 =
xc[i3 + 0] -
xc[i1 + 0], y13 =
xc[i3 + 1] -
xc[i1 + 1],
474 x21 =
xc[i1 + 0] -
xc[i2 + 0], y21 =
xc[i1 + 1] -
xc[i2 + 1];
476 const double jac = fabs(x21 * y13 - x13 * y21);
478 ske[0][0] += jac/12.0;
479 ske[0][1] += jac/24.0;
480 ske[0][2] += jac/24.0;
481 ske[1][0] += jac/24.0;
482 ske[1][1] += jac/12.0;
483 ske[1][2] += jac/24.0;
484 ske[2][0] += jac/24.0;
485 ske[2][1] += jac/24.0;
486 ske[2][2] += jac/12.0;
496 void AddElem(
int const ial[3],
double const ske[3][3],
double const fe[3],
497 int const id[],
int const ik[],
double sk[],
double f[])
499 for (
int i = 0; i < 3; ++i)
501 const int ii = ial[i],
505 for (
int j = 0; j < 3; ++j)
507 const int jj = ial[j];
508 bool not_found =
true;
511 not_found = (ik[ip] != jj);
514 while (not_found && ip < id2);
516 #ifndef NDEBUG // compiler option -DNDEBUG switches off the check
519 cout <<
"Error in AddElem: (" << ii <<
"," << jj <<
") ["
520 << ial[0] <<
"," << ial[1] <<
"," << ial[2] <<
"]\n";
524 sk[ip - 1] += ske[i][j];
536 :
Matrix( 0, 0 ), _iv(), _vv()
541 :
Matrix( static_cast<int>(fathers.
size())/2, 1+*max_element(fathers.cbegin(),fathers.cend()) ),
542 _iv(fathers), _vv(fathers.
size(),0.5)
551 assert(
Nrows()==
static_cast<int>(d.size()) );
553 for (
int k=0; k<
Nrows(); ++k)
555 if (
_iv[2*k]==
_iv[2*k+1] )
569 assert(
Nrows()==
static_cast<int>(wf.size()) );
570 assert(
Ncols()==
static_cast<int>(uc.size()) );
572 #pragma omp parallel for
573 for (
int k=0; k<
Nrows(); ++k)
575 wf[k] =
_vv[2*k]*uc[
_iv[2*k]] +
_vv[2*k+1]*uc[
_iv[2*k+1]];
600 assert(
Nrows()==
static_cast<int>(wf.size()) );
601 assert(
Ncols()==
static_cast<int>(uc.size()) );
604 for (
int k=0; k<
Ncols(); ++k) uc[k] = 0.0;
605 #pragma omp parallel for
606 for (
int k=0; k<
Nrows(); ++k)
611 uc[
_iv[2*k] ] +=
_vv[2*k ]*wf[k];
613 uc[
_iv[2*k+1]] +=
_vv[2*k+1]*wf[k];
618 uc[
_iv[2*k] ] += 2.0*
_vv[2*k ]*wf[k];
625 vector<double>
const &f, vector<double>
const &
u)
const
627 assert(
Nrows()==
static_cast<int>(w.size()) );
628 assert(
Ncols()==
static_cast<int>(
u.size()) );
629 assert( w.size()==f.size() );
631 for (
int k=0; k<
Nrows(); ++k)
640 for (
int k=0; k<
Nrows(); ++k)
642 cout << k <<
" : fathers(" <<
_iv[2*k] <<
"," <<
_iv[2*k+1] <<
") ";
643 cout <<
"weights(" <<
_vv[2*k] <<
"," <<
_vv[2*k+1] << endl;
652 if (
_iv[2*row ] == col) idx = 2*row;
653 if (
_iv[2*row+1] == col) idx = 2*row+1;
663 vector<bool> bdir(
Ncols(),
false);
664 for (
size_t kc=0; kc<idxc_dir.size(); ++kc)
666 bdir.at(idxc_dir[kc]) =
true;
669 for (
size_t j=0; j<
_iv.size(); ++j)
671 if ( bdir.at(
_iv[j]) )
_vv[j] = 0.0;
684 vector<double> &fc, vector<double> &ff, vector<double> &uf)
686 assert( P.
Nrows()==
static_cast<int>(ff.size()) );
687 assert( P.
Ncols()==
static_cast<int>(fc.size()) );
688 assert( ff.size()==uf.size() );
692 for (
int k=0; k<P.
Ncols(); ++k) fc[k] = 0.0;
695 #pragma omp parallel for
696 for (
int row = 0; row < SK.
_nrows; ++row)
699 for (
int ij = SK.
_id[row]; ij < SK.
_id[row + 1]; ++ij)
701 wi -= SK.
_sk[ij] * uf[ SK.
_ik[ij] ];
704 const int i1=P.
_iv[2*row];
705 const int i2=P.
_iv[2*row+1];
709 fc[i1] += P.
_vv[2*row ]*wi;
711 fc[i2] += P.
_vv[2*row +1]*wi;
716 fc[i1] += 2.0*P.
_vv[2*row ]*wi;