v0.15.5
Loading...
Searching...
No Matches
Classes | Typedefs | Enumerations | Functions | Variables
adjoint.cpp File Reference

Topology optimization using adjoint method with Python objective functions. More...

#include <boost/python.hpp>
#include <boost/python/def.hpp>
#include <boost/python/numpy.hpp>
#include <MoFEM.hpp>
#include <ElasticSpring.hpp>
#include <FluidLevel.hpp>
#include <CalculateTraction.hpp>
#include <NaturalDomainBC.hpp>
#include <NaturalBoundaryBC.hpp>
#include <HookeOps.hpp>
#include <ElasticPostProc.hpp>
#include <ObjectiveFunctionData.hpp>

Go to the source code of this file.

Classes

struct  DomainBCs
 [Define entities] More...
 
struct  BoundaryBCs
 Boundary conditions marker. More...
 
struct  PostProcEleByDim< 2 >
 
struct  PostProcEleByDim< 3 >
 
struct  Example
 [Example] More...
 
struct  OpAdJointGradTimesSymTensor< SPACE_DIM, IntegrationType::GAUSS, DomainBaseOp >
 
struct  OpStateSensitivity
 
struct  OpAdJointObjective
 

Typedefs

using EntData = EntitiesFieldData::EntData
 Entity data for field operations.
 
using DomainEle = PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::DomainEle
 Domain finite elements.
 
using BoundaryEle = PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::BoundaryEle
 Boundary finite elements.
 
using DomainEleOp = DomainEle::UserDataOperator
 Domain element operators.
 
using BoundaryEleOp = BoundaryEle::UserDataOperator
 
using DomainRhsBCs = NaturalBC< DomainEleOp >::Assembly< A >::LinearForm< I >
 Domain RHS natural BCs.
 
using OpDomainRhsBCs = DomainRhsBCs::OpFlux< DomainBCs, 1, SPACE_DIM >
 Domain flux operator.
 
using BoundaryRhsBCs = NaturalBC< BoundaryEleOp >::Assembly< A >::LinearForm< I >
 Boundary RHS natural BCs

 
using OpBoundaryRhsBCs = BoundaryRhsBCs::OpFlux< BoundaryBCs, 1, SPACE_DIM >
 Boundary flux operator.
 
using BoundaryLhsBCs = NaturalBC< BoundaryEleOp >::Assembly< A >::BiLinearForm< I >
 Boundary LHS natural BCs.
 
using OpBoundaryLhsBCs = BoundaryLhsBCs::OpFlux< BoundaryBCs, 1, SPACE_DIM >
 Boundary LHS flux operator.
 
using PostProcEleDomain = PostProcEleByDim< SPACE_DIM >::PostProcEleDomain
 
using SideEle = PostProcEleByDim< SPACE_DIM >::SideEle
 
using PostProcEleBdy = PostProcEleByDim< SPACE_DIM >::PostProcEleBdy
 
using DomainBaseOp = FormsIntegrators< DomainEleOp >::Assembly< A >::OpBase
 [Postprocess results]
 

Enumerations

enum  SensitivityMethod { DIRECT , ADJOINT }
 

Functions

Range get_range_from_block (MoFEM::Interface &m_field, const std::string block_name, int dim)
 
MoFEMErrorCode save_range (moab::Interface &moab, const std::string name, const Range r)
 
template<int DIM>
auto diff_symmetrize (FTensor::Number< DIM >)
 
int main (int argc, char *argv[])
 Main function for topology optimization tutorial using adjoint method.
 

Variables

constexpr int BASE_DIM = 1
 [Constants and material properties]
 
constexpr int SPACE_DIM
 [Define dimension]
 
constexpr AssemblyType A = AssemblyType::PETSC
 [Define dimension]
 
constexpr IntegrationType I
 Use Gauss quadrature for integration.
 
constexpr double young_modulus = 1
 [Material properties for linear elasticity]
 
constexpr double poisson_ratio = 0.3
 Poisson's ratio ν
 
