Skip to content
Snippets Groups Projects
Commit 34b90daa authored by Steinmann's avatar Steinmann
Browse files

redone flow requirement objectivbe

parent b8fb9bf2
Branches Sprint/2021-07
Tags
No related merge requests found
%% Cell type:markdown id: tags:
Formulieren der Optimierungsgleichung in pymoo
%% Cell type:markdown id: tags:
Es gilt die Kontinuitätsgleichung:
$ \Sigma \dot{V}_k(t) = O$
und die aus der Topologie resultierende Inzidenzmatrix $A_i$
sowie die aus dem Pumpenkennfeld folgende Beziehung:
$\Delta p=\alpha_1 Q^2+\alpha_2 Q n+\alpha_3 n^2 : n \in \{0\} \cup [n_{\mathrm{min}},n_{\mathrm{max}}] $
$P=\beta_1 Q^3+\beta_2 Q^2 n+\beta_3 Q n^2+\beta_4n^3+\beta_5$
und die beziehung für den Druckverlust an den Ventilen:
$\Delta p_{\mathrm{loss}} = - \frac{1}{2} \varrho \zeta \left(\frac{Q}{A}\right)^2 = -l Q^2 :l\in [l_{\mathrm{min}}:\infty )$
nun soll für einen Gegebenen Volumenstrom $Q$ eine Optimale Drehzahl bestimmt werden, welche die Pumpenlesitung minimiert.
$$
\begin{align*}
\mathrm{min} \sum_{p \in \mathcal{P}} Po_{p} \\
Q_{p,i} \geq \sum_{strang} Q_v + \sum_{strang} Q_p \\
Q_p , n\epsilon [n_{min},n_{max}] \\
\overrightarrow{n} = (1,n,n^2,n^3)^T \\
min P = A \overrightarrow{n} \\
-n\leq n_{min} \\
n\leq n_{max}
\end{align*}
$$
Förderhöhe als constraint continuität fomulieren pro strang
%% Cell type:code id: tags:
``` python
!pip install pyomo
```
%% Output
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pyomo in c:\users\steinmann\appdata\roaming\python\python312\site-packages (6.8.2)
Requirement already satisfied: ply in c:\users\steinmann\appdata\roaming\python\python312\site-packages (from pyomo) (3.11)
[notice] A new release of pip is available: 24.2 -> 25.0
[notice] To update, run: C:\Program Files\Python312\python.exe -m pip install --upgrade pip
%% Cell type:code id: tags:
``` python
#Pump-Powercurve and Pump-Hightcurve
import regression_own
(LR_H,LR_P)=regression_own.regress_pump()
```
%% Output
R^20.9998289611292903
R^20.9994449560888792
%% Cell type:code id: tags:
``` python
#Graph constroctor
#Alle Ventile sind direkt mit der Quelle/Senke Verbunden
import multiDiGraph as gr
nodes =['source','pump1','pump2','valveA','valveB','valveC']
graph = gr.construct_graph('source',('source','pump1',0.),('pump1','pump2',0.),('pump2','valveA',0.),('pump2','valveB',0.),
('pump1','valveC',0.),('valveA','source',4.),('valveB','source',4.),('valveC','source',4.))
#ist das notwendig?!?
for node in graph.nodes:
#definieren der Drehzahl für jede Pumpe im graphen
#inizieren des Durchflusses für jedes Ventil im Graphen
if 'pump' in node:
graph.nodes[node]['n']=750/3600
else:
graph.nodes[node]['n']=None
graph.nodes[node]['flow']=0.
if 'valve' in node:
graph.nodes[node]['flow']= graph[node]['source'][0]['weight']
for node in graph.nodes:
#Berechnen des Durchflusses im Knoten
if 'valve' in node:
continue
for inF in graph.predecessors(node):
graph.nodes[node]['flow'] += graph[inF][node][0]['weight']
#Berechnen des Durchflusses der abgehenden Kanten
tempF=graph.nodes[node]['flow']
SC=0
for outF in graph.successors(node):
if 'valve' in outF:
graph[node][outF][0]['weight']=graph.nodes[outF]['flow']
tempF=tempF - graph.nodes[outF]['flow']
else:
SC+=1
for outF in graph.successors(node):
if SC!=0. and not'valve' in outF:
graph[node][outF][0]['weight']=tempF/SC
else:continue
print(graph.nodes.data('flow'))
```
%% Output
[('source', 12.0), ('pump1', 12.0), ('pump2', 8.0), ('valveA', 4.0), ('valveB', 4.0), ('valveC', 4.0)]
%% Cell type:code id: tags:
``` python
import networkx as nx
Mtrx= nx.incidence_matrix(graph,nodes,oriented=True)
```
%% Cell type:code id: tags:
``` python
import networkx as nx
def create_dict(GR:nx.multidigraph):
data={None:{'nodes':{},
'pumps':{},
'valves':{},
}
}
for node in GR.nodes:
data[None]['nodes'][node]=None
data[None]['Q'][node]=GR.nodes[node]['flow']
if 'pump' in node:
data[None]['pumps'][node]=None
data[None]['n'][node]=0.
if 'valve' in node:
data[None]['valves'][node]=None
return data
```
%% Cell type:markdown id: tags:
Durchfluss aus Incidenzmatrix beerechnen
Zeilen = knoten
Spalten = kanten
Summe pro knoten = 0
Q pump muss größer gleich sein als alle nachfolgenden durchflüsse
%% Cell type:code id: tags:
``` python
#defining abstract modell for given Network
import pyomo.environ as pyo
from pyomo.dataportal import DataPortal
import numpy as np
from sklearn.linear_model import LinearRegression
modell = pyo.AbstractModel()
#notwendige Mengen zur Berechnung der Constraints
modell.nodes = pyo.Set()
modell.pumps = pyo.Set()
modell.valves = pyo.Set()
modell.Q_valve=pyo.Param(modell.valves)
#Optimierungsvariable
modell.n = pyo.Var(modell.pumps,bounds=(750/3600,1))
modell.Q = pyo.Var(modell.nodes)
#Objective
def PumpPower(modell):
return sum(np.dot(
np.array(
[modell.Q[i]**3,(modell.Q[i]**2)*modell.n[i],modell.Q[i]*modell.n[i]**2,modell.n[i]**3]
),LR_P.coef_
) for i in modell.pumps)
modell.Power_Objective = pyo.Objective(rule=PumpPower,sense=pyo.minimize)
def PumpFlow(modell,pump):
pump=np.dot(np.array([modell.Q[pump]**2,modell.n[pump]*modell.Q[pump],modell.n[pump]**2]),LR_H.coef_)
return pump>=sum(modell.Q_valve[node] for node in graph.successors(pump) if node in modell.valves)+sum(modell.Q[n] for n in graph.successors(node) if node in modell.pumps)
#modell.Flow_Objective = pyo.Objective(rule=PumpFlow,sense=pyo.as_boolean)
return np.dot(np.array([modell.Q[pump]**2,modell.n[pump]*modell.Q[pump],modell.n[pump]**2]),LR_H.coef_)
def Flow_req(modell,p):
return PumpFlow(modell,p) - pyo.summation(modell.Q,index=graph.successors(p))
modell.Flow_Objective = pyo.Objective(modell.pumps,rule=Flow_req,sense=pyo.minimize)
#Constaints
def continuityRule(modell,node):
return sum(modell.Q[i] for i in graph.predecessors(node))==sum(modell.Q[j] for j in graph.successors(node))
return pyo.summation(modell.Q, index=graph.predecessors(node))==pyo.summation(modell.Q, index=graph.successors(node))
#alternative
def continuityRule2(modell,node):
return 0.==sum(graph[node][i][0]['weight'] for i in graph[node])
#continuity adjustment for change in hight needed
#construction of test Data dictionairy missing
TestData={
None:{
'nodes':[key for key in graph.nodes.keys()],
'pumps':[key for key in graph.nodes.keys() if 'pump' in key],
'valves':[key for key in graph.nodes.keys() if 'valve' in key],
'Q_valve':{'valveA':4.,'valveB':4.,'valveC':4.},
}
}
print(TestData)
#data=DataPortal(data_dict=TestData)
#Optimierungsgleichung
#modell.pump_constraint = pyo.Constraint(expr=sum(modell.nodes[k] for k in modell.nodes)==0,rule=continuityRule)
#instance=modell.create_instance(graph,LR_H)
#instance.obj = pyo.Objective(expr=sum(PumpPower(modell.Q[i],modell.n[i],LR_P) for i in modell.pumps),sense=min)
```
%% Output
{None: {'nodes': ['source', 'pump1', 'pump2', 'valveA', 'valveB', 'valveC'], 'pumps': ['pump1', 'pump2'], 'valves': ['valveA', 'valveB', 'valveC'], 'Q_valve': {'valveA': 4.0, 'valveB': 4.0, 'valveC': 4.0}}}
%% Cell type:markdown id: tags:
Frage: gibt es nur eine Lösung für Drehzahl?
Bsp. Optimierung nach Dezentraler Pumpe um modell zu prüfen
%% Cell type:code id: tags:
``` python
from pyomo.opt import SolverFactory
#opt = pyo.SolverFactory('scipampl', executable=r'C:\Program Files\SCIPOptSuite 9.2.0\bin\scip.exe')
instance = modell.create_instance(TestData)
instance.Continuity_constaint=pyo.Constraint(instance.nodes, rule=continuityRule)
#result=opt.solve(instance, tee=True)
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment