22 : _nelem(0), _nvert_e(
nvert_e), _ndof_e(ndof_e), _nnode(0), _ndim(
ndim), _ia(0), _xc(0),
23 _bedges(0), _sdedges(0),
24 _nedge(0), _nedge_e(nedge_e), _edges(0), _ea(), _ebedges(),
32 void Mesh::SetValues(std::vector<double> &
v,
const function<
double(
double,
double)> &func)
const
35 assert(
nnode ==
static_cast<int>(
v.size()) );
36 for (
int k = 0; k <
nnode; ++k)
38 v[k] = func(
_xc[2 * k],
_xc[2 * k + 1] );
45 for (
size_t ik = 0; ik < idx.size(); ++ik)
47 const int k = idx[ik];
48 v[k] = func(
_xc[2 * k],
_xc[2 * k + 1] );
55 for (
size_t ik = 0; ik < idx.size(); ++ik)
57 const int k = idx[ik];
58 v[k] = func(
_xc[2 * k],
_xc[2 * k + 1] );
66 cout <<
"\n ############### Debug M E S H ###################\n";
67 cout <<
"\n ............... Coordinates ...................\n";
68 for (
int k = 0; k <
_nnode; ++k)
71 for (
int i = 0; i <
_ndof_e; ++i )
73 cout <<
_xc[2*k+i] <<
" ";
77 cout <<
"\n ............... Elements ...................\n";
78 for (
int k = 0; k <
_nelem; ++k)
81 for (
int i = 0; i <
_ndof_e; ++i )
85 cout <<
"\n ............... Boundary (vertices) .................\n";
86 cout <<
" _bedges : " <<
_bedges << endl;
92 cout <<
"\n ############### Debug M E S H (edge based) ###################\n";
93 cout <<
"\n ............... Coordinates ...................\n";
94 for (
int k = 0; k <
_nnode; ++k)
96 cout << k <<
" : " <<
_xc[2 * k] <<
" " <<
_xc[2 * k + 1] << endl;
99 cout <<
"\n ............... edges ...................\n";
100 for (
int k = 0; k <
_nedge; ++k)
103 for (
int i = 0; i < 2; ++i )
104 cout <<
_edges[2 * k + i] <<
" ";
108 cout <<
"\n ............... Elements (edges) .................\n";
110 for (
int k = 0; k <
_nelem; ++k)
117 cout <<
"\n ............... Boundary (edges) .................\n";
118 cout <<
" _ebedges : " <<
_ebedges << endl;
125 assert(
Nnodes() ==
static_cast<int>(
v.size()));
127 ofstream fout(
fname);
128 if ( !fout.is_open() )
130 cout <<
"\nFile " <<
fname <<
" has not been opened.\n\n" ;
131 assert( fout.is_open() &&
"File not opened." );
134 string const DELIMETER(
" ");
142 for (
int k = 0, kj = 0; k <
Nnodes(); ++k)
144 for (
int j = 0; j <
Ndims(); ++j, ++kj)
146 fout <<
_xc[kj] << DELIMETER;
153 for (
int k = 0, kj = 0; k <
Nelems(); ++k)
157 fout <<
_ia[kj] + OFFSET << DELIMETER;
163 for (
int k = 0; k <
Nnodes(); ++k)
165 fout <<
v[k] << endl;
176 string const DELIMETER(
" ");
180 string fname(basename +
"_coords.txt");
181 ofstream fout(
fname);
182 if ( !fout.is_open() )
184 cout <<
"\nFile " <<
fname <<
" has not been opened.\n\n" ;
185 assert( fout.is_open() &&
"File not opened." );
191 for (
int k = 0, kj = 0; k <
Nnodes(); ++k)
193 for (
int j = 0; j <
Ndims(); ++j, ++kj)
195 fout <<
_xc[kj] << DELIMETER;
205 string fname(basename +
"_elements.txt");
206 ofstream fout(
fname);
207 if ( !fout.is_open() )
209 cout <<
"\nFile " <<
fname <<
" has not been opened.\n\n" ;
210 assert( fout.is_open() &&
"File not opened." );
217 for (
int k = 0, kj = 0; k <
Nelems(); ++k)
221 fout <<
_ia[kj] + OFFSET << DELIMETER;
242 const string exec_m(
"matlab -nosplash < visualize_results.m");
247 const string fname(
"uv.txt");
250 int ierror = system(exec_m.c_str());
254 cout << endl <<
"Check path to Matlab/octave on your system" << endl;
265 vector<int> idx(
_bedges.size());
267 for (
size_t kb = 0; kb <
_bedges.size(); kb+=2 )
279 sort(idx.begin(), idx.end());
280 idx.erase( unique(idx.begin(), idx.end()), idx.end() );
290 sort(idx.begin(), idx.end());
291 idx.erase( unique(idx.begin(), idx.end()), idx.end() );
304 vector<vector<int>> vertex2elems(
_nnode, vector<int>(0));
305 for (
int k = 0; k <
Nelems(); ++k)
307 for (
int i = 0; i < 3; ++i)
309 vertex2elems[
_ia[3 * k + i]].push_back(k);
312 size_t max_neigh = 0;
313 for (
auto const &
v : vertex2elems)
315 max_neigh = max(max_neigh,
v.size());
327 unsigned int mbc(
_bedges.size() / 2);
330 vector<bool> bdir(
_nnode,
false);
338 for (
size_t kb = 0; kb <
_bedges.size(); kb+=2 )
341 bdir.at(
_bedges[kb]) = booldir;
342 bdir.at(
_bedges[kb+1]) = booldir;
345 vector<int> vert_visited;
346 vert_visited.reserve(max_neigh);
347 for (
int k = 0; k <
_nnode; ++k)
349 vert_visited.clear();
350 auto const &elems = vertex2elems[k];
351 int kedges =
static_cast<int>(
_edges.size()) / 2;
354 int nneigh = elems.size();
355 for (
int ne = 0; ne < nneigh; ++ne)
359 for (
int i = 3 *
e + 0; i < 3 *
e +
_nvert_e; ++i)
361 int const vert =
_ia[i];
366 auto const iv = find(vert_visited.cbegin(), vert_visited.cend(), vert);
367 if (iv == vert_visited.cend())
369 vert_visited.push_back(vert);
376 if (bdir[k] && bdir[vert])
391 int offset = iv - vert_visited.cbegin();
392 ke = kedges + offset;
395 auto ip = find_if(
_ea.begin() + 3 *
e,
_ea.begin() + 3 * (
e + 1),
396 [] (
int v) ->
bool {return v < 0;} );
398 assert(ip !=
_ea.cbegin() + 3 * (
e + 1));
418 vector<vector<int>> vertex2elems(
_nnode, vector<int>(0));
419 for (
int k = 0; k <
Nelems(); ++k)
421 for (
int i = 0; i < 3; ++i)
423 vertex2elems[
_ia[3 * k + i]].push_back(k);
426 size_t max_neigh = 0;
427 for (
auto const &
v : vertex2elems)
429 max_neigh = max(max_neigh,
v.size());
439 vector<int> vert_visited;
440 vert_visited.reserve(max_neigh);
441 for (
int k = 0; k <
_nnode; ++k)
443 vert_visited.clear();
444 auto const &elems = vertex2elems[k];
445 int kedges =
static_cast<int>(
_edges.size()) / 2;
448 int nneigh = elems.size();
449 for (
int ne = 0; ne < nneigh; ++ne)
453 for (
int i = 3 *
e + 0; i < 3 *
e +
_nvert_e; ++i)
455 int const vert =
_ia[i];
460 auto const iv = find(vert_visited.cbegin(), vert_visited.cend(), vert);
461 if (iv == vert_visited.cend())
463 vert_visited.push_back(vert);
472 int offset = iv - vert_visited.cbegin();
473 ke = kedges + offset;
476 auto ip = find_if(
_ea.begin() + 3 *
e,
_ea.begin() + 3 * (
e + 1),
477 [] (
int v) ->
bool {return v < 0;} );
479 assert(ip !=
_ea.cbegin() + 3 * (
e + 1));
487 unsigned int mbc(
_bedges.size() / 2);
490 for (
unsigned int kb = 0; kb < mbc; ++kb)
520 vector< pair<int, int> > edges(0);
523 for (
int k = 0; k <
Nelems(); ++k)
525 array < int, 3 + 1 > ivert{{
_ia[3 * k],
_ia[3 * k + 1],
_ia[3 * k + 2],
_ia[3 * k] }};
527 for (
int i = 0; i < 3; ++i)
530 if (ivert[i] < ivert[i + 1])
532 e2 = make_pair(ivert[i], ivert[i + 1]);
536 e2 = make_pair(ivert[i + 1], ivert[i]);
540 auto ip = find(edges.cbegin(), edges.cend(), e2);
541 if ( ip == edges.cend() )
551 eki = ip - edges.cbegin();
553 _ea[3 * k + i] = eki;
557 assert( nedges ==
static_cast<int>(edges.size()) );
559 _edges.resize(2 * nedges);
560 for (
int k = 0; k < nedges; ++k)
562 _edges[2 * k ] = edges[k].first;
563 _edges[2 * k + 1] = edges[k].second;
567 unsigned int mbc(
_bedges.size() / 2);
570 for (
unsigned int kb = 0; kb < mbc; ++kb)
572 const auto vv1 = make_pair(
_bedges[2 * kb ],
_bedges[2 * kb + 1]);
573 const auto vv2 = make_pair(
_bedges[2 * kb + 1],
_bedges[2 * kb ]);
574 auto ip1 = find(edges.cbegin(), edges.cend(), vv1);
575 if (ip1 == edges.cend())
577 ip1 = find(edges.cbegin(), edges.cend(), vv2);
578 assert(ip1 != edges.cend());
580 _ebedges[kb] = ip1 - edges.cbegin();
594 for (
int k = 0; k <
Nelems(); ++k)
598 for (
int j = 0; j < 3; ++j)
600 int const iedg =
_ea[3 * k + j];
601 ivert[2 * j ] =
_edges[2 * iedg ];
602 ivert[2 * j + 1] =
_edges[2 * iedg + 1];
604 sort(ivert.begin(), ivert.end());
605 auto const ip = unique(ivert.begin(), ivert.end());
606 assert( ip - ivert.begin() == 3 );
607 for (
int i = 0; i < 3; ++i)
609 _ia[3 * k + i] = ivert[i];
616 for (
unsigned int k = 0; k < mbc; ++k)
633 vector<vector<int>> v2v(
_nnode, vector<int>(0));
636 vector<int> cnt(
_nnode,0);
637 for (
size_t i = 0; i <
_ia.size(); ++i) ++cnt[
_ia[i]];
638 for (
size_t k = 0; k < v2v.size(); ++k)
650 int const v =
_ia[basis + k];
653 v2v[
v][cnt[
v]] =
_ia[basis + l];
661 for (
size_t v = 0;
v < v2v.size(); ++
v)
663 sort(v2v[
v].begin(), v2v[
v].
end());
664 auto ip = unique(v2v[
v].begin(), v2v[
v].
end());
665 v2v[
v].erase(ip, v2v[
v].
end());
674 vector<vector<int>> v2v(
_nnode, vector<int>(0));
681 int const v =
_ia[basis + k];
684 v2v[
v].push_back(
_ia[basis + l]);
689 for (
size_t v = 0;
v < v2v.size(); ++
v)
691 sort(v2v[
v].begin(), v2v[
v].
end());
692 auto ip = unique(v2v[
v].begin(), v2v[
v].
end());
693 v2v[
v].erase(ip, v2v[
v].
end());
715 if (!(ifs.is_open() && ifs.good()))
717 cerr <<
"Mesh::ReadVertexBasedMesh: Error cannot open file " <<
fname << endl;
718 assert(ifs.is_open());
722 cout <<
"ASCI file " <<
fname <<
" opened" << endl;
754 for (
int k = 0; k < nbedges * 2; ++k)
760 int const DUMMY{-9876};
764 cout << nbedges << endl;
765 for (
int k = 0; k < nbedges * 2; ++k)
775 cout <<
"\n ####### no subdomain info of edges available! #########\n";
777 cout <<
"\n End of File read " <<
_sdedges.at(2*nbedges-2) <<
" " <<
_sdedges.at(2*nbedges-1) <<
"\n" << endl;
785 if (!b_ia) cerr <<
"misfit: _nelem vs. _ia" << endl;
788 if (!b_xc) cerr <<
"misfit: _nnode vs. _xc" << endl;
791 if (!b_ea) cerr <<
"misfit: _nelem vs. _ea" << endl;
793 bool b_ed =
static_cast<int>(
_edges.size() / 2) ==
_nedge;
794 if (!b_ed) cerr <<
"misfit: _nedge vs. _edges" << endl;
797 return b_ia && b_xc && b_ea && b_ed;
818 :
Mesh(cmesh), _ibref(ibref), _nref(0), _vfathers(0)
827 cout << endl <<
" Adaptive Refinement not implemented yet." << endl;
828 assert(
_ibref.size() != 0);
838 cout <<
" NOT IMPLEMENTED: Mesh::RefineElements" << endl;
863 cout <<
"\n############ Refine Mesh " << nref <<
" times ";
864 double tstart = clock();
867 for (
int kr = 0; kr < nref; ++kr)
873 auto old_nedges(
Nedges());
874 auto old_nnodes(
Nnodes());
875 auto old_nelems(
Nelems());
879 vector<int> edge_sons(2 * old_nedges);
882 int new_nedge = 2 * old_nedges + 3 * old_nelems;
883 int new_nelem = 4 * old_nelems;
884 int new_nnode = old_nnodes + old_nedges;
886 _xc.reserve(2 * new_nnode);
889 for (
int vc = 0; vc < old_nnodes; ++vc)
897 _ea.resize(new_nelem * 3);
899 _edges.resize(2 * new_nedge);
900 vector<int> e_son(2 * old_nedges);
905 for (
int kc = 0; kc < old_nedges; ++kc)
908 int v1 = old_edges[2 * kc];
909 int v2 = old_edges[2 * kc + 1];
911 double xf = 0.5 * (
_xc[2 * v1 ] +
_xc[2 * v2 ] );
912 double yf = 0.5 * (
_xc[2 * v1 + 1] +
_xc[2 * v2 + 1] );
926 e_son[2 * kc + 1] = kf;
937 for (
int kc = 0; kc < old_nelems; ++kc)
939 array<array<int, 3>, 3 * 2> boundary;
942 for (
int j = 0; j < 3; ++j)
944 int ce = old_ea[3 * kc + j];
946 int s1 = e_son[2 * ce ];
947 int s2 = e_son[2 * ce + 1];
948 boundary[2 * j][2] = s1;
949 boundary[2 * j][0] =
_edges[2 * s1 + 0];
950 boundary[2 * j][1] =
_edges[2 * s1 + 1];
951 if (boundary[2 * j][0] > boundary[2 * j][1]) swap(boundary[2 * j][0], boundary[2 * j][1]);
952 boundary[2 * j + 1][2] = s2;
953 boundary[2 * j + 1][0] =
_edges[2 * s2 + 0];
954 boundary[2 * j + 1][1] =
_edges[2 * s2 + 1];
955 if (boundary[2 * j + 1][0] > boundary[2 * j + 1][1]) swap(boundary[2 * j + 1][0], boundary[2 * j + 1][1]);
958 sort(boundary.begin(), boundary.end());
960 int interior_1 = 2 * old_nedges + kc * 3;
961 int interior_2 = 2 * old_nedges + kc * 3 + 1;
962 int interior_3 = 2 * old_nedges + kc * 3 + 2;
964 _edges[interior_1 * 2 ] = boundary[0][1];
965 _edges[interior_1 * 2 + 1] = boundary[1][1];
967 _edges[interior_2 * 2 ] = boundary[2][1];
968 _edges[interior_2 * 2 + 1] = boundary[3][1];
970 _edges[interior_3 * 2 ] = boundary[4][1];
971 _edges[interior_3 * 2 + 1] = boundary[5][1];
973 _ea[kc * 3 * 4 ] = boundary[0][2];
974 _ea[kc * 3 * 4 + 1] = boundary[1][2];
975 _ea[kc * 3 * 4 + 2] = interior_1;
977 _ea[kc * 3 * 4 + 3] = boundary[2][2];
978 _ea[kc * 3 * 4 + 4] = boundary[3][2];
979 _ea[kc * 3 * 4 + 5] = interior_2;
981 _ea[kc * 3 * 4 + 6] = boundary[4][2];
982 _ea[kc * 3 * 4 + 7] = boundary[5][2];
983 _ea[kc * 3 * 4 + 8] = interior_3;
985 _ea[kc * 3 * 4 + 9] = interior_1;
986 _ea[kc * 3 * 4 + 10] = interior_2;
987 _ea[kc * 3 * 4 + 11] = interior_3;
993 unsigned int old_nbedges(old_ebedges.size());
997 for (
unsigned int ke = 0; ke < old_nbedges; ++ke)
999 const auto kc = old_ebedges[ke];
1011 #ifdef CUTHILL_MCKEE
1026 double duration = (clock() - tstart) / CLOCKS_PER_SEC;
1027 cout <<
"finished in " << duration <<
" sec. ########\n";
1036 auto const edges_old(
_edges);
1037 for (
size_t k = 0; k <
_edges.size(); k += 2)
1039 _edges[k ] = old2new[edges_old[k ]];
1040 _edges[k + 1] = old2new[edges_old[k + 1]];
1045 auto const coord_old(
_xc);
1046 for (
size_t k = 0; k <
_xc.size() / 2; ++k)
1048 _xc[2 * old2new[k] ] = coord_old[2 * k ];
1049 _xc[2 * old2new[k] + 1] = coord_old[2 * k + 1];
1060 for (
size_t k = 0; k <
_vfathers.size() / 2; ++k)
1062 _vfathers[2 * old2new[k] ] = old_fathers[2 * k ];
1063 _vfathers[2 * old2new[k] + 1] = old_fathers[2 * k + 1];
1073 const bool bvf = (
static_cast<int>(
_vfathers.size()) / 2 ==
Nnodes());
1082 : _gmesh(max(1, nlevel))
1084 _gmesh[0] = make_shared<Mesh>(cmesh);
1085 for (
int lev = 1; lev < nlevel; ++lev)
1087 _gmesh.at(lev) = make_shared<RefinedMesh>( *
_gmesh.at(lev - 1) );
1091 for (
size_t lev = 0; lev <
_gmesh.size(); ++lev)
1093 _gmesh[lev]->Del_EdgeConnectivity();
1101 _myid(myid), _procx(procx), _procy(procy), _neigh{{ -1, -1, -1, -1}}, _color(0),
1102 _xl(0.0), _xr(1.0), _yb(0.0), _yt(1.0), _nx(nx), _ny(ny)
1105 int const ky = _myid / _procx;
1106 int const kx = _myid % _procy;
1108 _neigh[0] = (ky == 0) ? -1 : _myid - _procx;
1109 _neigh[1] = (kx == _procx - 1) ? -1 : _myid + 1;
1110 _neigh[2] = (ky == _procy - 1) ? -1 : _myid + _procx;
1111 _neigh[3] = (kx == 0) ? -1 : _myid - 1;
1113 _color = (kx + ky) & 1 ;
1116 double const hx = 1. / _procx;
1117 double const hy = 1. / _procy;
1119 _xr = (kx + 1) * hx;
1121 _yt = (ky + 1) * hy;
1124 int const nnode = (_nx + 1) * (_ny + 1);
1125 Resize_Coords(
nnode, 2);
1126 GetCoordsInRectangle(_nx, _ny, _xl, _xr, _yb, _yt, GetCoords().data());
1129 int const nelem = 2 * _nx * _ny;
1130 Resize_Connectivity(
nelem, 3);
1131 GetConnectivityInRectangle(_nx, _ny, GetConnectivity().data());
1143 for (
int j = 0; j <=
_ny; ++j)
1146 for (
int i = 0; i <=
_nx; ++i, ++k)
1157 for (
int j = 0; j <=
_ny; ++j)
1160 for (
int i = 0; i <=
_nx; ++i, ++k)
1176 tr = (
_ny + 1) * (
_nx + 1) - 1;
1177 int const start[4] = { bl, br, tl, bl};
1178 int const end[4] = { br, tr, tr, tl};
1179 int const step[4] = { dx, dy, dx, dy};
1182 for (
int j = 0; j < 4; j++)
1186 for (
int i = start[j]; i <=
end[j]; i += step[j])
1193 sort(idx.begin(), idx.end());
1194 idx.erase( unique(idx.begin(), idx.end()), idx.end() );
1201 cerr <<
"Warning: Funktion not implemented. " << __FILE__ <<
"." << __LINE__ << endl;
1211 const string tmp( std::to_string(
_myid / 100) + to_string((
_myid % 100) / 10) + to_string(
_myid % 10) );
1213 const string namep = name +
"." +
tmp;
1214 ofstream ff(namep.c_str());
1216 ff.setf(ios::fixed, ios::floatfield);
1222 for (
int j = 0; j <=
_ny; ++j)
1224 for (
int i = 0; i <=
_nx; ++i, ++k)
1225 ff <<
xc[2 * k + 0] <<
" " <<
xc[2 * k + 1] <<
" " <<
u[k] << endl;
1234 double const xl,
double const xr,
double const yb,
double const yt,
1237 const double hx = (xr - xl) / nx,
1238 hy = (yt - yb) / ny;
1241 for (
int j = 0; j <= ny; ++j)
1243 const double y0 = yb + j * hy;
1244 for (
int i = 0; i <= nx; ++i, k += 2)
1246 xc[k ] = xl + i * hx;
1256 const int dx = nx + 1;
1259 for (
int j = 0; j < ny; ++j, ++k)
1261 for (
int i = 0; i < nx; ++i, ++k)
1265 ia[l + 2] = k + dx + 1;
1269 ia[l + 2] = k + dx + 1;