Material Inversion Example: Constant Thermal Conductivity
Background
The MOOSE optimization module provides a flexible framework for solving inverse optimization problems in MOOSE. This page is part of a set of examples for different types of inverse optimization problems.
Example: Constant Thermal Conductivity
In this example, material properties are the design parameters, described in this section on the theory page. This is a nonlinear optimization problem where the design parameters show up in the derivative of the PDE, see Inverse Optimization, Eq. (33). Getting a nonlinear optimization problem to converge is dependent on the initial guess and bounds for the design parameters. Even convergence doesn't guarantee a correct solution. All of this makes material inversion problems more difficult to solve than the linear optimization problems for force inversion.
Main-App Optimization Executioner
The main input file containing the optimization reporter, executioner and transfers is shown in Listing 1. The gradient of the PDE given by Inverse Optimization, Eq. (33) requires the temperature field from the forward problem to be available in the adjoint problem. This requires the forward problem temperature field be transferred to the adjoint problem. The adjoint problem also needs to be executed with the same material properties used in the forward problem, see the toAdjointParameter
transfer in Listing 1.
Listing 1:
[Optimization<<<{"href": "../../../syntax/Optimization/index.html"}>>>]
[]
[Mesh<<<{"href": "../../../syntax/Mesh/index.html"}>>>]
type = GeneratedMesh
dim = 2
nx = 10
ny = 10
xmax = 2
ymax = 2
[]
[OptimizationReporter<<<{"href": "../../../syntax/OptimizationReporter/index.html"}>>>]
type = GeneralOptimization
objective_name = objective_value
parameter_names = 'p1'
num_values = '1'
initial_condition = '7'
lower_bounds = '0'
upper_bounds = '10'
[]
[Reporters<<<{"href": "../../../syntax/Reporters/index.html"}>>>]
[main]
type = OptimizationData<<<{"description": "Reporter to hold measurement and simulation data for optimization problems", "href": "../../../source/reporters/OptimizationData.html"}>>>
measurement_points<<<{"description": "Point locations corresponding to each measurement value"}>>> = '0.2 0.2 0
0.8 0.6 0
0.2 1.4 0
0.8 1.8 0'
measurement_values<<<{"description": "Measurement values collected from locations given by measurement_points"}>>> = '226 254 214 146'
[]
[]
[Executioner<<<{"href": "../../../syntax/Executioner/index.html"}>>>]
type = Optimize
tao_solver = taoblmvm
petsc_options_iname = '-tao_gatol'
petsc_options_value = '0.0001'
verbose = true
[]
[MultiApps<<<{"href": "../../../syntax/MultiApps/index.html"}>>>]
[forward]
type = FullSolveMultiApp<<<{"description": "Performs a complete simulation during each execution.", "href": "../../../source/multiapps/FullSolveMultiApp.html"}>>>
input_files<<<{"description": "The input file for each App. If this parameter only contains one input file it will be used for all of the Apps. When using 'positions_from_file' it is also admissable to provide one input_file per file."}>>> = forward.i
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = "FORWARD"
clone_parent_mesh<<<{"description": "True to clone parent app mesh and use it for this MultiApp."}>>> = true
[]
[adjoint]
type = FullSolveMultiApp<<<{"description": "Performs a complete simulation during each execution.", "href": "../../../source/multiapps/FullSolveMultiApp.html"}>>>
input_files<<<{"description": "The input file for each App. If this parameter only contains one input file it will be used for all of the Apps. When using 'positions_from_file' it is also admissable to provide one input_file per file."}>>> = adjoint.i
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = "ADJOINT"
clone_parent_mesh<<<{"description": "True to clone parent app mesh and use it for this MultiApp."}>>> = true
[]
[]
[Transfers<<<{"href": "../../../syntax/Transfers/index.html"}>>>]
[toForward]
type = MultiAppReporterTransfer<<<{"description": "Transfers reporter data between two applications.", "href": "../../../source/transfers/MultiAppReporterTransfer.html"}>>>
to_multi_app<<<{"description": "The name of the MultiApp to transfer the data to"}>>> = forward
from_reporters<<<{"description": "List of the reporter names (object_name/value_name) to transfer the value from."}>>> = 'main/measurement_xcoord
main/measurement_ycoord
main/measurement_zcoord
main/measurement_time
main/measurement_values
OptimizationReporter/p1'
to_reporters<<<{"description": "List of the reporter names (object_name/value_name) to transfer the value to."}>>> = 'measure_data/measurement_xcoord
measure_data/measurement_ycoord
measure_data/measurement_zcoord
measure_data/measurement_time
measure_data/measurement_values
params/p1'
[]
[fromForward_mesh]
type = MultiAppCopyTransfer<<<{"description": "Copies variables (nonlinear and auxiliary) between multiapps that have identical meshes.", "href": "../../../source/transfers/MultiAppCopyTransfer.html"}>>>
from_multi_app<<<{"description": "The name of the MultiApp to receive data from"}>>> = forward
to_multi_app<<<{"description": "The name of the MultiApp to transfer the data to"}>>> = adjoint
source_variable<<<{"description": "The variable to transfer from."}>>> = 'temperature'
variable<<<{"description": "The auxiliary variable to store the transferred values in."}>>> = 'temperature_forward'
[]
[fromForward]
type = MultiAppReporterTransfer<<<{"description": "Transfers reporter data between two applications.", "href": "../../../source/transfers/MultiAppReporterTransfer.html"}>>>
from_multi_app<<<{"description": "The name of the MultiApp to receive data from"}>>> = forward
from_reporters<<<{"description": "List of the reporter names (object_name/value_name) to transfer the value from."}>>> = 'measure_data/misfit_values measure_data/objective_value'
to_reporters<<<{"description": "List of the reporter names (object_name/value_name) to transfer the value to."}>>> = 'main/misfit_values OptimizationReporter/objective_value'
[]
[toAdjoint]
type = MultiAppReporterTransfer<<<{"description": "Transfers reporter data between two applications.", "href": "../../../source/transfers/MultiAppReporterTransfer.html"}>>>
to_multi_app<<<{"description": "The name of the MultiApp to transfer the data to"}>>> = adjoint
from_reporters<<<{"description": "List of the reporter names (object_name/value_name) to transfer the value from."}>>> = 'main/measurement_xcoord
main/measurement_ycoord
main/measurement_zcoord
main/measurement_time
main/misfit_values
OptimizationReporter/p1'
to_reporters<<<{"description": "List of the reporter names (object_name/value_name) to transfer the value to."}>>> = 'misfit/measurement_xcoord
misfit/measurement_ycoord
misfit/measurement_zcoord
misfit/measurement_time
misfit/misfit_values
params/p1'
[]
[fromAdjoint]
type = MultiAppReporterTransfer<<<{"description": "Transfers reporter data between two applications.", "href": "../../../source/transfers/MultiAppReporterTransfer.html"}>>>
from_multi_app<<<{"description": "The name of the MultiApp to receive data from"}>>> = adjoint
from_reporters<<<{"description": "List of the reporter names (object_name/value_name) to transfer the value from."}>>> = 'adjoint_grad/inner_product'
to_reporters<<<{"description": "List of the reporter names (object_name/value_name) to transfer the value to."}>>> = 'OptimizationReporter/grad_p1'
[]
[]
[Outputs<<<{"href": "../../../syntax/Outputs/index.html"}>>>]
csv<<<{"description": "Output the scalar variable and postprocessors to a *.csv file using the default CSV output."}>>> = true
[]
(modules/optimization/test/tests/optimizationreporter/material/main.i)Forward Problem Sub-App
The forward input file containing the solution to the PDE of interest is shown in Listing 2. The optimization executioner is controlling the thermal_conductivity prop_name
in the thermal
Material block.
Listing 2:
[Mesh<<<{"href": "../../../syntax/Mesh/index.html"}>>>]
[]
[Variables<<<{"href": "../../../syntax/Variables/index.html"}>>>]
[temperature]
[]
[]
[Kernels<<<{"href": "../../../syntax/Kernels/index.html"}>>>]
[heat_conduction]
type = MatDiffusion<<<{"description": "Diffusion equation Kernel that takes an isotropic Diffusivity from a material property", "href": "../../../source/kernels/MatDiffusion.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature
diffusivity<<<{"description": "The diffusivity value or material property"}>>> = thermal_conductivity
[]
[heat_source]
type = BodyForce<<<{"description": "Demonstrates the multiple ways that scalar values can be introduced into kernels, e.g. (controllable) constants, functions, and postprocessors. Implements the weak form $(\\psi_i, -f)$.", "href": "../../../source/kernels/BodyForce.html"}>>>
value<<<{"description": "Coefficient to multiply by the body force term"}>>> = 1000
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature
[]
[]
[BCs<<<{"href": "../../../syntax/BCs/index.html"}>>>]
[left]
type = NeumannBC<<<{"description": "Imposes the integrated boundary condition $\\frac{\\partial u}{\\partial n}=h$, where $h$ is a constant, controllable value.", "href": "../../../source/bcs/NeumannBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = left
value<<<{"description": "For a Laplacian problem, the value of the gradient dotted with the normals on the boundary."}>>> = 0
[]
[right]
type = NeumannBC<<<{"description": "Imposes the integrated boundary condition $\\frac{\\partial u}{\\partial n}=h$, where $h$ is a constant, controllable value.", "href": "../../../source/bcs/NeumannBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = right
value<<<{"description": "For a Laplacian problem, the value of the gradient dotted with the normals on the boundary."}>>> = 0
[]
[bottom]
type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../../source/bcs/DirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = bottom
value<<<{"description": "Value of the BC"}>>> = 200
[]
[top]
type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../../source/bcs/DirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = top
value<<<{"description": "Value of the BC"}>>> = 100
[]
[]
[Functions<<<{"href": "../../../syntax/Functions/index.html"}>>>]
[thermo_conduct]
type = ParsedOptimizationFunction<<<{"description": "Function used for optimization that uses a parsed expression with parameter dependence.", "href": "../../../source/functions/ParsedOptimizationFunction.html"}>>>
expression<<<{"description": "The user defined function."}>>> = 'alpha'
param_symbol_names<<<{"description": "Names of parameters in 'expression' being optimized."}>>> = 'alpha'
param_vector_name<<<{"description": "Reporter or VectorPostprocessor vector containing parameter values."}>>> = 'params/p1'
[]
[]
[Materials<<<{"href": "../../../syntax/Materials/index.html"}>>>]
[steel]
type = GenericFunctionMaterial<<<{"description": "Material object for declaring properties that are populated by evaluation of Function object.", "href": "../../../source/materials/GenericFunctionMaterial.html"}>>>
prop_names<<<{"description": "The names of the properties this material will have"}>>> = 'thermal_conductivity'
prop_values<<<{"description": "The corresponding names of the functions that are going to provide the values for the variables"}>>> = 'thermo_conduct'
[]
[]
[Executioner<<<{"href": "../../../syntax/Executioner/index.html"}>>>]
type = Steady
solve_type = NEWTON
nl_abs_tol = 1e-8
nl_rel_tol = 1e-8
petsc_options_iname = '-ksp_type -pc_type -pc_factor_mat_solver_package'
petsc_options_value = 'preonly lu superlu_dist'
[]
[Reporters<<<{"href": "../../../syntax/Reporters/index.html"}>>>]
[measure_data]
type = OptimizationData<<<{"description": "Reporter to hold measurement and simulation data for optimization problems", "href": "../../../source/reporters/OptimizationData.html"}>>>
objective_name<<<{"description": "Name of reporter value defining the objective."}>>> = objective_value
variable<<<{"description": "Vector of variable names to sample at measurement points."}>>> = temperature
[]
[params]
type = ConstantReporter<<<{"description": "Reporter with constant values to be accessed by other objects, can be modified using transfers.", "href": "../../../source/reporters/ConstantReporter.html"}>>>
real_vector_names<<<{"description": "Names for each vector of reals value."}>>> = 'p1'
real_vector_values<<<{"description": "Values for vectors of reals."}>>> = '0' # Dummy value
[]
[]
[Outputs<<<{"href": "../../../syntax/Outputs/index.html"}>>>]
console<<<{"description": "Output the results using the default settings for Console output"}>>> = false
file_base<<<{"description": "Common file base name to be utilized with all output objects"}>>> = 'forward'
[]
(modules/optimization/test/tests/optimizationreporter/material/forward.i)Adjoint Problem Sub-App
The adjoint input file shown in Listing 3 computes the adjoint of the forward PDE. The adjoint problem uses ConstantReporter and ParsedOptimizationFunction objects to allow the main app to transfer the material property used in the forward problem to the adjoint problem. The temperature field computed in the forward problem was transferred back to the main app and is finally transferred from the main app into the adjoint problem using a MultiAppCopyTransfer. The gradient given by Inverse Optimization, Eq. (33) is computed by the ElementOptimizationDiffusionCoefFunctionInnerProduct vector-postprocessor.
Listing 3:
[Mesh<<<{"href": "../../../syntax/Mesh/index.html"}>>>]
[]
[Variables<<<{"href": "../../../syntax/Variables/index.html"}>>>]
[adjointVar]
[]
[]
[Kernels<<<{"href": "../../../syntax/Kernels/index.html"}>>>]
[heat_conduction]
type = MatDiffusion<<<{"description": "Diffusion equation Kernel that takes an isotropic Diffusivity from a material property", "href": "../../../source/kernels/MatDiffusion.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = adjointVar
diffusivity<<<{"description": "The diffusivity value or material property"}>>> = thermal_conductivity
[]
[]
[DiracKernels<<<{"href": "../../../syntax/DiracKernels/index.html"}>>>]
[pt]
type = ReporterPointSource<<<{"description": "Apply a point load defined by Reporter.", "href": "../../../source/dirackernels/ReporterPointSource.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = adjointVar
x_coord_name<<<{"description": "reporter x-coordinate name. This uses the reporter syntax <reporter>/<name>."}>>> = misfit/measurement_xcoord
y_coord_name<<<{"description": "reporter y-coordinate name. This uses the reporter syntax <reporter>/<name>."}>>> = misfit/measurement_ycoord
z_coord_name<<<{"description": "reporter z-coordinate name. This uses the reporter syntax <reporter>/<name>."}>>> = misfit/measurement_zcoord
value_name<<<{"description": "reporter value name. This uses the reporter syntax <reporter>/<name>."}>>> = misfit/misfit_values
[]
[]
[Reporters<<<{"href": "../../../syntax/Reporters/index.html"}>>>]
[misfit]
type = OptimizationData<<<{"description": "Reporter to hold measurement and simulation data for optimization problems", "href": "../../../source/reporters/OptimizationData.html"}>>>
[]
[params]
type = ConstantReporter<<<{"description": "Reporter with constant values to be accessed by other objects, can be modified using transfers.", "href": "../../../source/reporters/ConstantReporter.html"}>>>
real_vector_names<<<{"description": "Names for each vector of reals value."}>>> = 'p1'
real_vector_values<<<{"description": "Values for vectors of reals."}>>> = '0' # Dummy value
[]
[]
[AuxVariables<<<{"href": "../../../syntax/AuxVariables/index.html"}>>>]
[temperature_forward]
[]
[]
[BCs<<<{"href": "../../../syntax/BCs/index.html"}>>>]
[left]
type = NeumannBC<<<{"description": "Imposes the integrated boundary condition $\\frac{\\partial u}{\\partial n}=h$, where $h$ is a constant, controllable value.", "href": "../../../source/bcs/NeumannBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = adjointVar
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = left
value<<<{"description": "For a Laplacian problem, the value of the gradient dotted with the normals on the boundary."}>>> = 0
[]
[right]
type = NeumannBC<<<{"description": "Imposes the integrated boundary condition $\\frac{\\partial u}{\\partial n}=h$, where $h$ is a constant, controllable value.", "href": "../../../source/bcs/NeumannBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = adjointVar
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = right
value<<<{"description": "For a Laplacian problem, the value of the gradient dotted with the normals on the boundary."}>>> = 0
[]
[bottom]
type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../../source/bcs/DirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = adjointVar
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = bottom
value<<<{"description": "Value of the BC"}>>> = 0
[]
[top]
type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../../source/bcs/DirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = adjointVar
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = top
value<<<{"description": "Value of the BC"}>>> = 0
[]
[]
[Functions<<<{"href": "../../../syntax/Functions/index.html"}>>>]
[thermo_conduct]
type = ParsedOptimizationFunction<<<{"description": "Function used for optimization that uses a parsed expression with parameter dependence.", "href": "../../../source/functions/ParsedOptimizationFunction.html"}>>>
expression<<<{"description": "The user defined function."}>>> = 'alpha'
param_symbol_names<<<{"description": "Names of parameters in 'expression' being optimized."}>>> = 'alpha'
param_vector_name<<<{"description": "Reporter or VectorPostprocessor vector containing parameter values."}>>> = 'params/p1'
[]
[]
[Materials<<<{"href": "../../../syntax/Materials/index.html"}>>>]
[thermalProp]
type = GenericFunctionMaterial<<<{"description": "Material object for declaring properties that are populated by evaluation of Function object.", "href": "../../../source/materials/GenericFunctionMaterial.html"}>>>
prop_names<<<{"description": "The names of the properties this material will have"}>>> = 'thermal_conductivity'
prop_values<<<{"description": "The corresponding names of the functions that are going to provide the values for the variables"}>>> = 'thermo_conduct'
[]
[]
[Executioner<<<{"href": "../../../syntax/Executioner/index.html"}>>>]
type = Steady
solve_type = PJFNK
nl_abs_tol = 1e-8
nl_rel_tol = 1e-8
petsc_options_iname = '-ksp_type -pc_type -pc_factor_mat_solver_package'
petsc_options_value = 'preonly lu superlu_dist'
[]
[VectorPostprocessors<<<{"href": "../../../syntax/VectorPostprocessors/index.html"}>>>]
[adjoint_grad]
type = ElementOptimizationDiffusionCoefFunctionInnerProduct<<<{"description": "Compute the gradient for material inversion by taking the inner product of gradients of the forward and adjoint variables with material gradient", "href": "../../../source/vectorpostprocessors/ElementOptimizationDiffusionCoefFunctionInnerProduct.html"}>>>
variable<<<{"description": "The names of the variables that this VectorPostprocessor operates on"}>>> = adjointVar
forward_variable<<<{"description": "Variable from the forward solution"}>>> = temperature_forward
function<<<{"description": "Optimization function."}>>> = thermo_conduct
[]
[]
[Outputs<<<{"href": "../../../syntax/Outputs/index.html"}>>>]
console<<<{"description": "Output the results using the default settings for Console output"}>>> = false
file_base<<<{"description": "Common file base name to be utilized with all output objects"}>>> = 'adjoint'
[]
(modules/optimization/test/tests/optimizationreporter/material/adjoint.i)