프로젝트

일반

사용자정보

개정판 f1187004

IDf11870041102ea913299f518ecca85d5fd236a33
상위 ca43fed5
하위 a2d321e9

김연진이(가) 5년 이상 전에 추가함

issue #1060 : 계산식

Change-Id: Ic17bb7449542c39904972fa2039f847e74f654e6

차이점 보기:

HYTOS/HYTOS/Calculation.py
1
# coding: utf-8
2
"""
3
    This is calculation module
4
"""
5
import sys
6
import os
7
from AppDocData import *
8
import math
9

  
10
class Calculation:
11
    def __init__(self, hmb):
12
        self.initUnits()
13
        self._hmb = hmb
14
                    
15
        if self._hmb.phase_type == 'Vapor':
16
            self.calculation_Vapor()
17
        elif self._hmb.phase_type == 'Liquid':
18
            self.calculation_Liquid()
19
        elif self._hmb.phase_type == 'Mixed':
20
            self.calculation_Mixed()
21
    
22
    def initUnits(self):
23
        activeDrawing = AppDocData.instance().activeDrawing
24

  
25
        for attr in activeDrawing.attrs:
26
            if attr[0] == 'Units':
27
                self.flowrate_mass_unit = attr[1]['Flowrate_Mass']                
28
                self.flowrate_volume_unit = attr[1]['Flowrate_Volume']
29
                self.density_unit = attr[1]['Density']
30
                self.viscosity_unit = attr[1]['Viscosity']                
31
                self.velocity_unit = attr[1]['Velocity']
32
                self.pressure_unit = attr[1]['Pressure']
33
                self.length_unit = attr[1]['Length']
34
                self.pipe_diameter_unit = attr[1]['Pipe_Diameter']                
35
                self.roughness_unit = attr[1]['Roughness']                
36
                self.temperature_unit = attr[1]['Temperature']
37

  
38
    def getBarometricPressure(self):
39
        barometric_pressure = None
40

  
41
        if self.pressure_unit == 'kg/cm2':
42
            barometric_pressure = 1.033
43
        elif self.pressure_unit == 'bar':
44
            barometric_pressure = 1.01325
45
        elif self.pressure_unit == 'psi':
46
            barometric_pressure = 14.7
47
        elif self.pressure_unit == 'mmHg':
48
            barometric_pressure = 760
49
        elif self.pressure_unit == 'kPa':
50
            barometric_pressure = 101.325
51
        elif self.pressure_unit == 'MPa':
52
            barometric_pressure = 0.101325
53

  
54
        return barometric_pressure
55

  
56
    def calculation_Vapor(self):  
57
        
58

  
59
        # (1) density 입력
60

  
61
        Ref_baro = self.getBarometricPressure()
62

  
63
        press2 = 100 # To쪽 Equipment의 Pressure
64

  
65
        if self.pressure_unit == 'kg/cm2':
66
            press2 = press2 + Ref_baro
67
        elif self.pressure_unit == 'psi':
68
            press2 = press2 / 14.7 * 1.033 + Ref_baro
69
        elif self.pressure_unit == 'atm':
70
            press2 = press2 * 1.033 + Ref_baro
71
        elif self.pressure_unit == 'bar':
72
            press2 = press2 / 1.013 * 1.033 + Ref_baro
73
        elif self.pressure_unit == 'mmHg':
74
            press2 = press2 / 760 * 1.033 + Ref_baro
75
        elif self.pressure_unit == 'kPa':
76
            press2 = press2 / 101.325 * 1.033 + Ref_baro
77
        elif self.pressure_unit == 'MPa':
78
            press2 = press2 / 0.101325 * 1.033 + Ref_baro
79

  
80
        temp = self._hmb.temperature
81
        # temp를 kalvin으로 맞추기
82
        if self.temperature_unit == '℃':
83
            temp = temp + 273.15
84
        elif self.temperature_unit == '℉':
85
            temp = (temp - 32) / 1.8 + 273.15
86

  
87
        # 'MW 가져오기
88
        mw = self._hmb.molecular_weight
89

  
90
        # 'Z 가져오기
91
        z = self._hmb.compress_factor
92

  
93
        # 밀도 계산
94
        density2 = press2 * mw / 0.08206 / temp / z / 1.033
95

  
96
        # '밀도 입력
97
        if self.density_unit == 'kg/m3':
98
            density2 = density2
99
        elif self.density_unit == 'lb/ft3':
100
            density2 = density2 * 0.062428
101

  
102

  
103

  
104
        # (2) static P를 계산
105
        # 1. density 받음
106
        if self.density_unit == 'kg/m3':
107
            density2 = density2
108
        elif self.density_unit == 'lb/ft3':
109
            density2 = density2 * 16.0185
110

  
111
        # 2. elevation 받음
