jacobi_oo_STL
Loading...
Searching...
No Matches
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>
11using namespace std;
12
13Mesh::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
20
21void 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
32void 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
56void 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
106void 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// #####################################################################
130Mesh_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
168void 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
182void 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
227void 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
252void 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
273void 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
301void 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
347void 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
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
tmp(:,:).'
Mesh_2d_3_matlab(std::string const &fname)
Definition geom.cpp:391
std::vector< int > Index_DirichletNodes() const override
Definition geom.cpp:495
void SetU(std::vector< double > &u) const
Definition geom.cpp:168
std::vector< int > Index_DirichletNodes() const override
Definition geom.cpp:197
void SaveVectorP(std::string const &name, std::vector< double > const &u) const
Definition geom.cpp:227
void SetF(std::vector< double > &f) const
Definition geom.cpp:182
Mesh_2d_3_square(int nx, int ny, int myid=0, int procx=1, int procy=1)
Definition geom.cpp:130
Definition geom.h:12
const std::vector< double > & GetCoords() const
Definition geom.h:124
void Resize_Connectivity(int nelem, int nvert_e)
Definition geom.h:82
void Debug() const
Definition geom.cpp:32
void Resize_Coords(int nnodes, int ndim)
Definition geom.h:113
int Ndims() const
Definition geom.h:71
virtual ~Mesh()
Definition geom.cpp:18
Mesh(int ndim, int nvert_e=0, int ndof_e=0)
Definition geom.cpp:13
int Nelems() const
Definition geom.h:35
void Write_ascii_matlab(std::string const &fname, std::vector< double > const &v) const
Definition geom.cpp:56
int Nnodes() const
Definition geom.h:62
int NverticesElements() const
Definition geom.h:44
const std::vector< int > & GetConnectivity() const
Definition geom.h:93
void SetValues(std::vector< double > &v, const std::function< double(double, double)> &func) const
Definition geom.cpp:21
void Visualize(std::vector< double > const &v) const
Definition geom.cpp:106
void AddBound(int const ib, int const nx, int const ny, double w[], double const s[])
Definition geom.cpp:347
void GetBound(int const ib, int const nx, int const ny, double const w[], double s[])
Definition geom.cpp:301