constexpr double bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio))
 Bulk modulus K = E/(3(1-2ν))
 
constexpr double shear_modulus_G = young_modulus / (2 * (1 + poisson_ratio))
 Shear modulus G = E/(2(1+ν))
 
PetscBool is_plane_strain = PETSC_FALSE
 
SensitivityMethod derivative_type = ADJOINT
 
static char help [] = "...\n\n"
 [calculateGradient]
 

Detailed Description

Topology optimization using adjoint method with Python objective functions.


This tutorial demonstrates:

Definition in file adjoint.cpp.

Typedef Documentation

◆ BoundaryEle

Boundary finite elements.

Definition at line 48 of file adjoint.cpp.

◆ BoundaryEleOp

Boundary element operators

Definition at line 50 of file adjoint.cpp.

◆ BoundaryLhsBCs

Boundary LHS natural BCs.

Definition at line 62 of file adjoint.cpp.

◆ BoundaryRhsBCs

Boundary RHS natural BCs

Definition at line 60 of file adjoint.cpp.

◆ DomainBaseOp

[Postprocess results]

[calculateGradient]

Examples
mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp.

Definition at line 1318 of file adjoint.cpp.

◆ DomainEle

Domain finite elements.

Definition at line 47 of file adjoint.cpp.

◆ DomainEleOp

Domain element operators.

Definition at line 49 of file adjoint.cpp.

◆ DomainRhsBCs

Domain RHS natural BCs.

Definition at line 58 of file adjoint.cpp.

◆ EntData

Entity data for field operations.

Definition at line 46 of file adjoint.cpp.

◆ OpBoundaryLhsBCs

Boundary LHS flux operator.

Definition at line 63 of file adjoint.cpp.

◆ OpBoundaryRhsBCs

Boundary flux operator.

Definition at line 61 of file adjoint.cpp.

◆ OpDomainRhsBCs

Domain flux operator.

Definition at line 59 of file adjoint.cpp.

◆ PostProcEleBdy

Definition at line 81 of file adjoint.cpp.

◆ PostProcEleDomain

Definition at line 79 of file adjoint.cpp.

◆ SideEle

Definition at line 80 of file adjoint.cpp.

Enumeration Type Documentation

◆ SensitivityMethod

Enumerator
DIRECT 
ADJOINT 

Definition at line 90 of file adjoint.cpp.

90 {
91 DIRECT,
93};
@ DIRECT
Definition adjoint.cpp:91
@ ADJOINT
Definition adjoint.cpp:92

Function Documentation

◆ diff_symmetrize()

template<int DIM>
auto diff_symmetrize ( FTensor::Number< DIM >  )
inline
Examples
mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp.

Definition at line 1344 of file adjoint.cpp.

1344 {
1345
1346 FTensor::Index<'i', DIM> i;
1347 FTensor::Index<'j', DIM> j;
1348 FTensor::Index<'k', DIM> k;
1349 FTensor::Index<'l', DIM> l;
1350
1352
1353 t_diff(i, j, k, l) = 0;
1354 t_diff(0, 0, 0, 0) = 1;
1355 t_diff(1, 1, 1, 1) = 1;
1356
1357 t_diff(1, 0, 1, 0) = 0.5;
1358 t_diff(1, 0, 0, 1) = 0.5;
1359
1360 t_diff(0, 1, 0, 1) = 0.5;
1361 t_diff(0, 1, 1, 0) = 0.5;
1362
1363 if constexpr (DIM == 3) {
1364 t_diff(2, 2, 2, 2) = 1;
1365
1366 t_diff(2, 0, 2, 0) = 0.5;
1367 t_diff(2, 0, 0, 2) = 0.5;
1368 t_diff(0, 2, 0, 2) = 0.5;
1369 t_diff(0, 2, 2, 0) = 0.5;
1370
1371 t_diff(2, 1, 2, 1) = 0.5;
1372 t_diff(2, 1, 1, 2) = 0.5;
1373 t_diff(1, 2, 1, 2) = 0.5;
1374 t_diff(1, 2, 2, 1) = 0.5;
1375 }
1376
1377 return t_diff;
1378};
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k

