Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F63009812
cement_hydration.py
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, May 17, 03:02
Size
8 KB
Mime Type
text/x-python
Expires
Sun, May 19, 03:02 (2 d)
Engine
blob
Format
Raw Data
Handle
17720205
Attached To
rSPECMICP SpecMiCP / ReactMiCP
cement_hydration.py
View Options
#Copyright (c) 2014,2015 Fabien 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.
import
specmicp.database
as
database
import
specmicp.constraints
as
formulation
import
specmicp.solver
MASS_PERCENT_INDEX
=
0
HYDRATION_INDEX
=
1
def
hydration
(
minerals
,
wc
,
database_path
=
""
,
database_manager
=
None
,
aqueous_species
=
None
,
percent_v_entrained_air
=
0.0
,
list_minerals_to_keep
=
None
,
list_extra_component
=
[],
length_unit
=
"meter"
,
previous_sol
=
None
,
saturated_system
=
False
):
"""Thermodynamic Cement hydration
Return a SpecMiCPSolution
The first argument is a dictionary :
{label: (mass_percent, hydration degree)}
A new database is created for each p
Example :
>>> sol = hydration(
{"C3S": (0.8, 1.0), "C3A": (0.1, 1.0), "C4AF": (0.1, 1.0)},
0.4,
"../data/cemdata.js",
percent_v_entrained_air=0.0)
"""
if
database_manager
is
None
:
db
=
database
.
DatabaseManager
(
database_path
)
swapping
=
{
"H[+]"
:
"HO[-]"
,
"Al[3+]"
:
"Al(OH)4[-]"
,
"Fe[2+]"
:
"Fe(OH)4[-]"
,
"Si(OH)4"
:
"SiO(OH)3[-]"
}
db
.
swap_components
(
swapping
)
db
.
remove_gas_phases
()
else
:
db
=
database_manager
if
length_unit
==
"meter"
:
scaling
=
1.0
elif
length_unit
==
"decimeter"
:
scaling
=
1e3
elif
length_unit
==
"centimer"
:
scaling
=
1e6
else
:
raise
ValueError
(
"Unknown length unit"
)
scaling_M
=
1.0
rho_minerals
=
[]
is_kinetic
=
[]
# find the cement mass
# --------------------
sum_for_cement_mass
=
0.0
for
(
label
,
value
)
in
minerals
.
items
():
try
:
idm
=
db
.
mineral_label_to_id
(
label
)
rho_minerals
.
append
(
scaling_M
/
scaling
*
db
.
density_mineral
(
idm
))
is_kinetic
.
append
(
False
)
except
ValueError
:
idm
=
db
.
mineral_kinetic_label_to_id
(
label
)
rho_minerals
.
append
(
scaling_M
/
scaling
*
db
.
density_mineral_kinetic
(
idm
))
is_kinetic
.
append
(
True
)
sum_for_cement_mass
+=
value
[
MASS_PERCENT_INDEX
]
/
rho_minerals
[
-
1
]
sum_for_cement_mass
+=
wc
/
(
997.0
/
scaling
)
mc
=
(
1.0
-
percent_v_entrained_air
)
/
sum_for_cement_mass
inert_volume
=
0.0
# set the formulation
# -------------------
system
=
formulation
.
SpecMiCPFormulation
(
db
)
for
(
index
,
(
label
,
value
))
in
enumerate
(
minerals
.
items
()):
reactant_mass
=
value
[
MASS_PERCENT_INDEX
]
*
mc
concentration
=
value
[
HYDRATION_INDEX
]
*
reactant_mass
inert
=
(
1.0
-
value
[
HYDRATION_INDEX
])
*
reactant_mass
if
is_kinetic
[
index
]:
concentration
/=
scaling_M
*
db
.
molar_mass_mineral_kinetic
(
idm
)
inert
/=
rho_minerals
[
index
]
else
:
concentration
/=
scaling_M
*
db
.
molar_mass_mineral
(
idm
)
inert
/=
rho_minerals
[
index
]
system
.
add_mineral
(
label
,
concentration
)
inert_volume
+=
inert
system
.
set_inert_volume_fraction
(
inert_volume
)
system
.
set_mass_solution
(
wc
*
mc
)
if
aqueous_species
is
not
None
:
for
(
label
,
value
)
in
aqueous_species
.
items
():
system
.
add_aqueous_species
(
label
,
value
)
if
list_minerals_to_keep
is
not
None
:
system
.
set_list_minerals
(
list_minerals_to_keep
)
system
.
initialize_system
()
if
saturated_system
:
system
.
set_saturated_system
()
system
.
set_charge_keeper
(
"HO[-]"
)
# solve the problem
# -----------------
the_solver
=
specmicp
.
solver
.
SpecMiCPSolver
(
db
,
system
,
previous_sol
)
the_solver
.
set_length_unit
(
length_unit
)
the_solver
.
set_maximum_step_length
(
20
,
100
)
the_solver
.
enable_non_monotone_linesearch
()
the_solver
.
disable_condition_check
()
the_solver
.
set_tolerances
(
1e-8
,
1e-12
)
the_solver
.
set_non_ideality_tolerance
(
1e-12
)
if
previous_sol
is
None
:
map_init
=
{
"HO[-]"
:
-
2.0
,
"Ca[2+]"
:
-
2.0
,
"SiO(OH)3[-]"
:
-
5.0
}
extra_components
=
{
"Al(OH)4[-]"
:
-
3.0
,
"SO4[2-]"
:
-
3.0
,
"Fe(OH)4[-]"
:
-
4.0
}
for
(
label
,
value
)
in
extra_components
.
items
():
try
:
_
=
db
.
component_label_to_id
(
label
)
map_init
[
label
]
=
value
except
ValueError
:
pass
the_solver
.
initialize_variables
(
0.5
,
map_init
)
the_solver
.
solve
()
# return the solution
# -------------------
return
the_solver
.
get_solution
()
def
hydration_oxyde
(
oxyde_formulation
,
density_cement
,
wc
,
loss_of_ignition
,
database_path
=
""
,
database_manager
=
None
,
aqueous_species
=
None
,
percent_v_entrained_air
=
0.0
,
list_minerals_to_keep
=
None
,
list_extra_component
=
[],
length_unit
=
"meter"
,
previous_sol
=
None
,
saturated_system
=
False
,
degree_hydration
=
1.0
):
"""Thermodynamic Cement hydration
No hydration degree
Return a SpecMiCPSolution
The first argument is a dictionary :
{label: (mass_percent, hydration degree)}
A new database is created for each p
"""
if
database_manager
is
None
:
db
=
database
.
DatabaseManager
(
database_path
)
swapping
=
{
"H[+]"
:
"HO[-]"
,
"Al[3+]"
:
"Al(OH)4[-]"
,
"Fe[2+]"
:
"Fe(OH)4[-]"
,
"Si(OH)4"
:
"SiO(OH)3[-]"
}
db
.
swap_components
(
swapping
)
db
.
remove_gas_phases
()
else
:
db
=
database_manager
if
length_unit
==
"meter"
:
scaling
=
1.0
elif
length_unit
==
"decimeter"
:
scaling
=
1e3
elif
length_unit
==
"centimer"
:
scaling
=
1e6
else
:
raise
ValueError
(
"Unknown length unit"
)
scaling_M
=
1.0
# find the cement mass
# --------------------
sum_for_cement_mass
=
1.0
/
density_cement
+
wc
/
(
997.0
/
scaling
)
mc
=
(
1.0
-
percent_v_entrained_air
)
/
sum_for_cement_mass
# set the formulation
# -------------------
system
=
formulation
.
SpecMiCPFormulation
(
db
)
for
(
index
,
(
label
,
value
))
in
enumerate
(
oxyde_formulation
.
items
()):
concentration
=
value
*
mc
*
degree_hydration
concentration
/=
scaling_M
*
db
.
l_molar_mass_mineral_kinetic
(
label
)
system
.
add_mineral
(
label
,
concentration
)
system
.
set_inert_volume_fraction
(
mc
*
(
1.0
-
degree_hydration
)
/
density_cement
)
system
.
set_mass_solution
(
wc
*
mc
+
loss_of_ignition
*
mc
)
if
aqueous_species
is
not
None
:
for
(
label
,
value
)
in
aqueous_species
.
items
():
system
.
add_aqueous_species
(
label
,
value
)
if
list_minerals_to_keep
is
not
None
:
system
.
set_list_minerals
(
list_minerals_to_keep
)
system
.
initialize_system
()
if
saturated_system
:
system
.
set_saturated_system
()
system
.
set_charge_keeper
(
"HO[-]"
)
# solve the problem
# -----------------
the_solver
=
specmicp
.
solver
.
SpecMiCPSolver
(
db
,
system
,
previous_sol
)
the_solver
.
set_length_unit
(
length_unit
)
the_solver
.
set_maximum_step_length
(
20
,
100
)
the_solver
.
enable_non_monotone_linesearch
()
the_solver
.
disable_condition_check
()
the_solver
.
set_tolerances
(
1e-8
,
1e-12
)
the_solver
.
set_non_ideality_tolerance
(
1e-12
)
if
previous_sol
is
None
:
map_init
=
{
"HO[-]"
:
-
2.0
,
"Ca[2+]"
:
-
2.0
,
"SiO(OH)3[-]"
:
-
5.0
}
extra_components
=
{
"Al(OH)4[-]"
:
-
3.0
,
"SO4[2-]"
:
-
3.0
,
"Fe(OH)4[-]"
:
-
4.0
}
for
(
label
,
value
)
in
extra_components
.
items
():
try
:
_
=
db
.
component_label_to_id
(
label
)
map_init
[
label
]
=
value
except
ValueError
:
pass
the_solver
.
initialize_variables
(
0.5
,
map_init
)
the_solver
.
solve
()
# return the solution
# -------------------
return
the_solver
.
get_solution
()
Event Timeline
Log In to Comment