Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New validation case to reproduce Calderoni et al. (2008) #194

Open
wants to merge 2 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions test/tests/val-flibe/run_val_flibe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import numpy as np
import subprocess

# number of processors
n_proc = 4

filename = 'val-flibe.i'
search_strings = ["T = '${units ",'p_bnd = ',' file_base = ']
command_to_run = "mpirun -np "+str(n_proc)+" ~/projects/TMAP8/tmap8-opt -i val-flibe.i"

# Experimental data pressure and Temperature series
p_exp = np.array([1210,538,315,171,1210,538,315,1210,538,1210])
T_exp = np.array([700,700,700,700,650,650,650,600,600,550])


def run_terminal_command(command):
subprocess.run([command], shell=True, check=True)

def substitute_row(filename, search_string, replacement):
# Read the contents of the file
with open(filename, 'r') as file:
lines = file.readlines()
# Search for the row and substitute it
for i, line in enumerate(lines):
if search_string in line:
lines[i] = replacement + '\n' # Add a newline character for consistency
# Write the modified contents back to the file
with open(filename, 'w') as file:
file.writelines(lines)




# Names of output files for each case
output_fname = np.array([])
for p,T in zip(p_exp,T_exp):
output_fname = np.append(output_fname, 'val-flibe_'+str(p)+'_'+str(T))



for T,p,outName in zip(T_exp,p_exp,output_fname):
replacemens = ["T = '${units "+str(T)+" degC -> K}' # temperature", 'p_bnd = '+str(p)+' # pressure', " file_base = '"+outName+"'"]
substitute_row(filename, search_strings[0], replacemens[0])
substitute_row(filename, search_strings[1], replacemens[1])
substitute_row(filename, search_strings[2], replacemens[2])
# Run input file with new BCs
run_terminal_command(command_to_run)
print('########## Run at',p,'Pa and',T,'degC completed. ##########')
11 changes: 11 additions & 0 deletions test/tests/val-flibe/tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Tests]
design = 'ADMatDiffusion.md TimeDerivative.md InterfaceSorption.md EquilibriumBC.md ADDirichletBC.md'
issues = '#193'
[val-flibe]
type = CSVDiff
input = val-flibe.i
should_execute = True
csvdiff = val-flibe_out.csv
requirement = 'The system shall be able to model transient diffusion through a crucible containing molten salt with a constant concentration boundary condition as the species source.'
[]
[]
285 changes: 285 additions & 0 deletions test/tests/val-flibe/val-flibe.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
endtime = 140000 # simulation end time

R = 8.31446261815324 # Gas constant (from PhysicalConstants.h - https://physics.nist.gov/cgi-bin/cuu/Value?r)

T = '${units 550 degC -> K}' # temperature

p_bnd = 1210 # pressure

L_Ni = '${units 2 mm -> m}' # nickel thickness
L_salt = '${units 8.1 mm -> m}' # salt thickness

num_nodes = 200 # (-)

[Mesh]
[whole_domain]
type = GeneratedMeshGenerator
xmin = 0
xmax = '${fparse L_Ni + L_salt}'
dim = 1
nx = ${num_nodes}
[]
[block_1]
type = ParsedSubdomainMeshGenerator
input = whole_domain
combinatorial_geometry = 'x <= ${L_Ni}'
block_id = 0
[]
[block_2]
type = ParsedSubdomainMeshGenerator
input = block_1
combinatorial_geometry = 'x > ${L_Ni}'
block_id = 1
[]
[interface]
type = SideSetsBetweenSubdomainsGenerator
input = block_2
primary_block = '0' # Ni
paired_block = '1' # salt
new_boundary = 'interface'
[]
[interface_other_side]
type = SideSetsBetweenSubdomainsGenerator
input = interface
primary_block = '1' # salt
paired_block = '0' # Ni
new_boundary = 'interface_other'
[]
[]

[Variables]
[conc_Ni]
initial_condition = 0.9e-0
block = 0
[]
[conc_salt]
initial_condition = 0.3e-0
block = 1
[]
[]

[AuxVariables]
[enclosure_pressure]
family = SCALAR
initial_condition = ${p_bnd}
[]
[flux_x]
order = FIRST
family = MONOMIAL
[]
[p_div_RT_salt]
block = 1
initial_condition = 0.001
[]
[p_div_RT_Ni]
block = 0
initial_condition = 0.001
[]
[]

[Kernels]
[diff_Ni]
type = ADMatDiffusion
variable = conc_Ni
diffusivity = diffusivity_Ni
block = 0
[]
[diff_salt]
type = ADMatDiffusion
variable = conc_salt
diffusivity = diffusivity_salt
block = 1
[]
[time_diff_Ni]
type = TimeDerivative
variable = conc_Ni
block = 0
[]
[time_diff_salt]
type = TimeDerivative
variable = conc_salt
block = 1
[]
[]