◆ get_range_from_block()

Range get_range_from_block ( MoFEM::Interface m_field,
const std::string  block_name,
int  dim 
)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, and mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp.

Definition at line 2270 of file adjoint.cpp.

2271 {
2272 Range r;
2273
2274 auto mesh_mng = m_field.getInterface<MeshsetsManager>();
2275 auto bcs = mesh_mng->getCubitMeshsetPtr(
2276
2277 std::regex((boost::format("%s(.*)") % block_name).str())
2278
2279 );
2280
2281 for (auto bc : bcs) {
2282 Range faces;
2283 CHK_MOAB_THROW(bc->getMeshsetIdEntitiesByDimension(m_field.get_moab(), dim,
2284 faces, true),
2285 "get meshset ents");
2286 r.merge(faces);
2287 }
2288
2289 for (auto dd = dim - 1; dd >= 0; --dd) {
2290 if (dd >= 0) {
2291 Range ents;
2292 CHK_MOAB_THROW(m_field.get_moab().get_adjacencies(r, dd, false, ents,
2293 moab::Interface::UNION),
2294 "get adjs");
2295 r.merge(ents);
2296 } else {
2297 Range verts;
2298 CHK_MOAB_THROW(m_field.get_moab().get_connectivity(r, verts),
2299 "get verts");
2300 r.merge(verts);
2301 }
2303 m_field.getInterface<CommInterface>()->synchroniseEntities(r), "comm");
2304 }
2305
2306 return r;
2307};
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition ddTensor0.hpp:33
int r
Definition sdf.py:205
Managing BitRefLevels.
MoFEMErrorCode synchroniseEntities(Range &ent, std::map< int, Range > *received_ents, int verb=DEFAULT_VERBOSITY)
synchronize entity range on processors (collective)
virtual moab::Interface & get_moab()=0
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

◆ main()

int main ( int  argc,
char *  argv[] 
)

Main function for topology optimization tutorial using adjoint method.

This tutorial demonstrates structural topology optimization using:

  • MoFEM finite element library for elasticity analysis
  • Adjoint method for efficient gradient computation
  • TAO optimization library for design optimization
  • Python interface for flexible objective function definition

Workflow:

  1. Initialize MoFEM, PETSc and Python environments
  2. Read mesh and setup finite element problem
  3. Define objective function via Python interface
  4. Compute topology optimization modes as design variables
  5. Run gradient-based optimization using adjoint sensitivities
  6. Post-process optimized design

The adjoint method enables efficient gradient computation with cost independent of the number of design variables, making it suitable for large-scale topology optimization problems.

Required input files:

  • Mesh file (.h5m format from CUBIT)
  • Parameter file (param_file.petsc)
  • Objective function (objective_function.py)
Parameters
argcCommand line argument count
argvCommand line argument values
Returns
int Exit code (0 for success)

[Register MoFEM discrete manager in PETSc]

