Permalink
Browse files

Merge pull request #12639 from tophmatthews/ad_soret_12633

Added ADThermoDiffusion
  • Loading branch information...
lindsayad committed Jan 7, 2019
2 parents ceabe67 + e11dda5 commit c98deb1053d1910e2f01c1f7daf6735f83e0574c
@@ -0,0 +1,22 @@
# ADThermoDiffusion

## Description

`ADThermoDiffusion` implements thermodiffusion (also called thermophoresis, thermomigration, or the Soret effect)
or the movement of species due a temperature gradient. The mass flux $J$
is given as
\begin{equation}
\mathbf{J}=-S\nabla T
\end{equation}
where $S$ is Soret diffusion coefficient which is typically a combination of the
species concentration, temperature, and other material parameters. $S$ is kept
agnostic in this formulation and ultimately needs to be formulated in a separate
material property definition.

!syntax parameters /ADKernels/ADThermoDiffusion<RESIDUAL>

!syntax inputs /ADKernels/ADThermoDiffusion<RESIDUAL>

!syntax children /ADKernels/ADThermoDiffusion<RESIDUAL>

!bibtex bibliography
@@ -0,0 +1,35 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifndef ADDIFFUSION_H
#define ADDIFFUSION_H

#include "ADKernel.h"

template <ComputeStage compute_stage>
class ADThermoDiffusion;

declareADValidParams(ADThermoDiffusion);

template <ComputeStage compute_stage>
class ADThermoDiffusion : public ADKernel<compute_stage>
{
public:
ADThermoDiffusion(const InputParameters & parameters);

protected:
virtual ADResidual computeQpResidual() override;

const ADVariableGradient & _grad_temp;
const ADMaterialProperty(Real) & _soret_coeff;

usingKernelMembers;
};

#endif /* ADDIFFUSION_H */
@@ -0,0 +1,37 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "ADThermoDiffusion.h"

registerADMooseObject("MooseApp", ADThermoDiffusion);

defineADValidParams(
ADThermoDiffusion,
ADKernel,
params.addClassDescription(
"Calculates diffusion due to temperature gradient and Soret Coefficient");
params.addRequiredCoupledVar("temperature", "The coupled temperature variable.");
params.addParam<MaterialPropertyName>("soret_coefficient",
"soret_coefficient",
"The name of the Soret coefficient material property"););

template <ComputeStage compute_stage>
ADThermoDiffusion<compute_stage>::ADThermoDiffusion(const InputParameters & parameters)
: ADKernel<compute_stage>(parameters),
_grad_temp(adCoupledGradient("temperature")),
_soret_coeff(adGetADMaterialProperty<Real>("soret_coefficient"))
{
}

template <ComputeStage compute_stage>
ADResidual
ADThermoDiffusion<compute_stage>::computeQpResidual()
{
return _soret_coeff[_qp] * _grad_temp[_qp] * _grad_test[_i][_qp];
}
@@ -0,0 +1,36 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html
#ifndef ADSORETCOEFFTEST_H
#define ADSORETCOEFFTEST_H

#include "ADMaterial.h"

template <ComputeStage>
class ADSoretCoeffTest;

declareADValidParams(ADSoretCoeffTest);

template <ComputeStage compute_stage>
class ADSoretCoeffTest : public ADMaterial<compute_stage>
{
public:
ADSoretCoeffTest(const InputParameters & parameters);

protected:
virtual void computeQpProperties();

const ADVariableValue & _coupled_var;
const ADVariableValue & _temp;

ADMaterialProperty(Real) & _soret_coeff;

usingMaterialMembers;
};

#endif // ADSORETCOEFFTEST_H
@@ -0,0 +1,31 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html
#include "ADSoretCoeffTest.h"

registerADMooseObject("MiscTestApp", ADSoretCoeffTest);

defineADValidParams(
ADSoretCoeffTest, ADMaterial, params.addRequiredCoupledVar("coupled_var", "A coupled variable");
params.addRequiredCoupledVar("temperature", "The coupled temperature variable"););

template <ComputeStage compute_stage>
ADSoretCoeffTest<compute_stage>::ADSoretCoeffTest(const InputParameters & parameters)
: ADMaterial<compute_stage>(parameters),
_coupled_var(adCoupledValue("coupled_var")),
_temp(adCoupledValue("temperature")),
_soret_coeff(adDeclareADProperty<Real>("soret_coefficient"))
{
}

