프로젝트

일반

사용자정보

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

hytos / HYTOS / HYTOS / Shapes / EngineeringLoopItem.py @ 427ae4f8

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

1
# coding: utf-8
2
import os.path
3
import copy
4
import sys
5

    
6
try:
7
    from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QObject, QT_VERSION_STR, QRect
8
    from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont, QColor
9
    from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, \
10
        QGraphicsTextItem, QGraphicsRectItem
11
except ImportError:
12
    try:
13
        from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QRect, QObject, QT_VERSION_STR
14
        from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont, QColor
15
    except ImportError:
16
        raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
17

    
18
import math
19
from EngineeringAbstractItem import QEngineeringAbstractItem
20
from AppDocData import *
21

    
22

    
23
def is_blank(s):
24
    return not (s and s.strip())
25

    
26

    
27
def is_not_blank(s):
28
    return bool(s and s.strip())
29

    
30

    
31
class QEngineeringLoopItem(QEngineeringAbstractItem):
32
    """ This is QEngineeringLoopItem class """
33

    
34
    def __init__(self, _items):
35
        """ constructor """
36
        import uuid
37

    
38
        QEngineeringAbstractItem.__init__(self)
39

    
40
        self._UID = None
41
        self._name = None
42
        self.items = _items
43

    
44
        self.units = {}
45
        self.pressures = {}
46
        self.pressure_drops = {}
47
        self.density_elevations = {}
48
        self.extras = {}
49
        self.pattern = {}
50

    
51
        self.total_device_loss = None
52
        self.suction_line_friction_loss = None
53
        self.discharge_line_friction_loss = None
54
        self.line_total_friction_loss = None
55
        self.suction_device_loss = None
56
        self.discharge_device_loss = None
57
        self.total_suction_loss = None
58
        self.total_discharge_loss = None
59
        self.total_loss = None
60
        self.deviation = None
61

    
62
        self.fill_start = 0
63
        self.fill_end = None
64

    
65
    def __repr__(self):
66
        """ return string represent loop item """
67
        return '{}'.format(self.items)
68

    
69
    @property
70
    def name(self):
71
        return self._name
72

    
73
    @name.setter
74
    def name(self, value):
75
        self._name = value
76

    
77
    def calculate(self) -> list:
78
        """calculate Pressure Drop (Static), Pressure @ Pipe end point of stream line
79
        return error messages
80
        """
81
        from AppDocData import AppDocData
82

    
83
        messages = []
84
        try:
85
            # (0) Units
86
            self.init_units()
87

    
88
            # (1) 기기들의 del.p, p, el을 넣음
89
            self.p_eq_input()
90

    
91
            # (3) 계산 시작
92
            self.discharge_cal()
93

    
94
            if not self.items[1] in self.pressures or not self.pressures[self.items[1]]:
95
                messages = self.suction_cal()
96

    
97
            # Hole Calculation
98
            # cv와 pump가 다 없을때 (Hole Case)
99
            if self.fill_end - self.fill_start > 3:
100
                self.hole_calc(self.fill_start, self.fill_end)
101
                self.loss_input()
102
                self.cv_dp_cal()
103
                self.hole_recalc(self.fill_start, self.fill_end)
104
            else:
105
                self.loss_input()
106

    
107
            name = str(self.items[self.fill_start + 1])[:3]
108
            if name == 'CV_':
109
                self.pressure_drops[self.items[self.fill_start + 1]] = self.pressures[
110
                                                                           self.items[self.fill_start + 1]] - \
111
                                                                       self.pressures[
112
                                                                           self.items[self.fill_start + 2]]
113

    
114
                if self.pressure_drops[self.items[self.fill_start + 1]] < 0:
115
                    messages.append('Control valve pressure drop is below zero.')
116

    
117
            elif name == 'R_P' or name == 'L_P' or name == 'V_P' or name == 'R_K' or name == 'L_K':
118
                self.pressure_drops[self.items[self.fill_start + 1]] = self.pressures[
119
                                                                           self.items[self.fill_start + 2]] - \
120
                                                                       self.pressures[
121
                                                                           self.items[self.fill_start + 1]]
122

    
123
        except Exception as ex:
124
            from App import App
125
            message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
126
                      f"{sys.exc_info()[-1].tb_lineno}"
127
            App.mainWnd().addMessage.emit(MessageType.Error, message)
128

    
129
        return messages
130

    
131
    def init_units(self):
132
        try:
133
            app_doc_data = AppDocData.instance()
134
            self.units = [attr[1] for attr in app_doc_data.activeDrawing.attrs if attr[0] == 'Units'][0]
135
        except Exception as ex:
136
            from App import App
137
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
138
                                                           sys.exc_info()[-1].tb_lineno)
139
            App.mainWnd().addMessage.emit(MessageType.Error, message)
140

    
141
    def hole_calc(self, hole_start, hole_end):
142
        try:
143
            self.pressures[self.items[hole_end - 2]] = self.pressures[self.items[hole_end - 1]]
144
            for i in range(hole_end - 3, hole_start + 2, -3):
145
                # (1) density 입력
146
                self.discharge_den(i)
147

    
148
                # (2) static P를 계산
149
                self.discharge_static_cal(i)
150

    
151
                # (3) pressure drop 계산
152
                if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
153
                    self.pressure_drops[self.items[i]] = self.items[i].data.pressure_drop_friction
154
                    res = self.hole_p_cal(i)
155
                    if res == 0:
156
                        break
157
                elif self.items[i].data.phase_type == 'Vapor':
158
                    self.discharge_vapor_factor_length(i)
159
                    res = self.hole_p_cal(i)
160
                    if res == 0:
161
                        break
162
        except Exception as ex:
163
            from App import App
164
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
165
                                                           sys.exc_info()[-1].tb_lineno)
166
            App.mainWnd().addMessage.emit(MessageType.Error, message)
167

    
168
    def hole_recalc(self, hole_start, hole_end):
169
        try:
170
            self.pressures[self.items[hole_end - 2]] = self.pressures[self.items[hole_end - 1]] + \
171
                                                       self.pressure_drops[self.items[hole_end - 2]]
172
            for i in range(hole_end - 3, hole_start + 2, -3):
173
                # (1) density 입력
174
                self.discharge_den(i)
175

    
176
                # (2) static P를 계산
177
                self.discharge_static_cal(i)
178

    
179
                # (3) pressure drop 계산
180
                if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
181
                    self.pressure_drops[self.items[i]] = self.items[i].data.pressure_drop_friction
182
                    res = self.hole_p_cal(i)
183
                    if res == 0:
184
                        break
185
                elif self.items[i].phase_type == 'Vapor':
186
                    self.discharge_vapor_factor_length(i)
187
                    res = self.hole_p_cal(i)
188
                    if res == 0:
189
                        break
190
        except Exception as ex:
191
            from App import App
192
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
193
                                                           sys.exc_info()[-1].tb_lineno)
194
            App.mainWnd().addMessage.emit(MessageType.Error, message)
195

    
196
    def get_control_valve_equation(self):
197
        app_doc_data = AppDocData.instance()
198
        equation = app_doc_data.getConfigs('Control Valve', 'Equation')
199

    
200
        if len(equation) == 1:
201
            return equation[0].value
202
        else:
203
            return 'bd'
204

    
205
    def cv_dp_cal(self):
206
        try:
207
            acv = 0
208
            for i in range(2, len(self.items) - 3, 3):
209
                # if not self.items[i] in self.pressure_drops and str(self.items[i])[:3] == 'CV_':
210
                if self.pattern[self.items[i]] == -4125 and str(self.items[i])[:3] == 'CV_':
211
                    acv = i
212
                    break
213

    
214
            if acv:
215
                pf = (self.total_device_loss if self.total_device_loss else 0) + \
216
                     (self.line_total_friction_loss if self.line_total_friction_loss else 0)
217
                method = self.get_control_valve_equation()
218
                if method == 'bd':
219
                    self.bd_cal(pf, acv)
220
                elif method == 'lummus':
221
                    ap_lummus = 0
222
                    for i in range(2, len(self.items) - 3, 3):
223
                        if self.pattern[self.items[i]] == -4125:
224
                            name = str(self.items[i])[:3]
225
                            if name == 'R_P' or name == 'L_P' or name == 'V_P' or name == 'R_K' or name == 'L_K':
226
                                ap_lummus = i
227
                                break
228
                    self.lummus_cal(pf, acv, ap_lummus)
229
                elif method == 'mixed':
230
                    ap_lummus = 0
231
                    for i in range(2, len(self.items) - 3, 3):
232
                        if self.pattern[self.items[i]] == -4125:
233
                            name = str(self.items[i])[:3]
234
                            if name == 'R_P' or name == 'L_P' or name == 'V_P' or name == 'R_K' or name == 'L_K':
235
                                ap_lummus = i
236
                                break
237
                    self.mixed_cal(pf, acv, ap_lummus)
238
                elif method == 'aramco':
239
                    self.aramco_cal(pf, acv)
240
                elif method == 'user':
241
                    self.user_cal(acv)
242
        except Exception as ex:
243
            from App import App
244
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
245
                                                           sys.exc_info()[-1].tb_lineno)
246
            App.mainWnd().addMessage.emit(MessageType.Error, message)
247

    
248
    def mixed_cal(self, pf, acv, ap_lummus):
249
        try:
250
            mixedcvdp = [None, None, None, None, None]
251

    
252
            pressure_unit = self.units['Pressure']
253
            if pressure_unit == 'kg/cm2':
254
                mixedcvdp[0] = 0.7
255
            elif pressure_unit == 'psi':
256
                mixedcvdp[0] = 0.7 / 1.033 * 14.7
257
            elif pressure_unit == 'bar':
258
                mixedcvdp[0] = 0.7 / 1.033 * 1.013
259
            elif pressure_unit == 'mmHg':
260
                mixedcvdp[0] = 0.7 / 1.033 * 760
261
            elif pressure_unit == 'kPa':
262
                mixedcvdp[0] = 0.7 / 1.033 * 101.325
263
            elif pressure_unit == 'MPa':
264
                mixedcvdp[0] = 0.7 / 1.033 * 0.101325
265

    
266
            mixedcvdp[1] = pf / 3
267
            mixedcvdp[2] = ((1.1135 * (
268
                    (self.extras[self.items[acv]] if self.extras[self.items[acv]] else 0) / 100 + 1)) ** 2 - 1) * pf
269
            mixedcvdp[3] = self.pressures[self.items[ap_lummus + 1]] * 0.08  # 펌프 디스차지의 0.08구현
270

    
271
            # mixedcvdp (4)
272
            total_loss = 0  # (self.total_discharge_loss if self.total_discharge_loss else 0) + (self.total_suction_loss if self.total_suction_loss else 0)
273

    
274
            dpt = total_loss + pf
275
            dpf = pf / dpt
276
            od = self.extras[self.items[acv]]
277

    
278
            if od > 0.5:
279
                dpv = 0.06
280
            else:
281
                if dpf > 1:
282
                    dpf = 1
283
                    conv_od = 0.08 * dpf + 0.07
284

    
285
                    if conv_od >= od:
286
                        slope = (11 - 46 * dpf) / (7 + 8 * dpf)
287
                        dpv = slope * od + 0.5 * dpf
288
                    else:
289
                        slope = (4 * dpf + 5) / (8 * dpf - 43)
290
                        dpv = slope * od + 0.06 - slope * 0.5
291
                elif 0.75 < dpf and dpf <= 1:
292
                    conv_od = 0.08 * dpf + 0.07
293

    
294
                    if conv_od >= od:
295
                        slope = (11 - 46 * dpf) / (7 + 8 * dpf)
296
                        dpv = slope * od + 0.5 * dpf
297
                    else:
298
                        slope = (4 * dpf + 5) / (8 * dpf - 43)
299
                        dpv = slope * od + 0.06 - slope * 0.5
300
                elif 0.5 < dpf and dpf <= 0.75:
301
                    conv_od = 0.12 * dpf + 0.04
302

    
303
                    if conv_od >= od:
304
                        slope = (12.5 - 48 * dpf) / (4 + 12 * dpf)
305
                        dpv = slope * od + 0.5 * dpf
306
                    else:
307
                        slope = (2 * dpf + 6.5) / (12 * dpf - 46)
308
                        dpv = slope * od + 0.06 - slope * 0.5
309
                elif 0.4 < dpf and dpf <= 0.5:
310
                    conv_od = 0.2 * dpf
311

    
312
                    if conv_od >= od:
313
                        slope = (0.425 / dpf - 2)
314
                        dpv = slope * od + 0.5 * dpf
315
                    else:
316
                        slope = (10 * dpf + 2.5) / (20 * dpf - 50)
317
                        dpv = slope * od + 0.06 - slope * 0.5
318
                elif 0.25 <= dpf and dpf <= 0.4:
319
                    conv_od = 0.2333 * dpf - 0.0133
320

    
321
                    if conv_od >= od:
322
                        slope = (19 / 600 - 8 / 30 * dpf) / (7 / 30 * dpf - 1 / 75)
323
                        dpv = slope * od + dpf / 3 + 2 / 30
324
                    else:
325
                        slope = (dpf / 15 + 23 / 600) / (7 / 30 * dpf - 38.5 / 75)
326
                        dpv = slope * od + 0.06 - slope * 0.5
327
                elif 0.25 > dpf:
328
                    conv_od = 0.03
329

    
330
                    if conv_od >= od:
331
                        slope = -0.5
332
                        dpv = slope * od + 0.125
333
                    else:
334
                        slope = -5 / 47
335
                        dpv = slope * od + 0.06 - slope * 0.5
336

    
337
            mixedcvdp[4] = dpv * dpt
338

    
339
            maxdps = [None, None]
340
            # max dp 판별
341
            maxdps[0] = max(mixedcvdp[1], mixedcvdp[4])
342
            maxdps[1] = max(mixedcvdp[2], mixedcvdp[3])
343
            maxdp = max(maxdps[0], maxdps[1])
344

    
345
            if maxdp > mixedcvdp[0]:
346
                maxdp = maxdp
347
            elif maxdp < mixedcvdp[0]:
348
                maxdp = mixedcvdp[0]
349

    
350
            # 공통이 될 부분
351
            self.pressure_drops[self.items[acv]] = maxdp
352

    
353
        except Exception as ex:
354
            from App import App
355
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
356
                                                           sys.exc_info()[-1].tb_lineno)
357
            App.mainWnd().addMessage.emit(MessageType.Error, message)
358

    
359
    def lummus_cal(self, pf, acv, ap_lummus):
360
        try:
361
            lumcvdp = [None, None, None]
362

    
363
            lumcvdp[0] = self.pressures[self.items[ap_lummus + 1]] * 0.08  # 펌프 디스차지의 0.08구현
364

    
365
            pressure_unit = self.units['Pressure']
366
            if pressure_unit == 'kg/cm2':
367
                lumcvdp[2] = 0.7
368
            elif pressure_unit == 'psi':
369
                lumcvdp[2] = 0.7 / 1.033 * 14.7
370
            elif pressure_unit == 'bar':
371
                lumcvdp[2] = 0.7 / 1.033 * 1.013
372
            elif pressure_unit == 'mmHg':
373
                lumcvdp[2] = 0.7 / 1.033 * 760
374
            elif pressure_unit == 'kPa':
375
                lumcvdp[2] = 0.7 / 1.033 * 101.325
376
            elif pressure_unit == 'MPa':
377
                lumcvdp[2] = 0.7 / 1.033 * 0.101325
378

    
379
            # lumcvdp (1) (Chart) 결정
380
            total_loss = 0  # (self.total_discharge_loss if self.total_discharge_loss else 0) + (self.total_suction_loss if self.total_suction_loss else 0)
381

    
382
            dpt = total_loss + pf
383
            dpf = pf / dpt
384
            od = self.extras[self.items[acv]]
385

    
386
            if od > 0.5:
387
                dpv = 0.06
388
            else:
389
                if dpf > 1:
390
                    dpf = 1
391
                    conv_od = 0.08 * dpf + 0.07
392

    
393
                    if conv_od >= od:
394
                        slope = (11 - 46 * dpf) / (7 + 8 * dpf)
395
                        dpv = slope * od + 0.5 * dpf
396
                    else:
397
                        slope = (4 * dpf + 5) / (8 * dpf - 43)
398
                        dpv = slope * od + 0.06 - slope * 0.5
399
                elif 0.75 < dpf and dpf <= 1:
400
                    conv_od = 0.08 * dpf + 0.07
401

    
402
                    if conv_od >= od:
403
                        slope = (11 - 46 * dpf) / (7 + 8 * dpf)
404
                        dpv = slope * od + 0.5 * dpf
405
                    else:
406
                        slope = (4 * dpf + 5) / (8 * dpf - 43)
407
                        dpv = slope * od + 0.06 - slope * 0.5
408
                elif 0.5 < dpf and dpf <= 0.75:
409
                    conv_od = 0.12 * dpf + 0.04
410

    
411
                    if conv_od >= od:
412
                        slope = (12.5 - 48 * dpf) / (4 + 12 * dpf)
413
                        dpv = slope * od + 0.5 * dpf
414
                    else:
415
                        slope = (2 * dpf + 6.5) / (12 * dpf - 46)
416
                        dpv = slope * od + 0.06 - slope * 0.5
417
                elif 0.4 < dpf and dpf <= 0.5:
418
                    conv_od = 0.2 * dpf
419

    
420
                    if conv_od >= od:
421
                        slope = (0.425 / dpf - 2)
422
                        dpv = slope * od + 0.5 * dpf
423
                    else:
424
                        slope = (10 * dpf + 2.5) / (20 * dpf - 50)
425
                        dpv = slope * od + 0.06 - slope * 0.5
426
                elif 0.25 <= dpf and dpf <= 0.4:
427
                    conv_od = 0.2333 * dpf - 0.0133
428

    
429
                    if conv_od >= od:
430
                        slope = (19 / 600 - 8 / 30 * dpf) / (7 / 30 * dpf - 1 / 75)
431
                        dpv = slope * od + dpf / 3 + 2 / 30
432
                    else:
433
                        slope = (dpf / 15 + 23 / 600) / (7 / 30 * dpf - 38.5 / 75)
434
                        dpv = slope * od + 0.06 - slope * 0.5
435
                elif 0.25 > dpf:
436
                    conv_od = 0.03
437

    
438
                    if conv_od >= od:
439
                        slope = -0.5
440
                        dpv = slope * od + 0.125
441
                    else:
442
                        slope = -5 / 47
443
                        dpv = slope * od + 0.06 - slope * 0.5
444

    
445
            lumcvdp[1] = dpv * dpt
446

    
447
            maxdp = max(lumcvdp[0], lumcvdp[1])
448
            maxdp = max(maxdp, lumcvdp[2])
449

    
450
            # 공통이 될 부분
451
            self.pressure_drops[self.items[acv]] = maxdp
452

    
453
        except Exception as ex:
454
            from App import App
455
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
456
                                                           sys.exc_info()[-1].tb_lineno)
457
            App.mainWnd().addMessage.emit(MessageType.Error, message)
458

    
459
    def user_cal(self, acv):
460
        try:
461
            eq1 = 0
462
            eq2 = 0
463
            eq3 = 0
464
            eq4 = 0
465
            eq5 = 0
466

    
467
            A = (self.suction_device_loss if self.suction_device_loss else 0) + (
468
                self.suction_line_friction_loss if self.suction_line_friction_loss else 0)
469
            B = self.total_suction_loss if self.total_suction_loss else 0
470
            C = (self.discharge_device_loss if self.discharge_device_loss else 0) + (
471
                self.discharge_line_friction_loss if self.discharge_line_friction_loss else 0)
472
            D = self.total_discharge_loss if self.total_discharge_loss else 0
473
            E = self.pressures[self.items[0]]
474
            F = self.pressures[self.items[-1]]
475
            G = (self.extras[self.items[acv]] if self.extras[self.items[acv]] else 0) + 1
476

    
477
            app_doc_data = AppDocData.instance()
478
            user_equation = app_doc_data.getConfigs('User Equation')
479
            eq1 = 0
480
            eq2 = 0
481
            eq3 = 0
482
            eq4 = 0
483
            eq5 = 0
484
            if len(user_equation) > 0:
485
                for i in range(len(user_equation)):
486
                    key = user_equation[i].key
487
                    val = user_equation[i].value
488

    
489
                    if is_blank(val):
490
                        continue
491

    
492
                    if key == '1st':
493
                        eq1 = eval(val)
494
                    elif key == '2nd':
495
                        eq2 = eval(val)
496
                    elif key == '3rd':
497
                        eq3 = eval(val)
498
                    elif key == '4th':
499
                        eq4 = eval(val)
500
                    elif key == '5th':
501
                        eq5 = eval(val)
502

    
503
            userdp1 = max(eq1, eq2)
504
            userdp2 = max(eq3, eq4)
505
            userdp2 = max(userdp2, eq5)
506

    
507
            userdp = max(userdp1, userdp2)
508

    
509
            self.pressure_drops[self.items[acv]] = userdp
510
        except Exception as ex:
511
            from App import App
512
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
513
                                                           sys.exc_info()[-1].tb_lineno)
514
            App.mainWnd().addMessage.emit(MessageType.Error, message)
515

    
516
    def aramco_cal(self, pf, acv):
517
        try:
518
            aramcob = 0
519
            cv_type = self.items[acv].data.cv_type
520
            if cv_type == 'Single Plug':
521
                aramcob = 11
522
            elif cv_type == 'Double Plug':
523
                aramcob = 7
524
            elif cv_type == 'Cave(unbalanced)':
525
                aramcob = 4
526
            elif cv_type == 'Cave(balanced)':
527
                aramcob = 4
528
            elif cv_type == 'Butterfly':
529
                aramcob = 0
530
            elif cv_type == 'V-Ball':
531
                aramcob = 1
532

    
533
            pressure_unit = self.units['Pressure']
534
            if pressure_unit == 'kg/cm2':
535
                aramcob = aramcob / 14.7 * 1.033
536
            elif pressure_unit == 'psi':
537
                aramcob = aramcob
538
            elif pressure_unit == 'atm':
539
                aramcob = aramcob / 14.7
540
            elif pressure_unit == 'bar':
541
                aramcob = aramcob / 14.7 * 1.013
542
            elif pressure_unit == 'mmHg':
543
                aramcob = aramcob / 14.7 * 760
544
            elif pressure_unit == 'kPa':
545
                aramcob = aramcob / 14.7 * 101.325
546
            elif pressure_unit == 'MPa':
547
                aramcob = aramcob / 14.7 * 0.101325
548

    
549
            aramcodp = 0.05 * self.pressures[self.items[0]] + (1.1 * ((self.extras[self.items[acv]] if self.extras[
550
                self.items[acv]] else 0 / 100 + 1) ** 2 - 1) * pf) + aramcob
551

    
552
            # 공통이 될 부분
553
            self.pressure_drops[self.items[acv]] = aramcodp
554
        except Exception as ex:
555
            from App import App
556
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
557
                                                           sys.exc_info()[-1].tb_lineno)
558
            App.mainWnd().addMessage.emit(MessageType.Error, message)
559

    
560
    def bd_cal(self, pf, acv):
561
        from AppDocData import AppDocData
562

    
563
        try:
564
            bdcvdp = [None, None, None]
565

    
566
            bdcvdp[0] = ((1.1135 * (
567
                    (self.extras[self.items[acv]] if self.extras[self.items[acv]] else 0) / 100 + 1)) ** 2 - 1) * pf
568
            bdcvdp[1] = pf / 3
569

    
570
            pressure_unit = self.units['Pressure']
571
            if pressure_unit == 'kg/cm2':
572
                bdcvdp[2] = 0.7
573
            elif pressure_unit == 'psi':
574
                bdcvdp[2] = 0.7 / 1.033 * 14.7
575
            elif pressure_unit == 'bar':
576
                bdcvdp[2] = 0.7 / 1.033 * 1.013
577
            elif pressure_unit == 'mmHg':
578
                bdcvdp[2] = 0.7 / 1.033 * 760
579
            elif pressure_unit == 'kPa':
580
                bdcvdp[2] = 0.7 / 1.033 * 101.325
581
            elif pressure_unit == 'MPa':
582
                bdcvdp[2] = 0.7 / 1.033 * 0.101325
583

    
584
            max_dp = max(bdcvdp[0], bdcvdp[1])
585
            if max_dp < bdcvdp[2]:
586
                max_dp = bdcvdp[2]
587

    
588
            self.pressure_drops[self.items[acv]] = max_dp
589
        except Exception as ex:
590
            from App import App
591
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
592
                                                           sys.exc_info()[-1].tb_lineno)
593
            App.mainWnd().addMessage.emit(MessageType.Error, message)
594

    
595
    def final_suc_p_cal(self, i):
596
        res = self.suction_p_cal(i)
597
        if res == 0:
598
            return
599

    
600
    def final_loss_input(self):
601
        pass
602

    
603
        # line_total_friction_loss, total_loss, total_device_loss 값을 계산하지만 사용하는 곳이 없어서 일단 주석
