jacobi_oo_STL
geom.cpp
Go to the documentation of this file.
1 // see: http://llvm.org/docs/CodingStandards.html#include-style
2 #include "geom.h"
3 
4 #include <algorithm>
5 #include <cassert>
6 #include <fstream>
7 #include <iostream>
8 #include <list>
9 #include <string>
10 #include <vector>
11 using namespace std;
12 
13 Mesh::Mesh(int ndim, int nvert_e, int ndof_e)
14  : _nelem(0), _nvert_e(nvert_e), _ndof_e(ndof_e), _nnode(0), _ndim(ndim), _ia(0), _xc(0)
15 {
16 }
17 
19 {}
20 
21 void Mesh::SetValues(std::vector<double> &v, const std::function<double(double, double)> &func) const
22 {
23  int const nnode = Nnodes(); // number of vertices in mesh
24  assert( nnode == static_cast<int>(v.size()) );
25  for (int k = 0; k < nnode; ++k)
26  {
27  v[k] = func( _xc[2 * k], _xc[2 * k + 1] );
28  }
29 }
30 
31 
32 void Mesh::Debug() const
33 {
34  cout << "\n ############### Debug M E S H ###################\n";
35  cout << "\n ............... Coordinates ...................\n";
36  for (int k = 0; k < _nnode; ++k)
37  {
38  cout << k << " : " ;
39  for (int i = 0; i < _ndof_e; ++i )
40  {
41  cout << _xc[2*k+i] << " ";
42  }
43  cout << endl;
44  }
45  cout << "\n ............... Elements ...................\n";
46  for (int k = 0; k < _nelem; ++k)
47  {
48  cout << k << " : ";
49  for (int i = 0; i < _ndof_e; ++i )
50  cout << _ia[_ndof_e * k + i] << " ";
51  cout << endl;
52  }
53  return;
54 }
55 
56 void Mesh::Write_ascii_matlab(std::string const &fname, std::vector<double> const &v) const
57 {
58  assert(Nnodes() == static_cast<int>(v.size())); // fits vector length to mesh information?
59 
60  ofstream fout(fname); // open file ASCII mode
61  if ( !fout.is_open() )
62  {
63  cout << "\nFile " << fname << " has not been opened.\n\n" ;
64  assert( fout.is_open() && "File not opened." );
65  }
66 
67  string const DELIMETER(" "); // define the same delimeter as in matlab/ascii_read*.m
68  int const OFFSET(1); // convert C-indexing to matlab
69 
70  // Write data: #nodes, #space dimensions, #elements, #vertices per element
71  fout << Nnodes() << DELIMETER << Ndims() << DELIMETER << Nelems() << DELIMETER << NverticesElements() << endl;
72 
73  // Write cordinates: x_k, y_k in seperate lines
74  assert( Nnodes()*Ndims() == static_cast<int>(_xc.size()));
75  for (int k = 0, kj = 0; k < Nnodes(); ++k)
76  {
77  for (int j = 0; j < Ndims(); ++j, ++kj)
78  {
79  fout << _xc[kj] << DELIMETER;
80  }
81  fout << endl;
82  }
83 
84  // Write connectivity: ia_k,0, ia_k,1 etc in seperate lines
85  assert( Nelems()*NverticesElements() == static_cast<int>(_ia.size()));
86  for (int k = 0, kj = 0; k < Nelems(); ++k)
87  {
88  for (int j = 0; j < NverticesElements(); ++j, ++kj)
89  {
90  fout << _ia[kj] + OFFSET << DELIMETER; // C to matlab
91  }
92  fout << endl;
93  }
94 
95  // Write vector
96  for (int k = 0; k < Nnodes(); ++k)
97  {
98  fout << v[k] << endl;
99  }
100 
101  fout.close();
102  return;
103 }
104 
105 
106 void Mesh::Visualize(std::vector<double> const &v) const
107 {
108  // define external command
109  const string exec_m("matlab -nosplash < visualize_results.m"); // Matlab
110  //const string exec_m("octave --no-window-system --no-gui visualize_results.m"); // Octave
111  //const string exec_m("flatpak run org.octave.Octave visualize_results.m"); // Octave (flatpak): desktop GH
112 
113  const string fname("uv.txt");
114  Write_ascii_matlab(fname, v);
115 
116  int ierror = system(exec_m.c_str()); // call external command
117 
118  if (ierror != 0)
119  {
120  cout << endl << "Check path to Matlab/octave on your system" << endl;
121  }
122  cout << endl;
123  return;
124 }
125 
126 
127 
128 
129 // #####################################################################
130 Mesh_2d_3_square::Mesh_2d_3_square(int nx, int ny, int myid, int procx, int procy)
131  : Mesh(2, 3, 3), // two dimensions, 3 vertices, 3 dofs
132  _myid(myid), _procx(procx), _procy(procy), _neigh{{-1, -1, -1, -1}}, _color(0),
133 _xl(0.0), _xr(1.0), _yb(0.0), _yt(1.0), _nx(nx), _ny(ny)
134 {
135  //void IniGeom(int const myid, int const procx, int const procy, int neigh[], int &color)
136  int const ky = _myid / _procx;
137  int const kx = _myid % _procy; // MOD(myid,procx)
138  // Determine the neighbors of domain/rank myid
139  _neigh[0] = (ky == 0) ? -1 : _myid - _procx; // South
140  _neigh[1] = (kx == _procx - 1) ? -1 : _myid + 1; // East
141  _neigh[2] = (ky == _procy - 1) ? -1 : _myid + _procx; // North
142  _neigh[3] = (kx == 0) ? -1 : _myid - 1; // West
143 
144  _color = (kx + ky) & 1 ;
145 
146  // subdomain is part of unit square
147  double const hx = 1. / _procx;
148  double const hy = 1. / _procy;
149  _xl = kx * hx; // left
150  _xr = (kx + 1) * hx; // right
151  _yb = ky * hy; // bottom
152  _yt = (ky + 1) * hy; // top
153 
154  // Calculate coordinates
155  int const nnode = (_nx + 1) * (_ny + 1); // number of nodes
156  Resize_Coords(nnode, 2); // coordinates in 2D [nnode][ndim]
157  GetCoordsInRectangle(_nx, _ny, _xl, _xr, _yb, _yt, GetCoords().data());
158 
159  // Calculate element connectivity (linear triangles)
160  int const nelem = 2 * _nx * _ny; // number of elements
161  Resize_Connectivity(nelem, 3); // connectivity matrix [nelem][3]
162  GetConnectivityInRectangle(_nx, _ny, GetConnectivity().data());
163 
164  return;
165 }
166 
167 
168 void Mesh_2d_3_square::SetU(std::vector<double> &u) const
169 {
170  int dx = _nx + 1;
171  for (int j = 0; j <= _ny; ++j)
172  {
173  int k = j * dx;
174  for (int i = 0; i <= _nx; ++i, ++k)
175  {
176  u[k] = 0.0;
177  }
178  }
179 
180 }
181 
182 void Mesh_2d_3_square::SetF(std::vector<double> &f) const
183 {
184  int dx = _nx + 1;
185  for (int j = 0; j <= _ny; ++j)
186  {
187  int k = j * dx;
188  for (int i = 0; i <= _nx; ++i, ++k)
189  {
190  f[k] = 1.0;
191  }
192  }
193 
194 }
195 
196 
198 {
199  int const dx = 1,
200  dy = _nx + 1,
201  bl = 0,
202  br = _nx,
203  tl = _ny * (_nx + 1),
204  tr = (_ny + 1) * (_nx + 1) - 1;
205  int const start[4] = { bl, br, tl, bl},
206  end[4] = { br, tr, tr, tl},
207  step[4] = { dx, dy, dx, dy};
208 
209  vector<int> idx(0);
210  for (int j = 0; j < 4; j++)
211  {
212  if (_neigh[j] < 0)
213  {
214  for (int i = start[j]; i <= end[j]; i += step[j])
215  {
216  idx.push_back(i); // node i is Dirichlet node
217  }
218  }
219  }
220  // remove multiple elements
221  sort(idx.begin(), idx.end()); // sort
222  idx.erase( unique(idx.begin(), idx.end()), idx.end() ); // remove duplicate data
223 
224  return idx;
225 }
226 
227 void Mesh_2d_3_square::SaveVectorP(std::string const &name, vector<double> const &u) const
228 {
229 // construct the file name for subdomain myid
230  const string tmp( std::to_string(_myid / 100) + to_string((_myid % 100) / 10) + to_string(_myid % 10) );
231 
232  const string namep = name + "." + tmp;
233  ofstream ff(namep.c_str());
234  ff.precision(6);
235  ff.setf(ios::fixed, ios::floatfield);
236 
237  // assumes tensor product grid in unit square; rowise numbered (as generated in class constructor)
238  // output is provided for tensor product grid visualization ( similar to Matlab-surf() )
239  auto const &xc = GetCoords();
240  int k = 0;
241  for (int j = 0; j <= _ny; ++j)
242  {
243  for (int i = 0; i <= _nx; ++i, ++k)
244  ff << xc[2 * k + 0] << " " << xc[2 * k + 1] << " " << u[k] << endl;
245  ff << endl;
246  }
247 
248  ff.close();
249  return;
250 }
251 
252 void Mesh_2d_3_square::GetCoordsInRectangle(int const nx, int const ny,
253  double const xl, double const xr, double const yb, double const yt,
254  double xc[])
255 {
256  const double hx = (xr - xl) / nx,
257  hy = (yt - yb) / ny;
258 
259  int k = 0;
260  for (int j = 0; j <= ny; ++j)
261  {
262  const double y0 = yb + j * hy;
263  for (int i = 0; i <= nx; ++i, k += 2)
264  {
265  xc[k ] = xl + i * hx;
266  xc[k + 1] = y0;
267  }
268  }
269 
270  return;
271 }
272 
273 void Mesh_2d_3_square::GetConnectivityInRectangle(int const nx, int const ny, int ia[])
274 {
275  const int dx = nx + 1;
276  int k = 0;
277  int l = 0;
278  for (int j = 0; j < ny; ++j, ++k)
279  {
280  for (int i = 0; i < nx; ++i, ++k)
281  {
282  ia[l ] = k;
283  ia[l + 1] = k + 1;
284  ia[l + 2] = k + dx + 1;
285  l += 3;
286  ia[l ] = k;
287  ia[l + 1] = k + dx;
288  ia[l + 2] = k + dx + 1;
289  l += 3;
290  }
291  }
292  return;
293 }
294 
295 // #################### still some old code (--> MPI) ############################
296 
297 
298 // Copies the values of w corresponding to the boundary
299 // South (ib==1), East (ib==2), North (ib==3), West (ib==4)
300 
301 void GetBound(int const ib, int const nx, int const ny, double const w[], double s[])
302 {
303  const int //dx = 1,
304  dy = nx + 1,
305  bl = 0,
306  br = nx,
307  tl = ny * (nx + 1),
308  tr = (ny + 1) * (nx + 1) - 1;
309  switch (ib)
310  {
311  case 1:
312  {
313  for (int i = bl, j = 0; i <= br; ++i, ++j)
314  s[j] = w[i];
315  break;
316  }
317  case 3:
318  {
319  for (int i = tl, j = 0; i <= tr; ++i, ++j)
320  s[j] = w[i];
321  break;
322  }
323  case 4:
324  {
325  for (int i = bl, j = 0; i <= tl; i += dy, ++j)
326  s[j] = w[i];
327  break;
328  }
329  case 2:
330  {
331  for (int i = br, j = 0; i <= tr; i += dy, ++j)
332  s[j] = w[i];
333  break;
334  }
335  default:
336  {
337  cout << endl << "Wrong parameter ib in " << __FILE__ << ":" << __LINE__ << endl;
338  }
339  }
340  return;
341 }
342 
343 // ----------------------------------------------------------------------------------------------------------
344 // Computes w: = w + s at nodes on the boundary
345 // South (ib == 1), East (ib == 2), North (ib == 3), West (ib == 4)
346 
347 void AddBound(int const ib, int const nx, int const ny, double w[], double const s[])
348 {
349  int const dy = nx + 1,
350  bl = 0,
351  br = nx,
352  tl = ny * (nx + 1),
353  tr = (ny + 1) * (nx + 1) - 1;
354  switch (ib)
355  {
356  case 1:
357  {
358  for (int i = bl, j = 0; i <= br; ++i, ++j)
359  w[i] += s[j];
360  break;
361  }
362  case 3:
363  {
364  for (int i = tl, j = 0; i <= tr; ++i, ++j)
365  w[i] += s[j];
366  break;
367  }
368  case 4:
369  {
370  for (int i = bl, j = 0; i <= tl; i += dy, ++j)
371  w[i] += s[j];
372  break;
373  }
374  case 2:
375  {
376  for (int i = br, j = 0; i <= tr; i += dy, ++j)
377  w[i] += s[j];
378  break;
379  }
380  default:
381  {
382  cout << endl << "Wrong parameter ib in " << __FILE__ << ":" << __LINE__ << endl;
383  }
384  }
385  return;
386 }
387 
388 
389 // ####################################################################
390 
392  : Mesh(2, 3, 3), // two dimensions, 3 vertices, 3 dofs
393  bedges(0)
394 {
395  ifstream ifs(fname);
396  if (!(ifs.is_open() && ifs.good()))
397  {
398  cerr << "Mesh_2d_3_matlab: Error cannot open file " << fname << endl;
399  assert(ifs.is_open());
400  }
401 
402  int const OFFSET(1); // Matlab to C indexing
403  cout << "ASCI file " << fname << " opened" << endl;
404 
405  // Read some mesh constants
406  int nnode, ndim, nelem, nvert_e;
407  ifs >> nnode >> ndim >> nelem >> nvert_e;
408  cout << nnode << " " << ndim << " " << nelem << " " << nvert_e << endl;
409  assert(ndim == 2 && nvert_e == 3);
410 
411  // Allocate memory
412  Resize_Coords(nnode, ndim); // coordinates in 2D [nnode][ndim]
413  Resize_Connectivity(nelem, nvert_e); // connectivity matrix [nelem][nvert]
414 
415  // Read ccordinates
416  auto &xc = GetCoords();
417  for (int k = 0; k < nnode * ndim; ++k)
418  {
419  ifs >> xc[k];
420  }
421 
422  // Read connectivity
423  auto &ia = GetConnectivity();
424  for (int k = 0; k < nelem * nvert_e; ++k)
425  {
426  ifs >> ia[k];
427  ia[k] -= OFFSET; // Matlab to C indexing
428  }
429 
430  // additional read of boundary information (only start/end point)
431  int nbedges;
432  ifs >> nbedges;
433 
434  bedges.resize(nbedges * 2);
435  for (int k = 0; k < nbedges * 2; ++k)
436  {
437  ifs >> bedges[k];
438  bedges[k] -= OFFSET; // Matlab to C indexing
439  }
440 
441  return;
442 }
443 
444 // binary
445 //{
446 //ifstream ifs(fname, ios_base::in | ios_base::binary);
447 //if(!(ifs.is_open() && ifs.good()))
448 //{
449 //cerr << "ReadBinMatrix: Error cannot open file " << file << endl;
450 //assert(ifs.is_open());
451 //}
452 //cout << "ReadBinMatrix: file opened" << file << endl;
453 
454 
455 //}
456 
457 // binaryIO.cpp
458 //void read_binMatrix(const string& file, vector<int> &cnt, vector<int> &col, vector<double> &ele)
459 //{
460 
461 //ifstream ifs(file, ios_base::in | ios_base::binary);
462 
463 //if(!(ifs.is_open() && ifs.good()))
464 //{
465 //cerr << "ReadBinMatrix: Error cannot open file " << file << endl;
466 //assert(ifs.is_open());
467 //}
468 //cout << "ReadBinMatrix: Opened file " << file << endl;
469 
470 //int _size;
471 
472 //ifs.read(reinterpret_cast<char*>(&_size), sizeof(int)); // old: ifs.read((char*)&_size, sizeof(int));
473 //cnt.resize(_size);
474 //cout << "ReadBinMatrix: cnt size: " << _size << endl;
475 
476 //ifs.read((char*)&_size, sizeof(int));
477 //col.resize(_size);
478 //cout << "ReadBinMatrix: col size: " << _size << endl;
479 
480 //ifs.read((char*)&_size, sizeof(int));
481 //ele.resize(_size);
482 //cout << "ReadBinMatrix: ele size: " << _size << endl;
483 
484 
485 //ifs.read((char*)cnt.data(), cnt.size() * sizeof(int));
486 //ifs.read((char*)col.data(), col.size() * sizeof(int));
487 //ifs.read((char*)ele.data(), ele.size() * sizeof(double));
488 
489 //ifs.close();
490 //cout << "ReadBinMatrix: Finished reading matrix.." << endl;
491 
492 //}
493 
494 
496 {
497  vector<int> idx(bedges); // copy
498 
499  sort(idx.begin(), idx.end()); // sort
500  idx.erase( unique(idx.begin(), idx.end()), idx.end() ); // remove duplicate data
501 
502  return idx;
503 }
504 
505 
506 
507 
508 
509 
510 
511 
512 
513 
514 
515 
516 
517 
518 
519 
520 
521 
522 
Mesh::Write_ascii_matlab
void Write_ascii_matlab(std::string const &fname, std::vector< double > const &v) const
Definition: geom.cpp:56
xc
xc
Definition: ascii_read_meshvector.m:30
tmp
tmp(:,:).'
function
function[xc, ia, v]
Definition: ascii_read_meshvector.m:1
Mesh::Ndims
int Ndims() const
Definition: geom.h:71
Mesh::Resize_Coords
void Resize_Coords(int nnodes, int ndim)
Definition: geom.h:113
Mesh::Resize_Connectivity
void Resize_Connectivity(int nelem, int nvert_e)
Definition: geom.h:82
Mesh::GetConnectivity
const std::vector< int > & GetConnectivity() const
Definition: geom.h:93
Mesh::Mesh
Mesh(int ndim, int nvert_e=0, int ndof_e=0)
Definition: geom.cpp:13
Mesh
Definition: geom.h:11
Mesh::SetValues
void SetValues(std::vector< double > &v, const std::function< double(double, double)> &func) const
Definition: geom.cpp:21
Mesh_2d_3_square::Mesh_2d_3_square
Mesh_2d_3_square(int nx, int ny, int myid=0, int procx=1, int procy=1)
Definition: geom.cpp:130
Mesh::Nnodes
int Nnodes() const
Definition: geom.h:62
v
v
Definition: ascii_read_meshvector.m:40
Mesh_2d_3_square::SetU
void SetU(std::vector< double > &u) const
Definition: geom.cpp:168
Mesh_2d_3_square::SetF
void SetF(std::vector< double > &f) const
Definition: geom.cpp:182
Mesh::Visualize
void Visualize(std::vector< double > const &v) const
Definition: geom.cpp:106
GetBound
void GetBound(int const ib, int const nx, int const ny, double const w[], double s[])
Definition: geom.cpp:301
Mesh::~Mesh
virtual ~Mesh()
Definition: geom.cpp:18
Mesh_2d_3_matlab::Index_DirichletNodes
std::vector< int > Index_DirichletNodes() const override
Definition: geom.cpp:495
Mesh_2d_3_square::SaveVectorP
void SaveVectorP(std::string const &name, std::vector< double > const &u) const
Definition: geom.cpp:227
ndim
ndim
Definition: ascii_read_meshvector.m:23
geom.h
Mesh_2d_3_matlab::Mesh_2d_3_matlab
Mesh_2d_3_matlab(std::string const &fname)
Definition: geom.cpp:391
ia
ia
Definition: ascii_read_meshvector.m:35
nnode
function vertex minimal boundary edge info in an ASCII file Matlab indexing is stored(starts with 1). % % The output file format is compatible with Mesh_2d_3_matlab nnode
Definition: ascii_write_mesh.m:23
Mesh_2d_3_square::Index_DirichletNodes
std::vector< int > Index_DirichletNodes() const override
Definition: geom.cpp:197
Mesh::NverticesElements
int NverticesElements() const
Definition: geom.h:44
nelem
nelem
Definition: ascii_read_meshvector.m:24
Mesh::Debug
void Debug() const
Definition: geom.cpp:32
nvert_e
nvert_e
Definition: ascii_write_mesh.m:26
Mesh::GetCoords
const std::vector< double > & GetCoords() const
Definition: geom.h:124
Mesh::Nelems
int Nelems() const
Definition: geom.h:35
AddBound
void AddBound(int const ib, int const nx, int const ny, double w[], double const s[])
Definition: geom.cpp:347