[InterfaceKernels]
[tied]
type = InterfaceSorption
K0 = 0.564
Ea = 15800.0
n_sorption = 0.5
diffusivity = diffusivity_Ni_nonAD
unit_scale = 1
unit_scale_neighbor = 1
temperature = ${T}
variable = conc_Ni
neighbor_var = p_div_RT_salt
sorption_penalty = 0.1
boundary = 'interface'
[]
[]

[AuxKernels]
[flux_x_Ni]
type = DiffusionFluxAux
diffusivity = diffusivity_Ni
variable = flux_x
diffusion_variable = conc_Ni
component = x
block = 0
[]
[flux_x_salt]
type = DiffusionFluxAux
diffusivity = diffusivity_salt
variable = flux_x
diffusion_variable = conc_salt
component = x
block = 1
[]
[p_div_RT_Ni_kernel]
variable = p_div_RT_Ni
type = ParsedAux
expression = '(conc_Ni / (${R} * ${T} * 0.564 * exp(-15800/(${R}*${T}))))^2'
coupled_variables = 'conc_Ni'
[]
[p_div_RT_salt_kernel]
variable = p_div_RT_salt
type = ParsedAux
expression = '(conc_salt / (${R} * ${T} * 0.079 * exp(-35000/(${R}*${T}))))'
coupled_variables = 'conc_salt'
[]
[]

[BCs]
[left_flux]
type = EquilibriumBC
Ko = 0.564
activation_energy = 15800.0
boundary = left
enclosure_var = enclosure_pressure
temperature = ${T}
variable = conc_Ni
p = 0.5
[]
[right_flux]
type = ADDirichletBC
boundary = right
variable = conc_salt
value = 0.0
[]
[]

[Functions]
[diffusivity_Ni_func]
type = ParsedFunction
symbol_names = 'T'
symbol_values = '${T}'
expression = '0.0000007*exp(-39500/(${R}*T))'
[]

[diffusivity_salt_func]
type = ParsedFunction
symbol_names = 'T'
symbol_values = '${T}'
expression = '0.00000093*exp(-42000/(${R}*T))'
[]

[solubility_Ni_func]
type = ParsedFunction
symbol_names = 'T'
symbol_values = '${T}'
expression = '0.564 * exp(-15800/(${R}*T))'
[]

[solubility_salt_func]
type = ParsedFunction
symbol_names = 'T'
symbol_values = '${T}'
expression = '0.079 * exp(-35000/(${R}*T))'
[]
[]

[Materials]
[diff_solu]
type = ADGenericFunctionMaterial
prop_names = 'diffusivity_Ni diffusivity_salt solubility_Ni solubility_salt'
prop_values = 'diffusivity_Ni_func diffusivity_salt_func solubility_Ni_func solubility_salt_func'
outputs = all
[]
[converter_to_regular]
type = MaterialADConverter
ad_props_in = 'diffusivity_Ni diffusivity_salt'
reg_props_out = 'diffusivity_Ni_nonAD diffusivity_salt_nonAD'
[]
[]

[Postprocessors]
[avg_flux_right]
type = SideDiffusiveFluxAverage
variable = conc_salt
boundary = right
diffusivity = diffusivity_salt_nonAD
[]
[]

[Preconditioning]
[SMP]
type = SMP
full = true
[]
[]

[Executioner]
type = Transient
steady_state_detection = true
steady_state_start_time = 40000
steady_state_tolerance = 1e-9
scheme = bdf2 # bdf2 # crank-nicolson # explicit-euler
solve_type = NEWTON # LINEAR # JFNK # NEWTON
petsc_options = '-snes_ksp_ew'
petsc_options_iname = '-pc_type'
petsc_options_value = 'lu'
l_max_its = 10
nl_max_its = 13
nl_rel_tol = 1e-8 # nonlinear relative tolerance
nl_abs_tol = 1e-20 #1e-30 # nonlinear absolute tolerance
l_tol = 1e-6 # 1e-3 - 1e-5 # linear tolerance
end_time = ${endtime}
automatic_scaling = true
line_search = none
dtmax = 10.0
[TimeStepper]
type = IterationAdaptiveDT
dt = 1e-10
optimal_iterations = 18 # 6-10 or 18
growth_factor = 1.1
cutback_factor = 0.5
[]
[]

[Outputs]
execute_on = timestep_end
exodus = true
[csv]
type = CSV
file_base = 'val-flibe_1210_550'
time_step_interval = 500
[]
[]

[Dampers]
[limit_salt]
type = BoundingValueElementDamper
variable = conc_salt
max_value = 1e42
min_value = -0.01
min_damping = 0.001
[]
[limit_Ni]
type = BoundingValueElementDamper
variable = conc_Ni
max_value = 1e42
min_value = -0.01
min_damping = 0.001
[]
[]
Loading