604
        '''
605
        try:
606
            final_line_loss = 0
607
            final_dev_loss = 0
608
            # 라인(fric)
609
            for i in range(2, len(self.items) - 3, 3):
610
                final_line_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
611
            self.line_total_friction_loss = final_line_loss
612
            final_line_loss = 0
613

614
            # 라인(stat)
615
            for i in range(1, len(self.items) - 3, 3):
616
                final_line_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
617
            self.total_loss = final_line_loss
618
            final_line_loss = 0
619

620
            # 기기(total)
621
            for i in range(3, len(self.items) - 3, 3):
622
                name = str(self.items[i])[:3]
623
                if name == 'R_P' or name == 'L_P' or name == 'V_P' or name == 'R_K' or name == 'L_K' or name == 'CV_':
624
                    pass
625
                elif name == 'CV_':
626
                    if self.pattern[self.items[i]] != -4125:
627
                        final_dev_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
628
                else:
629
                    final_dev_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
630
            self.total_device_loss = final_dev_loss
631
            final_dev_loss = 0
632

633
        except Exception as ex:
634
            from App import App
635
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
636
                                                           sys.exc_info()[-1].tb_lineno)
637
            App.mainWnd().addMessage.emit(MessageType.Error, message)
638
        '''
639
    def loss_input(self):
640
        try:
641
            hole_start, hole_end = self.fill_start, self.fill_end
642

    
643
            line_loss = 0
644
            # 라인(suc)
645
            for i in range(1, hole_start + 1, 3):
646
                line_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
647
            self.suction_line_friction_loss = line_loss
648

    
649
            line_loss = 0
650
            for i in range(len(self.items) - 2, hole_start + 2, -3):
651
                if i == 3:
652
                    break
653
                if self.items[i] in self.pressure_drops and self.pressure_drops[self.items[i]]:
654
                    line_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
655
            self.discharge_line_friction_loss = line_loss
656

    
657
            line_loss = 0
658
            self.line_total_friction_loss = self.suction_line_friction_loss + self.discharge_line_friction_loss
659

    
660
            # 기기(suc)
661
            dev_loss = 0
662
            for i in range(2, hole_start - 1, 3):
663
                name = str(self.items[i])[:3]
664
                if name == 'R_P' or name == 'L_P' or name == 'V_P' or name == 'R_K' or name == 'L_K' or name == 'CV_':
665
                    pass
666
                else:
667
                    dev_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
668
            self.suction_device_loss = dev_loss
669

    
670
            # 기기(dis)
671
            dev_loss = 0
672
            for i in range(len(self.items) - 4, hole_start + 3, -3):
673
                name = str(self.items[i])[:3]
674
                if name == 'R_P' or name == 'L_P' or name == 'V_P' or name == 'R_K' or name == 'L_K' or name == 'CV_':
675
                    pass
676
                else:
677
                    dev_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
678
            self.discharge_device_loss = dev_loss
679

    
680
            self.total_device_loss = self.discharge_device_loss + self.suction_device_loss
681

    
682
            # 스태틱(suc)
683
            stat_loss = 0
684
            for i in range(0, hole_start - 3, 3):
685
                stat_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
686
            self.total_suction_loss = stat_loss
687

    
688
            # 스태틱(dis)
689
            stat_loss = 0
690
            for i in range(len(self.items) - 3, hole_start, -3):
691
                stat_loss += self.pressure_drops[self.items[i]] if self.items[i] in self.pressure_drops else 0
692
            self.total_discharge_loss = stat_loss
693
        except Exception as ex:
694
            from App import App
695
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
696
                                                           sys.exc_info()[-1].tb_lineno)
697
            App.mainWnd().addMessage.emit(MessageType.Error, message)
698

    
699
    def discharge_cal(self):
700
        try:
701
            if len(self.items) == 3:
702
                # 장치 2개와 Line 1개로 구성된 경우
703
                self.discharge_den(1)  # (1) density 입력
704
                self.discharge_static_cal(1)  # (2) static P를 계산
705

    
706
                # (3) pressure drop 계산
707
                # liquid 인 경우 stream 시트로부터 del.P를 입력해줌.
708
                # vapor인 경우 압력강하를 계산해주고 넣어주는 모듈
709
                if self.items[1].data.phase_type == 'Liquid' or self.items[1].data.phase_type == 'Mixed':
710
                    self.pressure_drops[self.items[1]] = self.items[1].data.pressure_drop_friction
711
                    self.discharge_p_cal(1)
712

    
713
                elif self.items[1].data.phase_type == 'Vapor':
714
                    self.discharge_vapor_factor_length(1)
715
                    self.discharge_p_cal(1)
716

    
717
                self.fill_end = 3
718
            else:
719
                for i in range(len(self.items) - 2, 0, -3):  # backward
720
                    self.discharge_den(i)  # (1) density 입력
721
                    self.discharge_static_cal(i)  # (2) static P를 계산
722

    
723
                    # (3) pressure drop 계산
724
                    # liquid 인 경우 stream 시트로부터 del.P를 입력해줌.
725
                    # vapor인 경우 압력강하를 계산해주고 넣어주는 모듈
726
                    if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
727
                        self.pressure_drops[self.items[i]] = self.items[i].data.pressure_drop_friction
728
                        asd = self.discharge_p_cal(i)
729
                        if asd == 0:
730
                            break
731
                    elif self.items[i].data.phase_type == 'Vapor':
732
                        self.discharge_vapor_factor_length(i)
733
                        asd = self.discharge_p_cal(i)
734
                        if asd == 0:
735
                            break
736

    
737
                self.fill_end = i
738
        except Exception as ex:
739
            from App import App
740
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
741
                                                           sys.exc_info()[-1].tb_lineno)
742
            App.mainWnd().addMessage.emit(MessageType.Error, message)
743

    
744
    def discharge_vapor_factor_length(self, i):
745
        from CalculationValidation import QCalculationValidation
746
        try:
747
            # '입력된 vapor의 압력과 밀도를 가지고 끊어서 계산하는 factor를 적용했을때 length가 얼마나 나오는지 판별하는 것.
748

    
749
            # pipe dia 가져오기
750
            ida = self.items[i].data.inside_pipe_size
751
            if is_blank(str(ida)):
752
                dlg = QCalculationValidation()
753
                detail = 'You have to input the ID of stream <{}>'.format(self.items[i].data.stream_no)
754
                dlg.show_dialog('Calculation will be terminated!', detail)
755
                return
756

    
757
            pipe_diameter_unit = self.units['Pipe_Diameter']
758
            if pipe_diameter_unit == 'in':
759
                ida = ida * 0.0254
760
            elif pipe_diameter_unit == 'mm':
761
                ida = ida / 1000
762

    
763
            # 'mass 가져오기 기준 kg/h
764
            mass = self.items[i].data.flowrate_mass
765
            flowrate_mass_unit = self.units['Flowrate_Mass']
766
            if flowrate_mass_unit == 'kg/h':
767
                mass = mass
768
            elif flowrate_mass_unit == 'g/min':
769
                mass = mass * 60 / 1000
770
            elif flowrate_mass_unit == 'lb/h':
771
                mass = mass * 0.453592
772
            elif flowrate_mass_unit == 't/h':
773
                mass = mass * 1000
774

    
775
            # 'g 구하기 (kg/m2/s)
776
            g = mass / 3600 / (3.1415 * ida ** 2 / 4)
777

    
778
            density_unit = self.units['Density']
779
            if density_unit == 'kg/m3':
780
                density2 = self.density_elevations[self.items[i]]
781
            else:
782
                density2 = self.density_elevations[self.items[i]] * 16.0185  # lb/ft3
783

    
784
            #density2 = self.density_elevations[self.items[i]]
785

    
786
            # '속도 계산 (m/s)
787
            velocity = 4 * mass / density2 / 3.1415 / ida ** 2 / 3600
788

    
789
            # 'Mach Number 계산
790
            # 'k 가져오기
791
            k = self.items[i].data.specific_heat_ratio
792

    
793
            # temp 가져오기
794
            temp = self.items[i].data.temperature
795
            # 'temp를 kalvin으로 맞추기
796
            temp_unit = self.units['Temperature']
797
            if temp_unit == '':
798
                temp = temp + 273.15
799
            elif temp_unit == '':
800
                temp = (temp - 32) / 1.8 + 273.15
801

    
802
            # 'MW 가져오기
803
            mw = self.items[i].data.molecular_weight
804

    
805
            mach = velocity / ((k * 9.80665 * 847.28 * temp / mw) ** 0.5)
806

    
807
            # '부피유량 계산
808
            volume = mass / density2
809

    
810
            # '현재 volume은 m3/h임. 부피유량 단위에 맞춰 뿌려줌
811
            flowrate_volume_unit = self.units['Flowrate_Volume']
812
            if flowrate_volume_unit == 'm3/h':
813
                self.items[i].data.flowrate_volume = round(volume, 3)
814
            elif flowrate_volume_unit == 'l/min':
815
                self.items[i].data.flowrate_volume = round(volume / 60 * 1000, 3)
816
            elif flowrate_volume_unit == 'ft3/h':
817
                self.items[i].data.flowrate_volume = round(volume * 35.3147, 3)
818
            elif flowrate_volume_unit == 'USgpm':
819
                self.items[i].data.flowrate_volume = round(volume * 4.40287, 3)
820
            elif flowrate_volume_unit == 'BPSD':
821
                self.items[i].data.flowrate_volume = round(volume * 150.955, 3)
822

    
823
            # ' viscosity 유닛 변환 (모두 kg/m.s로 바꿀것임)
824
            viscosity = self.items[i].data.viscosity
825
            viscosity_unit = self.units['Viscosity']
826
            if viscosity_unit == 'kg/m.sec':
827
                viscosity = viscosity
828
            elif viscosity_unit == 'cP':
829
                viscosity = viscosity * 0.001
830
            elif viscosity_unit == 'kg/m.h':
831
                viscosity = viscosity / 3600
832
            elif viscosity_unit == 'lb/ft.s':
833
                viscosity = viscosity * 1.48816
834

    
835
            # density case에 따라 re계산
836
            density_unit = self.units['Density']
837
            if density_unit == 'kg/m3':
838
                reynolds = ida * velocity * density2 / viscosity
839
            elif density_unit == 'lb/ft3':
840
                reynolds = ida * velocity * (density2 * 16.0185) / viscosity
841

    
842
            # roughness를 m로 바꿔줌
843
            rough = self.items[i].data.roughness
844
            roughness_unit = self.units['Roughness']
845
            if roughness_unit == 'm':
846
                rough = rough
847
            elif roughness_unit == 'ft':
848
                rough = rough * 0.3048
849
            elif roughness_unit == 'in':
850
                rough = rough * 0.0254
851
            elif roughness_unit == 'mm':
852
                rough = rough * 0.001
853

    
854
            # ' reynolds수에 따라 Fanning/Chen friction factor 계산
855
            if reynolds <= 2100:
856
                f = 4 * 16 / reynolds
857
            else:
858
                af = math.log(rough / ida / 3.7 + (6.7 / reynolds) ** 0.9) / math.log(10)
859
                f = (-2 * (math.log(rough / 3.7 / ida - 5.02 / reynolds * af) / math.log(10))) ** (-2)
860

    
861
            self.items[i].data.friction_factor = f
862

    
863
            # '속도와 mach 수 입력
864
            velocity_unit = self.units['Velocity']
865
            if velocity_unit == 'm/s':
866
                self.items[i].data.velocity = round(velocity, 3)
867
            elif velocity_unit == 'ft/s':
868
                self.items[i].data.velocity = round(velocity * 3.28084, 3)
869

    
870
            self.items[i].data.reynolds = round(mach, 5)
871

    
872
            Ref_baro = self.get_barometric_pressure()
873
            press2 = self.pressures[self.items[i + 1]] if self.pressures[self.items[i + 1]] else 0
874

    
875
            # 'pressure를 k.g.a로 맞춤
876
            pressure_unit = self.units['Pressure']
877
            if pressure_unit == 'kg/cm2':
878
                press2 = press2 + Ref_baro
879
            elif pressure_unit == 'psi':
880
                press2 = press2 / 14.7 * 1.033 + Ref_baro
881
            elif pressure_unit == 'atm':
882
                press2 = press2 * 1.033 + Ref_baro
883
            elif pressure_unit == 'bar':
884
                press2 = press2 / 1.013 * 1.033 + Ref_baro
885
            elif pressure_unit == 'mmHg':
886
                press2 = press2 / 760 * 1.033 + Ref_baro
887
            elif pressure_unit == 'kPa':
888
                press2 = press2 / 101.325 * 1.033 + Ref_baro
889
            elif pressure_unit == 'MPa':
890
                press2 = press2 / 0.101325 * 1.033 + Ref_baro
891

    
892
            press1est = press2 / 0.95  # HY_Calc_sht.Cells(2, 1)
893

    
894
            z = self.items[i].data.compress_factor
895
            density1est = press1est * mw / 0.08206 / temp / z / 1.033
