프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

hytos / HYTOS / HYTOS / Shapes / EngineeringLoopItem.py @ 4d27dd9c

이력 | 보기 | 이력해설 | 다운로드 (18.1 KB)

1
# coding: utf-8
2
import os.path
3
import copy
4
import sys
5
try:
6
    from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QObject, QT_VERSION_STR, QRect
7
    from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont, QColor
8
    from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsTextItem, QGraphicsRectItem
9
except ImportError:
10
    try:
11
        from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QRect, QObject, QT_VERSION_STR
12
        from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont, QColor
13
    except ImportError:
14
        raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
15

    
16
from EngineeringAbstractItem import QEngineeringAbstractItem
17
from AppDocData import *
18

    
19
class QEngineeringLoopItem(QEngineeringAbstractItem):
20
    """ This is QEngineeringLoopItem class """
21
    
22
    def __init__(self, _items):
23
        """ constructure """
24
        import uuid
25

    
26
        QEngineeringAbstractItem.__init__(self)
27

    
28
        self._UID = None
29
        self._name = None
30
        self.items = _items
31

    
32
        self.pressures = {}
33
        self.pressure_drops = {}
34
        self.density_elevations = {}
35
        self.extras = {}
36
 
37
    def __repr__(self):
38
        """ return string represent loop item """
39
        return '{}'.format(self.items)
40

    
41
    @property
42
    def name(self):
43
        return self._name
44

    
45
    @name.setter
46
    def name(self, value):
47
        self._name = value
48

    
49
    def calculate(self):
50
        """ calculate Pressure Drop (Static), Pressure @ Pipe end point of stream line """
51
        from AppDocData import AppDocData
52

    
53
        try:
54
            #(1) 기기들의 del.p, p, el을 넣음
55
            self.p_eq_input()
56

    
57
            #(3) 계산 시작
58
            self.discharge_cal()
59
            if not self.items[1] in self.pressures or not self.pressures[self.items[1]]: self.suction_cal()
60
        except Exception as ex:
61
            from App import App 
62
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
63
            App.mainWnd().addMessage.emit(MessageType.Error, message)
64

    
65
    def discharge_cal(self):
66
        try:
67
            for i in range(len(self.items) - 2, 0, -3): # backward
68
                self.discharge_den(i)           #(1) density 입력
69
                self.discharge_static_cal(i)    #(2) static P를 계산
70

    
71
                #(3) pressure drop 계산
72
                #liquid 인 경우 stream 시트로부터 del.P를 입력해줌.
73
                #vapor인 경우 압력강하를 계산해주고 넣어주는 모듈
74
                if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
75
                    self.pressure_drops[self.items[i]] = self.items[i].press_drop
76
                    asd = self.discharge_p_cal(i)
77
                    if asd == 0: break
78
                elif self.items[i].phase_type == 'Vapor':
79
                    pass #TODO: 
80
        except Exception as ex:
81
            from App import App 
82
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
83
            App.mainWnd().addMessage.emit(MessageType.Error, message)
84

    
85
    def suction_cal(self):
86
        try:
87
            for i in range(1, len(self.items) - 1, 3):
88
                self.suction_find_line(i)
89
                self.suction_static_cal(i) #static P를 계산해줌
90

    
91
                #라인이 liqiud 인지 vapor인지 판별
92
                if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
93
                    #liquid 인 경우 stream 데이타로부터 del.P를 입력해줌.
94
                    self.pressure_drops[self.items[i]] = self.items[i].data.pressure_drop_friction
95
                    res = self.suction_p_cal(i)
96
                    if res == 0: break
97
                elif self.items[i].data.phase_type == 'Vapor':
98
                    pass #TODO:
99
        except Exception as ex:
100
            from App import App 
101
            message = 'error occured({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
102
            App.mainWnd().addMessage.emit(MessageType.Error, message)
103

    
104
    def suction_find_line(self, i):
105
        if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
106
            self.density_elevations[self.items[i]] = self.items[i].data.density
107
        elif self.items[i].data.phase_type == 'Vapor':
108
            self.suction_vapor_density(i)
109
        else:
110
            raise ValueError('You have to input the properties of stream <{}>\nCalculation will be terminated !'.format(self.items[i].data.stream_no))
111

    
112
    def suction_vapor_density(self, i):
113
        pass
114

    
115
    def suction_static_cal(self, i):
116
        try:
117
            if self.items[i].data.phase_type == 'Mixed':
118
                pass    #TODO:
119
            else:
120
                app_doc_data = AppDocData.instance()
121
                units = [attr[1] for attr in app_doc_data.activeDrawing.attrs if attr[0] == 'Units'][0]
122
                if units['Density'] == 'kg/m3':
123
                    density2 = self.density_elevations[self.items[i]]
124
                else:
125
                    density2 = self.density_elevations[self.items[i]] * 16.0185 #lb/ft3
126

    
127
                #2 elevation 받음
128
                if units['Length'] == 'm':
129
                    el1 = self.density_elevations[self.items[i-1]]
130
                    el2 = self.density_elevations[self.items[i+1]]
131
                elif units['Length'] == 'in':
132
                    el1 = self.density_elevations[self.items[i-1]] * 0.0254
133
                    el2 = self.density_elevations[self.items[i+1]] * 0.0254
134
                elif units['Length'] == 'ft':
135
                    el1 = self.density_elevations[self.items[i-1]] * 0.3048 
136
                    el2 = self.density_elevations[self.items[i+1]] * 0.3048
137
                elif units['Length'] == 'yd':
138
                    el1 = self.density_elevations[self.items[i-1]] * 0.9144
139
                    el2 = self.density_elevations[self.items[i+1]] * 0.9144
140
                elif units['Length'] == 'mm':
141
                    el1 = self.density_elevations[self.items[i-1]] * 0.001
142
                    el2 = self.density_elevations[self.items[i+1]] * 0.001
143
                else:    #mile
144
                    el1 = self.density_elevations[self.items[i-1]] * 1609.34
145
                    el2 = self.density_elevations[self.items[i+1]] * 1609.34
146

    
147
                #3. static head 계산
148
                stat_dp = (el2 - el1) * density2 / 1000 * 9.80665 / 101.325 #atm으로 계산된 dp
149

    
150
                #4. 압력 유닛에 맞춰 뿌리기
151
                if units['Pressure'] == 'kg/cm2':
152
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 1.033
153
                elif units['Pressure'] == 'psi':
154
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 14.7
155
                elif units['Pressure'] == 'atm':
156
                    self.pressure_drops[self.items[i - 1]] = stat_dp
157
                elif units['Pressure'] == 'bar':
158
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 1.013
159
                elif units['Pressure'] == 'mmHg':
160
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 760
161
                elif units['Pressure'] == 'kPa':
162
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 101.325
163
                elif units['Pressure'] == 'MPa':
164
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 0.101325
165
        except Exception as ex:
166
            from App import App 
167
            message = 'error occured({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
168
            App.mainWnd().addMessage.emit(MessageType.Error, message)
169

    
170
    def p_eq_input(self):
171
        try:
172
            # 시작, 끝 기기의 pressure와 elevation을 구한다
173
            self.pressures[self.items[0]] = self.items[0].data.pressure
174
            self.density_elevations[self.items[0]] = self.items[0].data.elevation
175
            self.pressures[self.items[-1]] = self.items[-1].data.pressure
176
            self.density_elevations[self.items[-1]] = self.items[-1].data.elevation
177

    
178
            for i in range(2, len(self.items) - 2, 3):
179
                dp_eq = str(self.items[i])[:3]
180
                if dp_eq == 'HEX' or dp_eq == 'M_D' or dp_eq == 'M_R': dp_eq = str(self.items[i])[:3]
181

    
182
                #pressure drop
183
                self.pressure_drops[self.items[i]] = self.items[i].data.pressure_drop
184
                if not self.items[i].data.pressure_drop:
185
                    pass
186

    
187
                #elevation
188
                if dp_eq[:3] == 'M_R':
189
                    self.density_elevations[self.items[i]] = self.items[i].data.elevation
190
                    self.density_elevations[self.items[i+1]] = self.items[i+1].data.elevation
191
                else:
192
                    self.density_elevations[self.items[i]] = self.items[i].data.elevation
193
                    self.density_elevations[self.items[i+1]] = self.items[i+1].data.elevation
194

    
195
                if dp_eq[:3] == 'L_P' or dp_eq[:3] == 'R_P' or dp_eq[:3] == 'V_P' or dp_eq[:3] == 'R_K':
196
                    self.extras[self.items[i]] = self.items[i].data.over_design_cv
197
                elif dp_eq[:3] == 'CV_':
198
                    self.extras[self.items[i]] = self.items[i].data.over_design_cv
199
                    self.extras[self.items[i+1]] = None #TODO:
200
        except Exception as ex:
201
            from App import App 
