- boundaryThe list of boundary IDs from the mesh where this object applies
C++ Type:std::vector<BoundaryName>
Controllable:No
Description:The list of boundary IDs from the mesh where this object applies
- fluxThe flux
C++ Type:MaterialPropertyName
Controllable:No
Description:The flux
- variableThe name of the variable that this residual object operates on
C++ Type:NonlinearVariableName
Controllable:No
Description:The name of the variable that this residual object operates on
OpenBC
The OpenBC has not been documented. The content listed below should be used as a starting point for documenting the class, which includes the typical automatic documentation associated with a MooseObject; however, what is contained is ultimately determined by what is necessary to make the documentation clear for users.
An open BC where matters can freely flow in and out.
Overview
Example Input File Syntax
Input Parameters
- displacementsThe displacements
C++ Type:std::vector<VariableName>
Controllable:No
Description:The displacements
- prop_getter_suffixAn optional suffix parameter that can be appended to any attempt to retrieve/get material properties. The suffix will be prepended with a '_' character.
C++ Type:MaterialPropertyName
Controllable:No
Description:An optional suffix parameter that can be appended to any attempt to retrieve/get material properties. The suffix will be prepended with a '_' character.
Optional Parameters
- absolute_value_vector_tagsThe tags for the vectors this residual object should fill with the absolute value of the residual contribution
C++ Type:std::vector<TagName>
Controllable:No
Description:The tags for the vectors this residual object should fill with the absolute value of the residual contribution
- extra_matrix_tagsThe extra tags for the matrices this Kernel should fill
C++ Type:std::vector<TagName>
Controllable:No
Description:The extra tags for the matrices this Kernel should fill
- extra_vector_tagsThe extra tags for the vectors this Kernel should fill
C++ Type:std::vector<TagName>
Controllable:No
Description:The extra tags for the vectors this Kernel should fill
- matrix_tagssystemThe tag for the matrices this Kernel should fill
Default:system
C++ Type:MultiMooseEnum
Options:nontime, system
Controllable:No
Description:The tag for the matrices this Kernel should fill
- vector_tagsnontimeThe tag for the vectors this Kernel should fill
Default:nontime
C++ Type:MultiMooseEnum
Options:nontime, time
Controllable:No
Description:The tag for the vectors this Kernel should fill
Tagging Parameters
- control_tagsAdds user-defined labels for accessing object parameters via control logic.
C++ Type:std::vector<std::string>
Controllable:No
Description:Adds user-defined labels for accessing object parameters via control logic.
- diag_save_inThe name of auxiliary variables to save this BC's diagonal jacobian contributions to. Everything about that variable must match everything about this variable (the type, what blocks it's on, etc.)
C++ Type:std::vector<AuxVariableName>
Controllable:No
Description:The name of auxiliary variables to save this BC's diagonal jacobian contributions to. Everything about that variable must match everything about this variable (the type, what blocks it's on, etc.)
- enableTrueSet the enabled status of the MooseObject.
Default:True
C++ Type:bool
Controllable:Yes
Description:Set the enabled status of the MooseObject.
- implicitTrueDetermines whether this object is calculated using an implicit or explicit form
Default:True
C++ Type:bool
Controllable:No
Description:Determines whether this object is calculated using an implicit or explicit form
- save_inThe name of auxiliary variables to save this BC's residual contributions to. Everything about that variable must match everything about this variable (the type, what blocks it's on, etc.)
C++ Type:std::vector<AuxVariableName>
Controllable:No
Description:The name of auxiliary variables to save this BC's residual contributions to. Everything about that variable must match everything about this variable (the type, what blocks it's on, etc.)
- seed0The seed for the master random number generator
Default:0
C++ Type:unsigned int
Controllable:No
Description:The seed for the master random number generator
- use_displaced_meshFalseWhether or not this object should use the displaced mesh for computation. Note that in the case this is true but no displacements are provided in the Mesh block the undisplaced mesh will still be used.
Default:False
C++ Type:bool
Controllable:No
Description:Whether or not this object should use the displaced mesh for computation. Note that in the case this is true but no displacements are provided in the Mesh block the undisplaced mesh will still be used.
Advanced Parameters
Input Files
(test/tests/chemical-electrical/diffusion_vs_migration.i)
m = 1 # larger m means more migration compared to diffusion
R = 8.3145 #mJ/mmol/K
F = 96485 #mC/mmol
I = 3e-3 #mA
width = 0.03 #mm
in = '${fparse -I/width}'
t0 = '${fparse -1e-2/in}'
dt = '${fparse t0/100}'
Vmax = 4.3 #V
vf_se = 0.3
vf_cp = 0.5
vf_ca = 0.2
sigma_a = 0.2 #mS/mm
sigma_se = 0.1 #mS/mm
sigma_cp = 0.05 #mS/mm
sigma_ca = 0.2 #mS/mm
sigma_e = ${sigma_se}
sigma_c = '${fparse vf_se*sigma_se + vf_cp*sigma_cp + vf_ca*sigma_ca}'
l0 = 0
l1 = 0.04
l2 = 0.07
l3 = 0.12
cmax = 1e-3 #mmol/mm^3
c0_a = 1e-4
c0_e = 5e-4
c0_c = 1e-3
M_a = 8e-11
M_se = '${fparse sigma_se/F/F/m}'
M_cp = 4e-14
M_ca = 1e-13
M_e = ${M_se}
M_c = '${fparse vf_se*M_se + vf_cp*M_cp + vf_ca*M_ca}'
T0 = 300 #K
i0_a = 1e-1 #mA/mm^2
i0_c = 1e-1 #mA/mm^2
[GlobalParams]
energy_densities = 'dot(psi_c) q zeta m'
[]
[Mesh]
[battery]
type = GeneratedMeshGenerator
dim = 2
xmin = ${l0}
xmax = ${l3}
ymin = 0
ymax = ${width}
nx = 60
ny = 15
[]
[anode]
type = SubdomainBoundingBoxGenerator
input = battery
block_id = 1
block_name = anode
bottom_left = '${l0} 0 0'
top_right = '${l1} ${width} 0'
[]
[elyte]
type = SubdomainBoundingBoxGenerator
input = anode
block_id = 2
block_name = elyte
bottom_left = '${l1} 0 0'
top_right = '${l2} ${width} 0'
[]
[cathode]
type = SubdomainBoundingBoxGenerator
input = elyte
block_id = 3
block_name = cathode
bottom_left = '${l2} 0 0'
top_right = '${l3} ${width} 0'
[]
[anode_elyte]
type = BreakMeshByBlockGenerator
input = cathode
block_pairs = '1 2'
add_interface_on_two_sides = true
split_interface = true
[]
[cathode_elyte]
type = BreakMeshByBlockGenerator
input = anode_elyte
block_pairs = '2 3'
add_interface_on_two_sides = true
split_interface = true
[]
[]
[Variables]
[Phi]
[]
[c]
[]
[]
[AuxVariables]
[c_ref]
[]
[T]
initial_condition = ${T0}
[]
[]
[ICs]
[c_a]
type = ConstantIC
variable = c
value = ${c0_a}
block = 'anode'
[]
[c_e]
type = ConstantIC
variable = c
value = ${c0_e}
block = 'elyte'
[]
[c_c]
type = ConstantIC
variable = c
value = ${c0_c}
block = 'cathode'
[]
[c_ref_a]
type = ConstantIC
variable = c_ref
value = ${c0_a}
block = 'anode'
[]
[c_ref_e]
type = ConstantIC
variable = c_ref
value = ${c0_e}
block = 'elyte'
[]
[c_ref_c]
type = ConstantIC
variable = c_ref
value = ${c0_c}
block = 'cathode'
[]
[]
[Kernels]
# Charge balance
[charge_balance]
type = RankOneDivergence
variable = Phi
vector = i
[]
# Mass balance
[mass_balance_1]
type = TimeDerivative
variable = c
[]
[mass_balance_2]
type = RankOneDivergence
variable = c
vector = j
[]
[]
[InterfaceKernels]
[negative_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
factor = -1
factor_neighbor = 1
boundary = 'cathode_elyte'
[]
[positive_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
boundary = 'anode_elyte'
[]
[]
[Functions]
[in]
type = PiecewiseLinear
x = '0 ${t0}'
y = '0 ${in}'
[]
[]
[BCs]
[left]
type = FunctionNeumannBC
variable = Phi
boundary = left
function = in
[]
[right]
type = DirichletBC
variable = Phi
boundary = right
value = 0
[]
[open]
type = OpenBC
variable = c
flux = jm
boundary = 'left right'
[]
[]
[Materials]
# Electrodynamics
[conductivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'sigma'
subdomain_to_prop_value = 'anode ${sigma_a} elyte ${sigma_e} cathode ${sigma_c}'
[]
[charge_transport]
type = BulkChargeTransport
electrical_energy_density = q
electric_potential = Phi
electric_conductivity = sigma
temperature = T
[]
[current_density]
type = CurrentDensity
current_density = i
electric_potential = Phi
[]
# Migration
[migration]
type = Migration
electrochemical_energy_density = m
electric_potential = Phi
chemical_potential = mu
electric_conductivity = sigma
faraday_constant = ${F}
[]
[migration_flux]
type = MassFlux
mass_flux = jm
energy_densities = 'm'
chemical_potential = mu
[]
# Chemical reactions
[diffusivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'M'
subdomain_to_prop_value = 'anode ${M_a} elyte ${M_e} cathode ${M_c}'
[]
[chemical_energy]
type = EntropicChemicalEnergyDensity
chemical_energy_density = psi_c
concentration = c
ideal_gas_constant = ${R}
temperature = T
reference_concentration = c_ref
reference_chemical_potential = 1e3
[]
[chemical_potential]
type = ChemicalPotential
chemical_potential = mu
concentration = c
[]
[diffusion]
type = MassDiffusion
dual_chemical_energy_density = zeta
chemical_potential = mu
mobility = M
[]
[mass_flux]
type = MassFlux
mass_flux = j
chemical_potential = mu
[]
# Redox
[ramp]
type = ADGenericFunctionMaterial
prop_names = 'ramp'
prop_values = 'if(t<${t0},t/${t0},1)'
[]
[OCP_anode_graphite]
type = ADParsedMaterial
property_name = U
expression = 'x:=c/${cmax}; -(122.12*x^6-321.81*x^5+315.59*x^4-141.26*x^3+28.218*x^2-1.9057*x+0.0785)*ramp'
coupled_variables = c
material_property_names = 'ramp'
boundary = 'anode_elyte'
[]
[OCP_cathode_NMC111]
type = ADParsedMaterial
property_name = U
expression = 'x:=c/${cmax}; (6.0826-6.9922*x+7.1062*x^2-5.4549e-5*exp(124.23*x-114.2593)-2.5947*x^3)*ramp'
coupled_variables = c
material_property_names = 'ramp'
boundary = 'cathode_elyte'
[]
[charge_transfer_anode_elyte]
type = ChargeTransferReaction
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_a}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'anode_elyte'
[]
[charge_transfer_cathode_elyte]
type = ChargeTransferReaction
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_c}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'cathode_elyte'
[]
[]
[Postprocessors]
[V_l]
type = SideAverageValue
variable = Phi
boundary = left
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V_r]
type = SideAverageValue
variable = Phi
boundary = right
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V]
type = ParsedPostprocessor
function = 'V_r - V_l'
pp_names = 'V_l V_r'
execute_on = 'INITIAL TIMESTEP_END'
[]
[in]
type = FunctionValuePostprocessor
function = in
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[dt]
type = TimestepSize
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[dC]
type = ParsedPostprocessor
function = '-dt*in*${width}'
pp_names = 'dt in'
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[C]
type = CumulativeValuePostprocessor
postprocessor = dC
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_a_max]
type = NodalExtremeValue
variable = c
value_type = max
block = anode
[]
[c_c_min]
type = NodalExtremeValue
variable = c
value_type = min
block = cathode
[]
[mass_a]
type = ElementIntegralVariablePostprocessor
variable = c
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_e]
type = ElementIntegralVariablePostprocessor
variable = c
block = elyte
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_c]
type = ElementIntegralVariablePostprocessor
variable = c
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[]
[UserObjects]
[kill]
type = Terminator
expression = 'V >= ${Vmax}'
message = 'Voltage reached Vmax'
[]
[]
[Executioner]
type = Transient
solve_type = NEWTON
petsc_options_iname = '-pc_type'
petsc_options_value = 'lu'
automatic_scaling = true
line_search = none
nl_rel_tol = 1e-6
nl_abs_tol = 1e-10
nl_max_its = 20
l_max_its = 150
[Predictor]
type = SimplePredictor
scale = 1
skip_after_failed_timestep = true
[]
[TimeStepper]
type = IterationAdaptiveDT
dt = ${dt}
optimal_iterations = 7
iteration_window = 2
growth_factor = 1.2
cutback_factor = 0.5
cutback_factor_at_failure = 0.2
linear_iteration_ratio = 1000000
[]
dtmax = 1
end_time = 100000
[]
[Outputs]
file_base = 'diffusion_vs_migration'
exodus = true
print_linear_residuals = false
[]
(examples/LiB/CC_discharging.i)
I = 3e-3 #mA
width = 0.03 #mm
in = '${fparse I/width}'
t0 = '${fparse 1e-2/in}'
dt = '${fparse t0/100}'
sigma_a = 1e0 #mS/mm
sigma_e = 1e-1 #mS/mm
sigma_c = 1e-2 #mS/mm
l0 = 0
l1 = 0.04
l2 = 0.07
l3 = 0.12
cmin = 1e-4 #mmol/mm^3
cmax = 1e-3 #mmol/mm^3
D_a = 1e-3 #mm^2/s
D_e = 1e-4 #mm^2/s
D_c = 5e-5 #mm^2/s
R = 8.3145 #mJ/mmol/K
T0 = 300 #K
F = 96485 #mC/mmol
i0_a = 1e-1 #mA/mm^2
i0_c = 1e-1 #mA/mm^2
E_c = 1e5
E_e = 1e4
E_a = 2e5
nu_c = 0.3
nu_e = 0.25
nu_a = 0.3
u_penalty = 1e8
Omega = 60
beta = 1e-3
CTE = 1e-5
rho = 2.5e-9 #Mg/mm^3
cv = 2.7e8 #mJ/Mg/K
kappa = 2e-4 #mJ/mm/K/s
T_penalty = 2e-1
[GlobalParams]
energy_densities = 'dot(psi_m) dot(psi_c) chi q zeta m'
deformation_gradient = F
mechanical_deformation_gradient = Fm
eigen_deformation_gradient = Fg
swelling_deformation_gradient = Fs
thermal_deformation_gradient = Ft
[]
[Problem]
restart_file_base = 'CV_charging_I_${I}_cp/LATEST'
[]
[Mesh]
[battery]
type = GeneratedMeshGenerator
dim = 2
xmin = ${l0}
xmax = ${l3}
ymin = 0
ymax = ${width}
nx = 60
ny = 15
[]
[anode]
type = SubdomainBoundingBoxGenerator
input = battery
block_id = 1
block_name = anode
bottom_left = '${l0} 0 0'
top_right = '${l1} ${width} 0'
[]
[elyte]
type = SubdomainBoundingBoxGenerator
input = anode
block_id = 2
block_name = elyte
bottom_left = '${l1} 0 0'
top_right = '${l2} ${width} 0'
[]
[cathode]
type = SubdomainBoundingBoxGenerator
input = elyte
block_id = 3
block_name = cathode
bottom_left = '${l2} 0 0'
top_right = '${l3} ${width} 0'
[]
[interfaces]
type = BreakMeshByBlockGenerator
input = cathode
add_interface_on_two_sides = true
split_interface = true
[]
[]
[Variables]
[Phi]
[]
[c]
[]
[disp_x]
[]
[disp_y]
[]
[T]
[]
[]
[AuxVariables]
[c_ref]
[]
[T_ref]
initial_condition = ${T0}
[]
[Phi0]
[]
[]
[ICs]
[c_ref_min]
type = ConstantIC
variable = c_ref
value = ${cmin}
block = 'anode'
[]
[c_ref_mid]
type = ConstantIC
variable = c_ref
value = '${fparse (cmax+cmin)/2}'
block = 'elyte'
[]
[c_ref_max]
type = ConstantIC
variable = c_ref
value = ${cmax}
block = 'cathode'
[]
[]
[Kernels]
# Charge balance
[charge_balance]
type = RankOneDivergence
variable = Phi
vector = i
[]
# Mass balance
[mass_balance_1]
type = TimeDerivative
variable = c
[]
[mass_balance_2]
type = RankOneDivergence
variable = c
vector = j
[]
# Momentum balance
[momentum_balance_x]
type = RankTwoDivergence
variable = disp_x
component = 0
tensor = pk1
factor = -1
[]
[momentum_balance_y]
type = RankTwoDivergence
variable = disp_y
component = 1
tensor = pk1
factor = -1
[]
# Energy balance
[energy_balance_1]
type = EnergyBalanceTimeDerivative
variable = T
density = rho
specific_heat = cv
[]
[energy_balance_2]
type = RankOneDivergence
variable = T
vector = h
[]
[heat_source]
type = MaterialSource
variable = T
prop = r
coefficient = -1
[]
[]
[InterfaceKernels]
[negative_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
factor = -1
boundary = 'elyte_anode cathode_elyte'
[]
[positive_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
boundary = 'anode_elyte elyte_cathode'
[]
[heat]
type = MaterialInterfaceNeumannBC
variable = T
neighbor_var = T
prop = he
factor = 1
boundary = 'anode_elyte elyte_cathode elyte_anode cathode_elyte'
[]
[continuity_disp_x]
type = InterfaceContinuity
variable = disp_x
neighbor_var = disp_x
penalty = ${u_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[continuity_disp_y]
type = InterfaceContinuity
variable = disp_y
neighbor_var = disp_y
penalty = ${u_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[continuity_T]
type = InterfaceContinuity
variable = T
neighbor_var = T
penalty = ${T_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[]
[Functions]
[in]
type = PiecewiseLinear
x = '0 ${t0}'
y = '0 ${in}'
[]
[]
[BCs]
[left]
type = FunctionNeumannBC
variable = Phi
boundary = left
function = in
[]
[right]
type = DirichletBC
variable = Phi
boundary = right
value = 0
[]
[fix_x]
type = DirichletBC
variable = disp_x
value = 0
boundary = 'left right'
[]
[fix_y]
type = DirichletBC
variable = disp_y
value = 0
boundary = 'bottom'
[]
[open]
type = OpenBC
variable = c
flux = jm
boundary = 'left right'
[]
[]
[Constraints]
[y]
type = EqualValueBoundaryConstraint
variable = disp_y
penalty = ${u_penalty}
secondary = top
[]
[]
[Materials]
# Electrodynamics
[conductivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'sigma'
subdomain_to_prop_value = 'anode ${sigma_a} elyte ${sigma_e} cathode ${sigma_c}'
[]
[charge_transport]
type = BulkChargeTransport
electrical_energy_density = q
electric_potential = Phi
electric_conductivity = sigma
temperature = T
[]
[current_density]
type = CurrentDensity
current_density = i
electric_potential = Phi
[]
# Chemical reactions
[diffusivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'D'
subdomain_to_prop_value = 'anode ${D_a} elyte ${D_e} cathode ${D_c}'
[]
[mobility]
type = ADParsedMaterial
f_name = M
args = 'c_ref T_ref'
material_property_names = 'D'
function = 'D*c_ref/${R}/T_ref'
[]
[chemical_energy]
type = EntropicChemicalEnergyDensity
chemical_energy_density = psi_c
concentration = c
ideal_gas_constant = ${R}
temperature = T
reference_concentration = c_ref
[]
[chemical_potential]
type = ChemicalPotential
chemical_potential = mu
concentration = c
[]
[diffusion]
type = MassDiffusion
dual_chemical_energy_density = zeta
chemical_potential = mu
mobility = M
[]
[mass_flux]
type = MassFlux
mass_flux = j
chemical_potential = mu
[]
# Migration
[migration]
type = Migration
electrochemical_energy_density = m
electric_potential = Phi
chemical_potential = mu
electric_conductivity = sigma
faraday_constant = ${F}
[]
[migration_flux]
type = MassFlux
mass_flux = jm
energy_densities = 'm'
chemical_potential = mu
[]
# Redox
[OCP_anode_graphite]
type = ADParsedMaterial
f_name = U
function = 'x:=c/${cmax}; -(122.12*x^6-321.81*x^5+315.59*x^4-141.26*x^3+28.218*x^2-1.9057*x+0.0785)'
args = c
block = 'anode'
[]
[OCP_cathode_NMC111]
type = ADParsedMaterial
f_name = U
function = 'x:=c/${cmax}; (6.0826-6.9922*x+7.1062*x^2-5.4549e-5*exp(124.23*x-114.2593)-2.5947*x^3)'
args = c
block = 'cathode'
[]
[charge_transfer_anode_elyte]
type = ChargeTransferReaction
electrode = true
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_a}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'anode_elyte'
[]
[charge_transfer_elyte_anode]
type = ChargeTransferReaction
electrode = false
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_a}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'elyte_anode'
[]
[charge_transfer_cathode_elyte]
type = ChargeTransferReaction
electrode = true
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_c}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'cathode_elyte'
[]
[charge_transfer_elyte_cathode]
type = ChargeTransferReaction
electrode = false
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_c}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'elyte_cathode'
[]
# Thermal
[thermal_properties]
type = ADGenericConstantMaterial
prop_names = 'rho cv kappa'
prop_values = '${rho} ${cv} ${kappa}'
[]
[heat_conduction]
type = FourierPotential
thermal_energy_density = chi
thermal_conductivity = kappa
temperature = T
[]
[heat_flux]
type = HeatFlux
heat_flux = h
temperature = T
[]
[heat_source]
type = VariationalHeatSource
heat_source = r
temperature = T
[]
# Mechanical
[stiffness_c]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_c*nu_c/(1+nu_c)/(1-2*nu_c)} ${fparse E_c/2/(1+nu_c)}'
block = cathode
[]
[stiffness_e]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_e*nu_e/(1+nu_e)/(1-2*nu_e)} ${fparse E_e/2/(1+nu_e)}'
block = elyte
[]
[stiffness_a]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_a*nu_a/(1+nu_a)/(1-2*nu_a)} ${fparse E_a/2/(1+nu_a)}'
block = anode
[]
[swelling_coefficient]
type = ADGenericConstantMaterial
prop_names = 'beta'
prop_values = '${beta}'
[]
[swelling]
type = SwellingDeformationGradient
concentration = c
reference_concentration = c_ref
molar_volume = ${Omega}
swelling_coefficient = beta
[]
[thermal_expansion]
type = ThermalDeformationGradient
temperature = T
reference_temperature = T_ref
CTE = ${CTE}
[]
[defgrad]
type = MechanicalDeformationGradient
displacements = 'disp_x disp_y'
[]
[neohookean]
type = NeoHookeanSolid
elastic_energy_density = psi_m
lambda = lambda
shear_modulus = G
concentration = c
temperature = T
[]
[pk1]
type = FirstPiolaKirchhoffStress
first_piola_kirchhoff_stress = pk1
deformation_gradient_rate = dot(F)
[]
[]
[Postprocessors]
[V_l]
type = SideAverageValue
variable = Phi
boundary = left
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V_r]
type = SideAverageValue
variable = Phi
boundary = right
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V]
type = ParsedPostprocessor
function = 'V_r - V_l'
pp_names = 'V_l V_r'
execute_on = 'INITIAL TIMESTEP_END'
[]
[I]
type = ADSideIntegralMaterialProperty
property = i
component = 0
boundary = right
execute_on = 'INITIAL TIMESTEP_END'
[]
[dt]
type = TimestepSize
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[dC]
type = ParsedPostprocessor
function = '-dt*I'
pp_names = 'dt I'
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[C]
type = CumulativeValuePostprocessor
postprocessor = dC
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_a_max]
type = NodalExtremeValue
variable = c
value_type = max
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_c_min]
type = NodalExtremeValue
variable = c
value_type = min
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_a_min]
type = NodalExtremeValue
variable = c
value_type = min
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_c_max]
type = NodalExtremeValue
variable = c
value_type = max
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_a]
type = ElementIntegralVariablePostprocessor
variable = c
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_e]
type = ElementIntegralVariablePostprocessor
variable = c
block = elyte
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_c]
type = ElementIntegralVariablePostprocessor
variable = c
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[]
[UserObjects]
[kill_a]
type = Terminator
expression = 'c_a_min <= ${cmin}'
message = 'Concentration in anode is below the minimum allowable value.'
[]
[kill_c]
type = Terminator
expression = 'c_c_max >= ${cmax}'
message = 'Concentration in cathode exceeds the maximum allowable value.'
[]
[]
[Executioner]
type = Transient
solve_type = NEWTON
petsc_options_iname = '-pc_type'
petsc_options_value = 'lu'
automatic_scaling = true
nl_rel_tol = 1e-6
nl_abs_tol = 1e-10
nl_max_its = 20
[Predictor]
type = SimplePredictor
scale = 1
skip_after_failed_timestep = true
[]
[TimeStepper]
type = IterationAdaptiveDT
dt = ${dt}
optimal_iterations = 7
iteration_window = 2
growth_factor = 1.2
cutback_factor = 0.5
cutback_factor_at_failure = 0.2
linear_iteration_ratio = 1000000
[]
start_time = 0
end_time = 100000
[]
[Outputs]
file_base = 'CC_discharging_I_${I}'
csv = true
exodus = true
print_linear_residuals = false
checkpoint = true
[]
(test/tests/chemical-electrical-thermal/thermal_effects.i)
R = 8.3145 #mJ/mmol/K
F = 96485 #mC/mmol
I = 3e-3 #mA
width = 0.03 #mm
in = '${fparse -I/width}'
t0 = '${fparse -1e-2/in}'
dt = '${fparse t0/100}'
Vmax = 4.3 #V
vf_se = 0.3
vf_cp = 0.5
vf_ca = 0.2
sigma_a = 0.2 #mS/mm
sigma_se = 0.1 #mS/mm
sigma_cp = 0.05 #mS/mm
sigma_ca = 0.2 #mS/mm
sigma_e = ${sigma_se}
sigma_c = '${fparse vf_se*sigma_se + vf_cp*sigma_cp + vf_ca*sigma_ca}'
l0 = 0
l1 = 0.04
l2 = 0.07
l3 = 0.12
cmax = 1e-3 #mmol/mm^3
c0_a = 1e-4
c0_e = 5e-4
c0_c = 1e-3
M_a = 8e-11
M_se = 1e-11
M_cp = 4e-14
M_ca = 1e-13
M_e = ${M_se}
M_c = '${fparse vf_se*M_se + vf_cp*M_cp + vf_ca*M_ca}'
T0 = 300 #K
i0_a = 0.1 #mA/mm^2
i0_c = 0.1 #mA/mm^2
rho = 2.5e-9 #Mg/mm^3
cv = 2.7e8 #mJ/Mg/K
kappa = 2e-4 #mJ/mm/K/s
hconv = 9.5e-3 #mJ/mm^2/K/s
T_penalty = 2e-1
[GlobalParams]
energy_densities = 'dot(psi_c) q zeta chi m'
[]
[Mesh]
[battery]
type = GeneratedMeshGenerator
dim = 2
xmin = ${l0}
xmax = ${l3}
ymin = 0
ymax = ${width}
nx = 60
ny = 15
[]
[anode]
type = SubdomainBoundingBoxGenerator
input = battery
block_id = 1
block_name = anode
bottom_left = '${l0} 0 0'
top_right = '${l1} ${width} 0'
[]
[elyte]
type = SubdomainBoundingBoxGenerator
input = anode
block_id = 2
block_name = elyte
bottom_left = '${l1} 0 0'
top_right = '${l2} ${width} 0'
[]
[cathode]
type = SubdomainBoundingBoxGenerator
input = elyte
block_id = 3
block_name = cathode
bottom_left = '${l2} 0 0'
top_right = '${l3} ${width} 0'
[]
[anode_elyte]
type = BreakMeshByBlockGenerator
input = cathode
block_pairs = '1 2'
add_interface_on_two_sides = true
split_interface = true
[]
[cathode_elyte]
type = BreakMeshByBlockGenerator
input = anode_elyte
block_pairs = '2 3'
add_interface_on_two_sides = true
split_interface = true
[]
[]
[Variables]
[Phi]
[]
[c]
[]
[T]
initial_condition = ${T0}
[]
[]
[AuxVariables]
[c_ref]
[]
[T_ref]
initial_condition = ${T0}
[]
[]
[ICs]
[c_a]
type = ConstantIC
variable = c
value = ${c0_a}
block = 'anode'
[]
[c_e]
type = ConstantIC
variable = c
value = ${c0_e}
block = 'elyte'
[]
[c_c]
type = ConstantIC
variable = c
value = ${c0_c}
block = 'cathode'
[]
[c_ref_a]
type = ConstantIC
variable = c_ref
value = ${c0_a}
block = 'anode'
[]
[c_ref_e]
type = ConstantIC
variable = c_ref
value = ${c0_e}
block = 'elyte'
[]
[c_ref_c]
type = ConstantIC
variable = c_ref
value = ${c0_c}
block = 'cathode'
[]
[]
[Kernels]
# Charge balance
[charge_balance]
type = RankOneDivergence
variable = Phi
vector = i
[]
# Mass balance
[mass_balance_1]
type = TimeDerivative
variable = c
[]
[mass_balance_2]
type = RankOneDivergence
variable = c
vector = j
[]
# Energy balance
[energy_balance_1]
type = EnergyBalanceTimeDerivative
variable = T
density = rho
specific_heat = cv
[]
[energy_balance_2]
type = RankOneDivergence
variable = T
vector = h
[]
[heat_source]
type = MaterialSource
variable = T
prop = r
coefficient = -1
[]
[]
[InterfaceKernels]
[negative_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
factor = -1
factor_neighbor = 1
boundary = 'cathode_elyte'
[]
[positive_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
boundary = 'anode_elyte'
[]
[heat]
type = MaterialInterfaceNeumannBC
variable = T
neighbor_var = T
prop = he
factor = 1
factor_neighbor = 1
boundary = 'anode_elyte cathode_elyte'
[]
[continuity_T]
type = InterfaceContinuity
variable = T
neighbor_var = T
penalty = ${T_penalty}
boundary = 'anode_elyte cathode_elyte'
[]
[]
[Functions]
[in]
type = PiecewiseLinear
x = '0 ${t0}'
y = '0 ${in}'
[]
[]
[BCs]
[left]
type = FunctionNeumannBC
variable = Phi
boundary = left
function = in
[]
[right]
type = DirichletBC
variable = Phi
boundary = right
value = 0
[]
[open]
type = OpenBC
variable = c
flux = jm
boundary = 'left right'
[]
[hconv]
type = ADMatNeumannBC
variable = T
boundary = 'left right'
value = -1
boundary_material = qconv
[]
[]
[Materials]
# Electrodynamics
[conductivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'sigma'
subdomain_to_prop_value = 'anode ${sigma_a} elyte ${sigma_e} cathode ${sigma_c}'
[]
[charge_transport]
type = BulkChargeTransport
electrical_energy_density = q
electric_potential = Phi
electric_conductivity = sigma
temperature = T
[]
[current_density]
type = CurrentDensity
current_density = i
electric_potential = Phi
[]
# Migration
[migration]
type = Migration
electrochemical_energy_density = m
electric_potential = Phi
chemical_potential = mu
electric_conductivity = sigma
faraday_constant = ${F}
[]
[migration_flux]
type = MassFlux
mass_flux = jm
energy_densities = 'm'
chemical_potential = mu
[]
# Chemical reactions
[diffusivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'M'
subdomain_to_prop_value = 'anode ${M_a} elyte ${M_e} cathode ${M_c}'
[]
[chemical_energy]
type = EntropicChemicalEnergyDensity
chemical_energy_density = psi_c
concentration = c
ideal_gas_constant = ${R}
temperature = T
reference_concentration = c_ref
reference_chemical_potential = 1e3
[]
[chemical_potential]
type = ChemicalPotential
chemical_potential = mu
concentration = c
[]
[diffusion]
type = MassDiffusion
dual_chemical_energy_density = zeta
chemical_potential = mu
mobility = M
[]
[mass_flux]
type = MassFlux
mass_flux = j
chemical_potential = mu
[]
# Redox
[ramp]
type = ADGenericFunctionMaterial
prop_names = 'ramp'
prop_values = 'if(t<${t0},t/${t0},1)'
[]
[OCP_anode_graphite]
type = ADParsedMaterial
property_name = U
expression = 'x:=c/${cmax}; -(122.12*x^6-321.81*x^5+315.59*x^4-141.26*x^3+28.218*x^2-1.9057*x+0.0785)*ramp'
coupled_variables = c
material_property_names = 'ramp'
boundary = 'anode_elyte'
[]
[OCP_cathode_NMC111]
type = ADParsedMaterial
property_name = U
expression = 'x:=c/${cmax}; (6.0826-6.9922*x+7.1062*x^2-5.4549e-5*exp(124.23*x-114.2593)-2.5947*x^3)*ramp'
coupled_variables = c
material_property_names = 'ramp'
boundary = 'cathode_elyte'
[]
[charge_transfer_anode_elyte]
type = ChargeTransferReaction
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_a}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'anode_elyte'
[]
[charge_transfer_cathode_elyte]
type = ChargeTransferReaction
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_c}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'cathode_elyte'
[]
# Thermal
[thermal_properties]
type = ADGenericConstantMaterial
prop_names = 'rho cv kappa'
prop_values = '${rho} ${cv} ${kappa}'
[]
[heat_conduction]
type = FourierPotential
thermal_energy_density = chi
thermal_conductivity = kappa
temperature = T
[]
[heat_flux]
type = HeatFlux
heat_flux = h
temperature = T
[]
[heat_source]
type = VariationalHeatSource
heat_source = r
temperature = T
[]
[qconv]
type = ADParsedMaterial
property_name = qconv
expression = 'htc*(T-T_inf)'
coupled_variables = 'T'
constant_names = 'htc T_inf'
constant_expressions = '${hconv} ${T0}'
boundary = 'left right'
[]
[enthalpy]
type = ADParsedMaterial
f_name = enthalpy
function = 'rho*cv*(T-T_ref)'
args = 'T T_ref'
material_property_names = 'rho cv'
[]
[]
[Postprocessors]
[V_l]
type = SideAverageValue
variable = Phi
boundary = left
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V_r]
type = SideAverageValue
variable = Phi
boundary = right
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V]
type = ParsedPostprocessor
function = 'V_r - V_l'
pp_names = 'V_l V_r'
execute_on = 'INITIAL TIMESTEP_END'
[]
[in]
type = FunctionValuePostprocessor
function = in
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[dt]
type = TimestepSize
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[dC]
type = ParsedPostprocessor
function = '-dt*in*${width}'
pp_names = 'dt in'
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[C]
type = CumulativeValuePostprocessor
postprocessor = dC
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_a_max]
type = NodalExtremeValue
variable = c
value_type = max
block = anode
[]
[c_c_min]
type = NodalExtremeValue
variable = c
value_type = min
block = cathode
[]
[mass_a]
type = ElementIntegralVariablePostprocessor
variable = c
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_e]
type = ElementIntegralVariablePostprocessor
variable = c
block = elyte
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_c]
type = ElementIntegralVariablePostprocessor
variable = c
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[H_a]
type = ADElementIntegralMaterialProperty
mat_prop = enthalpy
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[H_e]
type = ADElementIntegralMaterialProperty
mat_prop = enthalpy
block = elyte
execute_on = 'INITIAL TIMESTEP_END'
[]
[H_c]
type = ADElementIntegralMaterialProperty
mat_prop = enthalpy
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[]
[UserObjects]
[kill]
type = Terminator
expression = 'V >= ${Vmax}'
message = 'Voltage reached Vmax'
[]
[]
[Executioner]
type = Transient
solve_type = NEWTON
petsc_options_iname = '-pc_type'
petsc_options_value = 'lu'
automatic_scaling = true
line_search = none
nl_rel_tol = 1e-6
nl_abs_tol = 1e-10
nl_max_its = 20
l_max_its = 150
[Predictor]
type = SimplePredictor
scale = 1
skip_after_failed_timestep = true
[]
[TimeStepper]
type = IterationAdaptiveDT
dt = ${dt}
optimal_iterations = 7
iteration_window = 2
growth_factor = 1.2
cutback_factor = 0.5
cutback_factor_at_failure = 0.2
linear_iteration_ratio = 1000000
[]
dtmax = 1
end_time = 100000
[]
[Outputs]
exodus = true
print_linear_residuals = false
[]
(examples/LiB/CC_charging.i)
I = 3e-3 #mA
width = 0.03 #mm
in = '${fparse -I/width}'
t0 = '${fparse -1e-2/in}'
dt = '${fparse t0/100}'
sigma_a = 1e0 #mS/mm
sigma_e = 1e-1 #mS/mm
sigma_c = 1e-2 #mS/mm
l0 = 0
l1 = 0.04
l2 = 0.07
l3 = 0.12
cmin = 1e-4 #mmol/mm^3
cmax = 1e-3 #mmol/mm^3
D_a = 1e-3 #mm^2/s
D_e = 1e-4 #mm^2/s
D_c = 5e-5 #mm^2/s
R = 8.3145 #mJ/mmol/K
T0 = 300 #K
F = 96485 #mC/mmol
i0_a = 1e-1 #mA/mm^2
i0_c = 1e-1 #mA/mm^2
E_c = 1e5
E_e = 1e4
E_a = 2e5
nu_c = 0.3
nu_e = 0.25
nu_a = 0.3
u_penalty = 1e8
Omega = 60
beta = 1e-3
CTE = 1e-5
rho = 2.5e-9 #Mg/mm^3
cv = 2.7e8 #mJ/Mg/K
kappa = 2e-4 #mJ/mm/K/s
T_penalty = 2e-1
[GlobalParams]
energy_densities = 'dot(psi_m) dot(psi_c) chi q zeta m'
deformation_gradient = F
mechanical_deformation_gradient = Fm
eigen_deformation_gradient = Fg
swelling_deformation_gradient = Fs
thermal_deformation_gradient = Ft
[]
[Mesh]
[battery]
type = GeneratedMeshGenerator
dim = 2
xmin = ${l0}
xmax = ${l3}
ymin = 0
ymax = ${width}
nx = 60
ny = 15
[]
[anode]
type = SubdomainBoundingBoxGenerator
input = battery
block_id = 1
block_name = anode
bottom_left = '${l0} 0 0'
top_right = '${l1} ${width} 0'
[]
[elyte]
type = SubdomainBoundingBoxGenerator
input = anode
block_id = 2
block_name = elyte
bottom_left = '${l1} 0 0'
top_right = '${l2} ${width} 0'
[]
[cathode]
type = SubdomainBoundingBoxGenerator
input = elyte
block_id = 3
block_name = cathode
bottom_left = '${l2} 0 0'
top_right = '${l3} ${width} 0'
[]
[interfaces]
type = BreakMeshByBlockGenerator
input = cathode
add_interface_on_two_sides = true
split_interface = true
[]
[]
[Variables]
[Phi]
[]
[c]
[]
[disp_x]
[]
[disp_y]
[]
[T]
initial_condition = ${T0}
[]
[]
[AuxVariables]
[c_ref]
[]
[T_ref]
initial_condition = ${T0}
[]
[]
[ICs]
[c_min]
type = ConstantIC
variable = c
value = ${cmin}
block = 'anode'
[]
[c_mid]
type = ConstantIC
variable = c
value = '${fparse (cmax+cmin)/2}'
block = 'elyte'
[]
[c_max]
type = ConstantIC
variable = c
value = ${cmax}
block = 'cathode'
[]
[c_ref_min]
type = ConstantIC
variable = c_ref
value = ${cmin}
block = 'anode'
[]
[c_ref_mid]
type = ConstantIC
variable = c_ref
value = '${fparse (cmax+cmin)/2}'
block = 'elyte'
[]
[c_ref_max]
type = ConstantIC
variable = c_ref
value = ${cmax}
block = 'cathode'
[]
[]
[Kernels]
# Charge balance
[charge_balance]
type = RankOneDivergence
variable = Phi
vector = i
[]
# Mass balance
[mass_balance_1]
type = TimeDerivative
variable = c
[]
[mass_balance_2]
type = RankOneDivergence
variable = c
vector = j
[]
# Momentum balance
[momentum_balance_x]
type = RankTwoDivergence
variable = disp_x
component = 0
tensor = pk1
factor = -1
[]
[momentum_balance_y]
type = RankTwoDivergence
variable = disp_y
component = 1
tensor = pk1
factor = -1
[]
# Energy balance
[energy_balance_1]
type = EnergyBalanceTimeDerivative
variable = T
density = rho
specific_heat = cv
[]
[energy_balance_2]
type = RankOneDivergence
variable = T
vector = h
[]
[heat_source]
type = MaterialSource
variable = T
prop = r
coefficient = -1
[]
[]
[InterfaceKernels]
[negative_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
factor = -1
boundary = 'elyte_anode cathode_elyte'
[]
[positive_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
boundary = 'anode_elyte elyte_cathode'
[]
[heat]
type = MaterialInterfaceNeumannBC
variable = T
neighbor_var = T
prop = he
factor = 1
boundary = 'anode_elyte elyte_cathode elyte_anode cathode_elyte'
[]
[continuity_disp_x]
type = InterfaceContinuity
variable = disp_x
neighbor_var = disp_x
penalty = ${u_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[continuity_disp_y]
type = InterfaceContinuity
variable = disp_y
neighbor_var = disp_y
penalty = ${u_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[continuity_T]
type = InterfaceContinuity
variable = T
neighbor_var = T
penalty = ${T_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[]
[Functions]
[in]
type = PiecewiseLinear
x = '0 ${t0}'
y = '0 ${in}'
[]
[]
[BCs]
[left]
type = FunctionNeumannBC
variable = Phi
boundary = left
function = in
[]
[right]
type = DirichletBC
variable = Phi
boundary = right
value = 0
[]
[fix_x]
type = DirichletBC
variable = disp_x
value = 0
boundary = 'left right'
[]
[fix_y]
type = DirichletBC
variable = disp_y
value = 0
boundary = 'bottom'
[]
[open]
type = OpenBC
variable = c
flux = jm
boundary = 'left right'
[]
[]
[Constraints]
[y]
type = EqualValueBoundaryConstraint
variable = disp_y
penalty = ${u_penalty}
secondary = top
[]
[]
[Materials]
# Electrodynamics
[conductivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'sigma'
subdomain_to_prop_value = 'anode ${sigma_a} elyte ${sigma_e} cathode ${sigma_c}'
[]
[charge_transport]
type = BulkChargeTransport
electrical_energy_density = q
electric_potential = Phi
electric_conductivity = sigma
temperature = T
[]
[current_density]
type = CurrentDensity
current_density = i
electric_potential = Phi
[]
# Chemical reactions
[diffusivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'D'
subdomain_to_prop_value = 'anode ${D_a} elyte ${D_e} cathode ${D_c}'
[]
[mobility]
type = ADParsedMaterial
f_name = M
args = 'c_ref T_ref'
material_property_names = 'D'
function = 'D*c_ref/${R}/T_ref'
[]
[chemical_energy]
type = EntropicChemicalEnergyDensity
chemical_energy_density = psi_c
concentration = c
ideal_gas_constant = ${R}
temperature = T
reference_concentration = c_ref
[]
[chemical_potential]
type = ChemicalPotential
chemical_potential = mu
concentration = c
[]
[diffusion]
type = MassDiffusion
dual_chemical_energy_density = zeta
chemical_potential = mu
mobility = M
[]
[mass_flux]
type = MassFlux
mass_flux = j
chemical_potential = mu
[]
# Migration
[migration]
type = Migration
electrochemical_energy_density = m
electric_potential = Phi
chemical_potential = mu
electric_conductivity = sigma
faraday_constant = ${F}
[]
[migration_flux]
type = MassFlux
mass_flux = jm
energy_densities = 'm'
chemical_potential = mu
[]
# Redox
[ramp]
type = ADGenericFunctionMaterial
prop_names = 'ramp'
prop_values = 'if(t<${t0},t/${t0},1)'
[]
[OCP_anode_graphite]
type = ADParsedMaterial
f_name = U
function = 'x:=c/${cmax}; -(122.12*x^6-321.81*x^5+315.59*x^4-141.26*x^3+28.218*x^2-1.9057*x+0.0785)*ramp'
args = c
material_property_names = 'ramp'
block = 'anode'
[]
[OCP_cathode_NMC111]
type = ADParsedMaterial
f_name = U
function = 'x:=c/${cmax}; (6.0826-6.9922*x+7.1062*x^2-5.4549e-5*exp(124.23*x-114.2593)-2.5947*x^3)*ramp'
args = c
material_property_names = 'ramp'
block = 'cathode'
[]
[charge_transfer_anode_elyte]
type = ChargeTransferReaction
electrode = true
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_a}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'anode_elyte'
[]
[charge_transfer_elyte_anode]
type = ChargeTransferReaction
electrode = false
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_a}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'elyte_anode'
[]
[charge_transfer_cathode_elyte]
type = ChargeTransferReaction
electrode = true
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_c}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'cathode_elyte'
[]
[charge_transfer_elyte_cathode]
type = ChargeTransferReaction
electrode = false
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_c}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'elyte_cathode'
[]
# Thermal
[thermal_properties]
type = ADGenericConstantMaterial
prop_names = 'rho cv kappa'
prop_values = '${rho} ${cv} ${kappa}'
[]
[heat_conduction]
type = FourierPotential
thermal_energy_density = chi
thermal_conductivity = kappa
temperature = T
[]
[heat_flux]
type = HeatFlux
heat_flux = h
temperature = T
[]
[heat_source]
type = VariationalHeatSource
heat_source = r
temperature = T
[]
# Mechanical
[stiffness_c]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_c*nu_c/(1+nu_c)/(1-2*nu_c)} ${fparse E_c/2/(1+nu_c)}'
block = cathode
[]
[stiffness_e]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_e*nu_e/(1+nu_e)/(1-2*nu_e)} ${fparse E_e/2/(1+nu_e)}'
block = elyte
[]
[stiffness_a]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_a*nu_a/(1+nu_a)/(1-2*nu_a)} ${fparse E_a/2/(1+nu_a)}'
block = anode
[]
[swelling_coefficient]
type = ADGenericConstantMaterial
prop_names = 'beta'
prop_values = '${beta}'
[]
[swelling]
type = SwellingDeformationGradient
concentration = c
reference_concentration = c_ref
molar_volume = ${Omega}
swelling_coefficient = beta
[]
[thermal_expansion]
type = ThermalDeformationGradient
temperature = T
reference_temperature = T_ref
CTE = ${CTE}
[]
[defgrad]
type = MechanicalDeformationGradient
displacements = 'disp_x disp_y'
[]
[neohookean]
type = NeoHookeanSolid
elastic_energy_density = psi_m
lambda = lambda
shear_modulus = G
concentration = c
temperature = T
[]
[pk1]
type = FirstPiolaKirchhoffStress
first_piola_kirchhoff_stress = pk1
deformation_gradient_rate = dot(F)
[]
[]
[Postprocessors]
[V_l]
type = SideAverageValue
variable = Phi
boundary = left
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V_r]
type = SideAverageValue
variable = Phi
boundary = right
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V]
type = ParsedPostprocessor
function = 'V_r - V_l'
pp_names = 'V_l V_r'
execute_on = 'INITIAL TIMESTEP_END'
[]
[I]
type = ADSideIntegralMaterialProperty
property = i
component = 0
boundary = right
execute_on = 'INITIAL TIMESTEP_END'
[]
[dt]
type = TimestepSize
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[dC]
type = ParsedPostprocessor
function = '-dt*I'
pp_names = 'dt I'
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[C]
type = CumulativeValuePostprocessor
postprocessor = dC
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_a_max]
type = NodalExtremeValue
variable = c
value_type = max
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_c_min]
type = NodalExtremeValue
variable = c
value_type = min
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_a_min]
type = NodalExtremeValue
variable = c
value_type = min
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_c_max]
type = NodalExtremeValue
variable = c
value_type = max
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_a]
type = ElementIntegralVariablePostprocessor
variable = c
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_e]
type = ElementIntegralVariablePostprocessor
variable = c
block = elyte
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_c]
type = ElementIntegralVariablePostprocessor
variable = c
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[]
[UserObjects]
[kill_a]
type = Terminator
expression = 'c_a_max >= ${cmax}'
message = 'Concentration in anode exceeds the maximum allowable value.'
[]
[kill_c]
type = Terminator
expression = 'c_c_min <= ${cmin}'
message = 'Concentration in cathode is below the minimum allowable value.'
[]
[]
[Executioner]
type = Transient
solve_type = NEWTON
petsc_options_iname = '-pc_type'
petsc_options_value = 'lu'
automatic_scaling = true
line_search = none
nl_rel_tol = 1e-6
nl_abs_tol = 1e-10
nl_max_its = 20
[Predictor]
type = SimplePredictor
scale = 1
skip_after_failed_timestep = true
[]
[TimeStepper]
type = IterationAdaptiveDT
dt = ${dt}
optimal_iterations = 7
iteration_window = 2
growth_factor = 1.2
cutback_factor = 0.5
cutback_factor_at_failure = 0.2
linear_iteration_ratio = 1000000
[]
end_time = 100000
[]
[Outputs]
file_base = 'CC_charging_I_${I}'
csv = true
exodus = true
print_linear_residuals = false
checkpoint = true
[]
(test/tests/chemical-electrical-thermal-mechanical/pressure.i)
R = 8.3145 #mJ/mmol/K
F = 96485 #mC/mmol
I = 3e-3 #mA
width = 0.03 #mm
in = '${fparse -I/width}'
t0 = '${fparse -1e-2/in}'
dt = '${fparse t0/100}'
Vmax = 4.3 #V
vf_se = 0.3
vf_cp = 0.5
vf_ca = 0.2
sigma_a = 0.2 #mS/mm
sigma_se = 0.1 #mS/mm
sigma_cp = 0.05 #mS/mm
sigma_ca = 0.2 #mS/mm
sigma_e = ${sigma_se}
sigma_c = '${fparse vf_se*sigma_se + vf_cp*sigma_cp + vf_ca*sigma_ca}'
l0 = 0
l1 = 0.04
l2 = 0.07
l3 = 0.12
cmax = 1e-3 #mmol/mm^3
c0_a = 1e-4
c0_e = 5e-4
c0_c = 1e-3
M_a = 8e-11
M_se = 1e-11
M_cp = 4e-14
M_ca = 1e-13
M_e = ${M_se}
M_c = '${fparse vf_se*M_se + vf_cp*M_cp + vf_ca*M_ca}'
T0 = 300 #K
i0_a = 0.1 #mA/mm^2
i0_c = 0.1 #mA/mm^2
rho = 2.5e-9 #Mg/mm^3
cv = 2.7e8 #mJ/Mg/K
kappa = 2e-4 #mJ/mm/K/s
hconv = 9.5e-3 #mJ/mm^2/K/s
T_penalty = 2e-1
E_e = 1e4
E_a = 2e5
nu_e = 0.25
nu_a = 0.3
nu_c = 0.3
d = 0
E_e_bar = '${fparse E_e/(1-nu_e*nu_e)}'
E_c_bar = '${fparse (1+d)/(1-d)*E_e_bar}'
E_c = '${fparse (1-nu_c*nu_c)*E_c_bar}'
Omega = 140
beta = 1
CTE = 1e-5
u_penalty = 1e8
P = 10
center = 0.12
spread = 0.01
[GlobalParams]
energy_densities = 'dot(psi_m) dot(psi_c) q zeta chi m'
displacements = 'disp_x disp_y'
deformation_gradient = F
mechanical_deformation_gradient = Fm
eigen_deformation_gradient = Fg
swelling_deformation_gradient = Fs
thermal_deformation_gradient = Ft
[]
[Mesh]
[battery]
type = GeneratedMeshGenerator
dim = 2
xmin = ${l0}
xmax = ${l3}
ymin = 0
ymax = ${width}
nx = 60
ny = 15
[]
[anode]
type = SubdomainBoundingBoxGenerator
input = battery
block_id = 1
block_name = anode
bottom_left = '${l0} 0 0'
top_right = '${l1} ${width} 0'
[]
[elyte]
type = SubdomainBoundingBoxGenerator
input = anode
block_id = 2
block_name = elyte
bottom_left = '${l1} 0 0'
top_right = '${l2} ${width} 0'
[]
[cathode]
type = SubdomainBoundingBoxGenerator
input = elyte
block_id = 3
block_name = cathode
bottom_left = '${l2} 0 0'
top_right = '${l3} ${width} 0'
[]
[anode_elyte]
type = BreakMeshByBlockGenerator
input = cathode
block_pairs = '1 2'
add_interface_on_two_sides = true
split_interface = true
[]
[cathode_elyte]
type = BreakMeshByBlockGenerator
input = anode_elyte
block_pairs = '2 3'
add_interface_on_two_sides = true
split_interface = true
[]
[]
[Variables]
[Phi]
[]
[c]
[]
[T]
initial_condition = ${T0}
[]
[disp_x]
[]
[disp_y]
[]
[]
[AuxVariables]
[c_ref]
[]
[T_ref]
initial_condition = ${T0}
[]
[j]
order = CONSTANT
family = MONOMIAL
[AuxKernel]
type = ADMaterialRealVectorValueAux
property = j
component = 0
[]
[]
[]
[ICs]
[c_a]
type = ConstantIC
variable = c
value = ${c0_a}
block = 'anode'
[]
[c_e]
type = ConstantIC
variable = c
value = ${c0_e}
block = 'elyte'
[]
[c_c]
type = ConstantIC
variable = c
value = ${c0_c}
block = 'cathode'
[]
[c_ref_a]
type = ConstantIC
variable = c_ref
value = ${c0_a}
block = 'anode'
[]
[c_ref_e]
type = ConstantIC
variable = c_ref
value = ${c0_e}
block = 'elyte'
[]
[c_ref_c]
type = ConstantIC
variable = c_ref
value = ${c0_c}
block = 'cathode'
[]
[]
[Kernels]
# Charge balance
[charge_balance]
type = RankOneDivergence
variable = Phi
vector = i
use_displaced_mesh = true
[]
# Mass balance
[mass_balance_1]
type = TimeDerivative
variable = c
[]
[mass_balance_2]
type = RankOneDivergence
variable = c
vector = j
use_displaced_mesh = true
[]
# Energy balance
[energy_balance_1]
type = EnergyBalanceTimeDerivative
variable = T
density = rho
specific_heat = cv
[]
[energy_balance_2]
type = RankOneDivergence
variable = T
vector = h
use_displaced_mesh = true
[]
[heat_source]
type = MaterialSource
variable = T
prop = r
coefficient = -1
[]
# Momentum balance
[momentum_balance_x]
type = RankTwoDivergence
variable = disp_x
component = 0
tensor = pk1
factor = -1
[]
[momentum_balance_y]
type = RankTwoDivergence
variable = disp_y
component = 1
tensor = pk1
factor = -1
[]
[]
[InterfaceKernels]
[negative_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
factor = -1
factor_neighbor = 1
boundary = 'cathode_elyte'
[]
[positive_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
boundary = 'anode_elyte'
[]
[heat]
type = MaterialInterfaceNeumannBC
variable = T
neighbor_var = T
prop = he
factor = 1
factor_neighbor = 1
boundary = 'anode_elyte cathode_elyte'
[]
[continuity_T]
type = InterfaceContinuity
variable = T
neighbor_var = T
penalty = ${T_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[continuity_disp_x]
type = InterfaceContinuity
variable = disp_x
neighbor_var = disp_x
penalty = ${u_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[continuity_disp_y]
type = InterfaceContinuity
variable = disp_y
neighbor_var = disp_y
penalty = ${u_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[]
[Functions]
[in]
type = PiecewiseLinear
x = '0 ${t0}'
y = '0 ${in}'
[]
[]
[BCs]
[left]
type = FunctionNeumannBC
variable = Phi
boundary = left
function = in
[]
[right]
type = DirichletBC
variable = Phi
boundary = right
value = 0
[]
[open]
type = OpenBC
variable = c
flux = jm
boundary = 'left right'
[]
[hconv]
type = ADMatNeumannBC
variable = T
boundary = 'left right'
value = -1
boundary_material = qconv
[]
[fix_x]
type = DirichletBC
variable = disp_x
value = 0
boundary = 'left right'
[]
[fix_y]
type = DirichletBC
variable = disp_y
value = 0
boundary = 'bottom'
[]
[traction]
enable = false
type = FunctionNeumannBC
variable = disp_y
boundary = 'top'
function = '-if(t<${t0},t/${t0}*${P},${P})/${spread}/sqrt(2*pi)*exp(-0.5*(x-${center})^2/${spread}^2)'
[]
[]
[Constraints]
[y]
enable = false
type = EqualValueBoundaryConstraint
variable = disp_y
penalty = ${u_penalty}
secondary = top
[]
[]
[Materials]
# Electrodynamics
[conductivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'sigma'
subdomain_to_prop_value = 'anode ${sigma_a} elyte ${sigma_e} cathode ${sigma_c}'
[]
[charge_transport]
type = BulkChargeTransport
electrical_energy_density = q
electric_potential = Phi
electric_conductivity = sigma
temperature = T
[]
[current_density]
type = CurrentDensity
current_density = i
electric_potential = Phi
[]
# Migration
[migration]
type = Migration
electrochemical_energy_density = m
electric_potential = Phi
chemical_potential = mu
electric_conductivity = sigma
faraday_constant = ${F}
[]
[migration_flux]
type = MassFlux
mass_flux = jm
energy_densities = 'm'
chemical_potential = mu
[]
# Chemical reactions
[diffusivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'M'
subdomain_to_prop_value = 'anode ${M_a} elyte ${M_e} cathode ${M_c}'
[]
[chemical_energy]
type = EntropicChemicalEnergyDensity
chemical_energy_density = psi_c
concentration = c
ideal_gas_constant = ${R}
temperature = T
reference_concentration = c_ref
reference_chemical_potential = 1e3
[]
[chemical_potential]
type = ChemicalPotential
chemical_potential = mu
concentration = c
[]
[diffusion]
type = MassDiffusion
dual_chemical_energy_density = zeta
chemical_potential = mu
mobility = M
[]
[mass_flux]
type = MassFlux
mass_flux = j
chemical_potential = mu
[]
# Redox
[ramp]
type = ADGenericFunctionMaterial
prop_names = 'ramp'
prop_values = 'if(t<${t0},t/${t0},1)'
[]
[OCP_anode_graphite]
type = ADParsedMaterial
property_name = U
expression = 'x:=c/${cmax}; -(122.12*x^6-321.81*x^5+315.59*x^4-141.26*x^3+28.218*x^2-1.9057*x+0.0785)*ramp'
coupled_variables = c
material_property_names = 'ramp'
boundary = 'anode_elyte'
[]
[OCP_cathode_NMC111]
type = ADParsedMaterial
property_name = U
expression = 'x:=c/${cmax}; (6.0826-6.9922*x+7.1062*x^2-5.4549e-5*exp(124.23*x-114.2593)-2.5947*x^3)*ramp'
coupled_variables = c
material_property_names = 'ramp'
boundary = 'cathode_elyte'
[]
[charge_transfer_anode_elyte]
type = ChargeTransferReaction
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_a}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'anode_elyte'
[]
[charge_transfer_cathode_elyte]
type = ChargeTransferReaction
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_c}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'cathode_elyte'
[]
# Thermal
[thermal_properties]
type = ADGenericConstantMaterial
prop_names = 'rho cv kappa'
prop_values = '${rho} ${cv} ${kappa}'
[]
[heat_conduction]
type = FourierPotential
thermal_energy_density = chi
thermal_conductivity = kappa
temperature = T
[]
[heat_flux]
type = HeatFlux
heat_flux = h
temperature = T
[]
[heat_source]
type = VariationalHeatSource
heat_source = r
temperature = T
[]
[qconv]
type = ADParsedMaterial
property_name = qconv
expression = 'htc*(T-T_inf)'
coupled_variables = 'T'
constant_names = 'htc T_inf'
constant_expressions = '${hconv} ${T0}'
boundary = 'left right'
[]
# Mechanical
[stiffness_c]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_c*nu_c/(1+nu_c)/(1-2*nu_c)} ${fparse E_c/2/(1+nu_c)}'
block = cathode
[]
[stiffness_e]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_e*nu_e/(1+nu_e)/(1-2*nu_e)} ${fparse E_e/2/(1+nu_e)}'
block = elyte
[]
[stiffness_a]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_a*nu_a/(1+nu_a)/(1-2*nu_a)} ${fparse E_a/2/(1+nu_a)}'
block = anode
[]
[swelling_coefficient]
type = ADGenericConstantMaterial
prop_names = 'beta'
prop_values = '${beta}'
[]
[swelling]
type = SwellingDeformationGradient
concentration = c
reference_concentration = c_ref
molar_volume = ${Omega}
swelling_coefficient = beta
[]
[thermal_expansion]
type = ThermalDeformationGradient
temperature = T
reference_temperature = T_ref
CTE = ${CTE}
[]
[defgrad]
type = MechanicalDeformationGradient
displacements = 'disp_x disp_y'
[]
[neohookean]
type = NeoHookeanSolid
elastic_energy_density = psi_m
lambda = lambda
shear_modulus = G
concentration = c
temperature = T
non_swelling_pressure = p
output_properties = 'p'
outputs = exodus
[]
[pk1]
type = FirstPiolaKirchhoffStress
first_piola_kirchhoff_stress = pk1
deformation_gradient_rate = dot(F)
[]
[]
[Postprocessors]
[V_l]
type = SideAverageValue
variable = Phi
boundary = left
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V_r]
type = SideAverageValue
variable = Phi
boundary = right
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V]
type = ParsedPostprocessor
function = 'V_r - V_l'
pp_names = 'V_l V_r'
execute_on = 'INITIAL TIMESTEP_END'
[]
[in]
type = FunctionValuePostprocessor
function = in
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[dt]
type = TimestepSize
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[dC]
type = ParsedPostprocessor
function = '-dt*in*${width}'
pp_names = 'dt in'
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[C]
type = CumulativeValuePostprocessor
postprocessor = dC
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_a_max]
type = NodalExtremeValue
variable = c
value_type = max
block = anode
[]
[c_c_min]
type = NodalExtremeValue
variable = c
value_type = min
block = cathode
[]
[mass_a]
type = ElementIntegralVariablePostprocessor
variable = c
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_e]
type = ElementIntegralVariablePostprocessor
variable = c
block = elyte
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_c]
type = ElementIntegralVariablePostprocessor
variable = c
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[E_c_bar]
type = ParsedPostprocessor
function = '${E_c_bar}'
execute_on = INITIAL
pp_names = ''
[]
[]
[UserObjects]
[kill]
type = Terminator
expression = 'V >= ${Vmax}'
message = 'Voltage reached Vmax'
[]
[]
[Executioner]
type = Transient
solve_type = NEWTON
petsc_options_iname = '-pc_type'
petsc_options_value = 'lu'
automatic_scaling = true
line_search = none
nl_rel_tol = 1e-6
nl_abs_tol = 1e-10
nl_max_its = 20
l_max_its = 150
[Predictor]
type = SimplePredictor
scale = 1
skip_after_failed_timestep = true
[]
[TimeStepper]
type = IterationAdaptiveDT
dt = ${dt}
optimal_iterations = 7
iteration_window = 2
growth_factor = 1.2
cutback_factor = 0.5
cutback_factor_at_failure = 0.2
linear_iteration_ratio = 1000000
[]
dtmax = 1
end_time = 100000
[]
[Outputs]
exodus = true
print_linear_residuals = false
[]
(examples/LiB/CV_charging.i)
I = 3e-3 #mA
width = 0.03 #mm
in = '${fparse -I/width}'
t0 = '${fparse -1e-2/in}'
dt = '${fparse t0/100}'
sigma_a = 1e0 #mS/mm
sigma_e = 1e-1 #mS/mm
sigma_c = 1e-2 #mS/mm
l0 = 0
l1 = 0.04
l2 = 0.07
l3 = 0.12
cmin = 1e-4 #mmol/mm^3
cmax = 1e-3 #mmol/mm^3
D_a = 1e-3 #mm^2/s
D_e = 1e-4 #mm^2/s
D_c = 5e-5 #mm^2/s
R = 8.3145 #mJ/mmol/K
T0 = 300 #K
F = 96485 #mC/mmol
i0_a = 1e-1 #mA/mm^2
i0_c = 1e-1 #mA/mm^2
E_c = 1e5
E_e = 1e4
E_a = 2e5
nu_c = 0.3
nu_e = 0.25
nu_a = 0.3
u_penalty = 1e8
Omega = 60
beta = 1e-3
CTE = 1e-5
rho = 2.5e-9 #Mg/mm^3
cv = 2.7e8 #mJ/Mg/K
kappa = 2e-4 #mJ/mm/K/s
T_penalty = 2e-1
[GlobalParams]
energy_densities = 'dot(psi_m) dot(psi_c) chi q zeta m'
deformation_gradient = F
mechanical_deformation_gradient = Fm
eigen_deformation_gradient = Fg
swelling_deformation_gradient = Fs
thermal_deformation_gradient = Ft
[]
[Problem]
restart_file_base = 'CC_charging_I_${I}_cp/LATEST'
[]
[Mesh]
[battery]
type = GeneratedMeshGenerator
dim = 2
xmin = ${l0}
xmax = ${l3}
ymin = 0
ymax = ${width}
nx = 60
ny = 15
[]
[anode]
type = SubdomainBoundingBoxGenerator
input = battery
block_id = 1
block_name = anode
bottom_left = '${l0} 0 0'
top_right = '${l1} ${width} 0'
[]
[elyte]
type = SubdomainBoundingBoxGenerator
input = anode
block_id = 2
block_name = elyte
bottom_left = '${l1} 0 0'
top_right = '${l2} ${width} 0'
[]
[cathode]
type = SubdomainBoundingBoxGenerator
input = elyte
block_id = 3
block_name = cathode
bottom_left = '${l2} 0 0'
top_right = '${l3} ${width} 0'
[]
[interfaces]
type = BreakMeshByBlockGenerator
input = cathode
add_interface_on_two_sides = true
split_interface = true
[]
[]
[Variables]
[Phi]
[]
[c]
[]
[disp_x]
[]
[disp_y]
[]
[T]
[]
[]
[AuxVariables]
[c_ref]
[]
[T_ref]
initial_condition = ${T0}
[]
[Phi0]
[]
[]
[ICs]
[c_ref_min]
type = ConstantIC
variable = c_ref
value = ${cmin}
block = 'anode'
[]
[c_ref_mid]
type = ConstantIC
variable = c_ref
value = '${fparse (cmax+cmin)/2}'
block = 'elyte'
[]
[c_ref_max]
type = ConstantIC
variable = c_ref
value = ${cmax}
block = 'cathode'
[]
[]
[AuxKernels]
[Phi0]
type = ParsedAux
variable = Phi0
function = 'Phi'
args = 'Phi'
execute_on = 'INITIAL'
[]
[]
[Kernels]
# Charge balance
[charge_balance]
type = RankOneDivergence
variable = Phi
vector = i
[]
# Mass balance
[mass_balance_1]
type = TimeDerivative
variable = c
[]
[mass_balance_2]
type = RankOneDivergence
variable = c
vector = j
[]
# Momentum balance
[momentum_balance_x]
type = RankTwoDivergence
variable = disp_x
component = 0
tensor = pk1
factor = -1
[]
[momentum_balance_y]
type = RankTwoDivergence
variable = disp_y
component = 1
tensor = pk1
factor = -1
[]
# Energy balance
[energy_balance_1]
type = EnergyBalanceTimeDerivative
variable = T
density = rho
specific_heat = cv
[]
[energy_balance_2]
type = RankOneDivergence
variable = T
vector = h
[]
[heat_source]
type = MaterialSource
variable = T
prop = r
coefficient = -1
[]
[]
[InterfaceKernels]
[negative_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
factor = -1
boundary = 'elyte_anode cathode_elyte'
[]
[positive_current]
type = MaterialInterfaceNeumannBC
variable = Phi
neighbor_var = Phi
prop = ie
boundary = 'anode_elyte elyte_cathode'
[]
[heat]
type = MaterialInterfaceNeumannBC
variable = T
neighbor_var = T
prop = he
factor = 1
boundary = 'anode_elyte elyte_cathode elyte_anode cathode_elyte'
[]
[continuity_disp_x]
type = InterfaceContinuity
variable = disp_x
neighbor_var = disp_x
penalty = ${u_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[continuity_disp_y]
type = InterfaceContinuity
variable = disp_y
neighbor_var = disp_y
penalty = ${u_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[continuity_T]
type = InterfaceContinuity
variable = T
neighbor_var = T
penalty = ${T_penalty}
boundary = 'anode_elyte elyte_cathode'
[]
[]
[Functions]
[in]
type = PiecewiseLinear
x = '0 ${t0}'
y = '0 ${in}'
[]
[]
[BCs]
[Phi]
type = CoupledVarDirichletBC
variable = Phi
boundary = 'left right'
value = Phi0
[]
[fix_x]
type = DirichletBC
variable = disp_x
value = 0
boundary = 'left right'
[]
[fix_y]
type = DirichletBC
variable = disp_y
value = 0
boundary = 'bottom'
[]
[open]
type = OpenBC
variable = c
flux = jm
boundary = 'left right'
[]
[]
[Constraints]
[y]
type = EqualValueBoundaryConstraint
variable = disp_y
penalty = ${u_penalty}
secondary = top
[]
[]
[Materials]
# Electrodynamics
[conductivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'sigma'
subdomain_to_prop_value = 'anode ${sigma_a} elyte ${sigma_e} cathode ${sigma_c}'
[]
[charge_transport]
type = BulkChargeTransport
electrical_energy_density = q
electric_potential = Phi
electric_conductivity = sigma
temperature = T
[]
[current_density]
type = CurrentDensity
current_density = i
electric_potential = Phi
[]
# Chemical reactions
[diffusivity]
type = ADPiecewiseConstantByBlockMaterial
prop_name = 'D'
subdomain_to_prop_value = 'anode ${D_a} elyte ${D_e} cathode ${D_c}'
[]
[mobility]
type = ADParsedMaterial
f_name = M
args = 'c_ref T_ref'
material_property_names = 'D'
function = 'D*c_ref/${R}/T_ref'
[]
[chemical_energy]
type = EntropicChemicalEnergyDensity
chemical_energy_density = psi_c
concentration = c
ideal_gas_constant = ${R}
temperature = T
reference_concentration = c_ref
[]
[chemical_potential]
type = ChemicalPotential
chemical_potential = mu
concentration = c
[]
[diffusion]
type = MassDiffusion
dual_chemical_energy_density = zeta
chemical_potential = mu
mobility = M
[]
[mass_flux]
type = MassFlux
mass_flux = j
chemical_potential = mu
[]
# Migration
[migration]
type = Migration
electrochemical_energy_density = m
electric_potential = Phi
chemical_potential = mu
electric_conductivity = sigma
faraday_constant = ${F}
[]
[migration_flux]
type = MassFlux
mass_flux = jm
energy_densities = 'm'
chemical_potential = mu
[]
# Redox
[OCP_anode_graphite]
type = ADParsedMaterial
f_name = U
function = 'x:=c/${cmax}; -(122.12*x^6-321.81*x^5+315.59*x^4-141.26*x^3+28.218*x^2-1.9057*x+0.0785)'
args = c
block = 'anode'
[]
[OCP_cathode_NMC111]
type = ADParsedMaterial
f_name = U
function = 'x:=c/${cmax}; (6.0826-6.9922*x+7.1062*x^2-5.4549e-5*exp(124.23*x-114.2593)-2.5947*x^3)'
args = c
block = 'cathode'
[]
[charge_transfer_anode_elyte]
type = ChargeTransferReaction
electrode = true
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_a}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'anode_elyte'
[]
[charge_transfer_elyte_anode]
type = ChargeTransferReaction
electrode = false
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_a}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'elyte_anode'
[]
[charge_transfer_cathode_elyte]
type = ChargeTransferReaction
electrode = true
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_c}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'cathode_elyte'
[]
[charge_transfer_elyte_cathode]
type = ChargeTransferReaction
electrode = false
charge_transfer_current_density = ie
charge_transfer_mass_flux = je
charge_transfer_heat_flux = he
electric_potential = Phi
neighbor_electric_potential = Phi
charge_transfer_coefficient = 0.5
exchange_current_density = ${i0_c}
faraday_constant = ${F}
ideal_gas_constant = ${R}
temperature = T
open_circuit_potential = U
boundary = 'elyte_cathode'
[]
# Thermal
[thermal_properties]
type = ADGenericConstantMaterial
prop_names = 'rho cv kappa'
prop_values = '${rho} ${cv} ${kappa}'
[]
[heat_conduction]
type = FourierPotential
thermal_energy_density = chi
thermal_conductivity = kappa
temperature = T
[]
[heat_flux]
type = HeatFlux
heat_flux = h
temperature = T
[]
[heat_source]
type = VariationalHeatSource
heat_source = r
temperature = T
[]
# Mechanical
[stiffness_c]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_c*nu_c/(1+nu_c)/(1-2*nu_c)} ${fparse E_c/2/(1+nu_c)}'
block = cathode
[]
[stiffness_e]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_e*nu_e/(1+nu_e)/(1-2*nu_e)} ${fparse E_e/2/(1+nu_e)}'
block = elyte
[]
[stiffness_a]
type = ADGenericConstantMaterial
prop_names = 'lambda G'
prop_values = '${fparse E_a*nu_a/(1+nu_a)/(1-2*nu_a)} ${fparse E_a/2/(1+nu_a)}'
block = anode
[]
[swelling_coefficient]
type = ADGenericConstantMaterial
prop_names = 'beta'
prop_values = '${beta}'
[]
[swelling]
type = SwellingDeformationGradient
concentration = c
reference_concentration = c_ref
molar_volume = ${Omega}
swelling_coefficient = beta
[]
[thermal_expansion]
type = ThermalDeformationGradient
temperature = T
reference_temperature = T_ref
CTE = ${CTE}
[]
[defgrad]
type = MechanicalDeformationGradient
displacements = 'disp_x disp_y'
[]
[neohookean]
type = NeoHookeanSolid
elastic_energy_density = psi_m
lambda = lambda
shear_modulus = G
concentration = c
temperature = T
[]
[pk1]
type = FirstPiolaKirchhoffStress
first_piola_kirchhoff_stress = pk1
deformation_gradient_rate = dot(F)
[]
[]
[Postprocessors]
[V_l]
type = SideAverageValue
variable = Phi
boundary = left
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V_r]
type = SideAverageValue
variable = Phi
boundary = right
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[V]
type = ParsedPostprocessor
function = 'V_r - V_l'
pp_names = 'V_l V_r'
execute_on = 'INITIAL TIMESTEP_END'
[]
[I]
type = ADSideIntegralMaterialProperty
property = i
component = 0
boundary = right
execute_on = 'INITIAL TIMESTEP_END'
[]
[dt]
type = TimestepSize
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[dC]
type = ParsedPostprocessor
function = '-dt*I'
pp_names = 'dt I'
outputs = none
execute_on = 'INITIAL TIMESTEP_END'
[]
[C]
type = CumulativeValuePostprocessor
postprocessor = dC
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_a_max]
type = NodalExtremeValue
variable = c
value_type = max
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_c_min]
type = NodalExtremeValue
variable = c
value_type = min
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_a_min]
type = NodalExtremeValue
variable = c
value_type = min
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[c_c_max]
type = NodalExtremeValue
variable = c
value_type = max
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_a]
type = ElementIntegralVariablePostprocessor
variable = c
block = anode
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_e]
type = ElementIntegralVariablePostprocessor
variable = c
block = elyte
execute_on = 'INITIAL TIMESTEP_END'
[]
[mass_c]
type = ElementIntegralVariablePostprocessor
variable = c
block = cathode
execute_on = 'INITIAL TIMESTEP_END'
[]
[]
[UserObjects]
[kill_i]
type = Terminator
expression = '-I <= 1e-6'
message = 'No current.'
[]
[]
[Executioner]
type = Transient
solve_type = NEWTON
petsc_options_iname = '-pc_type'
petsc_options_value = 'lu'
automatic_scaling = true
nl_rel_tol = 1e-6
nl_abs_tol = 1e-10
nl_max_its = 20
[Predictor]
type = SimplePredictor
scale = 1
skip_after_failed_timestep = true
[]
[TimeStepper]
type = IterationAdaptiveDT
dt = ${dt}
optimal_iterations = 7
iteration_window = 2
growth_factor = 1.2
cutback_factor = 0.5
cutback_factor_at_failure = 0.2
linear_iteration_ratio = 1000000
[]
start_time = 0
end_time = 100000
steady_state_start_time = 10
steady_state_detection = true
[]
[Outputs]
file_base = 'CV_charging_I_${I}'
csv = true
exodus = true
print_linear_residuals = false
checkpoint = true
[]