896

    
897
            # ' 라인 길이 도출 (m)
898
            estlength = (((press1est ** 2 - press2 ** 2) * mw / g ** 2 / 0.08206 / 1.033 ** 2 / temp / z * 101325) - (
899
                    2 * math.log(density1est / density2))) * ida / f
900

    
901
            # '라인 길이를 유닛에 맞춰서 변환
902
            length_unit = self.units['Length']
903
            if length_unit == 'm':
904
                estlength = estlength
905
            elif length_unit == 'in':
906
                estlength = estlength * 39.3701
907
            elif length_unit == 'ft':
908
                estlength = estlength * 3.28084
909
            elif length_unit == 'yd':
910
                estlength = estlength * 1.09361
911
            elif length_unit == 'mile':
912
                estlength = estlength * 0.000621371
913
            elif length_unit == 'mm':
914
                estlength = estlength * 1000
915

    
916
            equivalent_length = self.get_equivalent_length(i)
917
            if estlength > equivalent_length:
918
                # '주어진 길이를 가지고 압력 강하를 계산하는 모듈이 들어가야함 (safe)
919
                # ' length 여유 있음. 한번에 isothermal 식으로 계산
920
                self.discharge_vap_dp_cal1(i, press2, g, mw, temp, f, z, ida)
921
            else:
922
                # '끊어서 계산하는 모듈이 들어가야함
923
                # 'length 여유 없음. 압력 재계산->밀도 재계산->re, f 재계산->압력 재계산 체계로 가야함
924
                self.discharge_vap_dp_cal2(i, press2, g, mw, temp, f, z, ida, estlength, mass, density1est,
925
                                           equivalent_length)
926

    
927
        except Exception as ex:
928
            from App import App
929
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
930
                                                           sys.exc_info()[-1].tb_lineno)
931
            App.mainWnd().addMessage.emit(MessageType.Error, message)
932

    
933
    def discharge_vap_dp_cal1(self, i, press2, g, mw, temp, f, z, ida):
934
        try:
935
            # 끊은 결과 length가 여유가 있음. 그래서 단순 계산하는 모듈
936
            length = self.get_equivalent_length(i)
937

    
938
            # length를 m로 변환
939
            length_unit = self.units['Length']
940
            if length_unit == 'm':
941
                length = length
942
            elif length_unit == 'in':
943
                length = length * 0.0254
944
            elif length_unit == 'ft':
945
                length = length * 0.3048
946
            elif length_unit == 'yd':
947
                length = length * 0.9144
948
            elif length_unit == 'mile':
949
                length = length * 1609.34
950
            elif length_unit == 'mm':
951
                length = length * 0.001
952

    
953
            # Newton's Rule에 따라
954
            press1 = self.Vap_Discharge_1(press2, g, mw, temp, f, z, ida, length)
955
            pressure_unit = self.units['Pressure']
956
            if pressure_unit == 'kg/cm2':
957
                self.pressure_drops[self.items[i]] = press1 - press2
958
            elif pressure_unit == 'psi':
959
                self.pressure_drops[self.items[i]] = (press1 - press2) / 1.033 * 14.7
960
            elif pressure_unit == 'atm':
961
                self.pressure_drops[self.items[i]] = (press1 - press2) / 1.033
962
            elif pressure_unit == 'bar':
963
                self.pressure_drops[self.items[i]] = (press1 - press2) / 1.033 * 1.013
964
            elif pressure_unit == 'mmHg':
965
                self.pressure_drops[self.items[i]] = (press1 - press2) / 1.033 * 760
966
            elif pressure_unit == 'kPa':
967
                self.pressure_drops[self.items[i]] = (press1 - press2) / 1.033 * 101.325
968
            elif pressure_unit == 'MPa':
969
                self.pressure_drops[self.items[i]] = (press1 - press2) / 1.033 * 0.101325
970

    
971
            # Vapor DB에 입력
972
            vapor_pressure_gradient = []
973

    
974
            if pressure_unit == 'kg/cm2':
975
                vapor_pressure = round(press2, 3)
976
            elif pressure_unit == 'psi':
977
                vapor_pressure = round(press2 / 1.033 * 14.7, 3)
978
            elif pressure_unit == 'atm':
979
                vapor_pressure = round(press2 / 1.033, 3)
980
            elif pressure_unit == 'bar':
981
                vapor_pressure = round(press2 / 1.033 * 1.033, 3)
982
            elif pressure_unit == 'mmHg':
983
                vapor_pressure = round(press2 / 1.033 * 760)
984
            elif pressure_unit == 'kPa':
985
                vapor_pressure = round(press2 / 1.033 * 101.325, 3)
986
            elif pressure_unit == 'MPa':
987
                vapor_pressure = round(press2 / 10.33 * 0.101325, 3)
988

    
989
            velocity_unit = self.units['Velocity']
990
            if velocity_unit == 'm/s':
991
                vapor_velocity = round(self.items[i].data.velocity, 3)
992
            elif velocity_unit == 'ft/s':
993
                vapor_velocity = round(self.items[i].data.velocity * 3.28084, 3)
994

    
995
            density_unit = self.units['Density']
996
            if density_unit == 'kg/m3':
997
                vapor_density = round(self.density_elevations[self.items[i]], 3)
998
            elif density_unit == 'lb/ft3':
999
                vapor_density = round(self.density_elevations[self.items[i]] * 0.062428, 3)
1000

    
1001
            vapor_pressure_gradient.append([vapor_pressure, vapor_velocity, vapor_density, ''])
1002

    
1003
            if pressure_unit == 'kg/cm2':
1004
                vapor_pressure = round(press1, 3)
1005
            elif pressure_unit == 'psi':
1006
                vapor_pressure = round(press1 / 1.033 * 14.7, 3)
1007
            elif pressure_unit == 'atm':
1008
                vapor_pressure = round(press1 / 1.033, 3)
1009
            elif pressure_unit == 'bar':
1010
                vapor_pressure = round(press1 / 1.033 * 1.033, 3)
1011
            elif pressure_unit == 'mmHg':
1012
                vapor_pressure = round(press1 / 1.033 * 760)
1013
            elif pressure_unit == 'kPa':
1014
                vapor_pressure = round(press1 / 1.033 * 101.325, 3)
1015
            elif pressure_unit == 'MPa':
1016
                vapor_pressure = round(press1 / 10.33 * 0.101325, 3)
1017

    
1018
            if velocity_unit == 'm/s':
1019
                vapor_velocity = round(press1 * self.items[i].data.velocity / press2, 3)
1020
            elif velocity_unit == 'ft/s':
1021
                vapor_velocity = round(press1 * self.items[i].data.velocity / press2 * 3.28084, 3)
1022

    
1023
            if density_unit == 'kg/m3':
1024
                vapor_density = round(press1 * self.density_elevations[self.items[i]] / press2, 3)
1025
            elif density_unit == 'lb/ft3':
1026
                vapor_density = round(press1 * self.density_elevations[self.items[i]] / press2 * 0.062428, 3)
1027

    
1028
            if length_unit == 'm':
1029
                vapor_length = round(length, 3)
1030
            elif length_unit == 'in':
1031
                vapor_length = round(length * 39.3701, 3)
1032
            elif length_unit == 'ft':
1033
                vapor_length = round(length * 3.28084, 3)
1034
            elif length_unit == 'yd':
1035
                vapor_length = round(length * 1.09361, 3)
1036
            elif length_unit == 'mile':
1037
                vapor_length = round(length * 0.000621371, 3)
1038
            elif length_unit == 'mm':
1039
                vapor_length = round(length * 1000, 3)
1040

    
1041
            vapor_pressure_gradient.append([vapor_pressure, vapor_velocity, vapor_density, vapor_length])
1042

    
1043
            if self.items[i].vapor_pressure_gradient is None:
1044
                self.items[i].vapor_pressure_gradient = vapor_pressure_gradient
1045

    
1046
            self.discharge_p_cal(i)
1047

    
1048
        except Exception as ex:
1049
            from App import App
1050
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1051
                                                           sys.exc_info()[-1].tb_lineno)
1052
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1053

    
1054
    def vproperty_input(self, vapor_pressure_gradient, press2, density2, velocity, length):
1055
        try:
1056

    
1057
            pressure_unit = self.units['Pressure']
1058
            if pressure_unit == 'kg/cm2':
1059
                vapor_pressure = round(press2, 3)
1060
            elif pressure_unit == 'bar':
1061
                vapor_pressure = round(press2 / 1.033 * 1.013, 3)
1062
            elif pressure_unit == 'psi':
1063
                vapor_pressure = round(press2 / 1.033 * 14.7, 3)
1064
            elif pressure_unit == 'mmHg':
1065
                vapor_pressure = round(press2 / 1.033 * 760, 3)
1066
            elif pressure_unit == 'kPa':
1067
                vapor_pressure = round(press2 / 1.033 * 101.325, 3)
1068
            elif pressure_unit == 'MPa':
1069
                vapor_pressure = round(press2 / 1.033 * 0.101325, 3)
1070

    
1071
            velocity_unit = self.units['Velocity']
1072
            if velocity_unit == 'm/s':
1073
                vapor_velocity = round(velocity, 3)
1074
            elif velocity_unit == 'ft/s':
1075
                vapor_velocity = round(velocity * 3.28084, 3)
1076

    
1077
            density_unit = self.units['Density']
1078
            if density_unit == 'kg/m3':
1079
                vapor_density = round(density2, 3)
1080
            elif density_unit == 'lb/ft3':
1081
                vapor_density = round(density2 * 0.062428, 3)
1082

    
1083
            length_unit = self.units['Length']
1084
            if length_unit == 'm':
1085
                vapor_length = round(length, 3)
1086
            elif length_unit == 'in':
1087
                vapor_length = round(length * 39.3701, 3)
1088
            elif length_unit == 'ft':
1089
                vapor_length = round(length * 3.28084, 3)
1090
            elif length_unit == 'yd':
1091
                vapor_length = round(length * 1.09361, 3)
1092
            elif length_unit == 'mile':
1093
                vapor_length = round(length * 0.000621371, 3)
1094
            elif length_unit == 'mm':
1095
                vapor_length = round(length * 1000, 3)
1096

    
1097
            vapor_pressure_gradient.append([vapor_pressure, vapor_velocity, vapor_density, vapor_length])
1098
        except Exception as ex:
1099
            from App import App
1100
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1101
                                                           sys.exc_info()[-1].tb_lineno)
1102
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1103

    
1104
    def vproperty_recal(self, press1, mw, temp, z, ida, mass):
1105

    
1106
        press2 = press1
1107
        density2 = press2 * mw / 0.08206 / temp / z / 1.033
1108
        velocity = 4 * mass / density2 / 3.1415 / ida ** 2 / 3600
1109

    
1110
        return press2, density2, velocity
1111

    
1112
    def discharge_vap_dp_cal2(self, i, press2, g, mw, temp, f, z, ida, estlength, mass, density1est, equivalent_length):
1113
        try:
1114
            # ' 끊은 결과 length 여유가 없음, 고로 물성치 (밀도) 를 재계산해주어야 함
1115
            # ' 모든 물성들은 배열로 작성해야함
1116
            # ' 좌표 추적/설정
1117

    
1118
            ori_press2 = press2
1119
            trial_length = []
1120

    
1121
            trial_length.append(estlength)
1122

    
1123
            # Vapor DB에 입력
1124
            vapor_pressure_gradient = []
1125

    
1126
            pressure_unit = self.units['Pressure']
1127
            if pressure_unit == 'kg/cm2':
1128
                vapor_pressure = round(press2, 3)
1129
            elif pressure_unit == 'psi':
1130
                vapor_pressure = round(press2 / 1.033 * 14.7, 3)
1131
            elif pressure_unit == 'atm':
1132
                vapor_pressure = round(press2 / 1.033, 3)
1133
            elif pressure_unit == 'bar':
1134
                vapor_pressure = round(press2 / 1.033 * 1.033, 3)
1135
            elif pressure_unit == 'mmHg':
1136
                vapor_pressure = round(press2 / 1.033 * 760)
1137
            elif pressure_unit == 'kPa':
1138
                vapor_pressure = round(press2 / 1.033 * 101.325, 3)
1139
            elif pressure_unit == 'MPa':
1140
                vapor_pressure = round(press2 / 10.33 * 0.101325, 3)
1141

    
1142
            velocity_unit = self.units['Velocity']
1143
            if velocity_unit == 'm/s':
1144
                vapor_velocity = round(self.items[i].data.velocity, 3)
1145
            elif velocity_unit == 'ft/s':
1146
                vapor_velocity = round(self.items[i].data.velocity * 3.28084, 3)
1147

    
1148
            density_unit = self.units['Density']
1149
            if density_unit == 'kg/m3':
