Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F96504320
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
Fri, Dec 27, 09:04
Size
17 KB
Mime Type
text/x-c
Expires
Sun, Dec 29, 09:04 (2 d)
Engine
blob
Format
Raw Data
Handle
23194788
Attached To
rSPECMICP SpecMiCP / ReactMiCP
saturated_react.cpp
View Options
/*-------------------------------------------------------------------------------
Copyright (c) 2015 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"
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
);
}
OutputNodalVariables
::
OutputNodalVariables
(
RawDatabasePtr
the_database
,
mesh
::
Mesh1DPtr
the_mesh
,
const
units
::
UnitsSet
&
the_units
)
:
m_database
(
the_database
),
m_mesh
(
the_mesh
),
m_units
(
the_units
)
{}
void
OutputNodalVariables
::
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
();
m_out_poro
.
insert_comment_unit
(
"time"
,
"s"
);
m_out_poro
.
insert_comment_unit
(
"length"
,
io
::
length_unit_to_string
(
m_units
.
length
));
m_out_poro
<<
"Time"
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_poro
.
separator
();
m_out_poro
<<
m_mesh
->
get_position
(
node
);
}
m_out_poro
.
eol
();
}
void
OutputNodalVariables
::
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
(
"time"
,
"s"
);
m_out_diffusivity
.
insert_comment_unit
(
"length"
,
io
::
length_unit_to_string
(
m_units
.
length
));
m_out_diffusivity
.
insert_comment_unit
(
"diffusion coefficient"
,
io
::
surface_unit_to_string
(
m_units
.
length
)
+
"/s"
);
m_out_diffusivity
<<
"Time"
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_diffusivity
.
separator
();
m_out_diffusivity
<<
m_mesh
->
get_position
(
node
);
}
m_out_diffusivity
.
eol
();
}
void
OutputNodalVariables
::
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
(
"time"
,
"s"
);
m_out_aqueous
[
i
].
insert_comment_unit
(
"length"
,
io
::
length_unit_to_string
(
m_units
.
length
));
m_out_aqueous
[
i
].
insert_comment_unit
(
"Concentration"
,
"mol/"
+
io
::
volume_unit_to_string
(
m_units
.
length
));
m_out_aqueous
[
i
]
<<
"Time"
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_aqueous
[
i
].
separator
();
m_out_aqueous
[
i
]
<<
m_mesh
->
get_position
(
node
);
}
m_out_aqueous
[
i
].
eol
();
}
void
OutputNodalVariables
::
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
(
"time"
,
"s"
);
m_out_conc
[
i
].
insert_comment_unit
(
"length"
,
io
::
length_unit_to_string
(
m_units
.
length
));
m_out_conc
[
i
].
insert_comment_unit
(
"Concentration"
,
"mol/"
+
io
::
volume_unit_to_string
(
m_units
.
length
));
m_out_conc
[
i
]
<<
"Time"
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_conc
[
i
].
separator
();
m_out_conc
[
i
]
<<
m_mesh
->
get_position
(
node
);
}
m_out_conc
[
i
].
eol
();
}
void
OutputNodalVariables
::
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
(
"time"
,
"s"
);
m_out_solid
[
i
].
insert_comment_unit
(
"length"
,
io
::
length_unit_to_string
(
m_units
.
length
));
m_out_solid
[
i
].
insert_comment_unit
(
"Concentration"
,
"mol/"
+
io
::
volume_unit_to_string
(
m_units
.
length
));
m_out_solid
[
i
]
<<
"Time"
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_solid
[
i
].
separator
();
m_out_solid
[
i
]
<<
m_mesh
->
get_position
(
node
);
}
m_out_solid
[
i
].
eol
();
}
void
OutputNodalVariables
::
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_database
->
get_label_component
(
component
));
m_out_equilibrium_vars
[
i
].
insert_comment_date
();
m_out_equilibrium_vars
[
i
].
insert_comment_unit
(
"time"
,
"s"
);
m_out_equilibrium_vars
[
i
].
insert_comment_unit
(
"length"
,
io
::
length_unit_to_string
(
m_units
.
length
));
m_out_equilibrium_vars
[
i
].
insert_comment_unit
(
"molality"
,
"mol/kg"
);
m_out_equilibrium_vars
[
i
]
<<
"Time"
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_equilibrium_vars
[
i
].
separator
();
m_out_equilibrium_vars
[
i
]
<<
m_mesh
->
get_position
(
node
);
}
m_out_equilibrium_vars
[
i
].
eol
();
}
void
OutputNodalVariables
::
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
();
m_out_equilibrium_vars
[
i
].
insert_comment_unit
(
"time"
,
"s"
);
m_out_equilibrium_vars
[
i
].
insert_comment_unit
(
"length"
,
io
::
length_unit_to_string
(
m_units
.
length
));
m_out_equilibrium_vars
[
i
]
<<
"Time"
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_equilibrium_vars
[
i
].
separator
();
m_out_equilibrium_vars
[
i
]
<<
m_mesh
->
get_position
(
node
);
}
m_out_equilibrium_vars
[
i
].
eol
();
}
void
OutputNodalVariables
::
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_database
->
get_label_mineral
(
mineral
));
m_out_equilibrium_vars
[
i
].
insert_comment_date
();
m_out_equilibrium_vars
[
i
].
insert_comment_unit
(
"time"
,
"s"
);
m_out_equilibrium_vars
[
i
].
insert_comment_unit
(
"length"
,
io
::
length_unit_to_string
(
m_units
.
length
));
m_out_equilibrium_vars
[
i
]
<<
"Time"
;
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
m_out_equilibrium_vars
[
i
].
separator
();
m_out_equilibrium_vars
[
i
]
<<
m_mesh
->
get_position
(
node
);
}
m_out_equilibrium_vars
[
i
].
eol
();
}
void
OutputNodalVariables
::
output
(
scalar_t
time
,
SaturatedVariablesPtr
var
)
{
// 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
<<
var
->
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
<<
var
->
diffusion_coefficient
(
node
);
}
m_out_diffusivity
.
endl
();
}
// equilibrium vars
// ----------------
if
(
m_out_equilibrium_vars
.
size
()
>
0
)
{
for
(
auto
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
(
var
->
equilibrium_solution
(
node
),
m_database
,
m_units
);
for
(
auto
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
(
auto
var
=
0
;
var
<
m_out_equilibrium_vars
.
size
();
++
var
)
{
m_out_equilibrium_vars
[
var
].
endl
();
}
}
// nodal vars
// -----------
for
(
auto
aqueous
=
0
;
aqueous
<
m_index_aqueous
.
size
();
++
aqueous
)
{
m_out_aqueous
[
aqueous
]
<<
time
;
}
for
(
auto
solid
=
0
;
solid
<
m_index_solid
.
size
();
++
solid
)
{
m_out_solid
[
solid
]
<<
time
;
}
for
(
auto
tot
=
0
;
tot
<
m_index_conc
.
size
();
++
tot
)
{
m_out_conc
[
tot
]
<<
time
;
}
for
(
index_t
node:
m_mesh
->
range_nodes
())
{
for
(
auto
aqueous
=
0
;
aqueous
<
m_index_aqueous
.
size
();
++
aqueous
)
{
m_out_aqueous
[
aqueous
].
separator
();
m_out_aqueous
[
aqueous
]
<<
var
->
aqueous_concentration
(
node
,
m_index_aqueous
[
aqueous
]);
}
for
(
auto
solid
=
0
;
solid
<
m_index_solid
.
size
();
++
solid
)
{
m_out_solid
[
solid
].
separator
();
m_out_solid
[
solid
]
<<
var
->
solid_concentration
(
node
,
m_index_solid
[
solid
]);
}
for
(
auto
tot
=
0
;
tot
<
m_index_conc
.
size
();
++
tot
)
{
m_out_conc
[
tot
].
separator
();
m_out_conc
[
tot
]
<<
var
->
porosity
(
node
)
*
var
->
aqueous_concentration
(
node
,
m_index_conc
[
tot
])
+
var
->
solid_concentration
(
node
,
m_index_conc
[
tot
]);
}
}
for
(
auto
aqueous
=
0
;
aqueous
<
m_index_aqueous
.
size
();
++
aqueous
)
{
m_out_aqueous
[
aqueous
].
endl
();
}
for
(
auto
solid
=
0
;
solid
<
m_index_solid
.
size
();
++
solid
)
{
m_out_solid
[
solid
].
endl
();
}
for
(
auto
tot
=
0
;
tot
<
m_index_conc
.
size
();
++
tot
)
{
m_out_conc
[
tot
].
endl
();
}
}
void
OutputNodalVariables
::
output
(
scalar_t
time
,
reactmicp
::
solver
::
VariablesBasePtr
var
)
{
SaturatedVariablesPtr
true_var
=
cast_var_from_base
(
var
);
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
);
}
}
// end namespace io
}
// end namespace specmicp
Event Timeline
Log In to Comment