Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F100056599
saturated_react.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
Mon, Jan 27, 22:39
Size
22 KB
Mime Type
text/x-c
Expires
Wed, Jan 29, 22:39 (2 d)
Engine
blob
Format
Raw Data
Handle
23893028
Attached To
rSPECMICP SpecMiCP / ReactMiCP
saturated_react.cpp
View Options
/* =============================================================================
Copyright (c) 2014 - 2016
F. Georget <fabieng@princeton.edu> Princeton University
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 "saturated_react.hpp"
#include <iostream>
#include <fstream>
#include <chrono>
#include <ctime>
#include "../../dfpm/meshes/mesh1d.hpp"
#include "../../specmicp/adimensional/adimensional_system_solution_extractor.hpp"
#include "../../utils/dateandtime.hpp"
#include "../../physics/io/units.hpp"
#include "../systems/saturated_react/variables.hpp"
#include "../../utils/io/csv_formatter.hpp"
#include "../../dfpm/io/meshes.hpp"
#include "../../utils/compat.hpp"
#include "../../database/database_holder.hpp"
using
namespace
specmicp
::
reactmicp
::
systems
::
satdiff
;
namespace
specmicp
{
namespace
io
{
void
print_csv_header
(
CSVFile
&
ofile
)
{
ofile
.
insert_comment_line
(
"ReactMiCP"
);
ofile
.
insert_comment_line
(
"---------"
);
ofile
.
insert_comment_date
();
}
void
print_components_total_aqueous_concentration
(
RawDatabasePtr
the_database
,
SaturatedVariablesPtr
variables
,
mesh
::
Mesh1DPtr
the_mesh
,
const
units
::
UnitsSet
&
units_set
,
CSVFile
&
ofile
)
{
print_csv_header
(
ofile
);
ofile
.
insert_comment_line
(
"Total aqueous concentrations profiles"
);
ofile
.
insert_comment_line
(
"length unit : "
+
io
::
length_unit_to_string
(
units_set
.
length
));
ofile
.
insert_comment_line
(
"concentration unit : mol/"
+
io
::
volume_unit_to_string
(
units_set
.
length
));
ofile
<<
"Position"
;
for
(
index_t
component:
the_database
->
range_aqueous_component
())
{
ofile
.
separator
();
ofile
<<
the_database
->
get_label_component
(
component
);
}
ofile
.
eol
();
for
(
index_t
node:
the_mesh
->
range_nodes
())
{
ofile
<<
the_mesh
->
get_position
(
node
);
for
(
index_t
component:
the_database
->
range_aqueous_component
())
{
ofile
.
separator
();
ofile
<<
variables
->
aqueous_concentration
(
node
,
component
);
}
ofile
.
eol
();
}
ofile
.
flush
();
}
//! \brief Print the total aqueous concentrations in the CSV format in the file 'filepath'
void
print_components_total_aqueous_concentration
(
RawDatabasePtr
the_database
,
SaturatedVariablesPtr
variables
,
mesh
::
Mesh1DPtr
the_mesh
,
const
units
::
UnitsSet
&
units_set
,
const
std
::
string
&
filepath
)
{
CSVFile
ofile
(
filepath
);
print_components_total_aqueous_concentration
(
the_database
,
variables
,
the_mesh
,
units_set
,
ofile
);
}
//! \brief Print the total solid concentrations in the CSV format in 'ofile'
void
print_components_total_solid_concentration
(
RawDatabasePtr
the_database
,
SaturatedVariablesPtr
variables
,
mesh
::
Mesh1DPtr
the_mesh
,
const
units
::
UnitsSet
&
units_set
,
CSVFile
&
ofile
)
{
print_csv_header
(
ofile
);
ofile
.
insert_comment_line
(
"length unit : "
+
io
::
length_unit_to_string
(
units_set
.
length
));
ofile
.
insert_comment_line
(
"concentration unit : mol/"
+
io
::
volume_unit_to_string
(
units_set
.
length
));
ofile
<<
"Position"
;
for
(
index_t
component:
the_database
->
range_aqueous_component
())
{
ofile
.
separator
();
ofile
<<
the_database
->
get_label_component
(
component
);
}
ofile
.
eol
();
for
(
index_t
node:
the_mesh
->
range_nodes
())
{
ofile
<<
the_mesh
->
get_position
(
node
);
for
(
index_t
component:
the_database
->
range_aqueous_component
())
{
ofile
.
separator
();
ofile
<<
variables
->
solid_concentration
(
node
,
component
);
}
ofile
.
eol
();
}
ofile
.
flush
();
}
//! \brief Print the total solid concentrations in the CSV format in the file 'filepath'
void
print_components_total_solid_concentration
(
RawDatabasePtr
the_database
,
SaturatedVariablesPtr
variables
,
mesh
::
Mesh1DPtr
the_mesh
,
const
units
::
UnitsSet
&
units_set
,
const
std
::
string
&
filepath
)
{
CSVFile
ofile
(
filepath
);
print_components_total_solid_concentration
(
the_database
,
variables
,
the_mesh
,
units_set
,
ofile
);
}
//! \brief Print the solid phases profiles in 'ofile'
inline
void
print_minerals_profile
(
RawDatabasePtr
the_database
,
SaturatedVariablesPtr
variables
,
mesh
::
Mesh1DPtr
the_mesh
,
const
units
::
UnitsSet
&
units_set
,
CSVFile
&
ofile
)
{
print_csv_header
(
ofile
);
ofile
.
insert_comment_line
(
"Solid phase profiles"
);
ofile
.
insert_comment_line
(
"length unit : "
+
io
::
length_unit_to_string
(
units_set
.
length
));
ofile
<<
"Position"
;
for
(
index_t
mineral:
the_database
->
range_mineral
())
{
ofile
.
separator
();
ofile
<<
the_database
->
get_label_mineral
(
mineral
);
}
ofile
.
separator
();
ofile
<<
"Porosity"
;
ofile
.
separator
();
ofile
<<
"pH"
;
ofile
.
eol
();
for
(
index_t
node:
the_mesh
->
range_nodes
())
{
ofile
<<
the_mesh
->
get_position
(
node
);
AdimensionalSystemSolutionExtractor
extractor
(
variables
->
equilibrium_solution
(
node
),
the_database
,
units
::
UnitsSet
());
for
(
index_t
mineral:
the_database
->
range_mineral
())
{
ofile
.
separator
();
ofile
<<
extractor
.
volume_fraction_mineral
(
mineral
);
}
ofile
.
separator
();
ofile
<<
variables
->
porosity
(
node
);
ofile
.
separator
();
ofile
<<
extractor
.
pH
();
ofile
.
eol
();
}
ofile
.
flush
();
}
//! \brief Print the solid phases profiles in 'filepath'
void
print_minerals_profile
(
RawDatabasePtr
the_database
,
SaturatedVariablesPtr
variables
,
mesh
::
Mesh1DPtr
the_mesh
,
const
units
::
UnitsSet
&
units_set
,
const
std
::
string
&
filepath
)
{
CSVFile
ofile
(
filepath
);
print_minerals_profile
(
the_database
,
variables
,
the_mesh
,
units_set
,
ofile
);
}
// declaration of implementation
// =============================
//! \brief The implementation details of OutputNodalVariables
//!
//! \internal
struct
OutputNodalVariables
::
OutputNodalVariablesImpl:
public
database
::
DatabaseHolder
{
using
equilibrium_var_f
=
std
::
function
<
scalar_t
(
AdimensionalSystemSolutionExtractor
*
)
>
;
OutputNodalVariablesImpl
(
const
RawDatabasePtr
&
the_database
,
const
mesh
::
Mesh1DPtr
&
the_mesh
,
const
units
::
UnitsSet
&
the_units
)
:
database
::
DatabaseHolder
(
the_database
),
m_mesh
(
the_mesh
),
m_units
(
the_units
)
{}
// attributes
mesh
::
Mesh1DPtr
m_mesh
;
units
::
UnitsSet
m_units
;
std
::
vector
<
index_t
>
m_index_aqueous
{};
std
::
vector
<
index_t
>
m_index_solid
{};
std
::
vector
<
index_t
>
m_index_conc
{};
CSVFile
m_out_poro
{};
CSVFile
m_out_diffusivity
{};
std
::
vector
<
CSVFile
>
m_out_aqueous
{};
std
::
vector
<
CSVFile
>
m_out_solid
{};
std
::
vector
<
CSVFile
>
m_out_conc
{};
std
::
vector
<
CSVFile
>
m_out_equilibrium_vars
{};
std
::
vector
<
equilibrium_var_f
>
m_func_equilibrium_vars
{};
std
::
vector
<
CSVFile
>
m_out_custom
{};
std
::
vector
<
custom_f
>
m_func_custom
{};
// functions
void
print_csv_column_headers
(
CSVFile
&
out
);
void
register_porosity
(
const
std
::
string
&
filepath
);
void
register_diffusion_coefficient
(
const
std
::
string
&
filepath
);
void
register_total_aqueous_concentration
(
index_t
component
,
const
std
::
string
&
filepath
);
void
register_total_concentration
(
index_t
component
,
const
std
::
string
&
filepath
);
void
register_total_solid_concentration
(
index_t
component
,
const
std
::
string
&
filepath
);
void
register_molality_component
(
index_t
component
,
const
std
::
string
&
filepath
);
void
register_pH
(
const
std
::
string
&
filepath
);
void
register_volume_fraction_mineral
(
index_t
mineral
,
const
std
::
string
&
filepath
);
void
register_saturation_index_mineral_kinetic
(
index_t
mineral_kinetic
,
const
std
::
string
&
filepath
);
void
register_custom_function
(
custom_f
getter_function
,
const
std
::
string
&
filepath
,
const
std
::
string
&
msg
);
void
output
(
scalar_t
time
,
SaturatedVariablesPtr
var
);
};
// Main functions
// ===============
OutputNodalVariables
::
OutputNodalVariables
(
RawDatabasePtr
the_database
,
mesh
::
Mesh1DPtr
the_mesh
,
const
units
::
UnitsSet
&
the_units
)
:
m_impl
(
make_unique
<
OutputNodalVariablesImpl
>
(
the_database
,
the_mesh
,
the_units
))
{}
OutputNodalVariables
::~
OutputNodalVariables
()
=
default
;
void
OutputNodalVariables
::
register_porosity
(
const
std
::
string
&
filepath
)
{
m_impl
->
register_porosity
(
filepath
);
}
void
OutputNodalVariables
::
register_diffusion_coefficient
(
const
std
::
string
&
filepath
)
{
m_impl
->
register_diffusion_coefficient
(
filepath
);
}
void
OutputNodalVariables
::
register_total_aqueous_concentration
(
index_t
component
,
const
std
::
string
&
filepath
)
{
specmicp_assert_component_bounds
(
component
,
m_impl
->
get_database
());
m_impl
->
register_total_aqueous_concentration
(
component
,
filepath
);
}
void
OutputNodalVariables
::
register_total_concentration
(
index_t
component
,
const
std
::
string
&
filepath
)
{
specmicp_assert_component_bounds
(
component
,
m_impl
->
get_database
());
m_impl
->
register_total_concentration
(
component
,
filepath
);
}
void
OutputNodalVariables
::
register_total_solid_concentration
(
index_t
component
,
const
std
::
string
&
filepath
)
{
specmicp_assert_component_bounds
(
component
,
m_impl
->
get_database
());
m_impl
->
register_total_solid_concentration
(
component
,
filepath
);
}
void
OutputNodalVariables
::
register_molality_component
(
index_t
component
,
const
std
::
string
&
filepath
)
{
specmicp_assert_component_bounds
(
component
,
m_impl
->
get_database
());
m_impl
->
register_molality_component
(
component
,
filepath
);
}
void
OutputNodalVariables
::
register_pH
(
const
std
::
string
&
filepath
)
{
m_impl
->
register_pH
(
filepath
);
}
void
OutputNodalVariables
::
register_volume_fraction_mineral
(
index_t
mineral
,
const
std
::
string
&
filepath
)
{
specmicp_assert_mineral_bounds
(
mineral
,
m_impl
->
get_database
());
m_impl
->
register_volume_fraction_mineral
(
mineral
,
filepath
);
}
void
OutputNodalVariables
::
register_saturation_index_mineral_kinetic
(
index_t
mineral_kinetic
,
const
std
::
string
&
filepath
)
{
specmicp_assert_mineral_kinetic_bounds
(
mineral_kinetic
,
m_impl
->
get_database
());
m_impl
->
register_saturation_index_mineral_kinetic
(
mineral_kinetic
,
filepath
);
}
void
OutputNodalVariables
::
register_custom_function
(
custom_f
getter_function
,
const
std
::
string
&
filepath
,
const
std
::
string
&
msg
)
{
m_impl
->
register_custom_function
(
getter_function
,
filepath
,
msg
);
}
void
OutputNodalVariables
::
output
(
scalar_t
time
,
reactmicp
::
solver
::
VariablesBasePtr
var
)
{
SaturatedVariablesPtr
true_var
=
cast_var_from_base
(
var
);
m_impl
->
output
(
time
,
true_var
);
}
std
::
function
<
void
(
scalar_t
,
reactmicp
::
solver
::
VariablesBasePtr
)
>
OutputNodalVariables
::
get_output_for_reactmicp
()
{
return
std
::
bind
(
std
::
mem_fn
<
void
(
scalar_t
,
reactmicp
::
solver
::
VariablesBasePtr
)
>
(
&
OutputNodalVariables
::
output
),
this
,
std
::
placeholders
::
_1
,
std
::
placeholders
::
_2
);
}
RawDatabasePtr
OutputNodalVariables
::
get_database
()
{
return
m_impl
->
get_database
();
}
// #########################################
//
// Implementation
//
// ##########################################
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
print_csv_column_headers
(
CSVFile
&
out
)
{
out
.
insert_comment_unit
(
"time"
,
"s"
);
out
.
insert_comment_unit
(
"length"
,
io
::
length_unit_to_string
(
m_units
.
length
));
out
<<
"Time"
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
out
.
separator
();
out
<<
m_mesh
->
get_position
(
node
);
}
out
.
eol
();
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_porosity
(
const
std
::
string
&
filepath
)
{
m_out_poro
.
open
(
filepath
);
m_out_poro
.
insert_comment_line
(
"ReactMiCP - porosity"
);
m_out_poro
.
insert_comment_date
();
print_csv_column_headers
(
m_out_poro
);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_diffusion_coefficient
(
const
std
::
string
&
filepath
)
{
m_out_diffusivity
.
open
(
filepath
);
m_out_diffusivity
.
insert_comment_line
(
"ReactMiCP - diffusion coefficient"
);
m_out_diffusivity
.
insert_comment_date
();
m_out_diffusivity
.
insert_comment_unit
(
"diffusion coefficient"
,
io
::
surface_unit_to_string
(
m_units
.
length
)
+
"/s"
);
print_csv_column_headers
(
m_out_diffusivity
);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_total_aqueous_concentration
(
index_t
component
,
const
std
::
string
&
filepath
)
{
m_index_aqueous
.
push_back
(
component
);
m_out_aqueous
.
emplace_back
(
filepath
);
auto
i
=
m_out_aqueous
.
size
()
-
1
;
m_out_aqueous
[
i
].
open
(
filepath
);
m_out_aqueous
[
i
].
insert_comment_line
(
"ReactMiCP - aqueous concentration"
);
m_out_aqueous
[
i
].
insert_comment_date
();
m_out_aqueous
[
i
].
insert_comment_unit
(
"Concentration"
,
"mol/"
+
io
::
volume_unit_to_string
(
m_units
.
length
));
print_csv_column_headers
(
m_out_aqueous
[
i
]);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_total_concentration
(
index_t
component
,
const
std
::
string
&
filepath
)
{
m_index_conc
.
push_back
(
component
);
m_out_conc
.
emplace_back
(
filepath
);
auto
i
=
m_out_conc
.
size
()
-
1
;
m_out_conc
[
i
].
open
(
filepath
);
m_out_conc
[
i
].
insert_comment_line
(
"ReactMiCP - Total concentration"
);
m_out_conc
[
i
].
insert_comment_date
();
m_out_conc
[
i
].
insert_comment_unit
(
"Concentration"
,
"mol/"
+
io
::
volume_unit_to_string
(
m_units
.
length
));
print_csv_column_headers
(
m_out_conc
[
i
]);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_total_solid_concentration
(
index_t
component
,
const
std
::
string
&
filepath
)
{
m_index_solid
.
push_back
(
component
);
m_out_solid
.
emplace_back
(
filepath
);
auto
i
=
m_out_solid
.
size
()
-
1
;
m_out_solid
[
i
].
insert_comment_line
(
"ReactMiCP - solid concentration"
);
m_out_solid
[
i
].
insert_comment_date
();
m_out_solid
[
i
].
insert_comment_unit
(
"Concentration"
,
"mol/"
+
io
::
volume_unit_to_string
(
m_units
.
length
));
print_csv_column_headers
(
m_out_solid
[
i
]);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_molality_component
(
index_t
component
,
const
std
::
string
&
filepath
)
{
m_func_equilibrium_vars
.
emplace_back
(
std
::
bind
(
std
::
mem_fn
(
&
AdimensionalSystemSolutionExtractor
::
molality_component
),
std
::
placeholders
::
_1
,
component
));
m_out_equilibrium_vars
.
emplace_back
(
filepath
);
auto
i
=
m_out_equilibrium_vars
.
size
()
-
1
;
m_out_equilibrium_vars
[
i
].
insert_comment_line
(
"ReactMiCP - molality component "
+
m_data
->
get_label_component
(
component
));
m_out_equilibrium_vars
[
i
].
insert_comment_date
();
m_out_equilibrium_vars
[
i
].
insert_comment_unit
(
"molality"
,
"mol/kg"
);
print_csv_column_headers
(
m_out_equilibrium_vars
[
i
]);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_pH
(
const
std
::
string
&
filepath
)
{
m_func_equilibrium_vars
.
emplace_back
(
std
::
bind
(
std
::
mem_fn
(
&
AdimensionalSystemSolutionExtractor
::
pH
),
std
::
placeholders
::
_1
));
m_out_equilibrium_vars
.
emplace_back
(
filepath
);
auto
i
=
m_out_equilibrium_vars
.
size
()
-
1
;
m_out_equilibrium_vars
[
i
].
insert_comment_line
(
"ReactMiCP - pH"
);
m_out_equilibrium_vars
[
i
].
insert_comment_date
();
print_csv_column_headers
(
m_out_equilibrium_vars
[
i
]);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_volume_fraction_mineral
(
index_t
mineral
,
const
std
::
string
&
filepath
)
{
m_func_equilibrium_vars
.
emplace_back
(
std
::
bind
(
std
::
mem_fn
(
&
AdimensionalSystemSolutionExtractor
::
volume_fraction_mineral
),
std
::
placeholders
::
_1
,
mineral
));
m_out_equilibrium_vars
.
emplace_back
(
filepath
);
auto
i
=
m_out_equilibrium_vars
.
size
()
-
1
;
m_out_equilibrium_vars
[
i
].
insert_comment_line
(
"ReactMiCP - volume fraction mineral "
+
m_data
->
get_label_mineral
(
mineral
));
m_out_equilibrium_vars
[
i
].
insert_comment_date
();
print_csv_column_headers
(
m_out_equilibrium_vars
[
i
]);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_saturation_index_mineral_kinetic
(
index_t
mineral_kinetic
,
const
std
::
string
&
filepath
)
{
m_func_equilibrium_vars
.
emplace_back
(
std
::
bind
(
std
::
mem_fn
(
&
AdimensionalSystemSolutionExtractor
::
saturation_index_kinetic
),
std
::
placeholders
::
_1
,
mineral_kinetic
));
m_out_equilibrium_vars
.
emplace_back
(
filepath
);
auto
i
=
m_out_equilibrium_vars
.
size
()
-
1
;
m_out_equilibrium_vars
[
i
].
insert_comment_line
(
"ReactMiCP - Saturation index mineral "
+
m_data
->
get_label_mineral_kinetic
(
mineral_kinetic
));
m_out_equilibrium_vars
[
i
].
insert_comment_date
();
print_csv_column_headers
(
m_out_equilibrium_vars
[
i
]);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
register_custom_function
(
custom_f
getter_function
,
const
std
::
string
&
filepath
,
const
std
::
string
&
msg
)
{
m_func_custom
.
push_back
(
getter_function
);
m_out_custom
.
emplace_back
(
filepath
);
auto
i
=
m_out_custom
.
size
()
-
1
;
CSVFile
&
out
=
m_out_custom
[
i
];
out
.
insert_comment_line
(
"ReactMiCP"
);
out
.
insert_comment_line
(
msg
);
out
.
insert_comment_date
();
print_csv_column_headers
(
out
);
}
void
OutputNodalVariables
::
OutputNodalVariablesImpl
::
output
(
scalar_t
time
,
SaturatedVariablesPtr
variables
)
{
// upscaling
// ---------
if
(
m_out_poro
.
is_open
())
{
m_out_poro
<<
time
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_poro
.
separator
();
m_out_poro
<<
variables
->
porosity
(
node
);
}
m_out_poro
.
endl
();
}
if
(
m_out_diffusivity
.
is_open
())
{
m_out_diffusivity
<<
time
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_diffusivity
.
separator
();
m_out_diffusivity
<<
variables
->
diffusion_coefficient
(
node
);
}
m_out_diffusivity
.
endl
();
}
// equilibrium vars
// ----------------
if
(
m_out_equilibrium_vars
.
size
()
>
0
)
{
for
(
std
::
vector
<
CSVFile
>::
size_type
var
=
0
;
var
<
m_out_equilibrium_vars
.
size
();
++
var
)
{
m_out_equilibrium_vars
[
var
]
<<
time
;
}
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
AdimensionalSystemSolutionExtractor
extr
(
variables
->
equilibrium_solution
(
node
),
m_data
,
m_units
);
for
(
std
::
vector
<
CSVFile
>::
size_type
var
=
0
;
var
<
m_out_equilibrium_vars
.
size
();
++
var
)
{
m_out_equilibrium_vars
[
var
].
separator
();
m_out_equilibrium_vars
[
var
]
<<
m_func_equilibrium_vars
[
var
](
&
extr
);
}
}
for
(
std
::
vector
<
CSVFile
>::
size_type
var
=
0
;
var
<
m_out_equilibrium_vars
.
size
();
++
var
)
{
m_out_equilibrium_vars
[
var
].
endl
();
}
}
// nodal vars
// -----------
for
(
std
::
vector
<
CSVFile
>::
size_type
aqueous
=
0
;
aqueous
<
m_index_aqueous
.
size
();
++
aqueous
)
{
m_out_aqueous
[
aqueous
]
<<
time
;
}
for
(
std
::
vector
<
CSVFile
>::
size_type
solid
=
0
;
solid
<
m_index_solid
.
size
();
++
solid
)
{
m_out_solid
[
solid
]
<<
time
;
}
for
(
std
::
vector
<
CSVFile
>::
size_type
tot
=
0
;
tot
<
m_index_conc
.
size
();
++
tot
)
{
m_out_conc
[
tot
]
<<
time
;
}
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
for
(
std
::
vector
<
CSVFile
>::
size_type
aqueous
=
0
;
aqueous
<
m_index_aqueous
.
size
();
++
aqueous
)
{
m_out_aqueous
[
aqueous
].
separator
();
m_out_aqueous
[
aqueous
]
<<
variables
->
aqueous_concentration
(
node
,
m_index_aqueous
[
aqueous
]);
}
for
(
std
::
vector
<
CSVFile
>::
size_type
solid
=
0
;
solid
<
m_index_solid
.
size
();
++
solid
)
{
m_out_solid
[
solid
].
separator
();
m_out_solid
[
solid
]
<<
variables
->
solid_concentration
(
node
,
m_index_solid
[
solid
]);
}
for
(
std
::
vector
<
CSVFile
>::
size_type
tot
=
0
;
tot
<
m_index_conc
.
size
();
++
tot
)
{
m_out_conc
[
tot
].
separator
();
m_out_conc
[
tot
]
<<
variables
->
porosity
(
node
)
*
variables
->
aqueous_concentration
(
node
,
m_index_conc
[
tot
])
+
variables
->
solid_concentration
(
node
,
m_index_conc
[
tot
]);
}
}
for
(
std
::
vector
<
CSVFile
>::
size_type
aqueous
=
0
;
aqueous
<
m_index_aqueous
.
size
();
++
aqueous
)
{
m_out_aqueous
[
aqueous
].
endl
();
}
for
(
std
::
vector
<
CSVFile
>::
size_type
solid
=
0
;
solid
<
m_index_solid
.
size
();
++
solid
)
{
m_out_solid
[
solid
].
endl
();
}
for
(
std
::
vector
<
CSVFile
>::
size_type
tot
=
0
;
tot
<
m_index_conc
.
size
();
++
tot
)
{
m_out_conc
[
tot
].
endl
();
}
// custom functions
for
(
std
::
vector
<
CSVFile
>::
size_type
var
=
0
;
var
<
m_out_custom
.
size
();
++
var
)
{
auto
&
out
=
m_out_custom
[
var
];
out
<<
time
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
out
.
separator
();
out
<<
m_func_custom
[
var
](
node
,
variables
);
}
out
.
endl
();
}
}
}
// end namespace io
}
// end namespace specmicp
Event Timeline
Log In to Comment