Commit 91a726a6 authored by Jorn Baayen's avatar Jorn Baayen

Refine ekxamples some more.

parent 0dd265d1
......@@ -12,7 +12,7 @@ model Example
length = 20000,
uniform_nominal_depth = 5,
friction_coefficient = 35,
n_level_nodes = 4,
n_level_nodes = 21,
Q(each nominal = 100.0)
) annotation(Placement(visible = true, transformation(origin = {-60, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Deltares.ChannelFlow.Hydraulic.Branches.HomotopicTrapezoidal middle(
......@@ -25,7 +25,7 @@ model Example
length = 20000,
uniform_nominal_depth = 5,
friction_coefficient = 35,
n_level_nodes = 4,
n_level_nodes = 21,
Q(each nominal = 100.0)
) annotation(Placement(visible = true, transformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Deltares.ChannelFlow.Hydraulic.Branches.HomotopicTrapezoidal downstream(
......@@ -38,7 +38,7 @@ model Example
length = 20000,
uniform_nominal_depth = 5,
friction_coefficient = 35,
n_level_nodes = 4,
n_level_nodes = 21,
Q(each nominal = 100.0)
) annotation(Placement(visible = true, transformation(origin = {58, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Deltares.ChannelFlow.Hydraulic.Structures.DischargeControlledStructure dam_middle annotation(Placement(visible = true, transformation(origin = {30, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
......@@ -64,7 +64,12 @@ equation
connect(Discharge.HQ, upstream.HQUp) annotation(Line(points = {{-82, 0}, {-68, 0}}, color = {0, 0, 255}));
connect(Level.HQ, downstream.HQDown) annotation(Line(points = {{66, 0}, {82, 0}, {82, 0}, {82, 0}}, color = {0, 0, 255}));
initial equation
downstream.Q[2:downstream.n_level_nodes + 1] = Inflow_Q;
middle.Q[2:middle.n_level_nodes + 1] = Inflow_Q;
upstream.Q[2:upstream.n_level_nodes + 1] = Inflow_Q;
//der(downstream.H[1:upstream.n_level_nodes - 1]) = 0;//fill(0.0, upstream.n_level_nodes - 1);
//der(middle.H[1:middle.n_level_nodes - 1]) = 0; //fill(0.0, middle.n_level_nodes - 1);
//der(upstream.H[1:downstream.n_level_nodes - 1]) = 0;// fill(0.0, downstream.n_level_nodes - 1);
//downstream.Q[2:downstream.n_level_nodes + 1] = Inflow_Q;
//middle.Q[2:middle.n_level_nodes + 1] = Inflow_Q;
//upstream.Q[2:upstream.n_level_nodes + 1] = Inflow_Q;
// Start on set point
//downstream.H[downstream.n_level_nodes + 0] = 10;
end Example;
......@@ -12,5 +12,7 @@ model ExampleHybrid
output Modelica.SIunits.VolumeFlowRate Q_dam_middle = dam_middle.Q;
input Modelica.SIunits.VolumeFlowRate Q_dam_upstream(fixed = false, min = 0.0, max = 1000.0, nominal = 100.0) = dam_upstream.Q;
initial equation
upstream.H[4] = 20.0;
//upstream.H[4] = 20.0;
//middle.H[middle.n_level_nodes] = 15;
upstream.H[upstream.n_level_nodes] = 20;
end ExampleHybrid;
......@@ -3,6 +3,6 @@ model ExampleOptimization
input Modelica.SIunits.VolumeFlowRate Q_dam_upstream(fixed = false, min = 0.0, max = 1000.0, nominal = 100.0) = dam_upstream.Q;
input Modelica.SIunits.VolumeFlowRate Q_dam_middle(fixed = false, min = 0.0, max = 1000.0, nominal = 100.0) = dam_middle.Q;
initial equation
upstream.H[4] = 20.0;
middle.H[4] = 15.0;
middle.H[middle.n_level_nodes] = 15;
upstream.H[upstream.n_level_nodes] = 20;
end Example;
......@@ -52,7 +52,7 @@ class ExampleHybrid(
return goals
def solver_options(self):
def __solver_options(self):
options = super().solver_options()
options['ipopt.linear_solver'] = 'ma86'
options['ipopt.nlp_scaling_method'] = 'none'
......@@ -61,7 +61,7 @@ class ExampleHybrid(
options['expand'] = True #TODO
return options
def goal_programming_options(self):
def __goal_programming_options(self):
options = super().goal_programming_options()
options['scale_by_problem_size'] = False
options['keep_soft_constraints'] = False
......
......@@ -97,7 +97,7 @@ class ExampleOptimization(
@property
def extra_variables(self):
return super().extra_variables #+ [self._a_u, self._a_m]
return super().extra_variables + [self._a_u, self._a_m]
def bounds(self):
bounds = super().bounds()
......@@ -113,14 +113,14 @@ class ExampleOptimization(
def path_constraints(self, ensemble_member):
path_constraints = super().path_constraints(ensemble_member)
#path_constraints.append((self.state("dam_upstream.HQUp.Q") - self._a_u, -np.inf, 0.0))
#path_constraints.append((self.state("dam_middle.HQUp.Q") - self._a_m, -np.inf, 0.0))
path_constraints.append((self.state("dam_upstream.HQUp.Q") - self._a_u, -np.inf, 0.0))
path_constraints.append((self.state("dam_middle.HQUp.Q") - self._a_m, -np.inf, 0.0))
return path_constraints
def goals(self):
goals = [
#MinAmplitudeGoal('a_u', 2),
#MinAmplitudeGoal('a_m', 2),
MinAmplitudeGoal('a_u', 2),
MinAmplitudeGoal('a_m', 2),
]
return goals
......@@ -131,8 +131,8 @@ class ExampleOptimization(
TargetLevelGoal("dam_middle.HQUp.H", 15.0, 1.0, 1),
TargetLevelGoal("dam_upstream.HQUp.H", 20.0, 0.0, 2),
TargetLevelGoal("dam_middle.HQUp.H", 15.0, 0.0, 2),
TargetMaximumDischargeGoal("dam_upstream.HQUp.Q", 100, 0.0, 2),
TargetMaximumDischargeGoal("dam_middle.HQUp.Q", 100, 0.0, 2),
#TargetMaximumDischargeGoal("dam_upstream.HQUp.Q", 100, 0.0, 2), # instead of MinAmplitudeGoals above
#TargetMaximumDischargeGoal("dam_middle.HQUp.Q", 100, 0.0, 2),
SmoothingGoal("dam_upstream.HQUp.Q", 1e-2, 4),
SmoothingGoal("dam_middle.HQUp.Q", 1e-2, 4),
]
......
......@@ -34,11 +34,27 @@ class TargetLevelGoal(Goal):
order = 2
class TargetMaximumDischargeGoal(Goal):
"""Really Simple Target Level Goal"""
def __init__(self, state, target_level, margin, priority):
self.function_range = 0, 1000
self.function_nominal = 100
self.target_max = target_level + margin / 2
self.state = state
self.priority = priority
def function(self, optimization_problem, ensemble_member):
return optimization_problem.state(self.state)
order = 2
class SmoothingGoal(Goal):
"""Smoothing Goal"""
def __init__(self, state, priority):
self.function_nominal = 5e-1
def __init__(self, state, nominal, priority):
self.function_nominal = nominal
self.state = state
self.priority = priority
......@@ -81,7 +97,7 @@ class ExampleOptimization(
@property
def extra_variables(self):
return super().extra_variables + [self._a_u, self._a_m]
return super().extra_variables #+ [self._a_u, self._a_m]
def bounds(self):
bounds = super().bounds()
......@@ -89,6 +105,14 @@ class ExampleOptimization(
bounds['a_m'] = (0.0, 1000.0)
return bounds
def constant_inputs(self, ensemble_member):
constant_inputs = super().constant_inputs(ensemble_member)
#constant_inputs['Inflow_Q'].values.fill(500.0)
#constant_inputs['Inflow_Q'].values[0] = 100.0
#constant_inputs['Inflow_Q'].values.fill(100.0)
#constant_inputs['Inflow_Q'].values[0] = 500.0
return constant_inputs
def variable_nominal(self, variable):
if variable in set(['a_u', 'a_m']):
return 100.0
......@@ -97,28 +121,32 @@ class ExampleOptimization(
def path_constraints(self, ensemble_member):
path_constraints = super().path_constraints(ensemble_member)
path_constraints.append((self.state("dam_upstream.HQUp.Q") - self._a_u, -np.inf, 0.0))
path_constraints.append((self.state("dam_middle.HQUp.Q") - self._a_m, -np.inf, 0.0))
#path_constraints.append((self.state("dam_upstream.HQUp.Q") - self._a_u, -np.inf, 0.0))
#path_constraints.append((self.state("dam_middle.HQUp.Q") - self._a_m, -np.inf, 0.0))
return path_constraints
def goals(self):
goals = [
MinAmplitudeGoal('a_u', 2),
MinAmplitudeGoal('a_m', 2),
#MinAmplitudeGoal('a_u', 2),
#MinAmplitudeGoal('a_m', 2),
]
return goals
def path_goals(self):
path_goals = [
TargetLevelGoal("dam_upstream.HQUp.H", 20.0, 1.0, 1),
TargetLevelGoal("dam_middle.HQUp.H", 15.0, 1.0, 1),
#TargetLevelGoal("dam_upstream.HQUp.H", 20.0, 1.0, 1),
#TargetLevelGoal("dam_middle.HQUp.H", 15.0, 1.0, 1),
TargetLevelGoal("dam_upstream.HQUp.H", 20.0, 0.0, 2),
TargetLevelGoal("dam_middle.HQUp.H", 15.0, 0.0, 2),
SmoothingGoal("dam_upstream.HQUp.Q", 2),
SmoothingGoal("dam_middle.HQUp.Q", 2),
#TargetMaximumDischargeGoal("dam_upstream.HQUp.Q", 100, 0.0, 2),
#TargetMaximumDischargeGoal("dam_middle.HQUp.Q", 100, 0.0, 2),
#SmoothingGoal("dam_upstream.HQUp.Q", 1e-2, 4),
#SmoothingGoal("dam_middle.HQUp.Q", 1e-2, 4),
]
# TODO idea: spmile cutoff goal
return path_goals
def solver_options(self):
......@@ -132,7 +160,7 @@ class ExampleOptimization(
def goal_programming_options(self):
options = super().goal_programming_options()
options['keep_soft_constraints'] = False
options['keep_soft_constraints'] = True
options['scale_by_problem_size'] = False
return options
......
......@@ -8,10 +8,16 @@ class SteadyStateInitializationMixin(OptimizationProblem):
parameters = self.parameters(ensemble_member)
# Force steady-state initialization at t0 and at t1.
# TODO move to initial equation section.
n_level_nodes = 21
for reach in ['upstream', 'middle', 'downstream']:
for i in range(int(parameters[f'{reach}.n_level_nodes']) + 1):
for i in range(n_level_nodes + 1):
state = f'{reach}.Q[{i + 1}]'
c.append(
(self.der_at(state, times[0]), 0, 0)
)
for i in range(n_level_nodes):
state = f'{reach}.H[{i + 1}]'
c.append(
(self.der_at(state, times[0]), 0, 0)
)
return c
......@@ -4,7 +4,7 @@ from rtctools.optimization.optimization_problem import OptimizationProblem
class StepSizeParameterMixin(OptimizationProblem):
step_size = 5 * 60 # 15 minutes
step_size = 15 * 60 # 15 minutes
def times(self, variable=None):
times = super().times(variable)
......@@ -14,3 +14,14 @@ class StepSizeParameterMixin(OptimizationProblem):
p = super().parameters(ensemble_member)
p['step_size'] = self.step_size
return p
def solver_options(self):
o = super().solver_options()
o['expand'] = True
o['ipopt.linear_solver'] = 'ma86'
return o
def compiler_options(self):
o = super().compiler_options()
o['replace_parameter_values'] = True
return o
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment