Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
iwr
dune-vtk
Commits
3cb9300e
Commit
3cb9300e
authored
Apr 16, 2020
by
Praetorius, Simon
Browse files
add vtkwriter test based on dune/grid/io/file/test/checkvtkfile
parent
fb381494
Changes
11
Hide whitespace changes
Inline
Side-by-side
dune/vtk/filewriter.hh
View file @
3cb9300e
...
...
@@ -14,7 +14,7 @@ namespace Dune
virtual
~
FileWriter
()
=
default
;
/// Write to file given by `filename` and (optionally) store additional data in `dataDir`
virtual
void
write
(
std
::
string
const
&
filename
,
Std
::
optional
<
std
::
string
>
dataDir
=
{})
const
=
0
;
virtual
std
::
string
write
(
std
::
string
const
&
filename
,
Std
::
optional
<
std
::
string
>
dataDir
=
{})
const
=
0
;
};
}
// end namespace Dune
dune/vtk/pvdwriter.hh
View file @
3cb9300e
...
...
@@ -52,7 +52,7 @@ namespace Dune
* \param dir (Ignored) Timestep files are already written and their filenames are
* stored in \ref timesteps_.
**/
virtual
void
write
(
std
::
string
const
&
fn
,
Std
::
optional
<
std
::
string
>
dir
=
{})
const
override
;
virtual
std
::
string
write
(
std
::
string
const
&
fn
,
Std
::
optional
<
std
::
string
>
dir
=
{})
const
override
;
/// Attach point data to the writer, \see VtkFunction for possible arguments
template
<
class
Function
,
class
...
Args
>
...
...
dune/vtk/pvdwriter.impl.hh
View file @
3cb9300e
...
...
@@ -49,7 +49,7 @@ void PvdWriter<W>
template
<
class
W
>
void
PvdWriter
<
W
>
std
::
string
PvdWriter
<
W
>
::
write
(
std
::
string
const
&
fn
,
Std
::
optional
<
std
::
string
>
/*dir*/
)
const
{
auto
p
=
filesystem
::
path
(
fn
);
...
...
@@ -57,9 +57,12 @@ void PvdWriter<W>
p
.
remove_filename
();
p
/=
name
.
string
();
std
::
string
outputFilename
;
int
commRank
=
vtkWriter_
.
comm
().
rank
();
if
(
commRank
==
0
)
{
std
::
ofstream
out
(
p
.
string
()
+
".pvd"
,
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
outputFilename
=
p
.
string
()
+
".pvd"
;
std
::
ofstream
out
(
outputFilename
,
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
assert
(
out
.
is_open
());
out
.
imbue
(
std
::
locale
::
classic
());
...
...
@@ -69,6 +72,8 @@ void PvdWriter<W>
writeFile
(
out
);
}
return
outputFilename
;
}
...
...
dune/vtk/vtktimeserieswriter.hh
View file @
3cb9300e
...
...
@@ -76,8 +76,10 @@ namespace Dune
*
* \param fn Filename of the Timeseries file. May contain a directory and any file extension.
* \param dir The optional parameter specifies the directory of the partition files.
*
* \returns File name of the actual written file
**/
virtual
void
write
(
std
::
string
const
&
fn
,
Std
::
optional
<
std
::
string
>
dir
=
{})
const
override
;
virtual
std
::
string
write
(
std
::
string
const
&
fn
,
Std
::
optional
<
std
::
string
>
dir
=
{})
const
override
;
/// Attach point data to the writer, \see VtkFunction for possible arguments
template
<
class
Function
,
class
...
Args
>
...
...
dune/vtk/vtktimeserieswriter.impl.hh
View file @
3cb9300e
...
...
@@ -74,7 +74,7 @@ void VtkTimeseriesWriter<W>
template
<
class
W
>
void
VtkTimeseriesWriter
<
W
>
std
::
string
VtkTimeseriesWriter
<
W
>
::
write
(
std
::
string
const
&
fn
,
Std
::
optional
<
std
::
string
>
dir
)
const
{
assert
(
initialized_
);
...
...
@@ -96,9 +96,11 @@ void VtkTimeseriesWriter<W>
if
(
commSize
>
1
)
serial_fn
+=
"_p"
+
std
::
to_string
(
commRank
);
std
::
string
outputFilename
;
{
// write serial file
std
::
ofstream
serial_out
(
serial_fn
+
"."
+
vtkWriter_
.
getFileExtension
()
,
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
outputFilename
=
serial_fn
+
"."
+
vtkWriter_
.
getFileExtension
()
;
std
::
ofstream
serial_out
(
outputFilename
,
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
assert
(
serial_out
.
is_open
());
serial_out
.
imbue
(
std
::
locale
::
classic
());
...
...
@@ -111,8 +113,8 @@ void VtkTimeseriesWriter<W>
if
(
commSize
>
1
&&
commRank
==
0
)
{
// write parallel file
std
::
ofstream
parallel_out
(
parallel_fn
+
".p"
+
vtkWriter_
.
getFileExtension
()
,
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
outputFilename
=
parallel_fn
+
".p"
+
vtkWriter_
.
getFileExtension
()
;
std
::
ofstream
parallel_out
(
outputFilename
,
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
assert
(
parallel_out
.
is_open
());
parallel_out
.
imbue
(
std
::
locale
::
classic
());
...
...
@@ -122,6 +124,8 @@ void VtkTimeseriesWriter<W>
vtkWriter_
.
writeTimeseriesParallelFile
(
parallel_out
,
rel_fn
,
commSize
,
timesteps_
);
}
return
outputFilename
;
}
}
// end namespace Dune
dune/vtk/vtkwriterinterface.hh
View file @
3cb9300e
...
...
@@ -67,12 +67,7 @@ namespace Dune
,
format_
(
format
)
,
datatype_
(
datatype
)
{
#if !HAVE_VTK_ZLIB
if
(
format_
==
Vtk
::
COMPRESSED
)
{
std
::
cout
<<
"Dune is compiled without compression. Falling back to BINARY VTK output!
\n
"
;
format_
=
Vtk
::
BINARY
;
}
#endif
setFormat
(
format
);
}
...
...
@@ -80,8 +75,10 @@ namespace Dune
/**
* \param fn Filename of the VTK file. May contain a directory and any file extension.
* \param dir The optional parameter specifies the directory of the partition files for parallel writes.
*
* \returns File name that is actually written.
**/
virtual
void
write
(
std
::
string
const
&
fn
,
Std
::
optional
<
std
::
string
>
dir
=
{})
const
override
;
virtual
std
::
string
write
(
std
::
string
const
&
fn
,
Std
::
optional
<
std
::
string
>
dir
=
{})
const
override
;
/// \brief Attach point data to the writer
/**
...
...
@@ -112,6 +109,26 @@ namespace Dune
return
*
this
;
}
// Sets the VTK file format
void
setFormat
(
Vtk
::
FormatTypes
format
)
{
format_
=
format
;
#if !HAVE_VTK_ZLIB
if
(
format_
==
Vtk
::
COMPRESSED
)
{
std
::
cout
<<
"Dune is compiled without compression. Falling back to BINARY VTK output!
\n
"
;
format_
=
Vtk
::
BINARY
;
}
#endif
}
// Sets the global datatype used for coordinates and other global float values
void
setDatatype
(
Vtk
::
DataTypes
datatype
)
{
datatype_
=
datatype
;
}
private:
/// Write a serial VTK file in Unstructured format
virtual
void
writeSerialFile
(
std
::
ofstream
&
out
)
const
=
0
;
...
...
dune/vtk/vtkwriterinterface.impl.hh
View file @
3cb9300e
...
...
@@ -23,7 +23,7 @@
namespace
Dune
{
template
<
class
GV
,
class
DC
>
void
VtkWriterInterface
<
GV
,
DC
>
std
::
string
VtkWriterInterface
<
GV
,
DC
>
::
write
(
std
::
string
const
&
fn
,
Std
::
optional
<
std
::
string
>
dir
)
const
{
dataCollector_
->
update
();
...
...
@@ -43,8 +43,11 @@ void VtkWriterInterface<GV,DC>
if
(
comm
().
size
()
>
1
)
serial_fn
+=
"_p"
+
std
::
to_string
(
comm
().
rank
());
std
::
string
outputFilename
;
{
// write serial file
std
::
ofstream
serial_out
(
serial_fn
+
"."
+
fileExtension
(),
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
outputFilename
=
serial_fn
+
"."
+
fileExtension
();
std
::
ofstream
serial_out
(
outputFilename
,
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
assert
(
serial_out
.
is_open
());
serial_out
.
imbue
(
std
::
locale
::
classic
());
...
...
@@ -56,8 +59,9 @@ void VtkWriterInterface<GV,DC>
}
if
(
comm
().
size
()
>
1
&&
comm
().
rank
()
==
0
)
{
// write parallel file
std
::
ofstream
parallel_out
(
parallel_fn
+
".p"
+
fileExtension
(),
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
// write parallel filee
outputFilename
=
parallel_fn
+
".p"
+
fileExtension
();
std
::
ofstream
parallel_out
(
outputFilename
,
std
::
ios_base
::
ate
|
std
::
ios
::
binary
);
assert
(
parallel_out
.
is_open
());
parallel_out
.
imbue
(
std
::
locale
::
classic
());
...
...
@@ -67,6 +71,8 @@ void VtkWriterInterface<GV,DC>
writeParallelFile
(
parallel_out
,
rel_fn
,
comm
().
size
());
}
return
outputFilename
;
}
...
...
dune/vtk/writers/CMakeLists.txt
View file @
3cb9300e
...
...
@@ -9,3 +9,5 @@ install(FILES
vtkunstructuredgridwriter.hh
vtkunstructuredgridwriter.impl.hh
DESTINATION
${
CMAKE_INSTALL_INCLUDEDIR
}
/dune/vtkwriter/writers
)
add_subdirectory
(
test
)
\ No newline at end of file
dune/vtk/writers/test/CMakeLists.txt
0 → 100644
View file @
3cb9300e
dune_add_test
(
SOURCES test-vtkwriter.cc
LINK_LIBRARIES dunevtk
)
\ No newline at end of file
dune/vtk/writers/test/checkvtkfile.hh
0 → 100644
View file @
3cb9300e
#ifndef DUNE_VTK_TEST_CHECKVTKFILE_HH
#define DUNE_VTK_TEST_CHECKVTKFILE_HH
#include <cstddef>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <ios>
#include <iostream>
#include <ostream>
#include <set>
#include <sstream>
#include <string>
#include <sys/wait.h>
#include <dune/common/exceptions.hh>
#include <dune/common/test/testsuite.hh>
namespace
Dune
{
namespace
Impl
{
// quote so the result can be used inside '...' in python
// quotes not included in the result
inline
std
::
string
pyq
(
const
std
::
string
&
s
)
{
std
::
ostringstream
result
;
for
(
std
::
size_t
i
=
0
;
i
<
s
.
size
();
++
i
)
{
char
c
=
s
[
i
];
switch
(
c
)
{
case
'\''
:
result
<<
"
\\
'"
;
break
;
case
'\\'
:
result
<<
"
\\\\
"
;
break
;
case
'\n'
:
result
<<
"
\\
n"
;
break
;
default:
if
(
c
<
32
||
c
>=
127
)
result
<<
"
\\
x"
<<
std
::
hex
<<
std
::
setfill
(
'0'
)
<<
std
::
setw
(
2
)
<<
static_cast
<
int
>
(
c
);
else
result
<<
c
;
}
}
return
result
.
str
();
}
// quote so the result can be used inside '...' in the bourne shell
// quotes not included in the result
inline
std
::
string
shq
(
const
std
::
string
&
s
)
{
std
::
ostringstream
result
;
bool
pend
=
false
;
for
(
std
::
size_t
i
=
0
;
i
<
s
.
size
();
++
i
)
{
char
c
=
s
[
i
];
switch
(
c
)
{
case
'\0'
:
DUNE_THROW
(
Dune
::
NotImplemented
,
"Can't pass
\\
0 through the shell"
);
case
'\''
:
result
<<
(
pend
?
""
:
"'"
)
<<
"
\\
'"
;
pend
=
true
;
break
;
default:
result
<<
(
pend
?
"'"
:
""
)
<<
c
;
pend
=
false
;
break
;
}
}
if
(
pend
)
result
<<
"'"
;
return
result
.
str
();
}
inline
int
runShell
(
const
std
::
string
&
code
)
{
int
result
=
std
::
system
(
code
.
c_str
());
// Avoid returning anything that is a multiple of 256, unless the return
// value was 0. This way the return value can be directly used as an
// argument to exit(), which usually interprets its argument modulo 256.
if
(
WIFEXITED
(
result
))
return
WEXITSTATUS
(
result
);
if
(
WIFSIGNALED
(
result
))
return
WTERMSIG
(
result
)
+
256
;
else
return
513
;
}
inline
int
runPython
(
const
std
::
string
&
code
)
{
return
runShell
(
"python -c '"
+
shq
(
code
)
+
"'"
);
}
inline
bool
is_suffix
(
const
std
::
string
&
s
,
const
std
::
string
&
suffix
)
{
return
s
.
size
()
>=
suffix
.
size
()
&&
s
.
compare
(
s
.
size
()
-
suffix
.
size
(),
suffix
.
size
(),
suffix
)
==
0
;
}
inline
bool
havePythonVTK
()
{
static
const
bool
result
=
[]
{
// This check is invoked only once, even in a multithreading environment,
// since it is invoked in the initializer of a static variable.
if
(
runPython
(
"from vtk import *"
)
==
0
)
return
true
;
std
::
cerr
<<
"warning: python or python vtk module not available. This "
<<
"will result in skipped tests, since we cannot check that "
<<
"vtk can read the files we wrote."
<<
std
::
endl
;
return
false
;
}
();
return
result
;
}
inline
std
::
string
pythonVTKReader
(
const
std
::
string
&
filename
)
{
if
(
is_suffix
(
filename
,
".vtu"
))
return
"vtkXMLUnstructuredGridReader"
;
else
if
(
is_suffix
(
filename
,
".pvtu"
))
return
"vtkXMLPUnstructuredGridReader"
;
else
if
(
is_suffix
(
filename
,
".vts"
))
return
"vtkXMLStructuredGridReader"
;
else
if
(
is_suffix
(
filename
,
".pvts"
))
return
"vtkXMLPStructuredGridReader"
;
else
if
(
is_suffix
(
filename
,
".vtr"
))
return
"vtkXMLRectilinearGridReader"
;
else
if
(
is_suffix
(
filename
,
".pvtr"
))
return
"vtkXMLPRectilinearGridReader"
;
else
if
(
is_suffix
(
filename
,
".vti"
))
return
"vtkXMLImageDataReader"
;
else
if
(
is_suffix
(
filename
,
".pvti"
))
return
"vtkXMLPImageDataReader"
;
else
DUNE_THROW
(
Dune
::
NotImplemented
,
"Unknown vtk file extension: "
<<
filename
);
}
}
/* namespace Impl */
class
VTKChecker
{
public:
void
push
(
const
std
::
string
&
file
)
{
auto
res
=
files_
.
insert
(
file
);
if
(
not
res
.
second
)
{
testSuite_
.
check
(
false
,
"VTKChecker"
)
<<
"'"
<<
file
<<
"' was added multiple times"
;
}
}
int
check
()
{
if
(
not
Impl
::
havePythonVTK
())
{
return
77
;
}
else
if
(
not
files_
.
empty
())
{
const
int
result
=
Impl
::
runPython
(
generatePythonCode
());
testSuite_
.
check
(
result
==
0
);
}
return
testSuite_
.
exit
();
}
const
TestSuite
&
testSuite
()
const
{
return
testSuite_
;
}
private:
std
::
string
generatePythonCode
()
const
{
std
::
stringstream
code
;
code
<<
"from vtk import *
\n
"
<<
"import sys
\n
"
<<
"passed = True
\n
"
;
for
(
const
auto
&
file
:
files_
)
{
code
<<
"reader = "
<<
Impl
::
pythonVTKReader
(
file
)
<<
"()
\n
"
<<
"reader.SetFileName('"
<<
Impl
::
pyq
(
file
)
<<
"')
\n
"
<<
"reader.Update()
\n
"
<<
"if (not (reader.GetOutput().GetNumberOfCells() > 0)):
\n
"
<<
" print('ERROR in {}'.format('"
<<
Impl
::
pyq
(
file
)
<<
"'))
\n
"
<<
" passed = False
\n
"
;
}
code
<<
"sys.exit(0 if passed else 1)
\n
"
;
return
code
.
str
();
}
std
::
set
<
std
::
string
>
files_
;
TestSuite
testSuite_
;
};
}
/* namespace Dune */
#endif // DUNE_VTK_TEST_CHECKVTKFILE_HH
dune/vtk/writers/test/test-vtkwriter.cc
0 → 100644
View file @
3cb9300e
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#if HAVE_CONFIG_H
#include "config.h" // autoconf defines, needed by the dune headers
#endif
#include <algorithm>
#include <iostream>
#include <ostream>
#include <sstream>
#include <string>
#include <vector>
#include <dune/common/fvector.hh>
#include <dune/common/parallel/mpihelper.hh>
#include <dune/functions/gridfunctions/analyticgridviewfunction.hh>
#include <dune/grid/yaspgrid.hh>
#if HAVE_UG
#include <dune/grid/uggrid.hh>
#endif
#include <dune/vtk/vtkwriter.hh>
#include "checkvtkfile.hh"
// accumulate exit status
void
acc
(
int
&
accresult
,
int
result
)
{
if
(
accresult
==
0
||
(
accresult
==
77
&&
result
!=
0
))
accresult
=
result
;
}
struct
Acc
{
int
operator
()
(
int
v1
,
int
v2
)
const
{
acc
(
v1
,
v2
);
return
v1
;
}
};
template
<
class
GridView
>
int
testGridView
(
std
::
string
prefix
,
Dune
::
VTKChecker
&
vtkChecker
,
GridView
const
&
gridView
)
{
enum
{
dim
=
GridView
::
dimension
};
Dune
::
VtkWriter
<
GridView
>
vtk
(
gridView
);
auto
f1
=
Dune
::
Functions
::
makeAnalyticGridViewFunction
([](
const
auto
&
x
)
{
return
std
::
sin
(
x
.
two_norm
());
},
gridView
);
vtk
.
addCellData
(
f1
,
"scalar-valued lambda"
);
auto
f2
=
Dune
::
Functions
::
makeAnalyticGridViewFunction
([](
const
auto
&
x
)
{
return
x
;
},
gridView
);
vtk
.
addPointData
(
f2
,
"vector-valued lambda"
);
int
result
=
0
;
// ASCII files
{
vtk
.
setFormat
(
Dune
::
Vtk
::
ASCII
);
std
::
string
name
=
vtk
.
write
(
prefix
+
"_ascii"
);
if
(
gridView
.
comm
().
rank
()
==
0
)
vtkChecker
.
push
(
name
);
}
// BINARY files
{
vtk
.
setFormat
(
Dune
::
Vtk
::
BINARY
);
std
::
string
name
=
vtk
.
write
(
prefix
+
"_binary"
);
if
(
gridView
.
comm
().
rank
()
==
0
)
vtkChecker
.
push
(
name
);
}
// COMPRESSED files
{
vtk
.
setFormat
(
Dune
::
Vtk
::
COMPRESSED
);
std
::
string
name
=
vtk
.
write
(
prefix
+
"_compressed"
);
if
(
gridView
.
comm
().
rank
()
==
0
)
vtkChecker
.
push
(
name
);
}
return
result
;
}
template
<
class
Grid
>
int
testGrid
(
std
::
string
prefix
,
Dune
::
VTKChecker
&
vtkChecker
,
Grid
&
grid
)
{
if
(
grid
.
comm
().
rank
()
==
0
)
std
::
cout
<<
"vtkCheck("
<<
prefix
<<
")"
<<
std
::
endl
;
grid
.
globalRefine
(
1
);
int
result
=
0
;
acc
(
result
,
testGridView
(
prefix
+
"_leaf"
,
vtkChecker
,
grid
.
leafGridView
()
));
acc
(
result
,
testGridView
(
prefix
+
"_level0"
,
vtkChecker
,
grid
.
levelGridView
(
0
)
));
acc
(
result
,
testGridView
(
prefix
+
"_level1"
,
vtkChecker
,
grid
.
levelGridView
(
grid
.
maxLevel
())
));
return
result
;
}
int
main
(
int
argc
,
char
**
argv
)
{
using
namespace
Dune
;
const
MPIHelper
&
mpiHelper
=
MPIHelper
::
instance
(
argc
,
argv
);
if
(
mpiHelper
.
rank
()
==
0
)
std
::
cout
<<
"vtktest: MPI_Comm_size == "
<<
mpiHelper
.
size
()
<<
std
::
endl
;
int
result
=
0
;
// pass by default
VTKChecker
vtkChecker
;
YaspGrid
<
1
>
yaspGrid1
({
1.0
},
{
8
});
YaspGrid
<
2
>
yaspGrid2
({
1.0
,
2.0
},
{
8
,
4
});
YaspGrid
<
3
>
yaspGrid3
({
1.0
,
2.0
,
3.0
},
{
8
,
4
,
4
});
acc
(
result
,
testGrid
(
"yaspgrid_1d"
,
vtkChecker
,
yaspGrid1
));
acc
(
result
,
testGrid
(
"yaspgrid_2d"
,
vtkChecker
,
yaspGrid2
));
acc
(
result
,
testGrid
(
"yaspgrid_3d"
,
vtkChecker
,
yaspGrid3
));
#if HAVE_UG
auto
ugGrid2a
=
StructuredGridFactory
<
UGGrid
<
2
>>::
createSimplexGrid
({
0.0
,
0.0
},
{
1.0
,
2.0
},
{
2u
,
4u
});
auto
ugGrid3a
=
StructuredGridFactory
<
UGGrid
<
3
>>::
createSimplexGrid
({
0.0
,
0.0
,
0.0
},
{
1.0
,
2.0
,
3.0
},
{
2u
,
4u
,
6u
});
acc
(
result
,
testGrid
(
"uggrid_simplex_2d"
,
vtkChecker
,
*
ugGrid2a
));
acc
(
result
,
testGrid
(
"uggrid_simplex_3d"
,
vtkChecker
,
*
ugGrid3a
));
auto
ugGrid2b
=
StructuredGridFactory
<
UGGrid
<
2
>>::
createCubeGrid
({
0.0
,
0.0
},
{
1.0
,
2.0
},
{
2u
,
4u
});
auto
ugGrid3b
=
StructuredGridFactory
<
UGGrid
<
3
>>::
createCubeGrid
({
0.0
,
0.0
,
0.0
},
{
1.0
,
2.0
,
3.0
},
{
2u
,
4u
,
6u
});
acc
(
result
,
testGrid
(
"uggrid_cube_2d"
,
vtkChecker
,
*
ugGrid2b
));
acc
(
result
,
testGrid
(
"uggrid_cube_3d"
,
vtkChecker
,
*
ugGrid3b
));
#endif
acc
(
result
,
vtkChecker
.
check
());
mpiHelper
.
getCollectiveCommunication
().
allreduce
<
Acc
>
(
&
result
,
1
);
return
result
;
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment