2013-10-03 2 views
1

I는 간단한 방법으로 168 시간 (예를 들어, 일주일)는 VBA : 느린 해석 루프

이것은 어떤 입력 값과 화학적 값을 판독하고, 상기 몰 질량을 계산위한 고로 가스를 계산하는 코드를 가지고 체계. 그 후 솔버는 가스가 배출되는 화학적 형태 (주로 CO, CO2)를 계산합니다. 문제는 매우 느립니다. 이 엑셀 통합 문서를 열면 몇 분이 걸리고 더 많은 통합 문서가 열려있을 때 끝까지 실행할 수있게조차 신경 쓰지 않습니다.

나는 VBA에 매우 익숙하다. 그러나 VBA에서 방정식을 푸는 대신에 "excel worksheet"와 "iterate"사이에 값을 "반복"하는 대신에 좀 더 빠르다고 기대한다. VBA 솔버, 점차적으로 셀 값을 풀어서 - 만약 내가 방금 알고 있었다면, 가능한 경우 또는 좋은 아이디어.

그 개체의 코드, 먼저 일반 계산 :

Sub BFgas() 

Datamatrix = Range(Cells.Find("Datamatrix").Offset(1, 0).Address, Cells.Find("Datamatrix").Offset(21, 0).Address) 
ReDim BFoutput(1 To 168, 1 To 3) As Double 



M_pigiron_Matrix = Range(Cells.Find("BF1 Pig iron production").Offset(1, 0).Address, Cells.Find("BF1 Pig iron production").Offset(168 + 1, 0).Address) 
Bf_blast_Matrix = Range(Cells.Find("BF 1 - Blast").Offset(1, 0).Address, Cells.Find("BF 1 - Blast").Offset(168 + 1, 0).Address) 
Bf_oxygen_Matrix = Range(Cells.Find("BF 1 - Oxygen").Offset(1, 0).Address, Cells.Find("BF 1 - Oxygen").Offset(168 + 1, 0).Address) 

M = 1 
Do 

M_pigiron = M_pigiron_Matrix(M, 1) 'Tons of pig iron 
Bf_blast = Bf_blast_Matrix(M, 1) 'Nm3 
Bf_oxygen = Bf_oxygen_Matrix(M, 1) 'Nm3 

If Bf_blast = 0 Or Bf_oxygen = 0 Then 
Do 
M_pigiron = M_pigiron_Matrix(M, 1) 'Tons of pig iron 
Bf_blast = Bf_blast_Matrix(M, 1) 'Nm3 
Bf_oxygen = Bf_oxygen_Matrix(M, 1) 'Nm3 
M = M + 1 
Loop While Bf_oxygen = 0 Or Bf_blast = 0 
End If 



n_N2_blast = Bf_blast * Datamatrix(19, 1)/Datamatrix(17, 1) 'kmol 
n_O2_blast = Bf_blast * Datamatrix(18, 1)/Datamatrix(17, 1) 'kmol 
n_O2_oxygenintake = Bf_oxygen/Datamatrix(17, 1) 'kmol 
n_total_O_in = (n_O2_blast + n_O2_oxygenintake) * 2 'kmol 




'Calculates the amounts of coke, briquettes and scrap 

Cokeratio = Cells.Find("Input data").Offset(1, 1).Value2 
Briqratio = Cells.Find("Input data").Offset(2, 1).Value2 
Scrapratio = Cells.Find("Input data").Offset(3, 1).Value2 
m_oil = Cells.Find("Input data").Offset(4, 1).Value2 


m_coke = Cokeratio * M_pigiron * 1000 'kg 
m_briq = Briqratio * M_pigiron 'kg 
m_scrap = Scrapratio * M_pigiron 'kg 


'Fe/Iron calculations 
'Calculates the molar masses of iron and coal in pig iron, briqettes and scrap 

n_Fe_pigiron = Datamatrix(3, 1) * M_pigiron * 1000/Datamatrix(15, 1) 'kmol 

n_Fe_briq = Datamatrix(12, 1) * m_briq/Datamatrix(15, 1) 'kmol 

n_Fe_scrap = Datamatrix(13, 1) * m_scrap/Datamatrix(15, 1) 'kmol 

'Calculates how many kmol is needed from pellets 

n_Fe_pellets = n_Fe_pigiron - n_Fe_briq - n_Fe_scrap 
m_pellets = n_Fe_pellets/Datamatrix(11, 1) * Datamatrix(15, 1) 'Divides by the iron content 0.72, to get the total mass 



'O/Oxygen calculations 
'Calculates the total incoming oxygen 
'(m_pel*x_pellets,O + m_briq*x_O,briq)/M_O + n_blast,O2*2 + n_Oxygen,O2*2 

Oxygen_in = m_pellets * Datamatrix(10, 1)/Datamatrix(16, 1) + m_briq * Datamatrix(9, 1)/Datamatrix(16, 1) + n_total_O_in 'kmol 
Cells.Find("Solutions").Offset(0, 1).Value = Oxygen_in 

'C/Coal calculations 
'Calculates the incoming coal minus what comes out with the pig iron, leaving what comes out with the bf-gases 
'm_coke,*x_C,coke + m_oil*x_C,oil + m_br*x_br,C = m_rj*x_C,rj + V_tg*(y,co + y,co2) 