112
        el1 = 200 # From쪽 Equipment의 Elevation
113
        el2 = 100 # To쪽 Equipment의 Elevation
114
        if self.length_unit == 'm':
115
            el1 = el1
116
            el2 = el2
117
        elif self.length_unit == "in":
118
            el1 = el1 * 0.0254
119
            el2 = el2 * 0.0254
120
        elif self.length_unit == "ft":
121
            el1 = el1 * 0.3048
122
            el2 = el2 * 0.3048
123
        elif self.length_unit == "yd":
124
            el1 = el1 * 0.9144
125
            el2 = el2 * 0.9144
126
        elif self.length_unit == "mm":
127
            el1 = el1 * 0.001
128
            el2 = el2 * 0.001
129
        elif self.length_unit == 'mile':
130
            el1 = el1 * 1609.34
131
            el2 = el2 * 1609.34
132

  
133
        # 3. static head 계산 
134
        # 'atm으로 계산된 dp
135
        stat_dp = (el2 - el1) * density2 / 1000 * 9.80665 / 101.325 
136

  
137
        # 4. 압력 유닛에 맞춰 뿌리기
138
        if self.pressure_unit == 'kg/cm2':
139
            stat_dp = stat_dp * 1.033
140
        elif self.pressure_unit == 'psi':
141
            stat_dp = stat_dp * 14.7
142
        elif self.pressure_unit == 'atm':
143
            stat_dp = stat_dp
144
        elif self.pressure_unit == 'bar':
145
            stat_dp = stat_dp * 1.013
146
        elif self.pressure_unit == 'mmHg':
147
            stat_dp = stat_dp * 1.013
148
        elif self.pressure_unit == 'kPa':
149
            stat_dp = stat_dp * 101.325
150
        elif self.pressure_unit == 'MPa':
151
            stat_dp = stat_dp * 0.101325
152

  
153

  
154
        # '(3) pressure drop 계산
155
        # 'vapor인 경우 압력강하를 계산해주고 넣어주는 모듈
156

  
157
        # '입력된 vapor의 압력과 밀도를 가지고 끊어서 계산하는 factor를 적용했을때 length가 얼마나 나오는지 판별하는 것.
158
        ida = self._hmb.inside_pipe_size
159
        if self.pipe_diameter_unit == 'in':
160
            ida = ida * 0.0254
161
        elif self.pipe_diameter_unit == 'mm':
162
            ida = ida / 1000
163

  
164
        # 'mass 가져오기 기준 kg/h
165
        mass = self._hmb.flowrate_mass
166
        if self.flowrate_mass_unit == 'kg/h':
167
            mass = mass
168
        elif self.flowrate_mass_unit == 'g/min':
169
            mass = mass * 60 / 1000
170
        elif self.flowrate_mass_unit == 'lb/h':
171
            mass = mass * 0.453592
172
        elif self.flowrate_mass_unit == 't/h':
173
            mass = mass * 1000
174
        
175
        # 'g 구하기 (kg/m2/s)
176
        g = mass / 3600 / (3.1415 * ida ** 2 / 4)
177

  
178
        # '속도 계산 (m/s)
179
        velocity = 4 * mass / density2 / 3.1415 / ida ** 2 / 3600
180

  
181
        # 'k 가져오기
182
        k = self._hmb.specific_heat_ratio
183

  
184
        # 'Mach Number 계산
185
        mach = velocity / ((k * 9.80665 * 847.28 * temp / mw) ** 0.5)
186

  
187
        # '부피유량 계산
188
        volume = mass / density2
189

  
190
        # '현재 volume은 m3/h임. 부피유량 단위에 맞춰 뿌려줌
191
        if self.flowrate_volume_unit == 'm3/h':
192
            volume = round(volume, 3)    
193
        elif self.flowrate_volume_unit == 'l/min':
194
            volume = round(volume / 60 * 1000, 3)
195
        elif self.flowrate_volume_unit == 'ft3/h':
196
            volume = round(volume * 35.3147, 3)
197
        elif self.flowrate_volume_unit == 'USgpm':
198
            volume = round(volume * 4.40287, 3)
199
        elif self.flowrate_volume_unit == 'BPSD':
200
            volume = round(volume * 150.955, 3)
201

  
202
        viscosity = self._hmb.viscosity
203
        # ' viscosity 유닛 변환 (모두 kg/m.s로 바꿀것임)
204
        if self.viscosity_unit == 'kg/m.sec':
205
            viscosity = viscosity
206
        elif self.viscosity_unit == 'cP':
207
            viscosity = viscosity * 0.001
208
        elif self.viscosity_unit == 'kg/m.h':
209
            viscosity = viscosity / 3600
210
        elif self.viscosity_unit == 'lb/ft.sec':
211
            viscosity = viscosity * 1.48816
212

  
213
        # 'density case에 따라 re계산
214
        if self.density_unit == 'kg/m3':
215
            reynolds = ida * velocity * density2 / viscosity
216
        elif self.density_unit == 'lb/ft3':
217
            reynolds = ida * velocity * (density2 * 16.0185) / viscosity
218

  
219
        rough = self._hmb.roughness
220
        # 'roughness 를 m로 바꿔줌
221
        if self.roughness_unit == 'm':
222
            rough = rough
223
        elif self.roughness_unit == 'ft':
224
            rough = rough * 0.3048
225
        elif self.roughness_unit == 'in':
226
            rough = rough * 0.0254
227
        elif self.roughness_unit == 'mm':
228
            rough = rough * 0.001
229

  
230
        # ' reynolds수에 따라 Fanning/Chen friction factor 계산
231
        if reynolds <= 2100:
232
            f = 4 * 16 / reynolds
233
        else:
234
            af = math.log(rough / ida / 3.7 + (6.7 / reynolds) ** 0.9) / math.log(10)
235
            f = (-2 * (math.log(rough / 3.7 / ida - 5.02 / reynolds * af) / math.log(10))) ** (-2)
236

  
237
        # '속도와 마하 수 입력
238
        if self.velocity_unit == 'm/s':
239
            self._hmb.velocity = round(velocity, 3)
240
        elif self.velocity_unit == 'ft/s':
241
            self._hmb.velocity = round(velocity * 3.28084, 3)
242

  
243
        self._hmb.reynolds = round(mach, 5)
244

  
245

  
246
        press1est = press2 / 0.95 #HY_Calc_sht.Cells(2, 1)
247
        density1est = press1est * mw / 0.08206 / temp / z / 1.033
248

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

  
252
        # '라인 길이를 유닛에 맞춰서 변환
253
        if self.length_unit == 'm':
254
            estlength = estlength
255
        elif self.length_unit == 'in':
256
            estlength = estlength * 39.3701
257
        elif self.length_unit == 'ft':
258
            estlength = estlength * 3.28084
259
        elif self.length_unit == 'yd':
260
            estlength = estlength * 1.09361
261
        elif self.length_unit == 'mile':
262
            estlength = estlength * 0.000621371
263
        elif self.length_unit == 'mm':
264
            estlength = estlength * 1000
265
        
266
        if estlength > self._hmb.equivalent_length:
267
            # '주어진 길이를 가지고 압력 강하를 계산하는 모듈이 들어가야함 (safe)
268
            # ' length 여유 있음. 한번에 isothermal 식으로 계산
269

  
270

  
271
            # ' 끊은 결과 length가 여유가 있음. 그래서 단순 계산하는 모듈
272
            length = self._hmb.equivalent_length
273

  
274
            # 'length 를 m로 변환
275
            if self.length_unit == 'm':
276
                length = length
277
            elif self.length_unit == 'in':
278
                length = length * 0.0254
279
            elif self.length_unit == 'ft':
280
                length = length * 0.3048
281
            elif self.length_unit == 'yd':
282
                length = length * 0.9144
283
            elif self.length_unit == 'mile':
284
                length = length * 1609.34
285
            elif self.length_unit == 'mm':
286
                length = length * 0.001
287
            
288
            # 'Newton's Rule에 따라
289
            press1 = self.vap_discharge_1(press2, g, mw, temp, f, z, ida, length)
290

  
291
            line_drop_press = 0
292
            if self.pressure_unit == 'kg/cm2':
293
                line_drop_press = press1 - press2
294
            elif self.pressure_unit == 'psi':
295
                line_drop_press = (press1 - press2) / 1.033 * 14.7
296
            elif self.pressure_unit == 'atm':
297
                line_drop_press = (press1 - press2) / 1.033
298
            elif self.pressure_unit == 'bar':
299
                line_drop_press = (press1 - press2) / 1.033 * 1.013
300
            elif self.pressure_unit == 'mmHg':
301
                line_drop_press = (press1 - press2) / 1.033 * 760
302
            elif self.pressure_unit == 'kPa':
303
                line_drop_press = (press1 - press2) / 1.033 * 101.325
304
            elif self.pressure_unit == 'MPa':
305
                line_drop_press = (press1 - press2) / 1.033 * 0.101325
306

  
307

  
308
            # 'Hole Calculation
309
            # 'cv와 pump가 다 없을때 (Hole Case)
310

  
311

  
312

  
313

  
314
        else:
315
            # '끊어서 계산하는 모듈이 들어가야함
316
            # 'length 여유 없음. 압력 재계산->밀도 재계산->re, f 재계산->압력 재계산 체계로 가야함
317
            dev = 1
318

  
319

  
320
    def vap_discharge_1(self, p2, g, mw, temp, f, z, id, L_eq):
321
        R = 0.08206
