source: src/comm/comm_serial.cpp@ 01be70

Last change on this file since 01be70 was 97c25dd, checked in by Julian Iseringhausen <isering@…>, 14 years ago

Work on a red-black communication routine to half the communication amount.

git-svn-id: https://svn.version.fz-juelich.de/scafacos/trunk@1247 5161e1c8-67bf-11de-9fd5-51895aff932f

  • Property mode set to 100644
File size: 24.0 KB
Line 
1/**
2 * @file comm_serial.cpp
3 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
4 * @date Mon Apr 18 12:28:12 2011
5 *
6 * @brief VMG::CommSerial
7 *
8 */
9
10#ifdef HAVE_CONFIG_H
11#include <config.h>
12#endif
13
14#ifdef HAVE_BOOST_FILESYSTEM
15#include <boost/filesystem.hpp>
16namespace fs = boost::filesystem;
17#endif
18
19#include <cstdarg>
20#include <cstdio>
21#include <sstream>
22
23#include "base/discretization.hpp"
24#include "base/helper.hpp"
25#include "base/index.hpp"
26#include "base/linked_cell_list.hpp"
27#include "base/stencil.hpp"
28#include "base/vector.hpp"
29#include "comm/comm_serial.hpp"
30#include "comm/comm.hpp"
31#include "grid/multigrid.hpp"
32#include "grid/tempgrid.hpp"
33#include "mg.hpp"
34
35using namespace VMG;
36
37static char print_buffer[512];
38
39void CommSerial::InitCommSerial()
40{
41 error_norm_count = 0;
42 residual_count = 0;
43}
44
45void CommSerial::CommSubgrid(Grid& grid_old, Grid& grid_new)
46{
47 Grid::iterator iter;
48
49 if (&grid_old == &grid_new)
50 return;
51
52 for (iter = grid_old.Iterators().CompleteGrid().Begin(); iter != grid_old.Iterators().CompleteGrid().End(); ++iter)
53 grid_new(*iter) = grid_old.GetVal(*iter);
54}
55
56void CommSerial::CommAddSubgrid(Grid& grid_old, Grid& grid_new)
57{
58 Grid::iterator iter;
59
60 if (&grid_old == &grid_new)
61 return;
62
63 for (iter = grid_old.Iterators().CompleteGrid().Begin(); iter != grid_old.Iterators().CompleteGrid().End(); ++iter)
64 grid_new(*iter) += grid_old.GetVal(*iter);
65}
66
67Grid& CommSerial::GetFinerGrid(Multigrid& multigrid)
68{
69 return multigrid(multigrid.Level()+1);
70}
71
72Grid& CommSerial::GetCoarserGrid(Multigrid& multigrid)
73{
74 return multigrid(multigrid.Level()-1);
75}
76
77void CommSerial::CommFromGhosts(Grid& mesh)
78{
79 Grid::iterator iter;
80
81 const GridIteratorSuite& iterators = mesh.Iterators();
82 const Index& size = mesh.Local().Size();
83
84 if (BoundaryConditions().X() == Periodic) {
85
86 for (iter = iterators.Halo1().X().Begin(); iter != iterators.Halo1().X().End(); ++iter)
87 mesh((*iter).X()+size.X(), (*iter).Y(), (*iter).Z()) += mesh.GetVal(*iter);
88
89 for (iter = iterators.Halo2().X().Begin(); iter != iterators.Halo2().X().End(); ++iter)
90 mesh((*iter).X()-size.X(), (*iter).Y(), (*iter).Z()) += mesh.GetVal(*iter);
91 }
92
93 if (BoundaryConditions().Y() == Periodic) {
94
95 for (iter = iterators.Halo1().Y().Begin(); iter != iterators.Halo1().Y().End(); ++iter)
96 mesh((*iter).X(), (*iter).Y()+size.Y(), (*iter).Z()) += mesh.GetVal(*iter);
97
98 for (iter = iterators.Halo2().Y().Begin(); iter != iterators.Halo2().Y().End(); ++iter)
99 mesh((*iter).X(), (*iter).Y()-size.Y(), (*iter).Z()) += mesh.GetVal(*iter);
100
101 }
102
103 if (BoundaryConditions().Z() == Periodic) {
104
105 for (iter = iterators.Halo1().Z().Begin(); iter != iterators.Halo1().Z().End(); ++iter)
106 mesh((*iter).X(), (*iter).Y(), (*iter).Z()+size.Z()) += mesh.GetVal(*iter);
107
108 for (iter = iterators.Halo2().Z().Begin(); iter != iterators.Halo2().Z().End(); ++iter)
109 mesh((*iter).X(), (*iter).Y(), (*iter).Z()-size.Z()) += mesh.GetVal(*iter);
110
111 }
112
113#ifdef DEBUG_MATRIX_CHECKS
114 mesh.IsConsistent();
115#endif
116}
117
118void CommSerial::CommToGhosts(Grid& mesh)
119{
120 Grid::iterator iter;
121
122 const GridIteratorSuite& iterators = mesh.Iterators();
123 const Index& size = mesh.Local().Size();
124
125 if (BoundaryConditions().Z() == Periodic) {
126
127 for (iter = iterators.Halo1().Z().Begin(); iter != iterators.Halo1().Z().End(); ++iter)
128 mesh(*iter) = mesh.GetVal((*iter).X(), (*iter).Y(), (*iter).Z()+size.Z());
129
130 for (iter = iterators.Halo2().Z().Begin(); iter != iterators.Halo2().Z().End(); ++iter)
131 mesh(*iter) = mesh.GetVal((*iter).X(), (*iter).Y(), (*iter).Z()-size.Z());
132
133 }
134
135 if (BoundaryConditions().Y() == Periodic) {
136
137 for (iter = iterators.Halo1().Y().Begin(); iter != iterators.Halo1().Y().End(); ++iter)
138 mesh(*iter) = mesh.GetVal((*iter).X(), (*iter).Y()+size.Y(), (*iter).Z());
139
140 for (iter = iterators.Halo2().Y().Begin(); iter != iterators.Halo2().Y().End(); ++iter)
141 mesh(*iter) = mesh.GetVal((*iter).X(), (*iter).Y()-size.Y(), (*iter).Z());
142
143 }
144
145 if (BoundaryConditions().X() == Periodic) {
146
147 for (iter = iterators.Halo1().X().Begin(); iter != iterators.Halo1().X().End(); ++iter)
148 mesh(*iter) = mesh.GetVal((*iter).X()+size.X(), (*iter).Y(), (*iter).Z());
149
150 for (iter = iterators.Halo2().X().Begin(); iter != iterators.Halo2().X().End(); ++iter)
151 mesh(*iter) = mesh.GetVal((*iter).X()-size.X(), (*iter).Y(), (*iter).Z());
152
153 }
154
155#ifdef DEBUG_MATRIX_CHECKS
156 mesh.IsConsistent();
157#endif
158}
159
160void CommSerial::CommToGhostsRB(Grid& grid, const int& offset)
161{
162 CommToGhosts(grid);
163}
164
165Grid& CommSerial::GetGlobalCoarseGrid(Multigrid& multigrid)
166{
167 return multigrid(multigrid.MinLevel());
168}
169
170void CommSerial::CommParticles(const Grid& grid, std::list<Particle::Particle>& particles)
171{
172 Factory& factory = MG::GetFactory();
173 const vmg_int& num_particles_local = factory.GetObjectStorageVal<vmg_int>("PARTICLE_NUM_LOCAL");
174 vmg_float* x = factory.GetObjectStorageArray<vmg_float>("PARTICLE_POS_ARRAY");
175 vmg_float* q = factory.GetObjectStorageArray<vmg_float>("PARTICLE_CHARGE_ARRAY");
176
177 particles.clear();
178
179 for (vmg_int i=0; i<num_particles_local; ++i)
180 particles.push_back(Particle::Particle(&x[3*i], q[i], 0.0, 0.0, 0, i));
181}
182
183void CommSerial::CommLCListGhosts(const Grid& grid, Particle::LinkedCellList& lc)
184{
185 std::list<Particle::Particle>::iterator p_iter;
186 Grid::iterator g_iter;
187
188 for (int i=2; i>=0; --i) {
189
190 if (BoundaryConditions()[i] == Periodic) {
191
192 for (g_iter=lc.Iterators().Boundary1()[i].Begin(); g_iter!=lc.Iterators().Boundary1()[i].End(); ++g_iter)
193 lc(*g_iter).clear();
194
195 for (g_iter=lc.Iterators().NearBoundary1()[i].Begin(); g_iter!=lc.Iterators().NearBoundary1()[i].End(); ++g_iter)
196 for (p_iter=lc(*g_iter).begin(); p_iter!=lc(*g_iter).end(); ++p_iter)
197 lc.AddParticleToComplete(p_iter->Pos() + grid.Extent().Size(), p_iter->Charge(),
198 p_iter->Pot(), p_iter->Force(),
199 p_iter->Rank(), p_iter->Index());
200
201 for (g_iter=lc.Iterators().Boundary2()[i].Begin(); g_iter!=lc.Iterators().Boundary2()[i].End(); ++g_iter)
202 lc(*g_iter).clear();
203
204 for (g_iter=lc.Iterators().NearBoundary2()[i].Begin(); g_iter!=lc.Iterators().NearBoundary2()[i].End(); ++g_iter)
205 for (p_iter=lc(*g_iter).begin(); p_iter!=lc(*g_iter).end(); ++p_iter)
206 lc.AddParticleToComplete(p_iter->Pos() - grid.Extent().Size(), p_iter->Charge(),
207 p_iter->Pot(), p_iter->Force(),
208 p_iter->Rank(), p_iter->Index());
209
210 }
211 }
212}
213
214void CommSerial::CommAddPotential(std::list<Particle::Particle>& particles)
215{
216 std::list<Particle::Particle>::iterator iter;
217 vmg_float* p = MG::GetFactory().GetObjectStorageArray<vmg_float>("PARTICLE_POTENTIAL_ARRAY");
218
219 for (iter=particles.begin(); iter!=particles.end(); ++iter)
220 p[iter->Index()] += iter->Pot();
221}
222
223void CommSerial::CommAddPotential(Particle::LinkedCellList& lc)
224{
225 Grid::iterator lc_iter;
226 std::list<Particle::Particle>::iterator p_iter;
227 vmg_float* p = MG::GetFactory().GetObjectStorageArray<vmg_float>("PARTICLE_POTENTIAL_ARRAY");
228
229 for (lc_iter=lc.Iterators().Local().Begin(); lc_iter!=lc.Iterators().Local().End(); ++lc_iter)
230 for (p_iter=lc(*lc_iter).begin(); p_iter!=lc(*lc_iter).end(); ++p_iter)
231 p[p_iter->Index()] += p_iter->Pot();
232}
233
234void CommSerial::PrintString(const char* format, ...)
235{
236 va_list args;
237 va_start(args, format);
238 vsprintf(print_buffer, format, args);
239 printf("VMG: %s\n", print_buffer);
240 va_end(args);
241}
242
243void CommSerial::PrintStringOnce(const char* format, ...)
244{
245 va_list args;
246 va_start(args, format);
247 vsprintf(print_buffer, format, args);
248 printf("VMG: %s\n", print_buffer);
249 va_end(args);
250}
251
252void CommSerial::PrintXML(const std::string& filename, const std::string& xml_data)
253{
254 pugi::xml_document doc;
255 doc.load(xml_data.c_str());
256
257 pugi::xml_node node_global = doc.prepend_child("Global");
258 pugi::xml_node node_num_processes = node_global.append_child("NumProcesses");
259 pugi::xml_node node_num_processes_data = node_num_processes.append_child(pugi::node_pcdata);
260 node_num_processes_data.set_value(Helper::ToString(GlobalProcs().Product()).c_str());
261
262 doc.save_file(filename.c_str());
263}
264
265void CommSerial::PrintXMLAll(const std::string& filename, const std::string& xml_data)
266{
267 PrintXML(filename, xml_data);
268}
269
270void CommSerial::OpenFileAndPrintHeader(std::ofstream& out, const Grid& mesh, const char* information, bool inner)
271{
272 char path_str[129];
273 int count = OutputCount();
274
275 sprintf(path_str, "%s%04d.dat", OutputPath().c_str(), count);
276
277 out.open(path_str, std::ios::trunc);
278
279 if (!out.good()) {
280#ifdef DEBUG_OUTPUT
281 printf("Multigrid: File %s not accessible.\n", path_str);
282#endif /* DEBUG_OUTPUT */
283 return;
284 }
285
286 out << "# vtk DataFile Version 2.0" << std::endl
287 << count << ": " << information << std::endl
288 << "ASCII" << std::endl
289 << "DATASET STRUCTURED_POINTS" << std::endl;
290
291 if (inner) {
292 out << "DIMENSIONS "
293 << mesh.Local().Size().X() << " "
294 << mesh.Local().Size().Y() << " "
295 << mesh.Local().Size().Z() << std::endl;
296 }else {
297 out << "DIMENSIONS "
298 << mesh.Local().SizeTotal().X() << " "
299 << mesh.Local().SizeTotal().Y() << " "
300 << mesh.Local().SizeTotal().Z() << std::endl;
301 }
302
303 out << "ORIGIN 0 0 0" << std::endl
304 << "SPACING " << mesh.MeshWidth() << " "
305 << mesh.MeshWidth() << " "
306 << mesh.MeshWidth() << std::endl;
307
308 if (inner)
309 out << "POINT_DATA " << mesh.Local().Size().Product() << std::endl;
310 else
311 out << "POINT_DATA " << mesh.Local().SizeTotal().Product() << std::endl;
312
313 out << "SCALARS residual double 1" << std::endl
314 << "LOOKUP_TABLE default" << std::endl;
315}
316
317void CommSerial::PrintDefect(Grid& sol, Grid& rhs, const char* information)
318{
319 std::ofstream out_file;
320 std::stringstream out;
321
322 TempGrid *temp = MG::GetTempGrid();
323 temp->SetProperties(sol);
324 temp->ImportFromResidual(sol, rhs);
325
326#ifdef DEBUG_MATRIX_CHECKS
327 temp->IsConsistent();
328#endif
329
330 OpenFileAndPrintHeader(out_file, *temp, information, true);
331
332 assert(out_file.good());
333
334 if (!out_file.good())
335 return;
336
337 for (int k=temp->Local().Begin().Z(); k<temp->Local().End().Z(); k++)
338 for (int j=temp->Local().Begin().Y(); j<temp->Local().End().Y(); j++)
339 for (int i=temp->Local().Begin().X(); i<temp->Local().End().X(); i++)
340 out << std::scientific << temp->GetVal(i,j,k) << std::endl;
341
342 out_file << out.str();
343
344 out_file.close();
345}
346
347void CommSerial::PrintGrid(Grid& mesh, const char* information)
348{
349 std::stringstream out;
350 std::ofstream out_file;
351
352 CommToGhosts(mesh);
353
354 OpenFileAndPrintHeader(out_file, mesh, information, false);
355
356 for (int k=0; k<mesh.Local().SizeTotal().Z(); k++)
357 for (int j=0; j<mesh.Local().SizeTotal().Y(); j++)
358 for (int i=0; i<mesh.Local().SizeTotal().X(); i++)
359 out << std::scientific << mesh.GetVal(i,j,k) << std::endl;
360
361 out_file << out.str();
362 out_file.close();
363}
364
365void CommSerial::PrintCorrectedGrid(Grid& mesh, const char* information)
366{
367 std::ofstream out_file;
368 std::stringstream out;
369
370 CommToGhosts(mesh);
371
372 OpenFileAndPrintHeader(out_file, mesh, information, false);
373
374 for (int k=0; k<mesh.Local().SizeTotal().Z(); k++)
375 for (int j=0; j<mesh.Local().SizeTotal().Y(); j++)
376 for (int i=0; i<mesh.Local().SizeTotal().X(); i++)
377 out << std::scientific << mesh.GetCorrectedVal(i,j,k) << std::endl;
378
379 out_file << out.str();
380
381 out_file.close();
382}
383
384void CommSerial::PrintInnerGrid(Grid& mesh, const char* information)
385{
386 std::ofstream out_file;
387 std::stringstream out;
388
389 CommToGhosts(mesh);
390
391 OpenFileAndPrintHeader(out_file, mesh, information, true);
392
393 for (int k=mesh.Local().Begin().Z(); k<mesh.Local().End().Z(); k++)
394 for (int j=mesh.Local().Begin().Y(); j<mesh.Local().End().Y(); j++)
395 for (int i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
396 out << std::scientific << mesh.GetVal(i,j,k) << std::endl;
397
398 out_file << out.str();
399
400 out_file.close();
401}
402
403void CommSerial::PrintInnerCorrectedGrid(Grid& mesh, const char* information)
404{
405 std::ofstream out_file;
406 std::stringstream out;
407
408 CommToGhosts(mesh);
409
410 OpenFileAndPrintHeader(out_file, mesh, information, true);
411
412 for (int k=mesh.Local().Begin().Z(); k<mesh.Local().End().Z(); k++)
413 for (int j=mesh.Local().Begin().Y(); j<mesh.Local().End().Y(); j++)
414 for (int i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
415 out << std::scientific << mesh.GetCorrectedVal(i,j,k) << std::endl;
416
417 out_file << out.str();
418
419 out_file.close();
420}
421
422void CommSerial::PrintAllSettings()
423{
424 Multigrid* mg = MG::GetFactory().Get("SOL")->Cast<Multigrid>();
425 std::stringstream buf;
426 std::ofstream out;
427
428 buf << OutputPath() << "settings.txt";
429
430 out.open(buf.str().c_str(), std::ios::trunc);
431
432 for (int i=mg->MinLevel(); i<=mg->MaxLevel(); ++i) {
433
434 out << "GRID LEVEL " << i << std::endl
435
436 << "GLOBAL" << std::endl
437 << "BEGINFINEST: " << (*mg)(i).Global().BeginFinest() << std::endl
438 << "ENDFINEST: " << (*mg)(i).Global().EndFinest() << std::endl
439 << "SIZEFINEST: " << (*mg)(i).Global().SizeFinest() << std::endl
440 << "BEGINLOCAL: " << (*mg)(i).Global().BeginLocal() << std::endl
441 << "ENDLOCAL: " << (*mg)(i).Global().EndLocal() << std::endl
442 << "SIZELOCAL: " << (*mg)(i).Global().SizeLocal() << std::endl
443 << "SIZEGLOBAL: " << (*mg)(i).Global().SizeGlobal() << std::endl
444 << "BOUNDARYTYPE: " << (*mg)(i).Global().BoundaryType() << std::endl
445
446 << "LOCAL" << std::endl
447 << "SIZE: " << (*mg)(i).Local().Size() << std::endl
448 << "SIZETOTAL: " << (*mg)(i).Local().SizeTotal() << std::endl
449 << "BEGIN: " << (*mg)(i).Local().Begin() << std::endl
450 << "END: " << (*mg)(i).Local().End() << std::endl
451 << "HALOBEGIN1: " << (*mg)(i).Local().HaloBegin1() << std::endl
452 << "HALOEND1: " << (*mg)(i).Local().HaloEnd1() << std::endl
453 << "HALOBEGIN2: " << (*mg)(i).Local().HaloBegin2() << std::endl
454 << "HALOEND2: " << (*mg)(i).Local().HaloEnd2() << std::endl
455 << "BOUNDARYBEGIN1: " << (*mg)(i).Local().BoundaryBegin1() << std::endl
456 << "BOUNDARYEND1: " << (*mg)(i).Local().BoundaryEnd1() << std::endl
457 << "BOUNDARYBEGIN2: " << (*mg)(i).Local().BoundaryBegin2() << std::endl
458 << "BOUNDARYEND2: " << (*mg)(i).Local().BoundaryEnd2() << std::endl
459 << "ALIGNMENTBEGIN: " << (*mg)(i).Local().AlignmentBegin() << std::endl
460 << "ALIGNMENTEND: " << (*mg)(i).Local().AlignmentEnd() << std::endl
461
462 << "EXTENT" << std::endl
463 << "SIZE: " << (*mg)(i).Extent().Size() << std::endl
464 << "SIZEFACTOR: " << (*mg)(i).Extent().SizeFactor() << std::endl
465 << "BEGIN: " << (*mg)(i).Extent().Begin() << std::endl
466 << "END: " << (*mg)(i).Extent().End() << std::endl
467 << "MESHWIDTH: " << (*mg)(i).Extent().MeshWidth() << std::endl;
468
469 }
470
471 assert(out.good());
472 out.close();
473}
474
475void CommSerial::DebugPrintError(const Grid& sol, const char* information)
476{
477 Index i;
478 std::ofstream out_file;
479 std::stringstream out;
480
481 OpenFileAndPrintHeader(out_file, sol, information, false);
482
483 for (i.Z()=0; i.Z()<sol.Local().SizeTotal().Z(); ++i.Z())
484 for (i.Y()=0; i.Y()<sol.Local().SizeTotal().Y(); ++i.Y())
485 for (i.X()=0; i.X()<sol.Local().SizeTotal().X(); ++i.X())
486 out << std::scientific << sol.DebugKnownSolution(i) - sol.GetVal(i) << std::endl;
487
488 out_file << out.str();
489
490 out_file.close();
491}
492
493void CommSerial::DebugPrintErrorNorm(Grid& sol)
494{
495#ifdef HAVE_LIBGSL
496 char path_str[129];
497 std::ofstream out;
498 const vmg_float sp = sol.MeshWidth();
499 const vmg_float sp_3_inv = 1.0/(sp*sp*sp);
500 const int numsamples = 1e6;
501 const vmg_float numsamples_inv = 1.0 / numsamples;
502 vmg_float val1, val2, diff;
503
504 vmg_float norm_L1 = 0.0;
505 vmg_float norm_L2 = 0.0;
506 vmg_float norm_Linfty = 0.0;
507 vmg_float norm_u_L1 = 0.0;
508 vmg_float norm_u_L2 = 0.0;
509 vmg_float norm_u_Linfty = 0.0;
510
511 Vector x, x_le, x_ri;
512 Index ind;
513
514 gsl_qrng *q = gsl_qrng_alloc(gsl_qrng_niederreiter_2, 3);
515
516 sprintf(path_str, "%serror.txt", defects_path_str.c_str());
517
518 out.open(path_str, std::ios::app);
519
520 assert(out.good());
521
522 CommToGhosts(sol);
523
524 for (int i=0; i<numsamples; i++) {
525
526 gsl_qrng_get(q, x.vec());
527
528 ind = x / sp;
529
530 x_le = x - sp * static_cast<Vector>(ind);
531 x_ri = sp - x_le;
532
533 for (int j=0; j<3; ++j)
534 if (this->BoundaryConditions()[j] == Periodic)
535 ind[j] += sol.Local().Begin()[j];
536
537 val1 = ( sol.GetVal(ind) * x_ri[0] * x_ri[1] * x_ri[2] +
538 sol.GetVal(ind[0]+1, ind[1] , ind[2] ) * x_le[0] * x_ri[1] * x_ri[2] +
539 sol.GetVal(ind[0] , ind[1]+1, ind[2] ) * x_ri[0] * x_le[1] * x_ri[2] +
540 sol.GetVal(ind[0] , ind[1] , ind[2]+1) * x_ri[0] * x_ri[1] * x_le[2] +
541 sol.GetVal(ind[0]+1, ind[1]+1, ind[2] ) * x_le[0] * x_le[1] * x_ri[2] +
542 sol.GetVal(ind[0]+1, ind[1] , ind[2]+1) * x_le[0] * x_ri[1] * x_le[2] +
543 sol.GetVal(ind[0] , ind[1]+1, ind[2]+1) * x_ri[0] * x_le[1] * x_le[2] +
544 sol.GetVal(ind[0]+1, ind[1]+1, ind[2]+1) * x_le[0] * x_le[1] * x_le[2] ) * sp_3_inv;
545
546 val2 = sol.DebugKnownSolution(x);
547
548 diff = fabs(val1 - val2);
549
550 norm_L1 += diff * numsamples_inv;
551 norm_L2 += diff*diff * numsamples_inv;
552 norm_Linfty = std::max(norm_Linfty, diff);
553
554 norm_u_L1 += fabs(val2) * numsamples_inv;
555 norm_u_L2 += val2*val2 * numsamples_inv;
556 norm_u_Linfty = std::max(norm_u_Linfty, fabs(val2));
557 }
558
559 norm_L2 = sqrt(norm_L2);
560 norm_u_L2 = sqrt(norm_u_L2);
561
562 std::cout << std::scientific << std::endl
563 << "Error L1-norm: " << norm_L1 << std::endl
564 << "Error L2-norm: " << norm_L2 << std::endl
565 << "Error Linfty-norm: " << norm_Linfty << std::endl
566 << "Relative error L1-norm: " << norm_L1 / norm_u_L1 << std::endl
567 << "Relative error L2-norm: " << norm_L2 / norm_u_L2 << std::endl
568 << "Relative error Linfty-norm: " << norm_Linfty / norm_u_Linfty << std::endl;
569
570 gsl_qrng_free(q);
571
572 out << std::scientific << error_norm_count++ << " "
573 << norm_L1 << " "
574 << norm_L2 << " "
575 << norm_Linfty << " "
576 << norm_L1/norm_u_L1 << " "
577 << norm_L2/norm_u_L2 << " "
578 << norm_Linfty/norm_u_Linfty << std::endl;
579
580 out.close();
581
582#endif
583}
584
585inline int GetIndex(const Grid& grid, int i, int j, int k)
586{
587 if (grid.Global().BoundaryType() == LocallyRefined)
588 return k + grid.Local().Size().Z() * (j + grid.Local().Size().Y() * i);
589 else
590 return k + grid.Local().SizeTotal().Z() * (j + grid.Local().SizeTotal().Y() * i);
591}
592
593void CommSerial::PrintGridStructureLevel(Grid& grid, std::ofstream& out)
594{
595 const vmg_float sp = grid.MeshWidth();
596 int numLines;
597
598 if (grid.Global().BoundaryType() == LocallyRefined)
599 numLines = grid.Local().Size().X() * grid.Local().Size().Y() +
600 grid.Local().Size().Y() * grid.Local().Size().Z() +
601 grid.Local().Size().X() * grid.Local().Size().Z();
602 else
603 numLines = grid.Local().SizeTotal().X() * grid.Local().SizeTotal().Y() +
604 grid.Local().SizeTotal().Y() * grid.Local().SizeTotal().Z() +
605 grid.Local().SizeTotal().X() * grid.Local().SizeTotal().Z();
606
607 out << " <Piece";
608
609 if (grid.Global().BoundaryType() == LocallyRefined) {
610 out << " NumberOfPoints=\"" << grid.Local().Size().Product() << "\""
611 << " NumberOfVerts=\"" << grid.Local().Size().Product() << "\"";
612 }else {
613 out << " NumberOfPoints=\"" << grid.Local().SizeTotal().Product() << "\""
614 << " NumberOfVerts=\"" << grid.Local().SizeTotal().Product() << "\"";
615 }
616
617 out << " NumberOfLines=\"" << numLines << "\""
618 << " NumberOfStrips=\"0\""
619 << " NumberOfPolys=\"0\"" << ">" << std::endl
620 << " <Points>" << std::endl
621 << " <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl
622 << " ";
623
624 if (grid.Global().BoundaryType() == LocallyRefined) {
625 for (int i=0; i<grid.Local().Size().X(); i++)
626 for (int j=0; j<grid.Local().Size().Y(); j++)
627 for (int k=0; k<grid.Local().Size().Z(); k++)
628 out << grid.Extent().Begin().X() + i * sp << " "
629 << grid.Extent().Begin().Y() + j * sp << " "
630 << grid.Extent().Begin().Z() + k * sp << " ";
631 }else {
632 for (int i=0; i<grid.Local().SizeTotal().X(); i++)
633 for (int j=0; j<grid.Local().SizeTotal().Y(); j++)
634 for (int k=0; k<grid.Local().SizeTotal().Z(); k++)
635 out << grid.Extent().Begin().X() + i * sp << " "
636 << grid.Extent().Begin().Y() + j * sp << " "
637 << grid.Extent().Begin().Z() + k * sp << " ";
638 }
639
640 out << std::endl
641 << " </DataArray>" << std::endl
642 << " </Points>" << std::endl
643 << " <Verts>" << std::endl
644 << " <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">" << std::endl
645 << " ";
646
647 if (grid.Global().BoundaryType() == LocallyRefined) {
648 for (int i=0; i<grid.Local().Size().Product(); i++)
649 out << i << " ";
650 }else {
651 for (int i=0; i<grid.Local().SizeTotal().Product(); i++)
652 out << i << " ";
653 }
654
655 out << std::endl
656 << " </DataArray>" << std::endl
657 << " <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">" << std::endl
658 << " ";
659
660 if (grid.Global().BoundaryType() == LocallyRefined) {
661 for (int i=1; i<=grid.Local().Size().Product(); i++)
662 out << i << " ";
663 }else {
664 for (int i=1; i<=grid.Local().SizeTotal().Product(); i++)
665 out << i << " ";
666 }
667
668 out << std::endl
669 << " </DataArray>" << std::endl
670 << " </Verts>" << std::endl
671 << " <Lines>" << std::endl
672 << " <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">" << std::endl
673 << " ";
674
675 if (grid.Global().BoundaryType() == LocallyRefined) {
676 for (int i=0; i<grid.Local().Size().X(); i++)
677 for (int j=0; j<grid.Local().Size().Y(); j++)
678 out << GetIndex(grid,i,j,0) << " "
679 << GetIndex(grid,i,j,grid.Local().Size().Z()-1) << " ";
680
681 for (int j=0; j<grid.Local().Size().Y(); j++)
682 for (int k=0; k<grid.Local().Size().Z(); k++)
683 out << GetIndex(grid,0,j,k) << " "
684 << GetIndex(grid,grid.Local().Size().X()-1,j,k) << " ";
685
686 for (int i=0; i<grid.Local().Size().X(); i++)
687 for (int k=0; k<grid.Local().Size().Z(); k++)
688 out << GetIndex(grid,i,0,k) << " "
689 << GetIndex(grid,i,grid.Local().Size().Y()-1,k) << " ";
690 }else {
691 for (int i=0; i<grid.Local().SizeTotal().X(); i++)
692 for (int j=0; j<grid.Local().SizeTotal().Y(); j++)
693 out << GetIndex(grid,i,j,0) << " "
694 << GetIndex(grid,i,j,grid.Local().SizeTotal().Z()-1) << " ";
695
696 for (int j=0; j<grid.Local().SizeTotal().Y(); j++)
697 for (int k=0; k<grid.Local().SizeTotal().Z(); k++)
698 out << GetIndex(grid,0,j,k) << " "
699 << GetIndex(grid,grid.Local().SizeTotal().X()-1,j,k) << " ";
700
701 for (int i=0; i<grid.Local().SizeTotal().X(); i++)
702 for (int k=0; k<grid.Local().SizeTotal().Z(); k++)
703 out << GetIndex(grid,i,0,k) << " "
704 << GetIndex(grid,i,grid.Local().SizeTotal().Y()-1,k) << " ";
705 }
706
707 out << std::endl
708 << " </DataArray>" << std::endl
709 << " <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">" << std::endl
710 << " ";
711
712 for (int i=1; i<=numLines; i++)
713 out << 2*i << " ";
714
715 out << std::endl
716 << " </DataArray>" << std::endl
717 << " </Lines>" << std::endl
718 << " </Piece>" << std::endl;
719}
720
721void CommSerial::DebugPrintGridStructure(Multigrid& grid)
722{
723 std::ofstream out;
724 char path_str[129];
725
726 sprintf(path_str, "%sgrid.vtp", OutputPath().c_str());
727
728 out.open(path_str, std::ios::trunc);
729
730 if (!out.good()) {
731#ifdef DEBUG_OUTPUT
732 printf("Multigrid: File %s not accessible.\n", path_str);
733#endif /* DEBUG_OUTPUT */
734 return;
735 }
736
737 out << "<?xml version=\"1.0\"?>" << std::endl
738 << "<VTKFile type=\"PolyData\">" << std::endl
739 << " <PolyData>" << std::endl;
740
741 for (int i=grid.MinLevel(); i<=grid.MaxLevel(); i++)
742 PrintGridStructureLevel(grid(i), out);
743
744 out << " </PolyData>" << std::endl
745 << "</VTKFile>" << std::endl;
746
747 out.close();
748}
749
750std::string CommSerial::CreateOutputDirectory()
751{
752#ifdef HAVE_BOOST_FILESYSTEM
753 std::string path, unique_path;
754 std::stringstream unique_suffix;
755 int suffix_counter = 0;
756 char buffer[129];
757 time_t rawtime;
758 struct tm *timeinfo;
759
760 time(&rawtime);
761 timeinfo = localtime(&rawtime);
762 strftime(buffer, 128, "./output/%Y_%m_%d_%H_%M_%S/", timeinfo);
763 path = buffer;
764
765 if (!fs::exists("output"))
766 fs::create_directory("output");
767
768 unique_path = path;
769
770 while (fs::exists(unique_path.c_str())) {
771
772 unique_suffix.str("");
773 unique_suffix << "_" << suffix_counter++ << "/";
774
775 unique_path = path;
776 unique_path.replace(unique_path.size()-1, 1, unique_suffix.str());
777
778 }
779
780 fs::create_directory(unique_path.c_str());
781
782 return unique_path;
783
784#else
785
786 return "./";
787
788#endif
789}
Note: See TracBrowser for help on using the repository browser.