1150
                vapor_density = round(self.density_elevations[self.items[i]], 3)
1151
            elif density_unit == 'lb/ft3':
1152
                vapor_density = round(self.density_elevations[self.items[i]] * 0.062428, 3)
1153

    
1154
            vapor_pressure_gradient.append([vapor_pressure, vapor_velocity, vapor_density, ''])
1155

    
1156
            # 'press2 재정의 끝
1157
            press2, density2, velocity = self.vproperty_recal(press2 / 0.95, mw, temp, z, ida, mass)
1158
            self.vproperty_input(vapor_pressure_gradient, press2, density2, velocity, estlength)
1159

    
1160
            for j in range(1, 100):
1161
                press1est = press2 / 0.95
1162
                estlength = (((
1163
                                      press1est ** 2 - press2 ** 2) * mw / g ** 2 / 0.08206 / 1.033 ** 2 / temp / z * 101325) - (
1164
                                     2 * math.log(density1est / density2))) * ida / f
1165

    
1166
                trial_length.append(trial_length[j - 1] + estlength)
1167

    
1168
                if trial_length[j] > equivalent_length:
1169
                    # 모두 다 했음. 남은 길이로 끝냄
1170
                    remain_length = equivalent_length - trial_length[j - 1]
1171
                    press1 = self.Vap_Discharge_1(press2, g, mw, temp, f, z, ida, remain_length)
1172
                    press2, density2, velocity = self.vproperty_recal(press1, mw, temp, z, ida, mass)
1173
                    self.vproperty_input(vapor_pressure_gradient, press2, density2, velocity, remain_length)
1174
                    break
1175
                else:
1176
                    press1 = self.Vap_Discharge_1(press2, g, mw, temp, f, z, ida, estlength)
1177
                    press2, density2, velocity = self.vproperty_recal(press1, mw, temp, z, ida, mass)
1178
                    self.vproperty_input(vapor_pressure_gradient, press2, density2, velocity, estlength)
1179

    
1180
            if self.items[i].vapor_pressure_gradient is None:
1181
                self.items[i].vapor_pressure_gradient = vapor_pressure_gradient
1182

    
1183
            # self.pressure_drops[self.items[i]] = press2 - ori_press2
1184
            self.pressure_drops[self.items[i]] = vapor_pressure_gradient[-1][0] - vapor_pressure_gradient[0][0]
1185

    
1186
        except Exception as ex:
1187
            from App import App
1188
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1189
                                                           sys.exc_info()[-1].tb_lineno)
1190
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1191

    
1192
    def Vap_Discharge_1(self, p2, g, mw, temp, f, z, id, L_eq):
1193
        try:
1194
            R = 0.08206
1195

    
1196
            Tmp_Const = 101325 * mw / (1.033 ** 2 * (g ** 2) * R * temp * z)
1197
            Tmp_Const2 = id / f
1198
            pressure_unit = self.units['Pressure']
1199
            if pressure_unit == 'kg/cm2':
1200
                const_iteration = 5
1201
            elif pressure_unit == 'psi':
1202
                const_iteration = 75
1203
            elif pressure_unit == 'atm':
1204
                const_iteration = 5
1205
            elif pressure_unit == 'bar':
1206
                const_iteration = 5
1207
            elif pressure_unit == 'mmHg':
1208
                const_iteration = 3800
1209
            elif pressure_unit == 'kPa':
1210
                const_iteration = 506
1211
            elif pressure_unit == 'MPa':
1212
                const_iteration = 0.5
1213

    
1214
            x2 = p2 + const_iteration
1215
            delta_x_past = 0
1216

    
1217
            loop = True
1218
            while loop:
1219
                X = x2
1220
                f_x = (Tmp_Const2 * (Tmp_Const * (X ** 2 - p2 ** 2) - 2 * math.log(X / p2))) - L_eq
1221
                df_x = 2 * Tmp_Const2 * (Tmp_Const * X - 1 / X)
1222
                x2 = X - (f_x / df_x)
1223
                delta_x = x2 - X
1224
                if abs(delta_x_past) == abs(delta_x):
1225
                    break
1226

    
1227
                delta_x_past = delta_x
1228

    
1229
                if delta_x == 0 or x2 < 0:
1230
                    loop = False
1231

    
1232
            return x2
1233

    
1234
        except Exception as ex:
1235
            from App import App
1236
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1237
                                                           sys.exc_info()[-1].tb_lineno)
1238
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1239

    
1240
    def get_equivalent_length(self, i):
1241
        try:
1242
            if self.items[i].data.equivalent_length_input:
1243
                return self.items[i].data.equivalent_length_input
1244
            else:
1245
                return self.items[i].data.equivalent_length_cal
1246
        except Exception as ex:
1247
            from App import App
1248
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1249
                                                           sys.exc_info()[-1].tb_lineno)
1250
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1251

    
1252
    def suction_cal(self) -> list:
1253
        messages = []
1254
        try:
1255
            for i in range(1, len(self.items) - 1, 3):
1256
                self.suction_find_line(i)
1257
                self.suction_static_cal(i)  # static P를 계산해줌
1258

    
1259
                # 라인이 liquid 인지 vapor인지 판별
1260
                if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
1261
                    # liquid 인 경우 stream 데이타로부터 del.P를 입력해줌.
1262
                    self.pressure_drops[self.items[i]] = self.items[i].data.pressure_drop_friction
1263
                    res, message = self.suction_p_cal(i)
1264
                    if message:
1265
                        messages.append(message)
1266

    
1267
                    if res == 0:
1268
                        break
1269
                elif self.items[i].data.phase_type == 'Vapor':
1270
                    # vapor인 경우 압력강하를 계산해주고 넣어주는 모듈
1271
                    message = self.suction_vapor_factor_length(i)
1272
                    if message:
1273
                        messages.append(message)
1274

    
1275
                    res, message = self.suction_p_cal(i)
1276
                    if message:
1277
                        messages.append(message)
1278

    
1279
                    if res == 0:
1280
                        break
1281

    
1282
            self.fill_start = i
1283
        except Exception as ex:
1284
            from App import App
1285
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
1286
                                                           sys.exc_info()[-1].tb_lineno)
1287
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1288

    
1289
        return messages
1290

    
1291
    def suction_find_line(self, i):
1292
        self.extras[self.items[i]] = self.items[i].data.phase_type
1293
        if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
1294
            self.density_elevations[self.items[i]] = self.items[i].data.density
1295
        elif self.items[i].data.phase_type == 'Vapor':
1296
            self.suction_vapor_density(i)
1297
        else:
1298
            raise ValueError('You have to input the properties of stream <{}>\nCalculation will be terminated !'.format(
1299
                self.items[i].data.stream_no))
1300

    
1301
    def suction_vapor_density(self, i):
1302
        try:
1303

    
1304
            Ref_baro = self.get_barometric_pressure()
1305
            press2 = self.pressures[self.items[i - 1]]
1306

    
1307
            # '여기에 아래의 p를 이용하여 density를 넣는 항을 만들어줘야함 (완료)
1308
            # 'pressure를 k.g.a로 맞춤
1309
            pressure_unit = self.units['Pressure']
1310
            if pressure_unit == 'kg/cm2':
1311
                press2 = press2 + Ref_baro
1312
            elif pressure_unit == 'psi':
1313
                press2 = press2 / 14.7 * 1.033 + Ref_baro
1314
            elif pressure_unit == 'atm':
1315
                press2 = press2 * 1.033 + Ref_baro
1316
            elif pressure_unit == 'bar':
1317
                press2 = press2 / 1.013 * 1.033 + Ref_baro
1318
            elif pressure_unit == 'mmHg':
1319
                press2 = press2 / 760 * 1.033 + Ref_baro
1320
            elif pressure_unit == 'kPa':
1321
                press2 = press2 / 101.325 * 1.033 + Ref_baro
1322
            elif pressure_unit == 'MPa':
1323
                press2 = press2 / 0.101325 * 1.033 + Ref_baro
1324

    
1325
            # temp 가져오기
1326
            temp = self.items[i].data.temperature
1327
            # 'temp를 kalvin으로 맞추기
1328
            temp_unit = self.units['Temperature']
1329
            if temp_unit == '':
1330
                temp = temp + 273.15
1331
            elif temp_unit == '':
1332
                temp = (temp - 32) / 1.8 + 273.15
1333

    
1334
            # 'MW 가져오기
1335
            mw = self.items[i].data.molecular_weight
1336

    
1337
            # 'Z 가져오기
1338
            z = self.items[i].data.compress_factor
1339

    
1340
            # 밀도 계산
1341
            density2 = press2 * mw / 0.08206 / temp / z / 1.033
1342

    
1343
            # '밀도 입력
1344
            density_unit = self.units['Density']
1345
            if density_unit == 'kg/m3':
1346
                density2 = density2
1347
            elif density_unit == 'lb/ft3':
1348
                density2 = density2 * 0.062428
1349

    
1350
            self.density_elevations[self.items[i]] = density2
1351
        except Exception as ex:
1352
            from App import App
1353
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1354
                                                           sys.exc_info()[-1].tb_lineno)
1355
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1356

    
1357
    def suction_static_cal(self, i):
1358
        try:
1359
            if self.items[i].data.phase_type == 'Mixed':
1360
                self.pressure_drops[self.items[i - 1]] = self.items[i].data.pressure_drop_static
1361
            else:
1362
                density_unit = self.units['Density']
1363
                if density_unit == 'kg/m3':
1364
                    density2 = self.density_elevations[self.items[i]]
1365
                else:
1366
                    density2 = self.density_elevations[self.items[i]] * 16.0185  # lb/ft3
1367

    
1368
                # 2 elevation 받음
1369
                el1 = self.density_elevations[self.items[i - 1]] if self.items[i - 1] in self.density_elevations else 0
1370
                el2 = self.density_elevations[self.items[i + 1]] if self.items[i + 1] in self.density_elevations else 0
1371
                length_unit = self.units['Length']
1372
                if length_unit == 'm':
1373
                    el1 = el1
1374
                    el2 = el2
1375
                elif length_unit == 'in':
1376
                    el1 = el1 * 0.0254
1377
                    el2 = el2 * 0.0254
1378
                elif length_unit == 'ft':
1379
                    el1 = el1 * 0.3048
1380
                    el2 = el2 * 0.3048
1381
                elif length_unit == 'yd':
1382
                    el1 = el1 * 0.9144
1383
                    el2 = el2 * 0.9144
1384
                elif length_unit == 'mm':
1385
                    el1 = el1 * 0.001
1386
                    el2 = el2 * 0.001
1387
                else:  # mile
1388
                    el1 = el1 * 1609.34
1389
                    el2 = el2 * 1609.34
1390

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

    
1394
                # 4. 압력 유닛에 맞춰 뿌리기
1395
                pressure_unit = self.units['Pressure']
1396
                if pressure_unit == 'kg/cm2':
1397
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 1.033
1398
                elif pressure_unit == 'psi':
1399
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 14.7
1400
                elif pressure_unit == 'atm':
1401
                    self.pressure_drops[self.items[i - 1]] = stat_dp
1402
                elif pressure_unit == 'bar':
1403
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 1.013
1404
                elif pressure_unit == 'mmHg':
1405
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 760
1406
                elif pressure_unit == 'kPa':
1407
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 101.325
1408
                elif pressure_unit == 'MPa':
1409
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 0.101325
1410
        except Exception as ex:
1411
            from App import App
1412
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
1413
                                                           sys.exc_info()[-1].tb_lineno)
1414
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1415

    
1416
    def p_eq_input(self):
1417
        try:
1418
            # 시작, 끝 기기의 pressure와 elevation을 구한다
1419
            self.pressures[self.items[0]] = self.items[0].data.pressure
1420
            self.density_elevations[self.items[0]] = self.items[0].data.elevation
1421
            self.pressures[self.items[-1]] = self.items[-1].data.pressure
1422
            self.density_elevations[self.items[-1]] = self.items[-1].data.elevation
1423

    
1424
            if len(self.items) == 3:
1425
                # 장치 2개와 Line 1개로 구성된 경우
1426
                pass
1427
            else:
1428
                for i in range(2, len(self.items) - 3, 3):
1429
                    self.pattern[self.items[i]] = -4142
1430

    
1431
                    if self.items[i].data is None:
1432
                        self.pressure_drops[self.items[i]] = 0
1433
                        self.density_elevations[self.items[i]] = 0
1434
                        self.density_elevations[self.items[i + 1]] = 0
1435
                        continue
1436

    
1437
                    dp_eq = str(self.items[i])[:3]
1438
                    if dp_eq == 'HEX' or dp_eq == 'M_D' or dp_eq == 'M_R':
1439
                        dp_eq = str(self.items[i])[:3]
1440

    
1441
                    # pressure drop
1442
                    if self.items[i].data.pressure_drop is not None:
1443
                        self.pressure_drops[self.items[i]] = self.items[i].data.pressure_drop
1444
                    else:
1445
                        self.pattern[self.items[i]] = -4125
1446

    
1447
                    # elevation
1448
                    if self.items[i].data.elevation is None:
1449
                        self.density_elevations[self.items[i]] = 0
1450
                        self.density_elevations[self.items[i + 1]] = 0
1451
                    else:
1452
                        if dp_eq[:3] == 'M_R':
1453
                            self.density_elevations[self.items[i]] = self.items[i].data.elevation
1454
                            self.density_elevations[self.items[i + 1]] = self.items[i + 1].data.elevation
1455
                        else:
1456
                            self.density_elevations[self.items[i]] = self.items[i].data.elevation
1457
                            self.density_elevations[self.items[i + 1]] = self.items[i + 1].data.elevation
1458

    
1459
                    if dp_eq[:3] == 'L_P' or dp_eq[:3] == 'R_P' or dp_eq[:3] == 'V_P' or dp_eq[:3] == 'R_K':
1460
                        self.extras[self.items[i]] = self.items[i].data.over_design_cv \
1461
                            if self.items[i].data.over_design_cv else 0
1462
                    elif dp_eq[:3] == 'CV_':
1463
                        self.extras[self.items[i]] = self.items[i].data.over_design_cv \
1464
                            if self.items[i].data.over_design_cv else 0  # over% factor
1465
                        self.extras[self.items[i + 1]] = None  # for aramco
1466

    
1467
                        if self.items[i].data.pressure_drop is None:
1468
                            pass
1469

    
1470
        except Exception as ex:
1471
            from App import App
1472
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1473
                                                           sys.exc_info()[-1].tb_lineno)
1474
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1475

    
1476
    def discharge_den(self, i):
1477
        try:
1478
            self.extras[self.items[i]] = self.items[i].data.phase_type
1479
            # 1. density 받음
1480
            if self.items[i].data.phase_type == 'Liquid' or self.items[i].data.phase_type == 'Mixed':
1481
                self.density_elevations[self.items[i]] = self.items[i].density
1482
            elif self.items[i].data.phase_type == 'Vapor':
1483
                self.discharge_vapor_density(i)
1484
        except Exception as ex:
1485
            from App import App
1486
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1487
                                                           sys.exc_info()[-1].tb_lineno)
1488
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1489

    
1490
    def get_barometric_pressure(self):
1491
        try:
1492
            unit = self.units['Pressure']
1493
            if unit == 'kg/cm2':
1494
                barometric_pressure = 1.033
1495
            elif unit == 'bar':
1496
                barometric_pressure = 1.01325 / 0.980665
1497
            elif unit == 'psi':
1498
                barometric_pressure = 14.7 / 14.22334
1499
            elif unit == 'mmHg':
1500
                barometric_pressure = 760 / 735.5591
1501
            elif unit == 'kPa':
1502
                barometric_pressure = 101.325 / 98.0665
1503
            elif unit == 'MPa':
1504
                barometric_pressure = 0.101325 / 0.0980665
1505

    
1506
            return barometric_pressure
1507
        except Exception as ex:
1508
            from App import App
1509
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1510
                                                           sys.exc_info()[-1].tb_lineno)
1511
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1512

    
1513
    def discharge_vapor_density(self, i):
1514
        try:
1515
            Ref_baro = self.get_barometric_pressure()
1516
            press2 = self.pressures[self.items[i + 1]] if self.pressures[self.items[i + 1]] else 0
1517

    
1518
            # '여기에 아래의 p를 이용하여 density를 넣는 항을 만들어줘야함
1519
            # 'pressure를 k.g.a로 맞춤
1520
            pressure_unit = self.units['Pressure']
1521
            if pressure_unit == 'kg/cm2':
1522
                press2 = press2 + Ref_baro
1523
            elif pressure_unit == 'psi':
1524
                press2 = press2 / 14.7 * 1.033 + Ref_baro
1525
            elif pressure_unit == 'atm':
1526
                press2 = press2 * 1.033 + Ref_baro
1527
            elif pressure_unit == 'bar':
1528
                press2 = press2 / 1.013 * 1.033 + Ref_baro
1529
            elif pressure_unit == 'mmHg':
1530
                press2 = press2 / 760 * 1.033 + Ref_baro
1531
            elif pressure_unit == 'kPa':
1532
                press2 = press2 / 101.325 * 1.033 + Ref_baro
1533
            elif pressure_unit == 'MPa':
1534
                press2 = press2 / 0.101325 * 1.033 + Ref_baro
1535

    
1536
            # temp 가져오기
1537
            temp = self.items[i].data.temperature
1538
            # 'temp를 kalvin으로 맞추기
1539
            temp_unit = self.units['Temperature']
1540
            if temp_unit == '':
1541
                temp = temp + 273.15
1542
            elif temp_unit == '':
1543
                temp = (temp - 32) / 1.8 + 273.15
1544

    
1545
            # 'MW 가져오기
1546
            mw = self.items[i].data.molecular_weight
1547

    
1548
            # 'Z 가져오기
1549
            z = self.items[i].data.compress_factor
1550

    
1551
            # 밀도 계산
1552
            density2 = press2 * mw / 0.08206 / temp / z / 1.033
1553

    
1554
            # '밀도 입력
1555
            density_unit = self.units['Density']
1556
            if density_unit == 'kg/m3':
1557
                density2 = density2
1558
            elif density_unit == 'lb/ft3':
1559
                density2 = density2 * 0.062428
1560

    
1561
            self.density_elevations[self.items[i]] = density2
1562
        except Exception as ex:
1563
            from App import App
1564
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1565
                                                           sys.exc_info()[-1].tb_lineno)
1566
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1567

    
1568
    def discharge_static_cal(self, i):
1569
        """ (2) static P를 계산 """
1570

    
1571
        try:
1572
            if self.items[i].data.phase_type == 'Mixed':
1573
                self.pressure_drops[self.items[i - 1]] = self.items[i].data.pressure_drop_static
1574
            else:
1575
                # 1. density 받음
1576
                density_unit = self.units['Density']
1577
                if density_unit == 'kg/m3':
1578
                    density2 = self.density_elevations[self.items[i]]
1579
                else:
1580
                    density2 = self.density_elevations[self.items[i]] * 16.0185  # lb/ft3
1581

    
1582
                # 2 elevation 받음
1583
                el1 = self.density_elevations[self.items[i - 1]] if self.items[i - 1] in self.density_elevations else 0
1584
                el2 = self.density_elevations[self.items[i + 1]] if self.items[i + 1] in self.density_elevations else 0
1585

    
1586
                length_unit = self.units['Length']
1587
                if length_unit == 'm':
1588
                    el1 = el1
1589
                    el2 = el2
1590
                elif length_unit == 'in':
1591
                    el1 = el1 * 0.0254
1592
                    el2 = el2 * 0.0254
1593
                elif length_unit == 'ft':
1594
                    el1 = el1 * 0.3048
1595
                    el2 = el2 * 0.3048
1596
                elif length_unit == 'yd':
1597
                    el1 = el1 * 0.9144
1598
                    el2 = el2 * 0.9144
1599
                elif length_unit == 'mm':
1600
                    el1 = el1 * 0.001
1601
                    el2 = el2 * 0.001
1602
                else:  # mile
1603
                    el1 = el1 * 1609.34
1604
                    el2 = el2 * 1609.34
1605

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

    
1609
                # 4. 압력 유닛에 맞춰 뿌리기
1610
                pressure_unit = self.units['Pressure']
1611
                if pressure_unit == 'kg/cm2':
1612
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 1.033
1613
                elif pressure_unit == 'psi':
1614
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 14.7
1615
                elif pressure_unit == 'atm':
1616
                    self.pressure_drops[self.items[i - 1]] = stat_dp
1617
                elif pressure_unit == 'bar':
1618
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 1.013
1619
                elif pressure_unit == 'mmHg':
1620
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 760
1621
                elif pressure_unit == 'kPa':
1622
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 101.325
1623
                elif pressure_unit == 'MPa':
1624
                    self.pressure_drops[self.items[i - 1]] = stat_dp * 0.101325
1625
        except Exception as ex:
1626
            from App import App
1627
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1628
                                                           sys.exc_info()[-1].tb_lineno)
1629
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1630

    
1631
    def suction_vapor_factor_length(self, i) -> str:
1632
        from CalculationValidation import QCalculationValidation
1633

    
1634
        message = ''
1635
        try:
1636
            # '입력된 vapor의 압력과 밀도를 가지고 끊어서 계산하는 factor를 적용했을때 length가 얼마나 나오는지 판별하는 것.
1637

    
1638
            # pipe dia 가져오기
1639
            ida = self.items[i].data.inside_pipe_size
1640
            if is_blank(str(ida)):
1641
                message = 'You have to input the ID of stream <{}>'.format(self.items[i].data.stream_no)
1642
                return message
1643

    
1644
            pipe_diameter_unit = self.units['Pipe_Diameter']
1645
            if pipe_diameter_unit == 'in':
1646
                ida = ida * 0.0254
1647
            elif pipe_diameter_unit == 'mm':
1648
                ida = ida / 1000
1649

    
1650
            # 'mass 가져오기 기준 kg/h
1651
            mass = self.items[i].data.flowrate_mass
1652
            flowrate_mass_unit = self.units['Flowrate_Mass']
1653
            if flowrate_mass_unit == 'kg/h':
1654
                mass = mass
1655
            elif flowrate_mass_unit == 'g/min':
1656
                mass = mass * 60 / 1000
1657
            elif flowrate_mass_unit == 'lb/h':
1658
                mass = mass * 0.453592
1659
            elif flowrate_mass_unit == 't/h':
1660
                mass = mass * 1000
1661

    
1662
            # 'g 구하기 (kg/m2/s)
1663
            g = mass / 3600 / (3.1415 * ida ** 2 / 4)
1664

    
1665
            density_unit = self.units['Density']
1666
            if density_unit == 'kg/m3':
1667
                density2 = self.density_elevations[self.items[i]]
1668
            else:
1669
                density2 = self.density_elevations[self.items[i]] * 16.0185  # lb/ft3
1670

    
1671
            # '속도 계산 (m/s)
1672
            velocity = 4 * mass / density2 / 3.1415 / ida ** 2 / 3600
1673

    
1674
            # 'Mach Number 계산
1675
            # 'k 가져오기
1676
            k = self.items[i].data.specific_heat_ratio
1677

    
1678
            # temp 가져오기
1679
            temp = self.items[i].data.temperature
1680
            # 'temp를 kalvin으로 맞추기
1681
            temp_unit = self.units['Temperature']
1682
            if temp_unit == '':
1683
                temp = temp + 273.15
1684
            elif temp_unit == '':
1685
                temp = (temp - 32) / 1.8 + 273.15
1686

    
1687
            # 'MW 가져오기
1688
            mw = self.items[i].data.molecular_weight
1689

    
1690
            mach = velocity / ((k * 9.80665 * 847.28 * temp / mw) ** 0.5)
1691

    
1692
            # '부피유량 계산
1693
            volume = mass / density2
1694

    
1695
            # '현재 volume은 m3/h임. 부피유량 단위에 맞춰 뿌려줌
1696
            flowrate_volume_unit = self.units['Flowrate_Volume']
1697
            if flowrate_volume_unit == 'm3/h':
1698
                self.items[i].data.flowrate_volume = round(volume, 3)
1699
            elif flowrate_volume_unit == 'l/min':
1700
                self.items[i].data.flowrate_volume = round(volume / 60 * 1000, 3)
1701
            elif flowrate_volume_unit == 'ft3/h':
1702
                self.items[i].data.flowrate_volume = round(volume * 35.3147, 3)
1703
            elif flowrate_volume_unit == 'USgpm':
1704
                self.items[i].data.flowrate_volume = round(volume * 4.40287, 3)
1705
            elif flowrate_volume_unit == 'BPSD':
1706
                self.items[i].data.flowrate_volume = round(volume * 150.955, 3)
1707

    
1708
            viscosity = self.items[i].data.viscosity
1709
            # ' viscosity 유닛 변환 (모두 kg/m.s로 바꿀것임)
1710
            viscosity_unit = self.units['Viscosity']
1711
            if viscosity_unit == 'kg/m.sec':
1712
                viscosity = viscosity
1713
            elif viscosity_unit == 'cP':
1714
                viscosity = viscosity * 0.001
1715
            elif viscosity_unit == 'kg/m.h':
1716
                viscosity = viscosity / 3600
1717
            elif viscosity_unit == 'lb/ft.s':
1718
                viscosity = viscosity * 1.48816
1719

    
1720
            # density case에 따라 re계산
