Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F72979520
dumper_text.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Jul 17, 22:07
Size
8 KB
Mime Type
text/x-c++
Expires
Fri, Jul 19, 22:07 (2 d)
Engine
blob
Format
Raw Data
Handle
19127225
Attached To
rLIBMULTISCALE LibMultiScale
dumper_text.cc
View Options
/**
* @file dumper_text.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Wed Dec 04 12:14:29 2013
*
* @brief This allows to generate a formated text file
*
* @section LICENSE
*
* Copyright INRIA and CEA
*
* The LibMultiScale is a C++ parallel framework for the multiscale
* coupling methods dedicated to material simulations. This framework
* provides an API which makes it possible to program coupled simulations
* and integration of already existing codes.
*
* This Project was initiated in a collaboration between INRIA Futurs Bordeaux
* within ScAlApplix team and CEA/DPTA Ile de France.
* The project is now continued at the Ecole Polytechnique Fédérale de Lausanne
* within the LSMS/ENAC laboratory.
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*
*/
#include "dumper_text.hh"
#include "compute_interface.hh"
#include "lib_md.hh"
#include "lm_common.hh"
#include "lm_communicator.hh"
/* -------------------------------------------------------------------------- */
#include <iomanip>
#include <typeinfo>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
template
<
typename
T
>
void
DumperText
::
dump
(
ContainerArray
<
T
>
&
cont
)
{
// const UInt Dim = cont.getDim();
compute_concat
.
build
(
cont
);
this
->
dump
(
static_cast
<
Component
&>
(
compute_concat
));
// CommGroup &group = cont.getCommGroup();
// // only root node will dump the result of this compute
// UInt my_rank = group.getMyRank();
// if (my_rank != this->rank)
// return;
// if (!is_head_printed) {
// std::string fname;
// fname = this->getBaseName() + ".txt";
// my_file.open(fname.c_str());
// if (!my_file.is_open()) {
// LM_FATAL("could not open output file " << fname);
// }
// printHead(compute_concat, my_file);
// is_head_printed = true;
// my_file << std::endl;
// }
// LM_ASSERT(cont.size() % Dim == 0, "invalid container");
// UInt n_entries = cont.size() / Dim;
// for (UInt entry = 0; entry < n_entries; ++entry) {
// my_file << current_step << separator;
// if (!no_print_entry_flag)
// my_file << entry << separator;
// dumpCompute(compute_concat, entry, my_file);
// my_file << std::endl;
// }
// if (line_break)
// my_file << std::endl;
}
/* -------------------------------------------------------------------------- */
void
DumperText
::
dump
(
Component
&
cont
)
{
auto
&
compute
=
dynamic_cast
<
ComputeInterface
&>
(
cont
);
if
(
!
is_head_printed
)
{
std
::
string
fname
;
fname
=
this
->
getBaseName
()
+
".txt"
;
my_file
.
open
(
fname
.
c_str
());
if
(
!
my_file
.
is_open
())
{
LM_FATAL
(
"could not open output file "
<<
fname
);
}
printHead
(
compute
,
my_file
);
is_head_printed
=
true
;
my_file
<<
std
::
endl
;
}
dumpCompute
(
compute
,
my_file
);
}
/* -------------------------------------------------------------------------- */
void
DumperText
::
printHead
(
ComputeInterface
&
cont
,
std
::
ofstream
&
file
)
{
file
<<
comment_tag
<<
" timestep"
<<
separator
;
if
(
!
no_print_entry_flag
)
my_file
<<
"entry"
<<
separator
;
for
(
auto
&&
kv
:
cont
.
getOutputs
())
{
std
::
string
key
=
kv
.
first
;
try
{
cont
.
getOutputAsArray
(
key
);
}
catch
(
LibMultiScaleException
&
e
)
{
LM_FATAL_RE
(
e
,
"It seems that output "
<<
cont
.
getID
()
<<
"."
<<
key
<<
" is not an array: however dumper text can only "
"deal with arrays"
);
}
ContainerArray
<
Real
>
&
v
=
cont
.
getOutputAsArray
(
key
);
if
(
v
.
rows
()
==
0
)
continue
;
UInt
ncols
=
v
.
cols
();
if
(
ncols
>
1
)
for
(
UInt
j
=
0
;
j
<
ncols
;
++
j
)
{
if
(
cont
.
getID
()
!=
""
)
my_file
<<
cont
.
getID
()
<<
":"
;
my_file
<<
key
<<
'-'
<<
std
::
to_string
(
j
)
<<
separator
;
}
else
{
if
(
cont
.
getID
()
!=
""
)
my_file
<<
cont
.
getID
()
<<
":"
;
my_file
<<
key
<<
separator
;
}
}
}
/* --------------------------------------------------------------------------
*/
void
DumperText
::
dumpCompute
(
ComputeInterface
&
cont
,
std
::
ofstream
&
)
{
std
::
vector
<
UInt
>
sizes
;
std
::
vector
<
std
::
string
>
keys
;
std
::
vector
<
ContainerArray
<
Real
>
*>
arrays
;
for
(
auto
&&
kv
:
cont
.
getOutputs
())
{
auto
&&
key
=
kv
.
first
;
auto
&&
output
=
cont
.
getOutputAsArray
(
key
);
keys
.
push_back
(
key
);
if
(
output
.
rows
()
==
0
)
continue
;
sizes
.
push_back
(
output
.
rows
());
arrays
.
push_back
(
&
output
);
DUMP
(
key
<<
": "
<<
output
.
size
()
<<
" "
<<
output
.
rows
()
<<
" "
<<
output
.
cols
(),
DBG_DETAIL
);
}
auto
min_max
=
std
::
minmax_element
(
sizes
.
begin
(),
sizes
.
end
());
if
(
*
min_max
.
first
!=
*
min_max
.
second
)
LM_FATAL
(
cont
.
getID
()
<<
":"
<<
demangle
(
typeid
(
cont
).
name
())
<<
": All outputs do not have the size number of entries: "
<<
*
min_max
.
first
<<
" - "
<<
*
min_max
.
second
);
if
(
*
min_max
.
second
==
0
)
LM_FATAL
(
cont
.
getID
()
<<
":"
<<
typeid
(
cont
).
name
()
<<
": outputs do not have any entries"
);
for
(
UInt
i
=
0
;
i
<
sizes
[
0
];
++
i
)
{
my_file
<<
current_step
<<
separator
;
if
(
!
no_print_entry_flag
)
my_file
<<
i
<<
separator
;
for
(
auto
*
arr
:
arrays
)
{
auto
&
array
=
*
arr
;
for
(
UInt
j
=
0
;
j
<
array
.
cols
();
++
j
)
{
my_file
<<
std
::
setprecision
(
precision
)
<<
std
::
scientific
<<
array
(
i
,
j
)
<<
separator
;
}
}
my_file
<<
std
::
endl
;
}
}
/* --------------------------------------------------------------------------
*/
/* LMDESC TEXT
This allows to generate a formated text file taking as an entry the
result of a compute.
*/
/* LMHERITANCE compute_concat dumper */
/* LMEXAMPLE DUMPER txt TEXT INPUT md FREQ 100 PREFIX ./ SEPARATOR , PRECISION
* 8
*/
void
DumperText
::
declareParams
()
{
DumperInterface
::
declareParams
();
this
->
addSubParsableObject
(
compute_concat
);
/* LMKEYWORD SEPARATOR
The generated file will be arranged in columns provided the following
separator.
*/
this
->
parseKeyword
(
"SEPARATOR"
,
separator
,
"
\t
"
);
/* LMKEYWORD PRECISION
The generated file will use the provided precision.
*/
this
->
parseKeyword
(
"PRECISION"
,
precision
,
5u
);
/* LMKEYWORD RANK
The rank of processor which should generate the file
*/
this
->
parseKeyword
(
"RANK"
,
rank
,
0u
);
/* LMKEYWORD LINE_BREAK
Dump a line break between timestep series (default is FALSE)
*/
this
->
parseTag
(
"LINE_BREAK"
,
line_break
,
false
);
/* LMKEYWORD COMMENT
Give the tag to be used if comment should be written.
The default is \#.
*/
this
->
parseKeyword
(
"COMMENT"
,
comment_tag
,
"#"
);
/* LMKEYWORD NOPRINT_ENTRY
The entry column will not be included when this option is specified.
*/
this
->
parseTag
(
"NOPRINT_ENTRY"
,
no_print_entry_flag
,
false
);
}
/* --------------------------------------------------------------------------
*/
DumperText
::
DumperText
(
const
std
::
string
&
name
)
:
LMObject
(
name
),
compute_concat
(
this
->
getID
()
+
":concat"
)
{
separator
=
"
\t
"
;
precision
=
5
;
is_head_printed
=
false
;
rank
=
0
;
line_break
=
false
;
comment_tag
=
"#"
;
no_print_entry_flag
=
false
;
}
/* --------------------------------------------------------------------------
*/
DumperText
::~
DumperText
()
{}
/* --------------------------------------------------------------------------
*/
DECLARE_DUMPER_MAKE_CALL
(
DumperText
)
__END_LIBMULTISCALE__
Event Timeline
Log In to Comment