Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F100084999
hdf5_chloride.cpp
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
Tue, Jan 28, 02:40
Size
16 KB
Mime Type
text/x-c
Expires
Thu, Jan 30, 02:40 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
23897834
Attached To
rSPECMICP SpecMiCP / ReactMiCP
hdf5_chloride.cpp
View Options
/* =============================================================================
Copyright (c) 2014-2017 F. Georget <fabieng@princeton.edu> Princeton University
Copyright (c) 2017-2018 F. Georget <fabien.georget@epfl.ch> EPFL
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
============================================================================= */
#include "hdf5_chloride.hpp"
#include "specmicp_common/io/hdf5/file.hpp"
#include "specmicp_common/io/hdf5/group.hpp"
#include "specmicp_common/io/hdf5/dataset.hpp"
#include "specmicp_common/io/hdf5_timesteps.hpp"
#include "specmicp_common/io/hdf5/dataspace.hpp"
#include "H5Ppublic.h"
#include "specmicp/io/hdf5_adimensional.hpp"
#include "dfpm/io/hdf5_mesh.hpp"
#include "specmicp_database/io/hdf5_database.hpp"
#include "reactmicp/systems/chloride/variables.hpp"
#include "reactmicp/systems/chloride/dof_numbering.hpp"
#include "specmicp_common/log.hpp"
#define MESH_GRPNAME "mesh"
#define DATABASE_GRPNAME "database"
#define UNIT_ATTRIBUTE "unit"
#define MAIN_VARIABLES_GRPNAME "main_variables"
#define CHEMISTRY_SOLUTION_GRPNAME "chemistry_solution"
#define TRANSPORT_PROPERTIES_GRPNAME "transport_properties"
#define MAIN_VARS_VALNAME "main_variables"
#define TOTAL_IMMOBILE_CONC_VALNAME "total_immobile_concentration"
#define CURRENT_VALNAME "current"
#define FLUID_VELOCITY_VALNAME "fluid_velocity"
#define POROSITY_VALNAME "porosity"
#define RESISTANCE_FACTOR_VALNAME "resistance_factor"
namespace
specmicp
{
namespace
io
{
using
namespace
specmicp
::
reactmicp
::
systems
::
chloride
;
// ================================ //
// //
// Saver //
// //
// ================================ //
// Implementation declaration
// ==========================
struct
SPECMICP_DLL_LOCAL
ChlorideHDF5Saver
::
ChlorideHDF5SaverImpl
{
std
::
string
m_filepath
;
std
::
shared_ptr
<
ChlorideVariables
>
m_vars
;
ChlorideHDF5SaverImpl
(
const
std
::
string
&
filepath
,
std
::
shared_ptr
<
ChlorideVariables
>
vars
)
:
m_filepath
(
filepath
),
m_vars
(
vars
)
{
init_file
();
}
//! \brief Save a timestep
void
save_timestep
(
const
std
::
string
&
name
);
//! \brief Save the main variables
void
save_main_variables
(
hdf5
::
Group
&
timestep_grp
);
//! \brief Save the chemical solution
void
save_chemical_solution
(
hdf5
::
Group
&
timestep_grp
);
//! \brief Save the transport properties
void
save_transport_properties
(
hdf5
::
Group
&
timestep_grp
);
//! \brief create the file and save common values (mesh, db, units)
void
init_file
();
};
// Main interface
// ==============
ChlorideHDF5Saver
::
ChlorideHDF5Saver
(
const
std
::
string
&
filepath
,
std
::
shared_ptr
<
specmicp
::
reactmicp
::
systems
::
chloride
::
ChlorideVariables
>
vars
)
:
m_impl
(
utils
::
make_pimpl
<
ChlorideHDF5SaverImpl
>
(
filepath
,
vars
))
{
}
ChlorideHDF5Saver
::~
ChlorideHDF5Saver
()
=
default
;
void
ChlorideHDF5Saver
::
save_timestep
(
scalar_t
timestep
)
{
m_impl
->
save_timestep
(
std
::
to_string
(
timestep
));
}
// Implementation
// ==============
void
ChlorideHDF5Saver
::
ChlorideHDF5SaverImpl
::
save_timestep
(
const
std
::
string
&
name
)
{
hdf5
::
File
the_file
=
hdf5
::
File
::
open
(
m_filepath
,
hdf5
::
OpenMode
::
OpenReadWrite
);
hdf5
::
Group
timestep_grp
=
the_file
.
create_group
(
name
);
save_main_variables
(
timestep_grp
);
save_chemical_solution
(
timestep_grp
);
save_transport_properties
(
timestep_grp
);
}
void
ChlorideHDF5Saver
::
ChlorideHDF5SaverImpl
::
init_file
()
{
hdf5
::
File
the_file
=
hdf5
::
File
::
open
(
m_filepath
,
hdf5
::
OpenMode
::
CreateTruncate
);
save_mesh
(
the_file
,
MESH_GRPNAME
,
m_vars
->
get_mesh
());
save_database_labels
(
the_file
,
DATABASE_GRPNAME
,
m_vars
->
get_database
());
auto
the_units
=
m_vars
->
get_units
();
std
::
array
<
double
,
3
>
units_values
=
{
units
::
scaling_factor
(
the_units
.
length
),
units
::
scaling_factor
(
the_units
.
mass
),
units
::
scaling_factor
(
the_units
.
quantity
)
};
the_file
.
create_scalar_attribute
(
UNIT_ATTRIBUTE
,
units_values
);
}
void
ChlorideHDF5Saver
::
ChlorideHDF5SaverImpl
::
save_main_variables
(
hdf5
::
Group
&
timestep_grp
)
{
hdf5
::
Group
main_vars_grp
=
timestep_grp
.
create_group
(
MAIN_VARIABLES_GRPNAME
);
main_vars_grp
.
create_vector_dataset
(
MAIN_VARS_VALNAME
,
m_vars
->
main_variables
());
main_vars_grp
.
create_vector_dataset
(
TOTAL_IMMOBILE_CONC_VALNAME
,
m_vars
->
total_immobile_concentrations
());
main_vars_grp
.
create_vector_dataset
(
CURRENT_VALNAME
,
m_vars
->
current
());
main_vars_grp
.
create_scalar_attribute
<
1
>
(
FLUID_VELOCITY_VALNAME
,
{
m_vars
->
fluid_velocity
(),});
}
void
ChlorideHDF5Saver
::
ChlorideHDF5SaverImpl
::
save_chemical_solution
(
hdf5
::
Group
&
timestep_grp
)
{
hdf5
::
Group
chem_grp
=
timestep_grp
.
create_group
(
CHEMISTRY_SOLUTION_GRPNAME
);
for
(
auto
node:
m_vars
->
get_mesh
()
->
range_nodes
())
{
if
(
m_vars
->
adim_solution
(
node
).
is_valid
)
{
save_adimensional_system_solution
(
chem_grp
,
std
::
to_string
(
node
),
m_vars
->
adim_solution
(
node
));
}
}
}
void
ChlorideHDF5Saver
::
ChlorideHDF5SaverImpl
::
save_transport_properties
(
hdf5
::
Group
&
timestep_grp
)
{
hdf5
::
Group
trans_grp
=
timestep_grp
.
create_group
(
TRANSPORT_PROPERTIES_GRPNAME
);
trans_grp
.
create_vector_dataset
(
POROSITY_VALNAME
,
m_vars
->
porosity
());
trans_grp
.
create_vector_dataset
(
RESISTANCE_FACTOR_VALNAME
,
m_vars
->
resistance_factor
());
}
// ================================ //
// //
// Reader //
// //
// ================================ //
// Implementation declaration
// ==========================
struct
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
{
ChlorideHDF5ReaderImpl
(
const
std
::
string
&
filepath
,
RawDatabasePtr
t_database
)
:
m_file
(
hdf5
::
File
::
open
(
filepath
,
hdf5
::
OpenMode
::
OpenReadOnly
)),
m_timesteps
(
m_file
),
m_numbering
(
t_database
->
nb_component
()),
m_rawdata
(
t_database
)
{
m_mesh
=
get_mesh
();
}
units
::
UnitsSet
get_units
();
AdimensionalSystemSolution
get_adim_solution
(
std
::
string
timestep
,
index_t
node
);
mesh
::
Mesh1DPtr
get_mesh
()
{
return
read_mesh
(
m_file
,
MESH_GRPNAME
);
}
Vector
main_variable_vs_x
(
const
std
::
string
&
timestep
,
index_t
ndof
,
const
std
::
string
&
variable
);
Vector
main_variable_vs_t
(
index_t
node
,
index_t
ndof
,
const
std
::
string
&
variables
);
Vector
current_vs_t
(
index_t
node
);
hdf5
::
Group
open_timestep
(
const
std
::
string
&
timestep
);
hdf5
::
Group
open_main_variables
(
const
std
::
string
&
timestep
);
hdf5
::
Group
open_chemistry_solutions
(
const
std
::
string
&
timestep
);
hdf5
::
Group
open_transport_properties
(
const
std
::
string
&
timestep
);
hdf5
::
File
m_file
;
HDF5Timesteps
m_timesteps
;
reactmicp
::
systems
::
chloride
::
DofNumbering
m_numbering
;
database
::
RawDatabasePtr
m_rawdata
;
mesh
::
Mesh1DPtr
m_mesh
;
};
// Main interface
// ==============
ChlorideHDF5Reader
::
ChlorideHDF5Reader
(
const
std
::
string
&
filepath
,
RawDatabasePtr
t_database
)
:
m_impl
(
utils
::
make_pimpl
<
ChlorideHDF5ReaderImpl
>
(
filepath
,
t_database
))
{}
ChlorideHDF5Reader
::~
ChlorideHDF5Reader
()
=
default
;
const
HDF5Timesteps
&
ChlorideHDF5Reader
::
get_timesteps
()
const
{
return
m_impl
->
m_timesteps
;
}
units
::
UnitsSet
ChlorideHDF5Reader
::
get_units
()
{
return
m_impl
->
get_units
();
}
mesh
::
Mesh1DPtr
ChlorideHDF5Reader
::
get_mesh
()
{
return
read_mesh
(
m_impl
->
m_file
,
MESH_GRPNAME
);
}
AdimensionalSystemSolution
ChlorideHDF5Reader
::
get_adim_solution
(
std
::
string
timestep
,
index_t
node
)
{
return
m_impl
->
get_adim_solution
(
timestep
,
node
);
}
//! \brief Return a SpecMiCP solution
AdimensionalSystemSolution
ChlorideHDF5Reader
::
get_adim_solution
(
scalar_t
timestep
,
index_t
node
)
{
auto
str_timestep
=
m_impl
->
m_timesteps
.
get_string
(
timestep
);
return
m_impl
->
get_adim_solution
(
str_timestep
,
node
);
}
Vector
ChlorideHDF5Reader
::
total_mobile_concentration_vs_x
(
scalar_t
timestep
,
const
std
::
string
&
component
)
{
const
auto
str_timestep
=
m_impl
->
m_timesteps
.
get_string
(
timestep
);
const
auto
ndof
=
m_impl
->
m_numbering
.
nodal_dof_component
(
m_impl
->
m_rawdata
->
get_id_component
(
component
));
return
m_impl
->
main_variable_vs_x
(
str_timestep
,
ndof
,
MAIN_VARS_VALNAME
);
}
Vector
ChlorideHDF5Reader
::
potential_vs_x
(
scalar_t
timestep
)
{
const
auto
str_timestep
=
m_impl
->
m_timesteps
.
get_string
(
timestep
);
const
auto
ndof
=
m_impl
->
m_numbering
.
nodal_dof_psi
();
return
m_impl
->
main_variable_vs_x
(
str_timestep
,
ndof
,
MAIN_VARS_VALNAME
);
}
Vector
ChlorideHDF5Reader
::
main_variable_vs_x
(
scalar_t
timestep
,
index_t
ndof
,
const
std
::
string
&
variables
)
{
const
std
::
string
tmstep
=
m_impl
->
m_timesteps
.
get_string
(
timestep
);
return
main_variable_vs_x
(
tmstep
,
ndof
,
variables
);
}
Vector
ChlorideHDF5Reader
::
main_variable_vs_x
(
const
std
::
string
&
timestep
,
index_t
ndof
,
const
std
::
string
&
variables
)
{
return
m_impl
->
main_variable_vs_x
(
timestep
,
ndof
,
variables
);
}
Vector
ChlorideHDF5Reader
::
main_variable_vs_t
(
index_t
node
,
index_t
ndof
,
const
std
::
string
&
variables
)
{
return
m_impl
->
main_variable_vs_t
(
ndof
,
node
,
variables
);
}
Vector
ChlorideHDF5Reader
::
total_mobile_concentration_vs_t
(
index_t
node
,
const
std
::
string
&
component
)
{
const
auto
ndof
=
m_impl
->
m_numbering
.
nodal_dof_component
(
m_impl
->
m_rawdata
->
get_id_component
(
component
));
return
m_impl
->
main_variable_vs_t
(
node
,
ndof
,
MAIN_VARS_VALNAME
);
}
Vector
ChlorideHDF5Reader
::
potential_vs_t
(
index_t
node
)
{
const
auto
ndof
=
m_impl
->
m_numbering
.
nodal_dof_psi
();
return
m_impl
->
main_variable_vs_t
(
node
,
ndof
,
MAIN_VARS_VALNAME
);
}
Vector
ChlorideHDF5Reader
::
current_vs_t
(
index_t
node
)
{
return
m_impl
->
main_variable_vs_t
(
node
,
0
,
CURRENT_VALNAME
);
}
// Implementation
// ==============
units
::
UnitsSet
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
::
get_units
()
{
units
::
UnitsSet
the_units
;
// quantity conversion factor was not solved in early version
// really early, can probably be simplified at some point
std
::
vector
<
double
>
conversion_factor
=
m_file
.
read_scalar_attribute
(
UNIT_ATTRIBUTE
);
the_units
.
length
=
units
::
from_scaling_factor
<
units
::
LengthUnit
>
(
conversion_factor
[
0
]);
the_units
.
mass
=
units
::
from_scaling_factor
<
units
::
MassUnit
>
(
conversion_factor
[
1
]);
if
(
conversion_factor
.
size
()
==
2
)
{
WARNING
<<
"Units for quantity of matter was not recorded, assuming moles."
;
}
else
{
the_units
.
quantity
=
units
::
from_scaling_factor
<
units
::
QuantityUnit
>
(
conversion_factor
[
2
]);
}
return
the_units
;
}
AdimensionalSystemSolution
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
::
get_adim_solution
(
std
::
string
timestep
,
index_t
node
)
{
auto
chem_grp
=
open_chemistry_solutions
(
timestep
);
return
read_adimensional_system_solution
(
chem_grp
,
std
::
to_string
(
node
));
}
hdf5
::
Group
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
::
open_timestep
(
const
std
::
string
&
timestep
)
{
return
m_file
.
open_group
(
timestep
);
}
hdf5
::
Group
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
::
open_main_variables
(
const
std
::
string
&
timestep
)
{
auto
timestep_grp
=
open_timestep
(
timestep
);
return
timestep_grp
.
open_group
(
MAIN_VARIABLES_GRPNAME
);
}
hdf5
::
Group
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
::
open_chemistry_solutions
(
const
std
::
string
&
timestep
)
{
auto
timestep_grp
=
open_timestep
(
timestep
);
return
timestep_grp
.
open_group
(
CHEMISTRY_SOLUTION_GRPNAME
);
}
hdf5
::
Group
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
::
open_transport_properties
(
const
std
::
string
&
timestep
)
{
auto
timestep_grp
=
open_timestep
(
timestep
);
return
timestep_grp
.
open_group
(
TRANSPORT_PROPERTIES_GRPNAME
);
}
Vector
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
::
main_variable_vs_x
(
const
std
::
string
&
timestep
,
index_t
ndof
,
const
std
::
string
&
variables
)
{
auto
main_var_grp
=
open_main_variables
(
timestep
);
Vector
out
=
main_var_grp
.
read_partial_vector_dataset
(
variables
,
ndof
,
m_numbering
.
ndof
(),
m_mesh
->
nb_nodes
(),
1
);
return
out
;
}
Vector
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
::
main_variable_vs_t
(
index_t
node
,
index_t
ndof
,
const
std
::
string
&
variables
)
{
Vector
out
(
m_timesteps
.
size
());
// get dataspace
const
hsize_t
nb_dofs
=
static_cast
<
hsize_t
>
(
m_mesh
->
nb_nodes
()
*
m_numbering
.
ndof
());
const
hsize_t
start
=
static_cast
<
hsize_t
>
(
m_numbering
.
dof
(
node
,
ndof
));
hdf5
::
Dataspace
file_space
=
hdf5
::
Dataspace
::
create_hyperslab
(
1
,
{
nb_dofs
,},
{
start
,},
{
1
,},
{
1
,},
{
1
,});
hdf5
::
Dataspace
mem_space
=
hdf5
::
Dataspace
::
create_simple
(
1
,
{
1
,});
for
(
size_t
ind
=
0
;
ind
<
m_timesteps
.
size
();
++
ind
)
{
hdf5
::
Group
grp
=
open_main_variables
(
m_timesteps
(
ind
));
hdf5
::
Dataset
data
=
grp
.
open_dataset
(
variables
);
herr_t
status
=
H5Dread
(
data
.
get_id
(),
H5T_NATIVE_DOUBLE
,
mem_space
.
get_id
(),
file_space
.
get_id
(),
H5P_DEFAULT
,
&
(
out
[
ind
]));
if
(
status
<
0
)
{
throw
std
::
runtime_error
(
"Error while reading dataset "
+
data
.
get_path
()
+
"."
);
}
}
return
out
;
}
Vector
ChlorideHDF5Reader
::
ChlorideHDF5ReaderImpl
::
current_vs_t
(
index_t
node
)
{
Vector
out
(
m_timesteps
.
size
());
// get dataspace
hdf5
::
Dataspace
file_space
=
hdf5
::
Dataspace
::
create_hyperslab
(
1
,
{
1
,},
{
static_cast
<
hsize_t
>
(
node
),},
{
1
,},
{
1
,},
{
1
,});
hdf5
::
Dataspace
mem_space
=
hdf5
::
Dataspace
::
create_simple
(
1
,
{
1
,});
for
(
size_t
ind
=
0
;
ind
<
m_timesteps
.
size
();
++
ind
)
{
hdf5
::
Group
grp
=
open_main_variables
(
m_timesteps
(
ind
));
hdf5
::
Dataset
data
=
grp
.
open_dataset
(
CURRENT_VALNAME
);
herr_t
status
=
H5Dread
(
data
.
get_id
(),
H5T_NATIVE_DOUBLE
,
mem_space
.
get_id
(),
file_space
.
get_id
(),
H5P_DEFAULT
,
&
(
out
[
ind
]));
if
(
status
<
0
)
{
throw
std
::
runtime_error
(
"Error while reading dataset "
+
data
.
get_path
()
+
"."
);
}
}
return
out
;
}
}
// namespace io
}
// namespace specmicp
Event Timeline
Log In to Comment