fast-aircraft-design / FAST-OAD

FAST-OAD: An open source framework for rapid Overall Aircraft Design
GNU General Public License v3.0
47 stars 25 forks source link

Cannot use a NewtonSolver with a FASTOADProblem #431

Closed florentLutz closed 2 years ago

florentLutz commented 2 years ago

Describe the bug A deepcopy attempt will fail after the process convergence when using A FASTOADProblem along with a NewtonSolver.

To Reproduce The following code provides with a simple example of how to make the error happen : test_implicit_component.zip

Expected behavior A behaviour like the one shown in the test_implicit_component_openmdao() pytest would be expected

Error message

FAILED      [ 50%]NL: Newton Converged in 6 iterations

test_implicit_component.py:71 (test_implicit_component_fast_oad)
def test_implicit_component_fast_oad():

        p = FASTOADProblem()

        p.model.add_subsystem("ivc_a", om.IndepVarComp("a", val=1.0), promotes=["*"])
        p.model.add_subsystem("ivc_b", om.IndepVarComp("b", val=-4.0), promotes=["*"])
        p.model.add_subsystem("ivc_c", om.IndepVarComp("c", val=3.0), promotes=["*"])
        p.model.add_subsystem("quad", QuadraticComp(), promotes=["*"])

        p.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
        p.model.linear_solver = om.DirectSolver()

        p.setup()

>       p.run_model()

test_implicit_component.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\site-packages\fastoad\openmdao\problem.py:64: in run_model
    ValidityDomainChecker.check_problem_variables(self)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\site-packages\fastoad\openmdao\validity_checker.py:164: in check_problem_variables
    cls._update_problem_limit_definitions(problem)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\site-packages\fastoad\openmdao\validity_checker.py:244: in _update_problem_limit_definitions
    variables = VariableList.from_problem(
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\site-packages\fastoad\openmdao\variables\variable_list.py:263: in from_problem
    problem = deepcopy(problem)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:172: in deepcopy
    y = _reconstruct(x, memo, *rv)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:270: in _reconstruct
    state = deepcopy(state, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:146: in deepcopy
    y = copier(x, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:230: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:172: in deepcopy
    y = _reconstruct(x, memo, *rv)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:270: in _reconstruct
    state = deepcopy(state, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:146: in deepcopy
    y = copier(x, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:230: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:172: in deepcopy
    y = _reconstruct(x, memo, *rv)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:270: in _reconstruct
    state = deepcopy(state, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:146: in deepcopy
    y = copier(x, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:230: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:172: in deepcopy
    y = _reconstruct(x, memo, *rv)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:270: in _reconstruct
    state = deepcopy(state, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:146: in deepcopy
    y = copier(x, memo)
..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:230: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

x = <SuperLU object at 0x000001E943339D20>
memo = {2100740560032: frozenset(), 2101032512192: OrderedDict(), 2101280719296: UNDEFINED, 2101280723328: {'_repr_string': 'UNDEFINED'}, ...}
_nil = []

    def deepcopy(x, memo=None, _nil=[]):
        """Deep copy operation on arbitrary Python objects.

        See the module's __doc__ string for more info.
        """

        if memo is None:
            memo = {}

        d = id(x)
        y = memo.get(d, _nil)
        if y is not _nil:
            return y

        cls = type(x)

        copier = _deepcopy_dispatch.get(cls)
        if copier is not None:
            y = copier(x, memo)
        else:
            if issubclass(cls, type):
                y = _deepcopy_atomic(x, memo)
            else:
                copier = getattr(x, "__deepcopy__", None)
                if copier is not None:
                    y = copier(memo)
                else:
                    reductor = dispatch_table.get(cls)
                    if reductor:
                        rv = reductor(x)
                    else:
                        reductor = getattr(x, "__reduce_ex__", None)
                        if reductor is not None:
>                           rv = reductor(4)
E                           TypeError: cannot pickle 'SuperLU' object

..\..\Anaconda3\envs\FAST_OAD_bug_replication\lib\copy.py:161: TypeError

Environment

Additional context It looks like the problem can be solver by using another solver, like a NonLinearBlockGS solver but it is not always possible to swap the two