1721
            density_unit = self.units['Density']
1722
            if density_unit == 'kg/m3':
1723
                reynolds = ida * velocity * density2 / viscosity
1724
            elif density_unit == 'lb/ft3':
1725
                reynolds = ida * velocity * (density2 * 16.0185) / viscosity
1726

    
1727
            # roughness를 m로 바꿔줌
1728
            rough = self.items[i].data.roughness
1729
            roughness_unit = self.units['Roughness']
1730
            if roughness_unit == 'm':
1731
                rough = rough
1732
            elif roughness_unit == 'ft':
1733
                rough = rough * 0.3048
1734
            elif roughness_unit == 'in':
1735
                rough = rough * 0.0254
1736
            elif roughness_unit == 'mm':
1737
                rough = rough * 0.001
1738

    
1739
            # ' reynolds수에 따라 Fanning/Chen friction factor 계산
1740
            if reynolds <= 2100:
1741
                f = 4 * 16 / reynolds
1742
            else:
1743
                af = math.log(rough / ida / 3.7 + (6.7 / reynolds) ** 0.9) / math.log(10)
1744
                f = (-2 * (math.log(rough / 3.7 / ida - 5.02 / reynolds * af) / math.log(10))) ** (-2)
1745

    
1746
            self.items[i].data.friction_factor = f
1747

    
1748
            # '속도와 mach 수 입력
1749
            velocity_unit = self.units['Velocity']
1750
            if velocity_unit == 'm/s':
1751
                self.items[i].data.velocity = round(velocity, 3)
1752
            elif velocity_unit == 'ft/s':
1753
                self.items[i].data.velocity = round(velocity * 3.28084, 3)
1754

    
1755
            self.items[i].data.reynolds = round(mach, 5)
1756

    
1757
            Ref_baro = self.get_barometric_pressure()
1758
            press2 = self.pressures[self.items[i - 1]]
1759

    
1760
            # pressure를 k.g.a로 맞춤
1761
            pressure_unit = self.units['Pressure']
1762
            if pressure_unit == 'kg/cm2':
1763
                press2 = press2 + Ref_baro
1764
            elif pressure_unit == 'psi':
1765
                press2 = press2 / 14.7 * 1.033 + Ref_baro
1766
            elif pressure_unit == 'atm':
1767
                press2 = press2 * 1.033 + Ref_baro
1768
            elif pressure_unit == 'bar':
1769
                press2 = press2 / 1.013 * 1.033 + Ref_baro
1770
            elif pressure_unit == 'mmHg':
1771
                press2 = press2 / 760 * 1.033 + Ref_baro
1772
            elif pressure_unit == 'kPa':
1773
                press2 = press2 / 101.325 * 1.033 + Ref_baro
1774
            elif pressure_unit == 'MPa':
1775
                press2 = press2 / 0.101325 * 1.033 + Ref_baro
1776

    
1777
            press1est = press2 * 0.95  # HY_Calc_sht.Cells(2, 1)
1778

    
1779
            z = self.items[i].data.compress_factor
1780
            density1est = press1est * mw / 0.08206 / temp / z / 1.033
1781

    
1782
            # ' 라인 길이 도출 (m)
1783
            estlength = abs(
1784
                (((press1est ** 2 - press2 ** 2) * mw / g ** 2 / 0.08206 / 1.033 ** 2 / temp / z * 101325) - (
1785
                        2 * math.log(density1est / density2))) * ida / f)
1786

    
1787
            # 라인 길이를 유닛에 맞춰서 변환
1788
            length_unit = self.units['Length']
1789
            if length_unit == 'm':
1790
                estlength = estlength
1791
            elif length_unit == 'in':
1792
                estlength = estlength * 39.3701
1793
            elif length_unit == 'ft':
1794
                estlength = estlength * 3.28084
1795
            elif length_unit == 'yd':
1796
                estlength = estlength * 1.09361
1797
            elif length_unit == 'mile':
1798
                estlength = estlength * 0.000621371
1799
            elif length_unit == 'mm':
1800
                estlength = estlength * 1000
1801

    
1802
            equivalent_length = self.get_equivalent_length(i)
1803
            if estlength > equivalent_length:
1804
                # '주어진 길이를 가지고 압력 강하를 계산하는 모듈이 들어가야함 (safe)
1805
                # ' length 여유 있음. 한번에 isothermal 식으로 계산
1806
                self.suction_vap_dp_cal1(i, press2, g, mw, temp, f, z, ida)
1807
            else:
1808
                # '끊어서 계산하는 모듈이 들어가야함
1809
                # 'length 여유 없음. 압력 재계산->밀도 재계산->re, f 재계산->압력 재계산 체계로 가야함
1810
                message = self.suction_vap_dp_cal2(i, press2, g, mw, temp, f, z, ida, estlength, mass, density1est,
1811
                                                   equivalent_length)
1812

    
1813
        except Exception as ex:
1814
            from App import App
1815
            _message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1816
                                                           sys.exc_info()[-1].tb_lineno)
1817
            App.mainWnd().addMessage.emit(MessageType.Error, _message)
1818

    
1819
        return message
1820

    
1821
    def suction_vap_dp_cal2(self, i, press2, g, mw, temp, f, z, ida, estlength, mass, density1est, equivalent_length) -> str:
1822
        from CalculationValidation import QCalculationValidation
1823

    
1824
        message = ''
1825
        try:
1826
            # 끊은 결과 length 여유가 없음, 고로 물성치 (밀도) 를 재계산해주어야 함
1827

    
1828
            ori_press2 = press2
1829
            trial_length = []
1830
            trial_length.append(estlength)
1831

    
1832
            # Vapor DB에 입력
1833
            vapor_pressure_gradient = []
1834

    
1835
            pressure_unit = self.units['Pressure']
1836
            if pressure_unit == 'kg/cm2':
1837
                vapor_pressure = round(press2, 3)
1838
            elif pressure_unit == 'psi':
1839
                vapor_pressure = round(press2 / 1.033 * 14.7, 3)
1840
            elif pressure_unit == 'atm':
1841
                vapor_pressure = round(press2 / 1.033, 3)
1842
            elif pressure_unit == 'bar':
1843
                vapor_pressure = round(press2 / 1.033 * 1.013, 3)
1844
            elif pressure_unit == 'mmHg':
1845
                vapor_pressure = round(press2 / 1.033 * 760, 3)
1846
            elif pressure_unit == 'kPa':
1847
                vapor_pressure = round(press2 / 1.033 * 101.325, 3)
1848
            elif pressure_unit == 'MPa':
1849
                vapor_pressure = round(press2 / 1.033 * 0.101325, 3)
1850

    
1851
            velocity_unit = self.units['Velocity']
1852
            if velocity_unit == 'm/s':
1853
                vapor_velocity = round(self.items[i].data.velocity, 3)
1854
            elif velocity_unit == 'ft/s':
1855
                vapor_velocity = round(self.items[i].data.velocity * 3.28084, 3)
1856

    
1857
            density_unit = self.units['Density']
1858
            if density_unit == 'kg/m3':
1859
                vapor_density = round(self.density_elevations[self.items[i]], 3)
1860
            elif density_unit == 'lb/ft3':
1861
                vapor_density = round(self.density_elevations[self.items[i]] * 0.062428, 3)
1862

    
1863
            vapor_pressure_gradient.append([vapor_pressure, vapor_velocity, vapor_density, ''])
1864

    
1865
            # 'press2 재정의 끝
1866
            press2, density2, velocity = self.vproperty_recal(press2 * 0.95, mw, temp, z, ida, mass)
1867
            self.vproperty_input(vapor_pressure_gradient, press2, density2, velocity, estlength)
1868

    
1869
            for j in range(1, 100):
1870
                press1est = press2 * 0.95
1871

    
1872
                if press2 < 0:
1873
                    message = 'Line {}\r\nCalculation is terminated\r\nGet Pipe length shorter or Pipe Dia. bigger'.format(self.items[i])
1874

    
1875
                estlength = abs(((( press1est ** 2 - press2 ** 2) * mw / g ** 2 / 0.08206 / 1.033 ** 2 / temp / z * 101325) -
1876
                                 (2 * math.log(density1est / density2))) * ida / f)
1877

    
1878
                trial_length.append(trial_length[j - 1] + estlength)
1879

    
1880
                if trial_length[j] > equivalent_length:
1881
                    remain_length = equivalent_length - trial_length[j - 1]
1882
                    press1 = self.Vap_Suction_1(press2, g, mw, temp, f, z, ida, remain_length)
1883
                    press2, density2, velocity = self.vproperty_recal(press1, mw, temp, z, ida, mass)
1884
                    self.vproperty_input(vapor_pressure_gradient, press2, density2, velocity, remain_length)
1885
                    break
1886
                else:
1887
                    press1 = self.Vap_Suction_1(press2, g, mw, temp, f, z, ida, estlength)
1888
                    press2, density2, velocity = self.vproperty_recal(press1, mw, temp, z, ida, mass)
1889
                    self.vproperty_input(vapor_pressure_gradient, press2, density2, velocity, estlength)
1890

    
1891
            if self.items[i].vapor_pressure_gradient is None:
1892
                self.items[i].vapor_pressure_gradient = vapor_pressure_gradient
1893
                
1894
            # self.pressure_drops[self.items[i]] = ori_press2 - press2
1895
            self.pressure_drops[self.items[i]] = vapor_pressure_gradient[0][0] - vapor_pressure_gradient[-1][0]
1896

    
1897
        except Exception as ex:
1898
            from App import App
1899
            message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
1900
                      f"{sys.exc_info()[-1].tb_lineno}"
1901
            App.mainWnd().addMessage.emit(MessageType.Error, message)
1902

    
1903
        return message
1904

    
1905
    def suction_vap_dp_cal1(self, i, press2, g, mw, temp, f, z, ida):
1906
        try:
1907
            # 끊은 결과 length가 여유가 있음. 그래서 단순 계산하는 모듈
1908
            length = self.get_equivalent_length(i)
1909

    
1910
            # length를 m로 변환
1911
            length_unit = self.units['Length']
1912
            if length_unit == 'm':
1913
                length = length
1914
            elif length_unit == 'in':
1915
                length = length * 0.0254
1916
            elif length_unit == 'ft':
1917
                length = length * 0.3048
1918
            elif length_unit == 'yd':
1919
                length = length * 0.9144
1920
            elif length_unit == 'mile':
1921
                length = length * 1609.34
1922
            elif length_unit == 'mm':
1923
                length = length * 0.001
1924

    
1925
            # Newton's Rule에 따라
1926
            press1 = self.Vap_Suction_1(press2, g, mw, temp, f, z, ida, length)
1927
            pressure_unit = self.units['Pressure']
1928
            if pressure_unit == 'kg/cm2':
1929
                self.pressure_drops[self.items[i]] = press2 - press1
1930
            elif pressure_unit == 'psi':
1931
                self.pressure_drops[self.items[i]] = (press2 - press1) / 1.033 * 14.7
1932
            elif pressure_unit == 'atm':
1933
                self.pressure_drops[self.items[i]] = (press2 - press1) / 1.033
1934
            elif pressure_unit == 'bar':
1935
                self.pressure_drops[self.items[i]] = (press2 - press1) / 1.033 * 1.013
1936
            elif pressure_unit == 'mmHg':
1937
                self.pressure_drops[self.items[i]] = (press2 - press1) / 1.033 * 760
1938
            elif pressure_unit == 'kPa':
1939
                self.pressure_drops[self.items[i]] = (press2 - press1) / 1.033 * 101.325
1940
            elif pressure_unit == 'MPa':
1941
                self.pressure_drops[self.items[i]] = (press2 - press1) / 1.033 * 0.101325
1942

    
1943
            # Vapor DB에 입력
1944
            vapor_pressure_gradient = []
1945

    
1946
            if pressure_unit == 'kg/cm2':
1947
                vapor_pressure = round(press2, 3)
1948
            elif pressure_unit == 'psi':
1949
                vapor_pressure = round(press2 / 1.033 * 14.7, 3)
1950
            elif pressure_unit == 'atm':
1951
                vapor_pressure = round(press2 / 1.033, 3)
1952
            elif pressure_unit == 'bar':
1953
                vapor_pressure = round(press2 / 1.033 * 1.033, 3)
1954
            elif pressure_unit == 'mmHg':
1955
                vapor_pressure = round(press2 / 1.033 * 760)
1956
            elif pressure_unit == 'kPa':
1957
                vapor_pressure = round(press2 / 1.033 * 101.325, 3)
1958
            elif pressure_unit == 'MPa':
1959
                vapor_pressure = round(press2 / 1.033 * 0.101325, 3)
1960

    
1961
            velocity_unit = self.units['Velocity']
1962
            if velocity_unit == 'm/s':
