Creating nodes with the same variables/constraints in Plasmo

I posted this on Slack, and was recommended to also post it here.

I am setting up a problem in Plasmo, in which some nodes have (some of) the same variables & constraints as other nodes. So I wanted to write a function that takes in a graph, and a symbol, and adds a node (with some constraints) to the graph with that node. Then afterwards, I could add the constraints specific to that node.

The below is a small MWE, however it doesn’t work. I was told on Slack that @optinode doesn’t see that name is actually :trial .

using Plasmo

graph = OptiGraph()

function CreateNode!(graph, name)
    @optinode(graph, name)
    @variable(name, y >= 2)

CreateNode!(graph, :trial)

@linkconstraint(graph, trail[:y] == 10)

I suppose that an alternative would be to create the node out of the function, and then have the function add variables/constraints to the node. Is there a cleaner way to do this?

1 Like

Hi @evrenmturan, welcome to the forum. Thanks for posting over here.

You can’t do what you are trying to do for two reasons:

  1. @optinode(graph, name) will create a node named name, not named what the value of name is.
  2. Even if you could, the optinode would be created in the scope of the CreateNode! function. It wouldn’t be visible to @linkconstraint outside.

Note that 2) isn’t a Plasmo or macro issue, it applies to all Julia code. For example:

julia> function foo(x)
           y = 1
           return x + y
foo (generic function with 1 method)

julia> foo(2)

julia> y
ERROR: UndefVarError: `y` not defined

I would do instead something like this:

using Plasmo
function create_node(graph, name::Symbol)
    node = Plasmo.add_node!(graph)
    node.label = string(name)
    @variable(node, y >= 2)
    graph[name] = node
    return node
graph = OptiGraph()
trial = create_node(graph, :trial)
@linkconstraint(graph, trial[:y] == 10)

Note that we return trial from create_node so that we can use it in @linkconstraint.

1 Like