finesse.solutions.base module

Base solution interface.

Solution classes contain the output from a Finesse simulation, and convenience methods for accessing, plotting and serialising that output.

Solutions intentionally do not contain references to the model that produced its results. This is so that the solution can be serialised without requiring the model that produced it itself be serialisable.

class finesse.solutions.base.BaseSolution(name, parent=None)[source]

Bases: ParameterChangingTreeNode

plot(self, *args, show=True, **kwargs)[source]

Plot solution(s).

If the solution contains child solutions, they are plotted in order. Solutions without plot arguments are skipped. Positional arguments passed to this method are assumed to be dict and are unpacked into calls to each child’s plot method. Global arguments to be passed to all plot methods can be specified directly as keyword arguments. Duplicate arguments specified in a positional argument dictionaries take precendence over global arguments.

Parameters

showbool, optional

Show the figures.

Other Parameters

*args

Sequence of dict to use as parameters for the call to each child solution’s plot method.

**kwargs

Keyword arguments supported by the child solution(s).

Notes

If the Nth solution contains no plot method, it still consumes the Nth positional argument passed to this method.

time

time: ‘double’

class finesse.solutions.base.ParameterChangingTreeNode(name, parent=None)[source]

Bases: TreeNode

get_all_parameters_changing(self)[source]
parameters_changing

parameters_changing: tuple

class finesse.solutions.base.SolutionSet(solutions)[source]

Bases: Set

A SolutionSet is a collection of solution objects that have been generated from running a model. When nested analyses have been used then you must then extract each of the nested solutions. The SolutionSet object makes this easier by collecting a variety of Solutions together so you can select common nested solutions within them, or extract some common attribute.

Take some overly simplistic example here where we have swept some variable and performed some other analysis at each step.

>>> import finesse
>>> model = finesse.Model()
>>> model.parse('''
... l l1 P=1
... pd P l1.p1.o
... xaxis(l1.P, lin, 0, 1, 2,
...     pre_step=series(
...         minimize(P, l1.P)
...     )
... )
... ''')
>>>
>>> sol = model.run()
>>> print(sol)
- Solution Tree
● xaxis - ArraySolution
╰──○ pre_step
   ├──○ series
   │  ╰──○ minimize - OptimizeSolution
   ├──○ series
   │  ╰──○ minimize - OptimizeSolution
   ╰──○ series
       ╰──○ minimize - OptimizeSolution

Here we have an optimisation solution buried in the pre_step events of the axis. We can get them all by simply calling:

>>> sol['pre_step', 'series', 'minimize']
<finesse.solutions.base.SolutionSet object at ...>

You can see which solutions you have selected using:

>>> sol['pre_step', 'series', 'minimize'].solutions
[<OptimizeSolution of series/xaxis/pre_step/series/minimize @ ... children=0>,
 <OptimizeSolution of series/xaxis/pre_step/series/minimize @ ... children=0>,
 <OptimizeSolution of series/xaxis/pre_step/series/minimize @ ... children=0>]

We can select a common attribute from these similar solutions by just acting on the SolutionSet, the attribute request is evaluated on each Solution present in the set and returned. For example, we can get the result attribute from each OptimisationSolution using:

>>> print(sol['pre_step', 'series', 'minimize'].result)
[ final_simplex: (array([[0.00e+00],
        [6.25e-05]]), array([0.00e+00, 6.25e-05]))
            fun: 0.0
        message: 'Optimization terminated successfully.'
           nfev: 6
            nit: 3
         status: 0
        success: True
              x: array([0.])
  ...
]

The returned attribute request will be a numpy array of objects or numerical values. This means it is possible to easily extract an array of values from a set of nested solutions.

Which returns a tuple of the requested attributes from each of the nested solutions. You can also slice the solution object, which will again returns a reduced SolutionSet:

>>> sol['pre_step', 'series', 'minimize'][::2]
<finesse.solutions.base.SolutionSet object at ...>

Each individual solution can be extracted using the SolutionSet.solutions attribute which returns a list of solution you can iterate over.