202
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
203
            App.mainWnd().addMessage.emit(MessageType.Error, message)
204

    
205
    def discharge_den(self, i):
206
        try:
207
            app_doc_data = AppDocData.instance()
208
            units = [attr[1] for attr in app_doc_data.activeDrawing.attrs if attr[0] == 'Units'][0]
209

    
210
            #1. density 받음
211
            if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
212
                self.density_elevations[self.items[i]] = self.items[i].density
213
            elif self.items[i].data.phase_type == 'Vapor':
214
                self.discharge_vapor_density(i)
215
        except Exception as ex:
216
            from App import App 
217
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
218
            App.mainWnd().addMessage.emit(MessageType.Error, message)
219

    
220
    def discharge_vapor_density(self, i):
221
        pass
222

    
223
    def discharge_static_cal(self, i):
224
        """ (2) static P를 계산 """
225

    
226
        try:
227
            app_doc_data = AppDocData.instance()
228
            units = [attr[1] for attr in app_doc_data.activeDrawing.attrs if attr[0] == 'Units'][0]
229

    
230
            #1. density 받음
231
            if self.items[i].data.phase_type == 'Mixed':
232
                pass    #TODO: 
233
            else:
234
                if units['Density'] == 'kg/m3':
235
                    density2 = self.density_elevations[self.items[i]]
236
                else:
237
                    density2 = self.density_elevations[self.items[i]] * 16.0185 #lb/ft3
238

    
239
            #2 elevation 받음
240
            if units['Length'] == 'm':
241
                el1 = self.density_elevations[self.items[i-1]]
242
                el2 = self.density_elevations[self.items[i+1]]
243
            elif units['Length'] == 'in':
244
                el1 = self.density_elevations[self.items[i-1]] * 0.0254
245
                el2 = self.density_elevations[self.items[i+1]] * 0.0254
246
            elif units['Length'] == 'ft':
247
                el1 = self.density_elevations[self.items[i-1]] * 0.3048 
248
                el2 = self.density_elevations[self.items[i+1]] * 0.3048
249
            elif units['Length'] == 'yd':
250
                el1 = self.density_elevations[self.items[i-1]] * 0.9144
251
                el2 = self.density_elevations[self.items[i+1]] * 0.9144
252
            elif units['Length'] == 'mm':
253
                el1 = self.density_elevations[self.items[i-1]] * 0.001
254
                el2 = self.density_elevations[self.items[i+1]] * 0.001
255
            else:    #mile
256
                el1 = self.density_elevations[self.items[i-1]] * 1609.34
257
                el2 = self.density_elevations[self.items[i+1]] * 1609.34
258

    
259
            #3. static head 계산
260
            stat_dp = (el2 - el1) * density2 / 1000 * 9.80665 / 101.325 #atm으로 계산된 dp
261

    
262
            #4. 압력 유닛에 맞춰 뿌리기
263
            if units['Pressure'] == 'kg/cm2':
264
                self.pressure_drops[self.items[i - 1]] = stat_dp * 1.033
265
            elif units['Pressure'] == 'psi':
266
                self.pressure_drops[self.items[i - 1]] = stat_dp * 14.7
267
            elif units['Pressure'] == 'atm':
268
                self.pressure_drops[self.items[i - 1]] = stat_dp
269
            elif units['Pressure'] == 'bar':
270
                self.pressure_drops[self.items[i - 1]] = stat_dp * 1.013
271
            elif units['Pressure'] == 'mmHg':
272
                self.pressure_drops[self.items[i - 1]] = stat_dp * 760
273
            elif units['Pressure'] == 'kPa':
274
                self.pressure_drops[self.items[i - 1]] = stat_dp * 101.325
275
            elif units['Pressure'] == 'MPa':
276
                self.pressure_drops[self.items[i - 1]] = stat_dp * 0.101325
277
        except Exception as ex:
278
            from App import App 
279
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
280
            App.mainWnd().addMessage.emit(MessageType.Error, message)
281

    
282
    def suction_p_cal(self, i):
283
        res = 1
284

    
285
        try:
286
            app_doc_data = AppDocData.instance()
287
            units = [attr[1] for attr in app_doc_data.activeDrawing.attrs if attr[0] == 'Units'][0]
288

    
289
            self.pressures[self.items[i]] = self.pressures[self.items[i - 1]] - self.pressure_drops[self.items[i - 1]]
290

    
291
            pressure_unit = units['Pressure']
292
            if pressure_unit == 'kg/cm2':
