5 #include "cuthill_mckee_ordering.h"
23 : _nelem(0), _nvert_e(
nvert_e), _ndof_e(ndof_e), _nnode(0), _ndim(
ndim), _ia(0), _xc(0),
24 _bedges(0), _sdedges(0),
25 _nedge(0), _nedge_e(nedge_e), _edges(0), _ea(), _ebedges(),
33 void Mesh::SetValues(std::vector<double> &
v,
const function<
double(
double,
double)> &func)
const
36 assert(
nnode ==
static_cast<int>(
v.size()) );
37 for (
int k = 0; k <
nnode; ++k)
39 v[k] = func(
_xc[2 * k],
_xc[2 * k + 1] );
46 for (
size_t ik = 0; ik < idx.size(); ++ik)
48 const int k = idx[ik];
49 v[k] = func(
_xc[2 * k],
_xc[2 * k + 1] );
56 for (
size_t ik = 0; ik < idx.size(); ++ik)
58 const int k = idx[ik];
59 v[k] = func(
_xc[2 * k],
_xc[2 * k + 1] );
67 cout <<
"\n ############### Debug M E S H ###################\n";
68 cout <<
"\n ............... Coordinates ...................\n";
69 for (
int k = 0; k <
_nnode; ++k)
72 for (
int i = 0; i <
_ndof_e; ++i )
74 cout <<
_xc[2*k+i] <<
" ";
78 cout <<
"\n ............... Elements ...................\n";
79 for (
int k = 0; k <
_nelem; ++k)
82 for (
int i = 0; i <
_ndof_e; ++i )
86 cout <<
"\n ............... Boundary (vertices) .................\n";
87 cout <<
" _bedges : " <<
_bedges << endl;
93 cout <<
"\n ############### Debug M E S H (edge based) ###################\n";
94 cout <<
"\n ............... Coordinates ...................\n";
95 for (
int k = 0; k <
_nnode; ++k)
97 cout << k <<
" : " <<
_xc[2 * k] <<
" " <<
_xc[2 * k + 1] << endl;
100 cout <<
"\n ............... edges ...................\n";
101 for (
int k = 0; k <
_nedge; ++k)
104 for (
int i = 0; i < 2; ++i )
105 cout <<
_edges[2 * k + i] <<
" ";
109 cout <<
"\n ............... Elements (edges) .................\n";
111 for (
int k = 0; k <
_nelem; ++k)
118 cout <<
"\n ............... Boundary (edges) .................\n";
119 cout <<
" _ebedges : " <<
_ebedges << endl;
126 assert(
Nnodes() ==
static_cast<int>(
v.size()));
128 ofstream fout(fname);
129 if ( !fout.is_open() )
131 cout <<
"\nFile " << fname <<
" has not been opened.\n\n" ;
132 assert( fout.is_open() &&
"File not opened." );
135 string const DELIMETER(
" ");
143 for (
int k = 0, kj = 0; k <
Nnodes(); ++k)
145 for (
int j = 0; j <
Ndims(); ++j, ++kj)
147 fout <<
_xc[kj] << DELIMETER;
154 for (
int k = 0, kj = 0; k <
Nelems(); ++k)
158 fout <<
_ia[kj] + OFFSET << DELIMETER;
164 for (
int k = 0; k <
Nnodes(); ++k)
166 fout <<
v[k] << endl;
177 string const DELIMETER(
" ");
181 string fname(basename +
"_coords.txt");
182 ofstream fout(fname);
183 if ( !fout.is_open() )
185 cout <<
"\nFile " << fname <<
" has not been opened.\n\n" ;
186 assert( fout.is_open() &&
"File not opened." );
192 for (
int k = 0, kj = 0; k <
Nnodes(); ++k)
194 for (
int j = 0; j <
Ndims(); ++j, ++kj)
196 fout <<
_xc[kj] << DELIMETER;
206 string fname(basename +
"_elements.txt");
207 ofstream fout(fname);
208 if ( !fout.is_open() )
210 cout <<
"\nFile " << fname <<
" has not been opened.\n\n" ;
211 assert( fout.is_open() &&
"File not opened." );
218 for (
int k = 0, kj = 0; k <
Nelems(); ++k)
222 fout <<
_ia[kj] + OFFSET << DELIMETER;
243 const string exec_m(
"matlab -nosplash < visualize_results.m");
248 const string fname(
"uv.txt");
251 int ierror = system(exec_m.c_str());
255 cout << endl <<
"Check path to Matlab/octave on your system" << endl;
266 vector<int> idx(
_bedges.size());
268 for (
size_t kb = 0; kb <
_bedges.size(); kb+=2 )
280 sort(idx.begin(), idx.end());
281 idx.erase( unique(idx.begin(), idx.end()), idx.end() );
291 sort(idx.begin(), idx.end());
292 idx.erase( unique(idx.begin(), idx.end()), idx.end() );
305 vector<vector<int>> vertex2elems(
_nnode, vector<int>(0));
306 for (
int k = 0; k <
Nelems(); ++k)
308 for (
int i = 0; i < 3; ++i)
310 vertex2elems[
_ia[3 * k + i]].push_back(k);
313 size_t max_neigh = 0;
314 for (
auto const &
v : vertex2elems)
316 max_neigh = max(max_neigh,
v.size());
328 unsigned int mbc(
_bedges.size() / 2);
331 vector<bool> bdir(
_nnode,
false);
339 for (
size_t kb = 0; kb <
_bedges.size(); kb+=2 )
342 bdir.at(
_bedges[kb]) = booldir;
343 bdir.at(
_bedges[kb+1]) = booldir;
346 vector<int> vert_visited;
347 vert_visited.reserve(max_neigh);
348 for (
int k = 0; k <
_nnode; ++k)
350 vert_visited.clear();
351 auto const &elems = vertex2elems[k];
352 int kedges =
static_cast<int>(
_edges.size()) / 2;
355 int nneigh = elems.size();
356 for (
int ne = 0; ne < nneigh; ++ne)
360 for (
int i = 3 * e + 0; i < 3 * e +
_nvert_e; ++i)
362 int const vert =
_ia[i];
367 auto const iv = find(vert_visited.cbegin(), vert_visited.cend(), vert);
368 if (iv == vert_visited.cend())
370 vert_visited.push_back(vert);
377 if (bdir[k] && bdir[vert])
392 int offset = iv - vert_visited.cbegin();
393 ke = kedges + offset;
396 auto ip = find_if(
_ea.begin() + 3 * e,
_ea.begin() + 3 * (e + 1),
397 [] (
int v) ->
bool {return v < 0;} );
399 assert(ip !=
_ea.cbegin() + 3 * (e + 1));
419 vector<vector<int>> vertex2elems(
_nnode, vector<int>(0));
420 for (
int k = 0; k <
Nelems(); ++k)
422 for (
int i = 0; i < 3; ++i)
424 vertex2elems[
_ia[3 * k + i]].push_back(k);
427 size_t max_neigh = 0;
428 for (
auto const &
v : vertex2elems)
430 max_neigh = max(max_neigh,
v.size());
440 vector<int> vert_visited;
441 vert_visited.reserve(max_neigh);
442 for (
int k = 0; k <
_nnode; ++k)
444 vert_visited.clear();
445 auto const &elems = vertex2elems[k];
446 int kedges =
static_cast<int>(
_edges.size()) / 2;
449 int nneigh = elems.size();
450 for (
int ne = 0; ne < nneigh; ++ne)
454 for (
int i = 3 * e + 0; i < 3 * e +
_nvert_e; ++i)
456 int const vert =
_ia[i];
461 auto const iv = find(vert_visited.cbegin(), vert_visited.cend(), vert);
462 if (iv == vert_visited.cend())
464 vert_visited.push_back(vert);
473 int offset = iv - vert_visited.cbegin();
474 ke = kedges + offset;
477 auto ip = find_if(
_ea.begin() + 3 * e,
_ea.begin() + 3 * (e + 1),
478 [] (
int v) ->
bool {return v < 0;} );
480 assert(ip !=
_ea.cbegin() + 3 * (e + 1));
488 unsigned int mbc(
_bedges.size() / 2);
491 for (
unsigned int kb = 0; kb < mbc; ++kb)
502 assert(e <
_edges.size());
521 vector< pair<int, int> > edges(0);
524 for (
int k = 0; k <
Nelems(); ++k)
526 array < int, 3 + 1 > ivert{{
_ia[3 * k],
_ia[3 * k + 1],
_ia[3 * k + 2],
_ia[3 * k] }};
528 for (
int i = 0; i < 3; ++i)
531 if (ivert[i] < ivert[i + 1])
533 e2 = make_pair(ivert[i], ivert[i + 1]);
537 e2 = make_pair(ivert[i + 1], ivert[i]);
541 auto ip = find(edges.cbegin(), edges.cend(), e2);
542 if ( ip == edges.cend() )
552 eki = ip - edges.cbegin();
554 _ea[3 * k + i] = eki;
558 assert( nedges ==
static_cast<int>(edges.size()) );
560 _edges.resize(2 * nedges);
561 for (
int k = 0; k < nedges; ++k)
563 _edges[2 * k ] = edges[k].first;
564 _edges[2 * k + 1] = edges[k].second;
568 unsigned int mbc(
_bedges.size() / 2);
571 for (
unsigned int kb = 0; kb < mbc; ++kb)
573 const auto vv1 = make_pair(
_bedges[2 * kb ],
_bedges[2 * kb + 1]);
574 const auto vv2 = make_pair(
_bedges[2 * kb + 1],
_bedges[2 * kb ]);
575 auto ip1 = find(edges.cbegin(), edges.cend(), vv1);
576 if (ip1 == edges.cend())
578 ip1 = find(edges.cbegin(), edges.cend(), vv2);
579 assert(ip1 != edges.cend());
581 _ebedges[kb] = ip1 - edges.cbegin();
595 for (
int k = 0; k <
Nelems(); ++k)
599 for (
int j = 0; j < 3; ++j)
601 int const iedg =
_ea[3 * k + j];
602 ivert[2 * j ] =
_edges[2 * iedg ];
603 ivert[2 * j + 1] =
_edges[2 * iedg + 1];
605 sort(ivert.begin(), ivert.end());
606 auto const ip = unique(ivert.begin(), ivert.end());
607 assert( ip - ivert.begin() == 3 );
608 for (
int i = 0; i < 3; ++i)
610 _ia[3 * k + i] = ivert[i];
617 for (
unsigned int k = 0; k < mbc; ++k)
634 vector<vector<int>> v2v(
_nnode, vector<int>(0));
637 vector<int> cnt(
_nnode,0);
638 for (
size_t i = 0; i <
_ia.size(); ++i) ++cnt[
_ia[i]];
639 for (
size_t k = 0; k < v2v.size(); ++k)
646 for (
int e = 0; e <
_nelem; ++e)
651 int const v =
_ia[basis + k];
654 v2v[
v][cnt[
v]] =
_ia[basis + l];
662 for (
size_t v = 0;
v < v2v.size(); ++
v)
664 sort(v2v[
v].begin(), v2v[
v].end());
665 auto ip = unique(v2v[
v].begin(), v2v[
v].end());
666 v2v[
v].erase(ip, v2v[
v].end());
675 vector<vector<int>> v2v(
_nnode, vector<int>(0));
677 for (
int e = 0; e <
_nelem; ++e)
682 int const v =
_ia[basis + k];
685 v2v[
v].push_back(
_ia[basis + l]);
690 for (
size_t v = 0;
v < v2v.size(); ++
v)
692 sort(v2v[
v].begin(), v2v[
v].end());
693 auto ip = unique(v2v[
v].begin(), v2v[
v].end());
694 v2v[
v].erase(ip, v2v[
v].end());
716 if (!(ifs.is_open() && ifs.good()))
718 cerr <<
"Mesh::ReadVertexBasedMesh: Error cannot open file " << fname << endl;
719 assert(ifs.is_open());
723 cout <<
"ASCI file " << fname <<
" opened" << endl;
755 for (
int k = 0; k < nbedges * 2; ++k)
761 int const DUMMY{-9876};
765 cout << nbedges << endl;
766 for (
int k = 0; k < nbedges * 2; ++k)
776 cout <<
"\n ####### no subdomain info of edges available! #########\n";
778 cout <<
"\n End of File read " <<
_sdedges.at(2*nbedges-2) <<
" " <<
_sdedges.at(2*nbedges-1) <<
"\n" << endl;
786 if (!b_ia) cerr <<
"misfit: _nelem vs. _ia" << endl;
789 if (!b_xc) cerr <<
"misfit: _nnode vs. _xc" << endl;
792 if (!b_ea) cerr <<
"misfit: _nelem vs. _ea" << endl;
794 bool b_ed =
static_cast<int>(
_edges.size() / 2) ==
_nedge;
795 if (!b_ed) cerr <<
"misfit: _nedge vs. _edges" << endl;
798 return b_ia && b_xc && b_ea && b_ed;
819 :
Mesh(cmesh), _ibref(ibref), _nref(0), _vfathers(0)
828 cout << endl <<
" Adaptive Refinement not implemented yet." << endl;
829 assert(
_ibref.size() != 0);
839 cout <<
" NOT IMPLEMENTED: Mesh::RefineElements" << endl;
864 cout <<
"\n############ Refine Mesh " << nref <<
" times ";
865 double tstart = clock();
868 for (
int kr = 0; kr < nref; ++kr)
874 auto old_nedges(
Nedges());
875 auto old_nnodes(
Nnodes());
876 auto old_nelems(
Nelems());
880 vector<int> edge_sons(2 * old_nedges);
883 int new_nedge = 2 * old_nedges + 3 * old_nelems;
884 int new_nelem = 4 * old_nelems;
885 int new_nnode = old_nnodes + old_nedges;
887 _xc.reserve(2 * new_nnode);
890 for (
int vc = 0; vc < old_nnodes; ++vc)
898 _ea.resize(new_nelem * 3);
900 _edges.resize(2 * new_nedge);
901 vector<int> e_son(2 * old_nedges);
906 for (
int kc = 0; kc < old_nedges; ++kc)
909 int v1 = old_edges[2 * kc];
910 int v2 = old_edges[2 * kc + 1];
912 double xf = 0.5 * (
_xc[2 * v1 ] +
_xc[2 * v2 ] );
913 double yf = 0.5 * (
_xc[2 * v1 + 1] +
_xc[2 * v2 + 1] );
927 e_son[2 * kc + 1] = kf;
938 for (
int kc = 0; kc < old_nelems; ++kc)
940 array<array<int, 3>, 3 * 2> boundary;
943 for (
int j = 0; j < 3; ++j)
945 int ce = old_ea[3 * kc + j];
947 int s1 = e_son[2 * ce ];
948 int s2 = e_son[2 * ce + 1];
949 boundary[2 * j][2] = s1;
950 boundary[2 * j][0] =
_edges[2 * s1 + 0];
951 boundary[2 * j][1] =
_edges[2 * s1 + 1];
952 if (boundary[2 * j][0] > boundary[2 * j][1]) swap(boundary[2 * j][0], boundary[2 * j][1]);
953 boundary[2 * j + 1][2] = s2;
954 boundary[2 * j + 1][0] =
_edges[2 * s2 + 0];
955 boundary[2 * j + 1][1] =
_edges[2 * s2 + 1];
956 if (boundary[2 * j + 1][0] > boundary[2 * j + 1][1]) swap(boundary[2 * j + 1][0], boundary[2 * j + 1][1]);
959 sort(boundary.begin(), boundary.end());
961 int interior_1 = 2 * old_nedges + kc * 3;
962 int interior_2 = 2 * old_nedges + kc * 3 + 1;
963 int interior_3 = 2 * old_nedges + kc * 3 + 2;
965 _edges[interior_1 * 2 ] = boundary[0][1];
966 _edges[interior_1 * 2 + 1] = boundary[1][1];
968 _edges[interior_2 * 2 ] = boundary[2][1];
969 _edges[interior_2 * 2 + 1] = boundary[3][1];
971 _edges[interior_3 * 2 ] = boundary[4][1];
972 _edges[interior_3 * 2 + 1] = boundary[5][1];
974 _ea[kc * 3 * 4 ] = boundary[0][2];
975 _ea[kc * 3 * 4 + 1] = boundary[1][2];
976 _ea[kc * 3 * 4 + 2] = interior_1;
978 _ea[kc * 3 * 4 + 3] = boundary[2][2];
979 _ea[kc * 3 * 4 + 4] = boundary[3][2];
980 _ea[kc * 3 * 4 + 5] = interior_2;
982 _ea[kc * 3 * 4 + 6] = boundary[4][2];
983 _ea[kc * 3 * 4 + 7] = boundary[5][2];
984 _ea[kc * 3 * 4 + 8] = interior_3;
986 _ea[kc * 3 * 4 + 9] = interior_1;
987 _ea[kc * 3 * 4 + 10] = interior_2;
988 _ea[kc * 3 * 4 + 11] = interior_3;
994 unsigned int old_nbedges(old_ebedges.size());
998 for (
unsigned int ke = 0; ke < old_nbedges; ++ke)
1000 const auto kc = old_ebedges[ke];
1012 #ifdef CUTHILL_MCKEE
1016 auto const perm = cuthill_mckee_reordering(
_edges);
1027 double duration = (clock() - tstart) / CLOCKS_PER_SEC;
1028 cout <<
"finished in " << duration <<
" sec. ########\n";
1037 auto const edges_old(
_edges);
1038 for (
size_t k = 0; k <
_edges.size(); k += 2)
1040 _edges[k ] = old2new[edges_old[k ]];
1041 _edges[k + 1] = old2new[edges_old[k + 1]];
1046 auto const coord_old(
_xc);
1047 for (
size_t k = 0; k <
_xc.size() / 2; ++k)
1049 _xc[2 * old2new[k] ] = coord_old[2 * k ];
1050 _xc[2 * old2new[k] + 1] = coord_old[2 * k + 1];
1061 for (
size_t k = 0; k <
_vfathers.size() / 2; ++k)
1063 _vfathers[2 * old2new[k] ] = old_fathers[2 * k ];
1064 _vfathers[2 * old2new[k] + 1] = old_fathers[2 * k + 1];
1074 const bool bvf = (
static_cast<int>(
_vfathers.size()) / 2 ==
Nnodes());
1083 : _gmesh(max(1, nlevel))
1085 _gmesh[0] = make_shared<Mesh>(cmesh);
1086 for (
int lev = 1; lev < nlevel; ++lev)
1088 _gmesh.at(lev) = make_shared<RefinedMesh>( *
_gmesh.at(lev - 1) );
1092 for (
size_t lev = 0; lev <
_gmesh.size(); ++lev)
1094 _gmesh[lev]->Del_EdgeConnectivity();
1102 _myid(myid), _procx(procx), _procy(procy), _neigh{{ -1, -1, -1, -1}}, _color(0),
1103 _xl(0.0), _xr(1.0), _yb(0.0), _yt(1.0), _nx(nx), _ny(ny)
1106 int const ky = _myid / _procx;
1107 int const kx = _myid % _procy;
1109 _neigh[0] = (ky == 0) ? -1 : _myid - _procx;
1110 _neigh[1] = (kx == _procx - 1) ? -1 : _myid + 1;
1111 _neigh[2] = (ky == _procy - 1) ? -1 : _myid + _procx;
1112 _neigh[3] = (kx == 0) ? -1 : _myid - 1;
1114 _color = (kx + ky) & 1 ;
1117 double const hx = 1. / _procx;
1118 double const hy = 1. / _procy;
1120 _xr = (kx + 1) * hx;
1122 _yt = (ky + 1) * hy;
1125 int const nnode = (_nx + 1) * (_ny + 1);
1126 Resize_Coords(
nnode, 2);
1127 GetCoordsInRectangle(_nx, _ny, _xl, _xr, _yb, _yt, GetCoords().data());
1130 int const nelem = 2 * _nx * _ny;
1131 Resize_Connectivity(
nelem, 3);
1132 GetConnectivityInRectangle(_nx, _ny, GetConnectivity().data());
1144 for (
int j = 0; j <=
_ny; ++j)
1147 for (
int i = 0; i <=
_nx; ++i, ++k)
1158 for (
int j = 0; j <=
_ny; ++j)
1161 for (
int i = 0; i <=
_nx; ++i, ++k)
1177 tr = (
_ny + 1) * (
_nx + 1) - 1;
1178 int const start[4] = { bl, br, tl, bl};
1179 int const end[4] = { br, tr, tr, tl};
1180 int const step[4] = { dx, dy, dx, dy};
1183 for (
int j = 0; j < 4; j++)
1187 for (
int i = start[j]; i <= end[j]; i += step[j])
1194 sort(idx.begin(), idx.end());
1195 idx.erase( unique(idx.begin(), idx.end()), idx.end() );
1202 cerr <<
"Warning: Funktion not implemented. " << __FILE__ <<
"." << __LINE__ << endl;
1212 const string tmp( std::to_string(
_myid / 100) + to_string((
_myid % 100) / 10) + to_string(
_myid % 10) );
1214 const string namep = name +
"." +
tmp;
1215 ofstream ff(namep.c_str());
1217 ff.setf(ios::fixed, ios::floatfield);
1223 for (
int j = 0; j <=
_ny; ++j)
1225 for (
int i = 0; i <=
_nx; ++i, ++k)
1226 ff <<
xc[2 * k + 0] <<
" " <<
xc[2 * k + 1] <<
" " << u[k] << endl;
1235 double const xl,
double const xr,
double const yb,
double const yt,
1238 const double hx = (xr - xl) / nx,
1239 hy = (yt - yb) / ny;
1242 for (
int j = 0; j <= ny; ++j)
1244 const double y0 = yb + j * hy;
1245 for (
int i = 0; i <= nx; ++i, k += 2)
1247 xc[k ] = xl + i * hx;
1257 const int dx = nx + 1;
1260 for (
int j = 0; j < ny; ++j, ++k)
1262 for (
int i = 0; i < nx; ++i, ++k)
1266 ia[l + 2] = k + dx + 1;
1270 ia[l + 2] = k + dx + 1;