[Register MoFEM discrete manager in PETSc

[Create MoAB]

< mesh database

< mesh database interface

[Create MoAB]

[Create MoFEM]

< finite element database

< finite element database interface

[Create MoFEM]

[Example]

[Example]

Definition at line 2217 of file adjoint.cpp.

2217 {
2218
2219 // Initialize Python environment for objective function interface
2220 Py_Initialize();
2221 np::initialize();
2222
2223 // Initialize MoFEM/PETSc and MOAB data structures
2224 const char param_file[] = "param_file.petsc";
2225 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
2226
2227 auto core_log = logging::core::get();
2228 core_log->add_sink(
2230
2231 core_log->add_sink(
2232 LogManager::createSink(LogManager::getStrmSync(), "FieldEvaluator"));
2233 LogManager::setLog("FieldEvaluator");
2234 MOFEM_LOG_TAG("FieldEvaluator", "field_eval");
2235
2236 try {
2237
2238 //! [Register MoFEM discrete manager in PETSc]
2239 DMType dm_name = "DMMOFEM";
2240 CHKERR DMRegister_MoFEM(dm_name);
2241 DMType dm_name_mg = "DMMOFEM_MG";
2243 //! [Register MoFEM discrete manager in PETSc
2244
2245 //! [Create MoAB]
2246 moab::Core mb_instance; ///< mesh database
2247 moab::Interface &moab = mb_instance; ///< mesh database interface
2248 //! [Create MoAB]
2249
2250 //! [Create MoFEM]
2251 MoFEM::Core core(moab); ///< finite element database
2252 MoFEM::Interface &m_field = core; ///< finite element database interface
2253 //! [Create MoFEM]
2254
2255 //! [Example]
2256
2257 Example ex(m_field);
2258 CHKERR ex.runProblem();
2259 //! [Example]
2260 }
2262
2264
2265 if (Py_FinalizeEx() < 0) {
2266 exit(120);
2267 }
2268}
static char help[]
[calculateGradient]
Definition adjoint.cpp:2185
#define CATCH_ERRORS
Catch errors.
#define CHKERR
Inline error check.
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
MoFEMErrorCode DMRegister_MGViaApproxOrders(const char sname[])
Register DM for Multi-Grid via approximation orders.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
[Example]
Definition plastic.cpp:216
Core (interface) class.
Definition Core.hpp:82
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:72
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:118
Deprecated interface functions.
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.

◆ save_range()

MoFEMErrorCode save_range ( moab::Interface &  moab,
const std::string  name,
const Range  r 
)

Definition at line 2309 of file adjoint.cpp.

2310 {
2312 auto out_meshset = get_temp_meshset_ptr(moab);
2313 CHKERR moab.add_entities(*out_meshset, r);
2314 CHKERR moab.write_file(name.c_str(), "VTK", "", out_meshset->get_ptr(), 1);
2316};
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.

Variable Documentation

◆ A

constexpr AssemblyType A = AssemblyType::PETSC
constexpr

[Define dimension]

Use PETSc for matrix/vector assembly

Definition at line 32 of file adjoint.cpp.

◆ BASE_DIM

constexpr int BASE_DIM = 1
constexpr

[Constants and material properties]

Dimension of the base functions

Definition at line 25 of file adjoint.cpp.

◆ bulk_modulus_K

constexpr double bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio))
constexpr

Bulk modulus K = E/(3(1-2ν))

Definition at line 39 of file adjoint.cpp.

◆ derivative_type

SensitivityMethod derivative_type = ADJOINT

◆ help

char help[] = "...\n\n"
static

[calculateGradient]

Definition at line 2185 of file adjoint.cpp.

◆ I

constexpr IntegrationType I
constexpr
Initial value:
=
IntegrationType::GAUSS

Use Gauss quadrature for integration.

Examples
mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp.

Definition at line 33 of file adjoint.cpp.

◆ is_plane_strain

PetscBool is_plane_strain = PETSC_FALSE

Flag for plane strain vs plane stress in 2D

Definition at line 42 of file adjoint.cpp.

◆ poisson_ratio

constexpr double poisson_ratio = 0.3
constexpr

Poisson's ratio ν

Definition at line 38 of file adjoint.cpp.

◆ shear_modulus_G

constexpr double shear_modulus_G = young_modulus / (2 * (1 + poisson_ratio))
constexpr

Shear modulus G = E/(2(1+ν))

Definition at line 40 of file adjoint.cpp.

◆ SPACE_DIM

constexpr int SPACE_DIM
constexpr
Initial value:
=
#define EXECUTABLE_DIMENSION
Definition plastic.cpp:13

[Define dimension]

Space dimension of problem (2D or 3D), set at compile time

Examples
mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp.

Definition at line 28 of file adjoint.cpp.

◆ young_modulus

constexpr double young_modulus = 1
constexpr

[Material properties for linear elasticity]

Young's modulus E

Definition at line 37 of file adjoint.cpp.