Restrict parameter combinations

This example explains how to use the constraint function when you want to restrict parameter combinations.

Sample File

Note

Keep the sample project open in Femtet and double-click on the sample code to execute it.

Design Variables and analysis conditions

../../_images/model1.png

Model appearance, analysis conditions and design variables

Variable Name

Description

external_r

Outer radius of the pipe.

internal_r

Inner radius of the pipe.

Objective Function

Max Mises stress of the pipe.

Sample Code

constrained_pipe.py
 1"""A sample to implement constrained optimization.
 2
 3This section describes the types of constraints and
 4the steps to run optimization on models that require them.
 5
 6"""
 7
 8from pyfemtet.opt import FEMOpt, OptunaOptimizer
 9from pyfemtet.opt.optimizer import PoFBoTorchSampler
10
11
12def mises_stress(Femtet):
13    """Calculate the von Mises stress as the objective function.
14
15    This function is called automatically by the FEMOpt
16    object while the optimization is running.
17
18    Args:
19        Femtet: When defining an objective or constraint
20            function using PyFemtet, the first argument
21            must take a Femtet instance.
22
23    Returns:
24        float: A single float representing the expression value you want to constrain.
25    """
26    return Femtet.Gogh.Galileo.GetMaxStress_py()[2]
27
28
29def radius_diff(Femtet, opt):
30    """Calculate the difference between the outer and inner radii of the pipe.
31
32    This constraint is called to ensure that the
33    inner radius of the pipe does not exceed the
34    outer radius while the optimization is running.
35
36    Note:
37        If you are using BoTorchSampler of OptunaOptimizer
38        and use strict constraints, be aware that accessing
39        the Femtet can be very slow, as it requires repeated
40        calculations to propose parameters.
41        We recommend that you do not access the Femtet,
42        but rather get the parameters and perform the
43        calculations via the Optimizer object, as in this
44        function example.
45
46        NOT recommended::
47
48            p = Femtet.GetVariableValue('p')
49
50        instead, use optimizer::
51
52            params = opt.get_parameter()
53            p = params['p']
54
55    Args:
56        Femtet: When defining an objective or constraint
57            function using PyFemtet, the first argument
58            must take a Femtet instance.
59        opt: This object allows you to obtain the outer
60            radius and inner radius values without going
61            through Femtet.
62    """
63    params = opt.get_parameter()
64    internal_r = params['internal_r']
65    external_r = params['external_r']
66    return external_r - internal_r
67
68
69if __name__ == '__main__':
70    # Setup optimization method
71    opt = OptunaOptimizer(
72        sampler_class=PoFBoTorchSampler,
73        sampler_kwargs=dict(
74            n_startup_trials=3,  # The first three samples are randomly sampled.
75        )
76    )
77    femopt = FEMOpt(opt=opt)
78
79    # Add parameters
80    femopt.add_parameter("external_r", 10, lower_bound=0.1, upper_bound=10)
81    femopt.add_parameter("internal_r", 5, lower_bound=0.1, upper_bound=10)
82
83    # Add the strict constraint not to exceed the
84    # outer radius while the optimization is running.
85    femopt.add_constraint(
86        fun=radius_diff,  # Constraint function (returns external radius - internal radius).
87        name='wall thickness',  # You can name the function anything you want.
88        lower_bound=1,  # Lower bound of constraint function (set minimum wall thickness is 1).
89        args=(femopt.opt,)  # Additional arguments passed to the function.
90    )
91
92    # Add the objective
93    femopt.add_objective(fun=mises_stress, name='Mises Stress')
94
95    # Run optimization.
96    femopt.set_random_seed(42)
97    femopt.optimize(n_trials=10)

Execution Result of the Sample Code

../../_images/result1.png

Execution result of constrained_pipe.py. There is no trial with pipe thickness < 1.

Note

Results may vary slightly depending on the versions of Femtet, PyFemtet, and the optimization engine it depends on.