1963
                vapor_velocity = round(self.items[i].data.velocity, 3)
1964
            elif velocity_unit == 'ft/s':
1965
                vapor_velocity = round(self.items[i].data.velocity * 3.28084, 3)
1966

    
1967
            density_unit = self.units['Density']
1968
            if density_unit == 'kg/m3':
1969
                vapor_density = round(self.density_elevations[self.items[i]], 3)
1970
            elif density_unit == 'lb/ft3':
1971
                vapor_density = round(self.density_elevations[self.items[i]] * 0.062428, 3)
1972

    
1973
            vapor_pressure_gradient.append([vapor_pressure, vapor_velocity, vapor_density, ''])
1974

    
1975
            if pressure_unit == 'kg/cm2':
1976
                vapor_pressure = round(press1, 3)
1977
            elif pressure_unit == 'psi':
1978
                vapor_pressure = round(press1 / 1.033 * 14.7, 3)
1979
            elif pressure_unit == 'atm':
1980
                vapor_pressure = round(press1 / 1.033, 3)
1981
            elif pressure_unit == 'bar':
1982
                vapor_pressure = round(press1 / 1.033 * 1.033, 3)
1983
            elif pressure_unit == 'mmHg':
1984
                vapor_pressure = round(press1 / 1.033 * 760)
1985
            elif pressure_unit == 'kPa':
1986
                vapor_pressure = round(press1 / 1.033 * 101.325, 3)
1987
            elif pressure_unit == 'MPa':
1988
                vapor_pressure = round(press1 / 10.33 * 0.101325, 3)
1989

    
1990
            if velocity_unit == 'm/s':
1991
                vapor_velocity = round(press1 * self.items[i].data.velocity / press2, 3)
1992
            elif velocity_unit == 'ft/s':
1993
                vapor_velocity = round(press1 * self.items[i].data.velocity / press2 * 3.28084, 3)
1994

    
1995
            if density_unit == 'kg/m3':
1996
                vapor_density = round(press1 * self.density_elevations[self.items[i]] / press2, 3)
1997
            elif density_unit == 'lb/ft3':
1998
                vapor_density = round(press1 * self.density_elevations[self.items[i]] / press2 * 0.062428, 3)
1999

    
2000
            if length_unit == 'm':
2001
                vapor_length = round(length, 3)
2002
            elif length_unit == 'in':
2003
                vapor_length = round(length * 39.3701, 3)
2004
            elif length_unit == 'ft':
2005
                vapor_length = round(length * 3.28084, 3)
2006
            elif length_unit == 'yd':
2007
                vapor_length = round(length * 1.09361, 3)
2008
            elif length_unit == 'mile':
2009
                vapor_length = round(length * 0.000621371, 3)
2010
            elif length_unit == 'mm':
2011
                vapor_length = round(length * 1000, 3)
2012

    
2013
            vapor_pressure_gradient.append([vapor_pressure, vapor_velocity, vapor_density, vapor_length])
2014

    
2015
            if self.items[i].vapor_pressure_gradient is None:
2016
                self.items[i].vapor_pressure_gradient = vapor_pressure_gradient
2017

    
2018
            self.suction_p_cal(i)
2019
        except Exception as ex:
2020
            from App import App
2021
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2022
                                                           sys.exc_info()[-1].tb_lineno)
2023
            App.mainWnd().addMessage.emit(MessageType.Error, message)
2024

    
2025
    def Vap_Suction_1(self, p2, g, mw, temp, f, z, id, L_eq):
2026
        try:
2027
            R = 0.08206
2028

    
2029
            Tmp_Const = 101325 * mw / (1.033 ** 2 * (g ** 2) * R * temp * z)
2030
            Tmp_Const2 = id / f
2031

    
2032
            x2 = p2
2033
            delta_x_past = 0
2034

    
2035
            loop = True
2036
            while loop:
2037
                X = x2
2038
                f_x = (Tmp_Const2 * (Tmp_Const * (p2 ** 2 - X ** 2) - 2 * math.log(p2 / X))) - L_eq
2039
                df_x = 2 * Tmp_Const2 * (1 / X - Tmp_Const * X)
2040
                x2 = X - (f_x / df_x)
2041
                delta_x = x2 - X
2042
                if abs(delta_x_past) == abs(delta_x):
2043
                    break
2044

    
2045
                delta_x_past = delta_x
2046

    
2047
                if delta_x == 0 or x2 < 0:
2048
                    loop = False
2049

    
2050
            if x2 < 0:
2051
                x2 = x2
2052

    
2053
            return x2
2054

    
2055
        except Exception as ex:
2056
            from App import App
2057
            message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
2058
                      f"{sys.exc_info()[-1].tb_lineno}"
2059
            App.mainWnd().addMessage.emit(MessageType.Error, message)
2060

    
2061
    def suction_p_cal(self, i):
2062
        from CalculationValidation import QCalculationValidation
2063
        res, message = 1, None
2064

    
2065
        try:
2066
            self.pressures[self.items[i]] = self.pressures[self.items[i - 1]] - self.pressure_drops[self.items[i - 1]]
2067

    
2068
            if self.pressures[self.items[i]] < 0:
2069
                pressure_unit = self.units['Pressure']
2070
                if pressure_unit == 'kg/cm2':
2071
                    pabsolute = self.pressures[self.items[i]] + 1.033
2072
                elif pressure_unit == 'psi':
2073
                    pabsolute = self.pressures[self.items[i]] + 14.7
2074
                elif pressure_unit == 'atm':
2075
                    pabsolute = self.pressures[self.items[i]] + 1
2076
                elif pressure_unit == 'bar':
2077
                    pabsolute = self.pressures[self.items[i]] + 1.013
2078
                elif pressure_unit == 'mmHg':
2079
                    pabsolute = self.pressures[self.items[i]] + 760
2080
                elif pressure_unit == 'kPa':
2081
                    pabsolute = self.pressures[self.items[i]] + 101.325
2082
                elif pressure_unit == 'MPa':
2083
                    pabsolute = self.pressures[self.items[i]] + 0.101325
2084

    
2085
                if pabsolute < 0:
2086
                    message = f"The absolute pressure of {self.items[i]} is below 0."
2087

    
2088
            if i < len(self.items) - 2:
2089
                self.pressures[self.items[i + 1]] = self.pressures[self.items[i]] - self.pressure_drops[self.items[i]]
2090
                if self.pressures[self.items[i + 1]] < 0:
2091
                    pressure_unit = self.units['Pressure']
2092
                    if pressure_unit == 'kg/cm2':
2093
                        pabsolute = self.pressures[self.items[i + 1]] + 1.033
2094
                    elif pressure_unit == 'psi':
2095
                        pabsolute = self.pressures[self.items[i + 1]] + 14.7
2096
                    elif pressure_unit == 'atm':
2097
                        pabsolute = self.pressures[self.items[i + 1]] + 1
2098
                    elif pressure_unit == 'bar':
2099
                        pabsolute = self.pressures[self.items[i + 1]] + 1.013
2100
                    elif pressure_unit == 'mmHg':
2101
                        pabsolute = self.pressures[self.items[i + 1]] + 760
2102
                    elif pressure_unit == 'kPa':
2103
                        pabsolute = self.pressures[self.items[i + 1]] + 101.325
2104
                    elif pressure_unit == 'MPa':
2105
                        pabsolute = self.pressures[self.items[i + 1]] + 0.101325
2106

    
2107
                    if pabsolute < 0:
2108
                        # dlg = QCalculationValidation()
2109
                        message = f"The absolute pressure of {self.items[i]} is below 0."
2110
                        # dlg.show_dialog('Calculation will be terminated!', detail)
2111

    
2112
                        # raise ValueError('The absolute pressure of {} is below 0.'.format(self.items[i + 1]))
2113

    
2114
                if self.pattern[self.items[i + 1]] == -4125:
2115
                    # 여기에 그 루프는 그만 하는 로직을 넣어줘야함
2116
                    res = 0
2117
                else:
2118
                    name = str(self.items[i + 1])[:3]
2119
                    if name == 'L_P' or name == 'R_P' or name == 'V_P' or name == 'R_K' or name == 'L_K':
2120
                        self.pressures[self.items[i + 2]] = self.pressures[self.items[i + 1]] + \
2121
                                                            self.pressure_drops[self.items[i + 1]]
2122
                    else:
2123
                        self.pressures[self.items[i + 2]] = self.pressures[self.items[i + 1]] - \
2124
                                                            self.pressure_drops[self.items[i + 1]]
2125
        except Exception as ex:
2126
            from App import App
2127
            _message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
2128
                                                           sys.exc_info()[-1].tb_lineno)
2129
            App.mainWnd().addMessage.emit(MessageType.Error, _message)
2130

    
2131
        return res, message
2132

    
2133
    def hole_p_cal(self, i):
2134
        res = 1
2135

    
2136
        try:
2137
            self.pressures[self.items[i]] = self.pressures[self.items[i + 1]] + self.pressure_drops[self.items[i]] \
2138
                if not self.pressure_drops[self.items[i]] is None else 0
2139

    
2140
            name = str(self.items[i - 2])[:3]
2141
            if i > 0:
2142
                self.pressures[self.items[i - 1]] = self.pressures[self.items[i]] + self.pressure_drops[
2143
                    self.items[i - 1]]
2144

    
2145
                if self.pattern[self.items[i - 2]] == -4125:
2146
                    # 여기에 그 루프는 그만 하는 로직을 넣어줘야함
2147
                    res = 0
2148
                else:
2149
                    if name == 'L_P' or name == 'R_P' or name == 'V_P' or name == 'R_K' or name == 'L_K':
2150
                        self.pressures[self.items[i - 2]] = self.pressures[self.items[i - 1]] - \
2151
                                                            self.pressure_drops[self.items[i - 2]]
2152
                    else:
2153
                        self.pressures[self.items[i - 2]] = self.pressures[self.items[i - 1]] + \
2154
                                                            self.pressure_drops[self.items[i - 2]]
2155

    
2156
                '''
2157
                if self.items[i - 2] in self.pressure_drops and self.pressure_drops[self.items[i - 2]] is not None:
2158
                    if index == 'L_P' or index == 'R_P' or index == 'V_P' or index == 'R_K' or index == 'L_K':
2159
                        self.pressures[self.items[i - 2]] = self.pressures[self.items[i - 1]] - \
2160
                                                            self.pressure_drops[self.items[i - 2]]
2161
                    else:
2162
                        self.pressures[self.items[i - 2]] = self.pressures[self.items[i - 1]] + \
2163
                                                            self.pressure_drops[self.items[i - 2]]
2164
                else:
2165
                    # 여기에 그 루프는 그만 하는 로직을 넣어줘야함
2166
                    res = 0
2167
                '''
2168
        except Exception as ex:
2169
            from App import App
2170
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
2171
                                                           sys.exc_info()[-1].tb_lineno)
2172
            App.mainWnd().addMessage.emit(MessageType.Error, message)
2173

    
2174
        return res
2175

    
2176
    def discharge_p_cal(self, i):
2177
        res = 1
2178

    
2179
        try:
2180
            pressure = 0 if self.pressures[self.items[i + 1]] is None else self.pressures[self.items[i + 1]]
2181
            pressure_drop = 0 if self.pressure_drops[self.items[i]] is None else self.pressure_drops[self.items[i]]
2182

    
2183
            self.pressures[self.items[i]] = pressure + pressure_drop
2184
            name = str(self.items[i - 2])[:3]
2185
            if i > 1:
2186
                self.pressures[self.items[i - 1]] = self.pressures[self.items[i]] + \
2187
                                                    self.pressure_drops[self.items[i - 1]]
2188

    
2189
                if self.pattern[self.items[i - 2]] == -4125:
2190
                    # 여기에 그 루프는 그만 하는 로직을 넣어줘야함
2191
                    res = 0
2192
                else:
2193
                    if name == 'L_P' or name == 'R_P' or name == 'V_P' or name == 'R_K' or name == 'L_K':
2194
                        self.pressures[self.items[i - 2]] = self.pressures[self.items[i - 1]] - self.pressure_drops[
2195
                            self.items[i - 2]]
2196
                    else:
2197
                        self.pressures[self.items[i - 2]] = self.pressures[self.items[i - 1]] + self.pressure_drops[
2198
                            self.items[i - 2]]
2199
        except Exception as ex:
2200
            from App import App
2201
            message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
2202
                      f"{sys.exc_info()[-1].tb_lineno}"
2203
            App.mainWnd().addMessage.emit(MessageType.Error, message)
2204

    
2205
        return res
2206

    
2207

    
2208
class Transfer(QObject):
2209
    onRemoved = pyqtSignal(QGraphicsItem)
2210

    
2211
    def __init__(self, parent=None):
2212
        QObject.__init__(self, parent)