LSDOlab / csdl

https://LSDOlab.github.io/csdl/
GNU Lesser General Public License v3.0
6 stars 3 forks source link

TypeError of the `csdl_om` simulator object #2

Open RuruX opened 2 years ago

RuruX commented 2 years ago

Hi Victor,

I was trying to build a CustomImplicitOperation object corresponding to the OpenMDAO ImplicitComponent class. I assume they are using the same methodology except for the syntax differences.

However, I was having trouble to simulate the model using csdl_om, that the error popped up saying "TypeError: CSDL-OM only accepts CSDL Model specifications to construct a Simulator." Here is the complete error message when running the ex_custom.py in the CSDL repository, with simulator defined with it.

Traceback (most recent call last):
  File "csdl_test.py", line 50, in <module>
    sim = Simulator(ExampleImplicitSimple())
  File "/home/ru/csdl_om/csdl_om/core/simulator.py", line 49, in __init__
    raise TypeError(
TypeError: CSDL-OM only accepts CSDL Model specifications to construct a Simulator.

And the complete code example I'm using is as below.

from csdl import CustomExplicitOperation, CustomImplicitOperation, NewtonSolver, ScipyKrylov
import csdl
import numpy as np

class ExampleImplicitSimple(CustomImplicitOperation):
    """
    :param var: x
    """
    def define(self):
        print("="*40)
        print(" Running define()...")
        print("="*40)
        self.add_input('a', val=1.)
        self.add_input('b', val=-4.)
        self.add_input('c', val=3.)
        self.add_output('x', val=0.)
        self.declare_derivatives('x', 'x')
        self.declare_derivatives('x', ['a', 'b', 'c'])

        self.linear_solver = ScipyKrylov()
        self.nonlinear_solver = NewtonSolver(solve_subsystems=False)

    def evaluate_residuals(self, inputs, outputs, residuals):
        print("="*40)
        print(" Running evaluate_residual()...")
        print("="*40)
        x = outputs['x']
        a = inputs['a']
        b = inputs['b']
        c = inputs['c']
        residuals['x'] = a * x**2 + b * x + c

    def compute_derivatives(self, inputs, outputs, derivatives):
        print("="*40)
        print(" Running compute_derivatives()...")
        print("="*40)
        a = inputs['a']
        b = inputs['b']
        x = outputs['x']

        derivatives['x', 'a'] = x**2
        derivatives['x', 'b'] = x
        derivatives['x', 'c'] = 1.0
        derivatives['x', 'x'] = 2 * a * x + b

from csdl_om import Simulator

# Generate an implementation.
sim = Simulator(ExampleImplicitSimple())
# Run simulation.
sim.run()
# Access values
print(sim['x'])

It seems that the CustomImplicitOperation object is not recognized by the simulator as a valid input, which should be a model object (here). Or it could also be me using the simulator wrong. Please let me know what you think.

Best, Ru

Meta

Here are the versions of CSDL and CSDL-OM I was using, which are both the latest as of the issue report.

Backtrace

``` ```

vgucsd commented 2 years ago

You will need to call csdl.custom from within a Model subclass and construct a Simulator from that Model. You cannot construct a Simulator from anything other than a Model. Consider the following:

from csdl import Model
from csdl_om import Simulator

class M(Model):
    def define(self):
        a = self.declare_variable('a', val=1.)
        b = self.declare_variable('b', val=-4.)
        c = self.declare_variable('c', val=3.)

        x = csdl.custom(a, b, c, op=ExampleImplicitSimple())
        self.register_output('x', x)

sim = Simulator(M())
sim.run()
print(sim['x'])

This produces the following output:

======================
custom_implict_op_0003
======================
NL: Newton Converged in 5 iterations
[1.]

A few things to note here:

e = ExampleImplicitSimple()
e.linear_solver = ScipyKrylov()
e.nonlinear_solver = NewtonSolver(solve_subsystems=False)
x = csdl.custom(a, b, c, op=e)

The reason I mention this is that you may want to leave the solvers out of the class definition until the user of your custom operation decides to use it, and you can leave it up to the user to decide what solvers to use.

vgucsd commented 2 years ago

I added the documentation label because this is something I have planned to document, but haven't yet gotten around to doing so.

RuruX commented 2 years ago

Thank you so much for your explanation! It has exactly solved my problem. And looking forward to seeing this represented in the documentation.

vgucsd commented 2 years ago

Since I've labeled this a documentation issue and this hasn't been documented, I'm reopening it.