ParameterMeshOptimization
Computes objective function, gradient and contains reporters for communicating between optimizeSolve and subapps using mesh-based parameter definition.
Overview
This optimization reporter performs the same type of optimization as OptimizationReporter, except the parameters are defined by a mesh and is meant to be used in conjunction with ParameterMeshFunction. The idea is that the parameters are defined as variables on the inputted mesh and the resulting values on the problem being optimized is based on the finite-element shape functions of the variable. The parameter mesh does not need to conform to the physics mesh, but every point in the physics mesh must be contained in parameter mesh. The parameters are defined with "parameter_names" and each name has the following options associated with it:
mesh ("parameter_meshes") (Required),
finite-element family ("parameter_families") where a single value input is applied to all parameters,
finite-element order ("parameter_orders") where a single value input is applied to all parameters,
initial condition which can be set by the following inputs:
from the input file using ("initial_condition") where all values or one value per group can be specified
from the parameter mesh using ("initial_condition_mesh_variable") where each parameter in the group is initialized from data read from the parameter mesh exodus file,
default is zero
lower bound which can be set by the following inputs:
from the input file using ("lower_bounds") where all values or one value per group can be specified
from the parameter mesh using ("lower_bound_mesh_variable") where each parameter in the group is initialized from data read from the parameter mesh exodus file
default is no bounds
upper bound can be set by the following inputs:
from the input file using ("upper_bounds") where all values or one value per group can be specified.
from the parameter mesh using ("upper_bound_mesh_variable") where each parameter in the group is initialized from data read from the parameter mesh exodus file
default is no bounds
ParameterMeshFunction, Table 1 shows common interpolation types for the parameters.
The mesh created must be replicated. Ensure this by having Mesh/parallel_type=REPLICATED
when creating the mesh.
Example Input File Syntax
The first step in doing mesh-based inverse optimization is creating the parameter mesh. The easiest way of doing this is defining the mesh in a separate input file and run it with --mesh-only
on command-line. The input below creates a two-by-two mesh outputted to exodus as parameter_mesh_in.e
:
[Mesh<<<{"href": "../../syntax/Mesh/index.html"}>>>]
[gmg]
type = GeneratedMeshGenerator<<<{"description": "Create a line, square, or cube mesh with uniformly spaced or biased elements.", "href": "../meshgenerators/GeneratedMeshGenerator.html"}>>>
dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 2
nx<<<{"description": "Number of elements in the X direction"}>>> = 2
ny<<<{"description": "Number of elements in the Y direction"}>>> = 2
[]
second_order<<<{"description": "Converts a first order mesh to a second order mesh. Note: This is NOT needed if you are reading an actual first order mesh."}>>> = true
parallel_type = REPLICATED
[]
(modules/optimization/test/tests/optimizationreporter/mesh_source/parameter_mesh.i)In the main optimization input, this mesh is then inputted into the ParameterMeshOptimization object:
[OptimizationReporter<<<{"href": "../../syntax/OptimizationReporter/index.html"}>>>]
type = ParameterMeshOptimization
objective_name = objective_value
parameter_names = 'source'
parameter_meshes = 'parameter_mesh_in.e'
[]
(modules/optimization/test/tests/optimizationreporter/mesh_source/main.i)The mesh is also used in the ParameterMeshFunction objects in the forward and adjoint inputs:
[Functions<<<{"href": "../../syntax/Functions/index.html"}>>>]
[src_func]
type = ParameterMeshFunction<<<{"description": "Optimization function with parameters represented by a mesh and finite-element shape functions.", "href": "../functions/ParameterMeshFunction.html"}>>>
exodus_mesh<<<{"description": "File containing parameter mesh."}>>> = parameter_mesh_in.e
parameter_name<<<{"description": "Reporter or VectorPostprocessor vector containing parameter values."}>>> = src_rep/vals
[]
[]
(modules/optimization/test/tests/optimizationreporter/mesh_source/forward.i)[Functions<<<{"href": "../../syntax/Functions/index.html"}>>>]
[src_func]
type = ParameterMeshFunction<<<{"description": "Optimization function with parameters represented by a mesh and finite-element shape functions.", "href": "../functions/ParameterMeshFunction.html"}>>>
exodus_mesh<<<{"description": "File containing parameter mesh."}>>> = parameter_mesh_in.e
parameter_name<<<{"description": "Reporter or VectorPostprocessor vector containing parameter values."}>>> = src_rep/vals
[]
[]
(modules/optimization/test/tests/optimizationreporter/mesh_source/adjoint.i)The transfer of parameters is the same as in other inverse optimization problems, see OptimizationReporter.
Example Input File Syntax For Restarting An Optimization Simulation
A good guess for the initial parameter values will help with the convergence of the optimization problem. In this example, initial conditions for the controllable parameters are given on an exodus mesh. The parameter values on the exodus mesh are the optimized parameter values found in the previous example. The parameter values from the above optimization problem are output by its forward problem onto the 10x10 mesh used by the FEM simulation. The forward problem parameter field is then projected onto a coarser two-by-two parameter mesh as a first order Lagrange nodal AuxVariable called restart_source
using SolutionUserObject and SolutionAux in the following input file
[Mesh<<<{"href": "../../syntax/Mesh/index.html"}>>>]
[gmg]
type = GeneratedMeshGenerator<<<{"description": "Create a line, square, or cube mesh with uniformly spaced or biased elements.", "href": "../meshgenerators/GeneratedMeshGenerator.html"}>>>
dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 2
nx<<<{"description": "Number of elements in the X direction"}>>> = 2
ny<<<{"description": "Number of elements in the Y direction"}>>> = 2
[]
second_order<<<{"description": "Converts a first order mesh to a second order mesh. Note: This is NOT needed if you are reading an actual first order mesh."}>>> = false
parallel_type = REPLICATED
[]
[Problem<<<{"href": "../../syntax/Problem/index.html"}>>>]
solve=false
[]
[AuxVariables<<<{"href": "../../syntax/AuxVariables/index.html"}>>>]
[restart_source]
order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = FIRST
family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = LAGRANGE
[]
[]
[UserObjects<<<{"href": "../../syntax/UserObjects/index.html"}>>>]
[restart_soln]
type = SolutionUserObject<<<{"description": "Reads a variable from a mesh in one simulation to another", "href": "../userobjects/SolutionUserObject.html"}>>>
mesh<<<{"description": "The name of the mesh file (must be xda/xdr or exodusII file)."}>>> = main_out_forward0.e
system_variables<<<{"description": "The name of the nodal and elemental variables from the file you want to use for values"}>>> = source
[]
[]
[AuxKernels<<<{"href": "../../syntax/AuxKernels/index.html"}>>>]
[restart_source]
type = SolutionAux<<<{"description": "Creates fields by using information from a SolutionUserObject.", "href": "../auxkernels/SolutionAux.html"}>>>
variable<<<{"description": "The name of the variable that this object applies to"}>>> = restart_source
solution<<<{"description": "The name of the SolutionUserObject"}>>> = restart_soln
[]
[]
[BCs<<<{"href": "../../syntax/BCs/index.html"}>>>]
[]
[Executioner<<<{"href": "../../syntax/Executioner/index.html"}>>>]
type = Steady
[]
[Outputs<<<{"href": "../../syntax/Outputs/index.html"}>>>]
exodus<<<{"description": "Output the results using the default settings for Exodus output."}>>> = true
[]
(modules/optimization/test/tests/optimizationreporter/mesh_source/parameter_mesh_restart.i)After the parameter mesh is initialized with parameter values, it can be used as an initial guess in the optimization problem. The AuxVariable restart_source
is then read in by OptimizationReporter
using initial_condition_mesh_variable
as the initial guess for the parameter field:
[OptimizationReporter<<<{"href": "../../syntax/OptimizationReporter/index.html"}>>>]
type = ParameterMeshOptimization
objective_name = objective_value
parameter_names = 'source'
parameter_meshes = 'parameter_mesh_restart_out.e'
exodus_timesteps_for_parameter_mesh_variable = 2
initial_condition_mesh_variable = restart_source
lower_bounds = -1
upper_bounds = 5
outputs = none
[]
(modules/optimization/test/tests/optimizationreporter/mesh_source/main_linearRestart.i)This optimization simulation is restarted with the optimized parameter values from the first example and convergence occurs in a single step. The ParameterMeshOptimization
reporter also defined an exodus_timesteps_for_parameter_mesh_variable
to identify which step to read from the exodus file. Constant lower and upper bounds were also given by lower_bounds
and upper_bounds
but do not have an effect on the optimization algorithm because it was started from the exact solution for the parameter field. To use bounds, the tao_solver
in the Executioner
block was changed to taoblmvm
(bounded lmvm). For difficult optimization problems, it is better to start with a good guess for the parameters than to tighten up their bounds. Multi-resolution optimization strategies Eslaminia et al. (2022) find better initial guesses for the parameters by starting with an easier to solve optimization problem containing a few controllable parameters and then reusing those optimized parameters as an initial guess for a more difficult optimization problem with more parameters. !syntax parameters /OptimizationReporter/ParameterMeshOptimization
Input Files
- (modules/optimization/test/tests/optimizationreporter/parameter_mesh_base/paramMeshOptRep.i)
- (modules/optimization/examples/simpleTransient/main_mesh.i)
- (modules/optimization/test/tests/optimizationreporter/mesh_source/main.i)
- (modules/optimization/examples/diffusion_reaction_XYDelaunay/optimize.i)
- (modules/optimization/examples/diffusion_reaction/optimize.i)
- (modules/optimization/test/tests/optimizationreporter/mesh_source/main_linearRestart.i)
- (modules/optimization/test/tests/optimizationreporter/parameter_mesh_base/twoParamMeshOptRep.i)
- (modules/optimization/test/tests/optimizationreporter/mesh_source/main_auto_adjoint.i)
References
- Mehran Eslaminia, Abdelrahman M Elmeliegy, and Murthy N Guddati.
Full waveform inversion through double-sweeping solver.
Journal of Computational Physics, 453:110914, 2022.[BibTeX]