Skip to content

Commit b6a15dc

Browse files
New validation case to reproduce Calderoni et al. (2008)
- Input file val-filbe.i - Debug input file val-flibe_test_BC.i - Python script to reproduce several measurements (Ref. idaholab#193)
1 parent 1fa0d61 commit b6a15dc

File tree

3 files changed

+621
-0
lines changed

3 files changed

+621
-0
lines changed

test/tests/val-flibe/run_val_flibe.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import numpy as np
2+
import subprocess
3+
4+
# number of processors
5+
n_proc = 4
6+
7+
filename = 'val-flibe.i'
8+
search_strings = ["T = '${units ",'p_bnd = ',' file_base = ']
9+
command_to_run = "mpirun -np "+str(n_proc)+" ~/projects/TMAP8/tmap8-opt -i val-flibe.i"
10+
11+
# Experimental data pressure and Temperature series
12+
p_exp = np.array([1210,538,315,171,1210,538,315,1210,538,1210])
13+
T_exp = np.array([700,700,700,700,650,650,650,600,600,550])
14+
15+
16+
def run_terminal_command(command):
17+
subprocess.run([command], shell=True, check=True)
18+
19+
def substitute_row(filename, search_string, replacement):
20+
# Read the contents of the file
21+
with open(filename, 'r') as file:
22+
lines = file.readlines()
23+
# Search for the row and substitute it
24+
for i, line in enumerate(lines):
25+
if search_string in line:
26+
lines[i] = replacement + '\n' # Add a newline character for consistency
27+
# Write the modified contents back to the file
28+
with open(filename, 'w') as file:
29+
file.writelines(lines)
30+
31+
32+
33+
34+
# Names of output files for each case
35+
output_fname = np.array([])
36+
for p,T in zip(p_exp,T_exp):
37+
output_fname = np.append(output_fname, 'val-flibe_'+str(p)+'_'+str(T))
38+
39+
40+
41+
for T,p,outName in zip(T_exp,p_exp,output_fname):
42+
replacemens = ["T = '${units "+str(T)+" degC -> K}' # temperature", 'p_bnd = '+str(p)+' # pressure', " file_base = '"+outName+"'"]
43+
substitute_row(filename, search_strings[0], replacemens[0])
44+
substitute_row(filename, search_strings[1], replacemens[1])
45+
substitute_row(filename, search_strings[2], replacemens[2])
46+
# Run input file with new BCs
47+
run_terminal_command(command_to_run)
48+
print('########## Run at',p,'Pa and',T,'degC completed. ##########')

test/tests/val-flibe/val-flibe.i

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
endtime = 140000 # simulation end time
2+
3+
R = 8.31446261815324 # Gas constant (from PhysicalConstants.h - https://physics.nist.gov/cgi-bin/cuu/Value?r)
4+
5+
T = '${units 550 degC -> K}' # temperature
6+
7+
p_bnd = 1210 # pressure
8+
9+
L_Ni = '${units 2 mm -> m}' # nickel thickness
10+
L_salt = '${units 8.1 mm -> m}' # salt thickness
11+
12+
num_nodes = 200 # (-)
13+
14+
[Mesh]
15+
[whole_domain]
16+
type = GeneratedMeshGenerator
17+
xmin = 0
18+
xmax = '${fparse L_Ni + L_salt}'
19+
dim = 1
20+
nx = ${num_nodes}
21+
[]
22+
[block_1]
23+
type = ParsedSubdomainMeshGenerator
24+
input = whole_domain
25+
combinatorial_geometry = 'x <= ${L_Ni}'
26+
block_id = 0
27+
[]
28+
[block_2]
29+
type = ParsedSubdomainMeshGenerator
30+
input = block_1
31+
combinatorial_geometry = 'x > ${L_Ni}'
32+
block_id = 1
33+
[]
34+
[interface]
35+
type = SideSetsBetweenSubdomainsGenerator
36+
input = block_2
37+
primary_block = '0' # Ni
38+
paired_block = '1' # salt
39+
new_boundary = 'interface'
40+
[]
41+
[interface_other_side]
42+
type = SideSetsBetweenSubdomainsGenerator
43+
input = interface
44+
primary_block = '1' # salt
45+
paired_block = '0' # Ni
46+
new_boundary = 'interface_other'
47+
[]
48+
[]
49+
50+
[Variables]
51+
[conc_Ni]
52+
initial_condition = 0.9e-0
53+
block = 0
54+
[]
55+
[conc_salt]
56+
initial_condition = 0.3e-0
57+
block = 1
58+
[]
59+
[]
60+
61+
[AuxVariables]
62+
[enclosure_pressure]
63+
family = SCALAR
64+
initial_condition = ${p_bnd}
65+
[]
66+
[flux_x]
67+
order = FIRST
68+
family = MONOMIAL
69+
[]
70+
[p_div_RT_salt]
71+
block = 1
72+
initial_condition = 0.001
73+
[]
74+
[p_div_RT_Ni]
75+
block = 0
76+
initial_condition = 0.001
77+
[]
78+
[]
79+
80+
[Kernels]
81+
[diff_Ni]
82+
type = ADMatDiffusion
83+
variable = conc_Ni
84+
diffusivity = diffusivity_Ni
85+
block = 0
86+
[]
87+
[diff_salt]
88+
type = ADMatDiffusion
89+
variable = conc_salt
90+
diffusivity = diffusivity_salt
91+
block = 1
92+
[]
93+
[time_diff_Ni]
94+
type = TimeDerivative
95+
variable = conc_Ni
96+
block = 0
97+
[]
98+
[time_diff_salt]
99+
type = TimeDerivative
100+
variable = conc_salt
101+
block = 1
102+
[]
103+
[]
104+
105+
[InterfaceKernels]
106+
[tied]
107+
type = InterfaceSorption
108+
K0 = 0.564
109+
Ea = 15800.0
110+
n_sorption = 0.5
111+
diffusivity = diffusivity_Ni_nonAD
112+
unit_scale = 1
113+
unit_scale_neighbor = 1
114+
temperature = ${T}
115+
variable = conc_Ni
116+
neighbor_var = p_div_RT_salt
117+
sorption_penalty = 0.1
118+
boundary = 'interface'
119+
[]
120+
[]
121+
122+
[AuxKernels]
123+
[flux_x_Ni]
124+
type = DiffusionFluxAux
125+
diffusivity = diffusivity_Ni
126+
variable = flux_x
127+
diffusion_variable = conc_Ni
128+
component = x
129+
block = 0
130+
[]
131+
[flux_x_salt]
132+
type = DiffusionFluxAux
133+
diffusivity = diffusivity_salt
134+
variable = flux_x
135+
diffusion_variable = conc_salt
136+
component = x
137+
block = 1
138+
[]
139+
[p_div_RT_Ni_kernel]
140+
variable = p_div_RT_Ni
141+
type = ParsedAux
142+
expression = '(conc_Ni / (${R} * ${T} * 0.564 * exp(-15800/(${R}*${T}))))^2'
143+
coupled_variables = 'conc_Ni'
144+
[]
145+
[p_div_RT_salt_kernel]
146+
variable = p_div_RT_salt
147+
type = ParsedAux
148+
expression = '(conc_salt / (${R} * ${T} * 0.079 * exp(-35000/(${R}*${T}))))'
149+
coupled_variables = 'conc_salt'
150+
[]
151+
[]
152+
153+
[BCs]
154+
[left_flux]
155+
type = EquilibriumBC
156+
Ko = 0.564
157+
activation_energy = 15800.0
158+
boundary = left
159+
enclosure_var = enclosure_pressure
160+
temperature = ${T}
161+
variable = conc_Ni
162+
p = 0.5
163+
[]
164+
[right_flux]
165+
type = ADDirichletBC
166+
boundary = right
167+
variable = conc_salt
168+
value = 0.0
169+
[]
170+
[]
171+
172+
[Functions]
173+
[diffusivity_Ni_func]
174+
type = ParsedFunction
175+
symbol_names = 'T'
176+
symbol_values = '${T}'
177+
expression = '0.0000007*exp(-39500/(${R}*T))'
178+
[]
179+
180+
[diffusivity_salt_func]
181+
type = ParsedFunction
182+
symbol_names = 'T'
183+
symbol_values = '${T}'
184+
expression = '0.00000093*exp(-42000/(${R}*T))'
185+
[]
186+
187+
[solubility_Ni_func]
188+
type = ParsedFunction
189+
symbol_names = 'T'
190+
symbol_values = '${T}'
191+
expression = '0.564 * exp(-15800/(${R}*T))'
192+
[]
193+
194+
[solubility_salt_func]
195+
type = ParsedFunction
196+
symbol_names = 'T'
197+
symbol_values = '${T}'
198+
expression = '0.079 * exp(-35000/(${R}*T))'
199+
[]
200+
[]
201+
202+
[Materials]
203+
[diff_solu]
204+
type = ADGenericFunctionMaterial
205+
prop_names = 'diffusivity_Ni diffusivity_salt solubility_Ni solubility_salt'
206+
prop_values = 'diffusivity_Ni_func diffusivity_salt_func solubility_Ni_func solubility_salt_func'
207+
outputs = all
208+
[]
209+
[converter_to_regular]
210+
type = MaterialADConverter
211+
ad_props_in = 'diffusivity_Ni diffusivity_salt'
212+
reg_props_out = 'diffusivity_Ni_nonAD diffusivity_salt_nonAD'
213+
[]
214+
[]
215+
216+
[Postprocessors]
217+
[avg_flux_right]
218+
type = SideDiffusiveFluxAverage
219+
variable = conc_salt
220+
boundary = right
221+
diffusivity = diffusivity_salt_nonAD
222+
[]
223+
[]
224+
225+
[Preconditioning]
226+
[SMP]
227+
type = SMP
228+
full = true
229+
[]
230+
[]
231+
232+
[Executioner]
233+
type = Transient
234+
steady_state_detection = true
235+
steady_state_start_time = 40000
236+
steady_state_tolerance = 1e-9
237+
scheme = bdf2 # bdf2 # crank-nicolson # explicit-euler
238+
solve_type = NEWTON # LINEAR # JFNK # NEWTON
239+
petsc_options = '-snes_ksp_ew'
240+
petsc_options_iname = '-pc_type'
241+
petsc_options_value = 'lu'
242+
l_max_its = 10
243+
nl_max_its = 13
244+
nl_rel_tol = 1e-8 # nonlinear relative tolerance
245+
nl_abs_tol = 1e-20 #1e-30 # nonlinear absolute tolerance
246+
l_tol = 1e-6 # 1e-3 - 1e-5 # linear tolerance
247+
end_time = ${endtime}
248+
automatic_scaling = true
249+
line_search = none
250+
dtmax = 10.0
251+
[TimeStepper]
252+
type = IterationAdaptiveDT
253+
dt = 1e-10
254+
optimal_iterations = 18 # 6-10 or 18
255+
growth_factor = 1.1
256+
cutback_factor = 0.5
257+
[]
258+
[]
259+
260+
[Outputs]
261+
execute_on = timestep_end
262+
exodus = true
263+
[csv]
264+
type = CSV
265+
file_base = 'val-flibe_1210_550'
266+
time_step_interval = 500
267+
[]
268+
[]
269+
270+
[Dampers]
271+
[limit_salt]
272+
type = BoundingValueElementDamper
273+
variable = conc_salt
274+
max_value = 1e42
275+
min_value = -0.01
276+
min_damping = 0.001
277+
[]
278+
[limit_Ni]
279+
type = BoundingValueElementDamper
280+
variable = conc_Ni
281+
max_value = 1e42
282+
min_value = -0.01
283+
min_damping = 0.001
284+
[]
285+
[]

0 commit comments

Comments
 (0)