source: src/comm/comm_serial.cpp@ 66f24d

Last change on this file since 66f24d was 48b662, checked in by Olaf Lenz <olenz@…>, 14 years ago

Moved files in scafacos_fcs one level up.

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

  • Property mode set to 100644
File size: 16.7 KB
RevLine 
[48b662]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 <iostream>
20#include <fstream>
21#include <cassert>
22#include <cmath>
23
24#include "base/discretization.hpp"
25#include "base/stencil.hpp"
26#include "base/vector.hpp"
27#include "comm/comm_serial.hpp"
28#include "comm/comm.hpp"
29#include "grid/multigrid.hpp"
30#include "grid/tempgrid.hpp"
31#include "mg.hpp"
32
33using namespace VMG;
34
35inline vmg_float pow_3(vmg_float val)
36{
37 return val*val*val;
38}
39
40void CommSerial::Init()
41{
42 output_count = 0;
43 error_norm_count = 0;
44 residual_count = 0;
45
46 /* Create directory to output defects */
47#ifdef HAVE_BOOST_FILESYSTEM
48 char buffer[129];
49 time_t rawtime;
50 struct tm *timeinfo;
51
52 time(&rawtime);
53 timeinfo = localtime(&rawtime);
54 strftime(buffer, 128, "output/%Y_%m_%d_%H_%M_%S/", timeinfo);
55 defects_path_str = buffer;
56#else
57 defects_path_str = "";
58#endif
59}
60
61void CommSerial::CreateOutputDirectory()
62{
63#ifdef HAVE_BOOST_FILESYSTEM
64 if (!fs::exists("output"))
65 fs::create_directory("output");
66
67 if (!fs::exists(defects_path_str.c_str()))
68 fs::create_directory(defects_path_str.c_str());
69#endif
70}
71
72Grid& CommSerial::GetFinerGrid(Multigrid& multigrid)
73{
74 return multigrid(multigrid.Level()+1);
75}
76
77Grid& CommSerial::GetCoarserGrid(Multigrid& multigrid)
78{
79 return multigrid(multigrid.Level()-1);
80}
81
82vmg_float CommSerial::ComputeResidualNorm(Multigrid& sol, Multigrid& rhs)
83{
84#ifdef DEBUG
85 sol().IsCompatible(rhs());
86 sol().IsConsistent();
87 rhs().IsConsistent();
88#endif
89
90 Stencil::iterator iter;
91 Index i;
92 vmg_float val;
93 vmg_float norm = 0.0;
94
95 const vmg_float prefactor = MG::GetDiscretization()->OperatorPrefactor(sol());
96 const Stencil& A = MG::GetDiscretization()->GetStencil();
97
98 this->CommToGhosts(sol());
99
100 if (sol().Global().BoundaryType() == LocallyRefined)
101 MG::GetDiscretization()->SetInnerBoundary(sol(), rhs(), sol(sol.Level()-1));
102
103 for (i.X()=rhs().Local().Begin().X(); i.X()<rhs().Local().End().X(); ++i.X())
104 for (i.Y()=rhs().Local().Begin().Y(); i.Y()<rhs().Local().End().Y(); ++i.Y())
105 for (i.Z()=rhs().Local().Begin().Z(); i.Z()<rhs().Local().End().Z(); ++i.Z()) {
106
107 val = rhs().GetVal(i) - prefactor * A.GetDiag() * sol().GetVal(i);
108
109 for (iter = A.begin(); iter != A.end(); iter++)
110 val -= prefactor * iter->val * sol().GetVal(i+iter);
111
112 norm += val*val;
113
114 }
115
116 norm = sqrt( pow_3(sol().MeshWidth()) * norm );
117
118#ifdef DEBUG
119 std::ofstream out;
120 char path_str[129];
121
122 CreateOutputDirectory();
123
124 sprintf(path_str, "%sresidual.txt", defects_path_str.c_str());
125
126 out.open(path_str, std::ios::app);
127
128 assert(out.good());
129
130 out << residual_count++ << " " << norm << std::endl;
131
132 out.close();
133#endif
134
135 return norm;
136}
137
138void CommSerial::CommFromGhosts(Grid& mesh)
139{
140 if (this->BoundaryConditions() == Periodic) {
141
142 // Copy values in x-direction
143 for (int i=mesh.Local().HaloBegin1().X(); i<mesh.Local().HaloEnd1().X(); i++)
144 for (int j=0; j<mesh.Local().SizeTotal().Y(); j++)
145 for (int k=0; k<mesh.Local().SizeTotal().Z(); k++) {
146 assert(i+mesh.Local().Size().X() >= mesh.Local().Begin().X() && i+mesh.Local().Size().X() < mesh.Local().End().X());
147 mesh(i+mesh.Local().Size().X(),j,k) += mesh.GetVal(i,j,k);
148 }
149
150 for (int i=mesh.Local().HaloBegin2().X(); i<mesh.Local().HaloEnd2().X(); i++)
151 for (int j=0; j<mesh.Local().SizeTotal().Y(); j++)
152 for (int k=0; k<mesh.Local().SizeTotal().Z(); k++) {
153 assert(i-mesh.Local().Size().X() >= mesh.Local().Begin().X() && i-mesh.Local().Size().X() < mesh.Local().End().X());
154 mesh(i-mesh.Local().Size().X(),j,k) += mesh.GetVal(i,j,k);
155 }
156
157 // Copy values in y-direction
158 for (int i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
159 for (int j=mesh.Local().HaloBegin1().Y(); j<mesh.Local().HaloEnd1().Y(); j++)
160 for (int k=0; k<mesh.Local().SizeTotal().Z(); k++) {
161
162 mesh(i,j+mesh.Local().Size().Y(),k) += mesh.GetVal(i,j,k);
163 }
164 for (int i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
165 for (int j=mesh.Local().HaloBegin2().Y(); j<mesh.Local().HaloEnd2().Y(); j++)
166 for (int k=0; k<mesh.Local().SizeTotal().Z(); k++)
167 mesh(i,j-mesh.Local().Size().Y(),k) += mesh.GetVal(i,j,k);
168
169 // Copy values in z-direction
170 for (int i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
171 for (int j=mesh.Local().Begin().Y(); j<mesh.Local().End().Y(); j++)
172 for (int k=mesh.Local().HaloBegin1().Z(); k<mesh.Local().HaloEnd1().Z(); k++)
173 mesh(i,j,k+mesh.Local().Size().Z()) += mesh.GetVal(i,j,k);
174
175 for (int i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
176 for (int j=mesh.Local().Begin().Y(); j<mesh.Local().End().Y(); j++)
177 for (int k=mesh.Local().HaloBegin2().Z(); k<mesh.Local().HaloEnd2().Z(); k++)
178 mesh(i,j,k-mesh.Local().Size().Z()) += mesh.GetVal(i,j,k);
179 }
180
181#ifdef DEBUG
182 mesh.IsConsistent();
183#endif
184}
185
186void CommSerial::CommToGhosts(Grid& mesh)
187{
188#ifdef DEBUG
189 mesh.IsConsistent();
190#endif
191
192 int i,j,k;
193
194 if (this->BoundaryConditions() == Periodic) {
195
196 // Copy values in z-direction
197 for (i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
198 for (j=mesh.Local().Begin().Y(); j<mesh.Local().End().Y(); j++)
199 for (k=mesh.Local().HaloBegin1().Z(); k<mesh.Local().HaloEnd1().Z(); k++)
200 mesh(i,j,k) = mesh.GetVal(i,j,k+mesh.Local().Size().Z());
201
202 for (i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
203 for (j=mesh.Local().Begin().Y(); j<mesh.Local().End().Y(); j++)
204 for (k=mesh.Local().HaloBegin2().Z(); k<mesh.Local().HaloEnd2().Z(); k++)
205 mesh(i,j,k) = mesh.GetVal(i,j,k-mesh.Local().Size().Z());
206
207 // Copy values in y-direction
208 for (i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
209 for (j=mesh.Local().HaloBegin1().Y(); j<mesh.Local().HaloEnd1().Y(); j++)
210 for (k=0; k<mesh.Local().SizeTotal().Z(); k++)
211 mesh(i,j,k) = mesh.GetVal(i,j+mesh.Local().Size().Y(),k);
212
213 for (i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
214 for (j=mesh.Local().HaloBegin2().Y(); j<mesh.Local().HaloEnd2().Y(); j++)
215 for (k=0; k<mesh.Local().SizeTotal().Z(); k++)
216 mesh(i,j,k) = mesh.GetVal(i,j-mesh.Local().Size().Y(),k);
217
218 // Copy values in x-direction
219 for (i=mesh.Local().HaloBegin1().X(); i<mesh.Local().HaloEnd1().X(); i++)
220 for (j=0; j<mesh.Local().SizeTotal().Y(); j++)
221 for (k=0; k<mesh.Local().SizeTotal().Z(); k++)
222 mesh(i,j,k) = mesh.GetVal(i+mesh.Local().Size().X(),j,k);
223
224 for (i=mesh.Local().HaloBegin2().X(); i<mesh.Local().HaloEnd2().X(); i++)
225 for (j=0; j<mesh.Local().SizeTotal().Y(); j++)
226 for (k=0; k<mesh.Local().SizeTotal().Z(); k++)
227 mesh(i,j,k) = mesh.GetVal(i-mesh.Local().Size().X(),j,k);
228 }
229
230#ifdef DEBUG
231 mesh.IsConsistent();
232#endif
233}
234
235void CommSerial::OpenFileAndPrintHeader(std::ofstream& out, const Grid& mesh, const char* information, bool inner)
236{
237 char file_str[129], path_str[129];
238 struct tm *timeinfo;
239 time_t rawtime;
240
241 CreateOutputDirectory();
242
243 output_count++;
244
245 time(&rawtime);
246 timeinfo = localtime(&rawtime);
247
248 strftime(file_str, 128, "%H_%M_%S", timeinfo);
249
250 sprintf(path_str, "%s%04d_%s.dat", defects_path_str.c_str(), output_count, file_str);
251
252 out.open(path_str, std::ios::trunc);
253
254 if (!out.good()) {
255 printf("Multigrid: File %s not accessible.\n", path_str);
256 return;
257 }
258
259 out << "# vtk DataFile Version 2.0" << std::endl
260 << output_count << ": " << information << std::endl
261 << "ASCII" << std::endl
262 << "DATASET STRUCTURED_POINTS" << std::endl;
263
264 if (inner) {
265 out << "DIMENSIONS "
266 << mesh.Local().Size().X() << " "
267 << mesh.Local().Size().Y() << " "
268 << mesh.Local().Size().Z() << std::endl;
269 }else {
270 out << "DIMENSIONS "
271 << mesh.Local().SizeTotal().X() << " "
272 << mesh.Local().SizeTotal().Y() << " "
273 << mesh.Local().SizeTotal().Z() << std::endl;
274 }
275
276 out << "ORIGIN 0 0 0" << std::endl
277 << "SPACING " << mesh.MeshWidth() << " "
278 << mesh.MeshWidth() << " "
279 << mesh.MeshWidth() << std::endl;
280
281 if (inner)
282 out << "POINT_DATA " << mesh.Local().Size().Product() << std::endl;
283 else
284 out << "POINT_DATA " << mesh.Local().SizeTotal().Product() << std::endl;
285
286 out << "SCALARS residual double 1" << std::endl
287 << "LOOKUP_TABLE default" << std::endl;
288}
289
290void CommSerial::PrintDefect(const Grid& sol, const Grid& rhs, const char* information)
291{
292 std::ofstream out;
293
294 TempGrid *temp = MG::GetTempGrid();
295 temp->SetProperties(sol);
296 temp->ImportFromResidual(sol, rhs);
297
298#ifdef DEBUG
299 temp->IsConsistent();
300#endif
301
302 OpenFileAndPrintHeader(out, *temp, information, true);
303
304 assert(out.good());
305
306 if (!out.good())
307 return;
308
309 for (int k=temp->Local().Begin().Z(); k<temp->Local().End().Z(); k++)
310 for (int j=temp->Local().Begin().Y(); j<temp->Local().End().Y(); j++)
311 for (int i=temp->Local().Begin().X(); i<temp->Local().End().X(); i++)
312 out << std::scientific << temp->GetVal(i,j,k) << std::endl;
313
314 out.close();
315}
316
317void CommSerial::PrintGrid(const Grid& mesh, const char* information)
318{
319 std::ofstream out;
320
321 OpenFileAndPrintHeader(out, mesh, information, false);
322
323 for (int k=0; k<mesh.Local().SizeTotal().Z(); k++)
324 for (int j=0; j<mesh.Local().SizeTotal().Y(); j++)
325 for (int i=0; i<mesh.Local().SizeTotal().X(); i++)
326 out << std::scientific << mesh.GetVal(i,j,k) << std::endl;
327
328 out.close();
329}
330
331void CommSerial::PrintCorrectedGrid(const Grid& mesh, const char* information)
332{
333 std::ofstream out;
334
335 OpenFileAndPrintHeader(out, mesh, information, false);
336
337 for (int k=0; k<mesh.Local().SizeTotal().Z(); k++)
338 for (int j=0; j<mesh.Local().SizeTotal().Y(); j++)
339 for (int i=0; i<mesh.Local().SizeTotal().X(); i++)
340 out << std::scientific << mesh.GetCorrectedVal(i,j,k) << std::endl;
341
342 out.close();
343}
344
345void CommSerial::PrintInnerGrid(const Grid& mesh, const char* information)
346{
347 std::ofstream out;
348
349 OpenFileAndPrintHeader(out, mesh, information, true);
350
351 for (int k=mesh.Local().Begin().Z(); k<mesh.Local().End().Z(); k++)
352 for (int j=mesh.Local().Begin().Y(); j<mesh.Local().End().Y(); j++)
353 for (int i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
354 out << std::scientific << mesh.GetVal(i,j,k) << std::endl;
355
356 out.close();
357}
358
359void CommSerial::PrintInnerCorrectedGrid(const Grid& mesh, const char* information)
360{
361 std::ofstream out;
362
363 OpenFileAndPrintHeader(out, mesh, information, true);
364
365 for (int k=mesh.Local().Begin().Z(); k<mesh.Local().End().Z(); k++)
366 for (int j=mesh.Local().Begin().Y(); j<mesh.Local().End().Y(); j++)
367 for (int i=mesh.Local().Begin().X(); i<mesh.Local().End().X(); i++)
368 out << std::scientific << mesh.GetCorrectedVal(i,j,k) << std::endl;
369
370 out.close();
371}
372
373void CommSerial::DebugPrintError(const Grid& sol, const char* information)
374{
375 Index i;
376 std::ofstream out;
377
378 OpenFileAndPrintHeader(out, sol, information, false);
379
380 for (i.Z()=0; i.Z()<sol.Local().SizeTotal().Z(); ++i.Z())
381 for (i.Y()=0; i.Y()<sol.Local().SizeTotal().Y(); ++i.Y())
382 for (i.X()=0; i.X()<sol.Local().SizeTotal().X(); ++i.X()) {
383 out << std::scientific << sol.DebugKnownSolution(i) - sol.GetVal(i) << std::endl;
384
385 }
386}
387
388inline int GetIndex(const Grid& grid, int i, int j, int k)
389{
390 if (grid.Global().BoundaryType() == LocallyRefined)
391 return k + grid.Local().Size().Z() * (j + grid.Local().Size().Y() * i);
392 else
393 return k + grid.Local().SizeTotal().Z() * (j + grid.Local().SizeTotal().Y() * i);
394}
395
396void CommSerial::PrintGridStructureLevel(Grid& grid, std::ofstream& out)
397{
398 const vmg_float sp = grid.MeshWidth();
399 int numLines;
400
401 if (grid.Global().BoundaryType() == LocallyRefined)
402 numLines = grid.Local().Size().X() * grid.Local().Size().Y() +
403 grid.Local().Size().Y() * grid.Local().Size().Z() +
404 grid.Local().Size().X() * grid.Local().Size().Z();
405 else
406 numLines = grid.Local().SizeTotal().X() * grid.Local().SizeTotal().Y() +
407 grid.Local().SizeTotal().Y() * grid.Local().SizeTotal().Z() +
408 grid.Local().SizeTotal().X() * grid.Local().SizeTotal().Z();
409
410 out << " <Piece";
411
412 if (grid.Global().BoundaryType() == LocallyRefined) {
413 out << " NumberOfPoints=\"" << grid.Local().Size().Product() << "\""
414 << " NumberOfVerts=\"" << grid.Local().Size().Product() << "\"";
415 }else {
416 out << " NumberOfPoints=\"" << grid.Local().SizeTotal().Product() << "\""
417 << " NumberOfVerts=\"" << grid.Local().SizeTotal().Product() << "\"";
418 }
419
420 out << " NumberOfLines=\"" << numLines << "\""
421 << " NumberOfStrips=\"0\""
422 << " NumberOfPolys=\"0\"" << ">" << std::endl
423 << " <Points>" << std::endl
424 << " <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl
425 << " ";
426
427 if (grid.Global().BoundaryType() == LocallyRefined) {
428 for (int i=0; i<grid.Local().Size().X(); i++)
429 for (int j=0; j<grid.Local().Size().Y(); j++)
430 for (int k=0; k<grid.Local().Size().Z(); k++)
431 out << grid.Extent().Begin().X() + i * sp << " "
432 << grid.Extent().Begin().Y() + j * sp << " "
433 << grid.Extent().Begin().Z() + k * sp << " ";
434 }else {
435 for (int i=0; i<grid.Local().SizeTotal().X(); i++)
436 for (int j=0; j<grid.Local().SizeTotal().Y(); j++)
437 for (int k=0; k<grid.Local().SizeTotal().Z(); k++)
438 out << grid.Extent().Begin().X() + i * sp << " "
439 << grid.Extent().Begin().Y() + j * sp << " "
440 << grid.Extent().Begin().Z() + k * sp << " ";
441 }
442
443 out << std::endl
444 << " </DataArray>" << std::endl
445 << " </Points>" << std::endl
446 << " <Verts>" << std::endl
447 << " <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">" << std::endl
448 << " ";
449
450 if (grid.Global().BoundaryType() == LocallyRefined) {
451 for (int i=0; i<grid.Local().Size().Product(); i++)
452 out << i << " ";
453 }else {
454 for (int i=0; i<grid.Local().SizeTotal().Product(); i++)
455 out << i << " ";
456 }
457
458 out << std::endl
459 << " </DataArray>" << std::endl
460 << " <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">" << std::endl
461 << " ";
462
463 if (grid.Global().BoundaryType() == LocallyRefined) {
464 for (int i=1; i<=grid.Local().Size().Product(); i++)
465 out << i << " ";
466 }else {
467 for (int i=1; i<=grid.Local().SizeTotal().Product(); i++)
468 out << i << " ";
469 }
470
471 out << std::endl
472 << " </DataArray>" << std::endl
473 << " </Verts>" << std::endl
474 << " <Lines>" << std::endl
475 << " <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">" << std::endl
476 << " ";
477
478 if (grid.Global().BoundaryType() == LocallyRefined) {
479 for (int i=0; i<grid.Local().Size().X(); i++)
480 for (int j=0; j<grid.Local().Size().Y(); j++)
481 out << GetIndex(grid,i,j,0) << " "
482 << GetIndex(grid,i,j,grid.Local().Size().Z()-1) << " ";
483
484 for (int j=0; j<grid.Local().Size().Y(); j++)
485 for (int k=0; k<grid.Local().Size().Z(); k++)
486 out << GetIndex(grid,0,j,k) << " "
487 << GetIndex(grid,grid.Local().Size().X()-1,j,k) << " ";
488
489 for (int i=0; i<grid.Local().Size().X(); i++)
490 for (int k=0; k<grid.Local().Size().Z(); k++)
491 out << GetIndex(grid,i,0,k) << " "
492 << GetIndex(grid,i,grid.Local().Size().Y()-1,k) << " ";
493 }else {
494 for (int i=0; i<grid.Local().SizeTotal().X(); i++)
495 for (int j=0; j<grid.Local().SizeTotal().Y(); j++)
496 out << GetIndex(grid,i,j,0) << " "
497 << GetIndex(grid,i,j,grid.Local().SizeTotal().Z()-1) << " ";
498
499 for (int j=0; j<grid.Local().SizeTotal().Y(); j++)
500 for (int k=0; k<grid.Local().SizeTotal().Z(); k++)
501 out << GetIndex(grid,0,j,k) << " "
502 << GetIndex(grid,grid.Local().SizeTotal().X()-1,j,k) << " ";
503
504 for (int i=0; i<grid.Local().SizeTotal().X(); i++)
505 for (int k=0; k<grid.Local().SizeTotal().Z(); k++)
506 out << GetIndex(grid,i,0,k) << " "
507 << GetIndex(grid,i,grid.Local().SizeTotal().Y()-1,k) << " ";
508 }
509
510 out << std::endl
511 << " </DataArray>" << std::endl
512 << " <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">" << std::endl
513 << " ";
514
515 for (int i=1; i<=numLines; i++)
516 out << 2*i << " ";
517
518 out << std::endl
519 << " </DataArray>" << std::endl
520 << " </Lines>" << std::endl
521 << " </Piece>" << std::endl;
522}
523
524void CommSerial::DebugPrintGridStructure(Multigrid& grid)
525{
526 std::ofstream out;
527 char path_str[129];
528
529 CreateOutputDirectory();
530
531 sprintf(path_str, "%sgrid.vtp", defects_path_str.c_str());
532
533 out.open(path_str, std::ios::trunc);
534
535 if (!out.good()) {
536 printf("Multigrid: File %s not accessible.\n", path_str);
537 return;
538 }
539
540 out << "<?xml version=\"1.0\"?>" << std::endl
541 << "<VTKFile type=\"PolyData\">" << std::endl
542 << " <PolyData>" << std::endl;
543
544 for (int i=grid.MinLevel(); i<=grid.MaxLevel(); i++)
545 PrintGridStructureLevel(grid(i), out);
546
547 out << " </PolyData>" << std::endl
548 << "</VTKFile>" << std::endl;
549
550 out.close();
551}
Note: See TracBrowser for help on using the repository browser.