293
                pabsolute = self.pressures[self.items[i]] + 1.033
294
            elif pressure_unit == 'psi':
295
                pabsolute = self.pressures[self.items[i]] + 14.7
296
            elif pressure_unit == 'atm':
297
                pabsolute = self.pressures[self.items[i]] + 1
298
            elif pressure_unit == 'bar':
299
                pabsolute = self.pressures[self.items[i]] + 1.013
300
            elif pressure_unit == 'mmHg':
301
                pabsolute = self.pressures[self.items[i]] + 760
302
            elif pressure_unit == 'kPa':
303
                pabsolute = self.pressures[self.items[i]] + 101.325
304
            elif pressure_unit == 'MPa':
305
                pabsolute = self.pressures[self.items[i]] + 0.101325
306

    
307
            if pabsolute < 0:
308
                raise ValueError('The absolute pressure of {} is below 0.'.format(self.items[i]))
309

    
310
            if i < len(self.items) - 2:
311
                self.pressures[self.items[i + 1]] = self.pressures[self.items[i]] - self.pressure_drops[self.items[i]]
312
                if self.pressures[self.items[i + 1]] < 0:
313
                    if pressure_unit == 'kg/cm2':
314
                        pabsolute = self.pressures[self.items[i + 1]] + 1.033
315
                    elif pressure_unit == 'psi':
316
                        pabsolute = self.pressures[self.items[i + 1]] + 14.7
317
                    elif pressure_unit == 'atm':
318
                        pabsolute = self.pressures[self.items[i + 1]] + 1
319
                    elif pressure_unit == 'bar':
320
                        pabsolute = self.pressures[self.items[i + 1]] + 1.013
321
                    elif pressure_unit == 'mmHg':
322
                        pabsolute = self.pressures[self.items[i + 1]] + 760
323
                    elif pressure_unit == 'kPa':
324
                        pabsolute = self.pressures[self.items[i + 1]] + 101.325
325
                    elif pressure_unit == 'MPa':
326
                        pabsolute = self.pressures[self.items[i + 1]] + 0.101325
327

    
328
                    if pabsolute < 0:
329
                        raise ValueError('The absolute pressure of {} is below 0.'.format(self.items[i + 1]))
330

    
331
                name = str(self.items[i + 1])[:3]
332
                if not self.pressure_drops[self.items[i + 1]]:
333
                    res = 0
334
                elif name == 'L_P' or name == 'R_P' or name == 'V_P' or name == 'R_K' or name == 'L_K':
335
                    self.pressures[self.items[i + 2]] = self.pressures[self.items[i + 1]] + self.pressure_drops[self.items[i + 1]]
336
                else:
337
                    self.pressures[self.items[i + 2]] = self.pressures[self.items[i + 1]] - self.pressure_drops[self.items[i + 1]]
338
        except Exception as ex:
339
            from App import App 
340
            message = 'error occured({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
341
            App.mainWnd().addMessage.emit(MessageType.Error, message)
342

    
343
        return res
344

    
345
    def discharge_p_cal(self, i):
346
        res = 1
347

    
348
        try:
349
            self.pressures[self.items[i]] = self.pressures[self.items[i + 1]] + self.pressure_drops[self.items[i]]
350
            index = str(self.items[i - 2])[:3]
351
            if i > 0:
352
                self.pressures[self.items[i - 1]] = self.pressures[self.items[i]] + self.pressure_drops[self.items[i - 1]]
353

    
354
                if self.pressure_drops[self.items[i - 2]]:
355
                    if index == 'L_P' or index == 'R_P' or index == 'V_P' or index == 'R_K' or index == 'L_K':
356
                        self.pressures[self.items[i - 2]] = self.pressures[self.items[i - 1]] + self.pressure_drops[self.items[i - 2]]
357
                    else:
358
                        self.pressures[self.items[i - 2]] = self.pressures[self.items[i - 1]] + self.pressure_drops[self.items[i - 2]]
359
                else:
360
                    #여기에 그 루프는 그만 하는 로직을 넣어줘야함
361
                    res = 0
362
        except Exception as ex:
363
            from App import App 
364
            message = 'error occured({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
365
            App.mainWnd().addMessage.emit(MessageType.Error, message)
366

    
367
        return res
368

    
369
class Transfer(QObject):
370
    onRemoved = pyqtSignal(QGraphicsItem)
371

    
372
    def __init__(self, parent = None):
373
        QObject.__init__(self, parent)
클립보드 이미지 추가 (최대 크기: 500 MB)