Construct a JuMP model from smaller models

Hey guys, I’m quite curious about the JuMP model object. Once I construct a JuMP model where all variables and expressions are organized into one model instance which goes through many scripts and it worked. It could be solved propriately and results could be accessed.
But then I started to construct the model from smaller models. Taking objective as example, it consists of many other cost terms which are defined in other scripts. For example

## Initialize model objective function
@expression(m, eObj, 0)
...(define other variables and expressions as well as constraints)
## Define model objective function
@objective(m, Min, eObj)
...
## Another objective
@expression(m, ePObj, 0)
...
## Add it into main objective
m[:eObj] += m[:ePObj]

But either gurobi or highs solver gives zero objective in the log, and results could be accessed with non-zero values, which is strange since the ePObj is proven not zero in the output files.

Welcome.
Consider this example:

# Simple JuMP LP Example
using JuMP, Gurobi
#
model = JuMP.Model()
set_optimizer(model, Gurobi.Optimizer)
#
@variable(model, x)
@variable(model, y)

@expression(model, eObj, x + y)

@objective(model, Min, eObj)
@constraint(model, x + 2y >= 5)
@constraint(model, 4x + y >= 6)
#
print(model)
#
optimize!(model);
value(x)
value(y)
objective_value(model)

with output

julia> print(model)
Min 3 x + 4 y
Subject to
 x + 2 y ≥ 5.0
 4 x + y ≥ 6.0

julia> value(x)
1.0

julia> value(y)
2.0

julia> objective_value(model)
3.0

To modify and update the objective, I would do something like this:

## Modification:
@expression(model, ePObj, 2x + 3y)
model[:eObj] += model[:ePObj]
@objective(model, Min, model[:eObj])
#
print(model)
#
optimize!(model)
value(x)
value(y)
objective_value(model)

with output

julia> print(model)
Min 3 x + 4 y
Subject to
 x + 2 y ≥ 5.0
 4 x + y ≥ 6.0

julia> value(x)
1.0

julia> value(y)
2.0

julia> objective_value(model)
11.0

I got many sub cost terms in m[:ePObj] as well, so I took the way of initializing this expression to zero first. And then add the costs term by term.

I declare the objective macro when all costs are added.

I changed @objective(model, Min, eObj) to @objective(model, Min, model[:eObj]) and the problem vanished. What’s wrong with the previous declaration.

What’s wrong with the previous declaration

I don’t know if I fully understand the problem. Do you have a reproducible example?

This works for me:

julia> using JuMP

julia> model = Model();

julia> @variable(model, x)
x

julia> @expression(model, eObj, x)
x

julia> @objective(model, Min, eObj)
x

julia> print(model)
Min x
Subject to

julia> eObj += x
2 x

julia> @objective(model, Min, eObj)
2 x

julia> print(model)
Min 2 x
Subject to