322

  
323
        Tmp_Const = 101325 * mw / (1.033 ** 2 * (g ** 2) * R * temp * z)
324
        Tmp_Const2 = id / f
325

  
326
        if self.pressure_unit == 'kg/cm2':
327
            const_iteration = 5
328
        elif self.pressure_unit == 'psi':
329
            const_iteration = 75
330
        elif self.pressure_unit == 'atm':
331
            const_iteration = 5
332
        elif self.pressure_unit == 'bar':
333
            const_iteration = 5
334
        elif self.pressure_unit == 'mmHg':
335
            const_iteration = 3800
336
        elif self.pressure_unit == 'kPa':
337
            const_iteration = 506
338
        elif self.pressure_unit == 'MPa':
339
            const_iteration = 0.5
340

  
341
        x2 = p2 + const_iteration
342
        delta_x_past = 0    
343

  
344
        loop = True
345
        while loop:
346
            X = x2        
347
            f_x = (Tmp_Const2 * (Tmp_Const * (X ** 2 - p2 ** 2) - 2 * math.log(X / p2))) - L_eq        
348
            df_x = 2 * Tmp_Const2 * (Tmp_Const * X - 1 / X)        
349
            x2 = X - (f_x / df_x)    
350
            delta_x = x2 - X        
351
            if abs(delta_x_past) == abs(delta_x):
352
                break
353

  
354
            delta_x_past = delta_x                            
355

  
356
            if delta_x == 0 or x2 < 0:
357
                loop = False
358

  
359
        '''
360
        Do
361
            X = x2        
362
            f_x = (Tmp_Const2 * (Tmp_Const * (X ^ 2 - p2 ^ 2) - 2 * Log(X / p2))) - L_eq        
363
            df_x = 2 * Tmp_Const2 * (Tmp_Const * X - 1 / X)        
364
            x2 = X - (f_x / df_x)    
365
            delta_x = x2 - X        
366
            If Abs(delta_x_past) = Abs(delta_x) Then Exit Do        
367
            delta_x_past = delta_x                            
368
        Loop Until delta_x = 0 Or x2 < 0
369
        '''
370

  
371
        return x2
372

  
373
    def calculation_Liquid(self):
374
        self._hmb.velocity = 2.889
375

  
376
    def calculation_Mixed(self):
377
        self._hmb.velocity = 2.889
HYTOS/HYTOS/MainWindow.py
108 108
        self.actionClose.triggered.connect(self.close)
109 109
        self.actionNew.triggered.connect(self.new_drawing)
110 110
        self.actionSave.triggered.connect(self.actionSaveCliked)
111
        self.actionCalculation.triggered.connect(self.calculation)
111 112
        self.actionLine.triggered.connect(self.onPlaceLine)
112 113
        self.actionConfiguration.triggered.connect(self.configuration)        
113 114
        self.actionInitialize.triggered.connect(self.onInitializeScene)        
......
669 670
        self.dlgOptions = QOptionsDialog(self)        
670 671
        self.dlgOptions.exec_()
671 672

  
673
    def calculation(self):
674
        from AppDocData import AppDocData
675
        from Calculation import Calculation
676

  
677
        try:
678
            appDocData = AppDocData.instance()
679
            if appDocData.imgName is None or appDocData.activeDrawing is None:
680
                self.showImageSelectionMessageBox()
681
                return
682
           
683
            hmbs = appDocData.activeDrawing.hmbTable._hmbs
684
            if hmbs is not None:            
685
                try:
686
                    self.progress = QProgressDialog(self.tr("Please wait for a while"), self.tr("Cancel"), 0, 100, self) if not hasattr(self, 'progress') else self.progress
687
                    self.progress.setWindowModality(Qt.WindowModal)
688
                    self.progress.setAutoReset(True)
689
                    self.progress.setAutoClose(True)
690
                    self.progress.setMinimum(0)
691
                    self.progress.resize(600,100)
692
                    self.progress.setWindowTitle(self.tr("Calculate data..."))
693
                    self.progress.show()
694
                    
695
                    maxValue = len(hmbs)
696
                    self.progress.setMaximum(maxValue)
697

  
698
                    for hmb in hmbs:   
699
                        self.progress.setValue(self.progress.value() + 1)
700

  
701
                        if hmb.phase_type:
702
                            Calculation(hmb)                
703
                            
704
                        QApplication.processEvents()
705

  
706
                    self.load_HMB()        
707
                finally:
708
                    self.progress.setValue(self.progress.maximum())
709
                    self.progress.hide()
710

  
711
        except Exception as ex:
712
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
713
            self.addMessage.emit(MessageType.Error, message)
672 714
    '''
673 715
        @brief  configuration
674 716
    '''

내보내기 Unified diff

클립보드 이미지 추가 (최대 크기: 500 MB)