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

redone flow requirement objectivbe

parent b8fb9bf2
No related branches found
No related tags found
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