template <ComputeStage compute_stage>
void
ADSoretCoeffTest<compute_stage>::computeQpProperties()
{
_soret_coeff[_qp] = _coupled_var[_qp] / _temp[_qp] / _temp[_qp];
}
@@ -0,0 +1,115 @@
# Steady-state test for the ThermoDiffusion kernel.
#
# This test applies a constant temperature gradient to drive thermo-diffusion
# in the variable u. At steady state, the thermo-diffusion is balanced by
# diffusion due to Fick's Law, so the total flux is
#
# J = -D ( grad(u) - ( Qstar u / R ) grad(1/T) )
#
# If there are no fluxes at the boundaries, then there is no background flux and
# these two terms must balance each other everywhere:
#
# grad(u) = ( Qstar u / R ) grad(1/T)
#
# The dx can be eliminated to give
#
# d(ln u) / d(1/T) = Qstar / R
#
# This can be solved to give the profile for u as a function of temperature:
#
# u = A exp( Qstar / R T )
#
# Here, we are using simple heat conduction with Dirichlet boundaries on 0 <= x <= 1
# to give a linear profile for temperature: T = x + 1. We also need to apply one
# boundary condition on u, which is u(x=0) = 1. These conditions give:
#
# u = exp( -(Qstar/R) (x/(x+1)) )
#
# This analytical result is tracked by the aux variable "correct_u".

[Mesh]
type = GeneratedMesh
dim = 1
nx = 100
[]

[Variables]
[./u]
initial_condition = 1
[../]
[./temp]
initial_condition = 1
[../]
[]

[ADKernels]
[./soret]
type = ADThermoDiffusion
variable = u
temperature = temp
[../]
[./diffC]
type = ADDiffusion
variable = u
[../]

# Heat diffusion gives a linear temperature profile to drive the Soret diffusion.
[./diffT]
type = ADDiffusion
variable = temp
[../]
[]

[BCs]
[./left]
type = DirichletBC
variable = u
boundary = left
value = 1
[../]

[./leftt]
type = DirichletBC
variable = temp
boundary = left
value = 1
[../]
[./rightt]
type = DirichletBC
variable = temp
boundary = right
value = 2
[../]
[]

[ADMaterials]
[./ad_soret_coefficient]
type = ADSoretCoeffTest
temperature = temp
coupled_var = u
[../]
[]

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

[Executioner]
type = Steady
[]

[Postprocessors]
[./error]
type = NodalL2Error
variable = u
function = 'exp(-x/(x+1))'
[../]
[]

[Outputs]
execute_on = FINAL
exodus = true
[]
Binary file not shown.
@@ -1,7 +1,31 @@
[Tests]
[./test]
[./thermo_diffusion]
type = 'Exodiff'
input = 'thermo_diffusion.i'
exodiff = 'thermo_diffusion_out.e'
requirement = 'Thermo diffusion shall reproduce an analytical solution'
design = "thermodiffusion.md"
issues = "#3392"
[../]
[./ad_thermo_diffusion]
type = 'Exodiff'
input = 'ad_thermo_diffusion.i'
exodiff = 'ad_thermo_diffusion_out.e'
requirement = 'AD thermo diffusion shall reproduce an analytical solution'
design = ""
issues = "#12633"
allow_test_objects = true
[../]
[./ad_thermo_diffusion_jacobian]
type = 'PetscJacobianTester'
input = 'ad_thermo_diffusion.i'
ratio_tol = 1e-7
difference_tol = 1e-3
run_sim = True
petsc_version = '>=3.9'
requirement = 'AD thermo diffusion shall work with material properties and the Jacobian shall be beautiful'
design = "jacobian_definition.md"
issues = "#5658"
allow_test_objects = true
[../]
[]
@@ -29,13 +29,8 @@

[Mesh]
type = GeneratedMesh
dim = 2
xmin = 0
xmax = 1
ymin = 0
ymax = 1
nx = 10
ny = 1
dim = 1
nx = 100
[]

[Variables]
@@ -55,16 +50,14 @@
gas_constant = 1
[../]
[./diffC]
type = CoefDiffusion
type = Diffusion
variable = u
coef = 1
[../]

# Heat diffusion gives a linear temperature profile to drive the Soret diffusion.
[./diffT]
type = CoefDiffusion
type = Diffusion
variable = temp
coef = 1
[../]
[]

@@ -99,34 +92,19 @@
[../]
[]

[Functions]
# The correct (analytical) result for the solution of u.
[./concentration_profile]
type = ParsedFunction
value = 'exp(-x/(x+1))'
[../]
[]

[AuxVariables]
[./correct_u]
[../]
[]

[AuxKernels]
# This kernel is just being used to plot the correct result for u.
[./copy_from_function]
type = FunctionAux
variable = correct_u
function = concentration_profile
[../]
[]

[Executioner]
type = Steady
[]

solve_type = 'PJFNK'
[Postprocessors]
[./error]
type = NodalL2Error
variable = u
function = 'exp(-x/(x+1))'
[../]
[]

[Outputs]
execute_on = FINAL
exodus = true
[]

0 comments on commit c98deb1

Please sign in to comment.