Coal_for_bf_gas = (m_coke * Datamatrix(4, 1)/Datamatrix(14, 1) + m_oil * Datamatrix(5, 1)/Datamatrix(14, 1) + m_briq * Datamatrix(6, 1)/Datamatrix(14, 1)) - M_pigiron * 1000 * Datamatrix(1, 1)/Datamatrix(14, 1) 
Cells.Find("Solutions").Offset(0, 2).Value = Coal_for_bf_gas 

'N/Nitrogen 
'Nitrogen is mainly what comes in with the blast 

N2_for_bf_gas = n_N2_blast 
Cells.Find("Solutions").Offset(0, 3).Value = N2_for_bf_gas 



'Sets in the hydrogen just in case 
'H/hydrogen 
'H_for_bf_gas = m_coke * Datamatrix(21, 1)/Datamatrix(20, 1) + m_oil * Datamatrix(7, 1)/Datamatrix(20, 1) 

솔버 부분 :

SolverReset 'Code solves the problem for a specific set of lines, in this case meaning hours 
SolverOptions Precision:=1, Iterations:=100, AssumeNonNeg:=True 
SolverOk setCell:=Cells.Find("Differences").Offset(1, 0).Address, MaxMinVal:=3, ValueOf:="0", ByChange:=Range(Cells.Find("Testing here").Offset(0, 1).Address, Cells.Find("Testing here").Offset(0, 3).Address) 

SolverAdd cellRef:=Range(Cells.Find("Testing here").Offset(0, 2).Address, Cells.Find("Testing here").Offset(0, 3).Address), _ 
relation:=3, _ 
formulaText:=0.1 

SolverAdd cellRef:=Range(Cells.Find("Testing here").Offset(0, 2).Address, Cells.Find("Testing here").Offset(0, 3).Address), _ 
relation:=1, _ 
formulaText:=0.4 

SolverAdd cellRef:=Cells.Find("Testing here").Offset(0, 1).Address, _ 
relation:=3, _ 
formulaText:=(Bf_blast + Bf_oxygen) * 1.2 

SolverAdd cellRef:=Cells.Find("Testing here").Offset(0, 1).Address, _ 
relation:=1, _ 
formulaText:=(Bf_blast + Bf_oxygen) * 2 

SolverSolve userFinish:=True 

BFoutput(M, 1) = Cells.Find("Testing here").Offset(0, 1).Value 
BFoutput(M, 2) = Cells.Find("Testing here").Offset(0, 2).Value 
BFoutput(M, 3) = Cells.Find("Testing here").Offset(0, 3).Value 



M = M + 1 
Loop While M < 169 

Cells.Find("BF1 - Output data").Offset(2, 0).Resize(UBound(BFoutput, 1), 3).Value = BFoutput 

답변

0

나는 화학 엔지니어 아니에요, 그래서 방정식 당신을 모르는 해결하려고 노력 중입니다.

저는 그것이 비선형, 일시적 및 반복적이라고 추측합니다. 168 * 3 = 504 자유도는 그다지 큰 것이 아니지만, 각 단계마다 반복되는 작은 시간 단계가 많은 경우 많은 작업이 될 수 있습니다.

내가 게시 한 코드에서 일시적인 문제가 발생했는지 정상 상태 문제인지 알 수 없습니다.

더 잘 알고있는 (고체 역학 및 열 전달) 수치 적 문제는 알고리즘에 매우 민감합니다. 방정식은 선택한 통합 계획에 따라 안정성을 이유로 시간 단계 제한을받을 수 있습니다.

비선형 정상 상태 문제를 푸는 경우 시간 단계 크기 대신 반복 단계 크기를 제외하고 동일한 설명이 적용됩니다.

나는 당신의 VB 코드에서 이것에 대해 많은 것을 주울 수는 없지만, 나는 이러한 권장 사항을 제공합니다 :

  1. 당신의 방정식을 쓰기, 푸리에을 변환 및 안정성 제한이 있는지 확인합니다.
  2. Matlab과 같은 도구 키트에 대해 생각해보십시오. 사용자 정의 코드보다 더욱 최적화 된 상자 구현을 벗어났습니다.
  3. VB 또는 Excel 용 프로파일 링 기능을 모르지만 데이터가 없으면 문제를 해결할 수 없습니다. 솔루션에 대한 가설을 세우기 전에 시간이 어디서 보내고 있는지에 대한 정보를 얻을 수 있는지 알 것입니다.
+0

제안 해 주셔서 감사합니다. 나는 앞으로 몇 주 동안 내가 할 수있는 것을 보게 될 것이다. "천천히"천천히 그러나 그것은 나보다 다른 사용자에게 상당히 짜증나는 경우 완전한 재앙이 아닙니다. – user2703642

+0

일주일은 모든 분석에 긴 시간입니다. 한 달 동안 한 번 실행 된 유한 요소 분석을 한 번 실행했습니다. 그러나 그것은 대형 변형 시트 금속판 플라스틱 성형 문제였습니다. 나는 당신의 문제가 크기 나 복잡성에 가까워 진다고 믿지 않습니다. – duffymo

+0

그건 나 자신에 대해 궁금해하고 있었던 것입니다. 단지 한 시간 동안 해결하기를 원한다면 Excel에 설정하는 데 시간이 많이 걸리지 않는 상당히 간단한 문제입니다.이 단순화 된 버전에는 3 가지 미지수가 있습니다. CO, CO2 및 가스량이 너무 길어서 꽤 놀랐습니다. 심지어 간격을 꽤 제한하려고 시도 했더라도. 그러나 내가 가진 제안을 살펴볼 것입니다. – user2703642