Found an issue with the book? Report it on Github.

1차원 열전달(One-Dimensional Heat Transfer)

1차원 열전달(One-Dimensional Heat Transfer)

상태 공간(State Space) 에 대한 이전의 논의에서 행렬과 벡터를 소개할때의 초점은 주로 배열의 수학적 측면에 있었습니다. 이 섹션에서는 배열을 사용하여 물리적인 변수의 1차원 공간 분포를 나타내는 방법을 좀 더 살펴보겠습니다.더불어, 배열과 관련된 모델리카의 여러 기능을 다루면서, 동작을 간결하게 표현할 수 있는 방법을 살펴보겠습니다.

아래와 같은 1차원 막대를 통해, 단순한 열 전달 문제를 중심으로 주제를 다루겠습니다.

Discretization of a one-dimensional bar

방정식의 유도(Deriving Equations)

수학적인 부분을 다루기 전에 짚고 넘어가야 할 중요한 사항이 있습니다.모델리카는 집중(lumped) 시스템을 표현하기 위한 언어이기 때문에, 동작이 상미분 방정식(ODE) 또는 경우에 따라 미분 대수 방정식(DAE)으로 표현되어야 합니다.즉, 모델리카에는 편미분 방정식(즉, 공간 방향에서 변수의 기울기를 포함하는 방정식)을 표현하는 수단이 포함되어 있지 않습니다.따라서 이 섹션에서는 로드를 개별 조각으로 이산화한 다음 각 개별(집합) 조각의 동작을 모델링할 때 발생하는 상미분 방정식을 유도합니다.

위에서 보여준 로드(1차원 막대)의 개별 섹션에서의 열 균형을 앞서 언급한 방식으로 살펴 보겠습니다.먼저 i^{th} 번째 섹션에서의 열용량을 고려해야 합니다. 이것은 다음과 같이 표현할 수 있습니다.

m_i C T_i

여기서 m i^{th} 섹션의 질량이고, C 는 정전용량(재료 속성)이고 T_i i^{th} 섹션의 온도입니다.질량을 다음과 같이 추가적으로 표현할 수 있습니다.

m_i = \rho V_i

여기서 :math:` ho` 는 재료 밀도이고 V_i i^{th} 섹션의 부피입니다. 마지막으로 i^{th} 섹션의 볼륨을 다음과 같이 표현할 수 있습니다.

V_i = A_c L_i

여기서 A_c 는 균일하다고 가정한 i^{th} 단면의 단면적이며, L_i i^{th} 섹션의 길이입니다. 이 예제에서는 로드가 동일한 크기의 조각으로 구성되어 있다고 가정하므로 세그먼트 길이 L_i를 다음과 같이 정의할 수 있습니다.

L_i = \frac{L}{n}

또한 막대의 길이에 따라 단면적이 균일하다고 가정하기 때문에, 각 세그먼트의 질량은 다음과 같이 주어질 수 있습니다.

m = \rho A_c L_i

이 경우 각 섹션의 열 정전용량은 다음과 같습니다.

\rho A_c L_i C T_i

이것은 차례로 해당 섹션에서 얻은 순 열이 다음과 같음을 의미합니다.

\rho A_c L_i C \frac{\mathrm{d} T_i}{\mathrm{d}t}

여기서 A_c , L_i C 는 시간에 따라 변하지 않는다고 가정합니다.

열용량을 다루면서 두 가지 다른 형태의 열 전달을 고려합니다.첫 번째 형태의 열 전달은 일부 주변 온도로의 대류이며, 각 섹션에서 손실된 열량은 다음과 같이 표현할 수 있습니다.

q_h = -h A_{s_i} (T_i-T_{amb})

여기서 h 는 대류 계수이고 A_{s_i} i^{th} 섹션의 표면적입니다. 다른 형태의 열 전달은 이웃 섹션으로의 전도입니다.여기에 두 가지 기여하는 항목이 있는데, 하나는 {i-1}^{th} 섹션에서 손실되고 다른 하나는 {i+1}^{th} 에서 손실됩니다. 이들은 각각 다음과 같이 나타낼 수 있습니다.

q_{k_{i \rightarrow {i-1}}} = -k A_c \frac{T_i-T_{i-1}}{L_i}
q_{k_{i \rightarrow {i+1}}} = -k A_c \frac{T_i-T_{i+1}}{L_i}

이러한 관계를 사용하여 첫 번째 요소에 대한 열 균형을 계산하면 다음과 같습니다.

\rho A_c L_i C \frac{\mathrm{d} T_1}{\mathrm{d}t} = - h A_{s_i} (T_1-T_{amb}) -k A_c \frac{T_1-T_2}{L_i}

마찬가지로 마지막 요소의 열 균형은 다음과 같습니다.

\rho A_c L_i C \frac{\mathrm{d} T_n}{\mathrm{d}t} = -h A_{s_n} (T_n-T_{amb}) -k A_c \frac{T_n-T_{n-1}}{L_i}

최종적으로는, 다른 모든 요소의 열 균형은 다음과 같이 표현 됩니다.

\rho A_c L_i C \frac{\mathrm{d} T_i}{\mathrm{d}t} = -h A_{s_i} (T_i-T_{amb}) -k A_c \frac{T_i-T_{i-1}}{L_i} -k A_c \frac{T_i-T_{i+1}}{L_i}

구현(Implementation)

다양한 물리량에 대한 자료형을 정의하는 것으로 시작합니다. 이렇게 하면 적절한 단위가 제공되며 시뮬레이션 소프트웨어에 따라 방정식에서 단위 검사를 수행할 수 있습니다.자료형(type) 정의는 다음과 같습니다.

  type Temperature=Real(unit="K", min=0);
  type ConvectionCoefficient=Real(unit="W/K", min=0);
  type ConductionCoefficient=Real(unit="W.m-1.K-1", min=0);
  type Mass=Real(unit="kg", min=0);
  type SpecificHeat=Real(unit="J/(K.kg)", min=0);
  type Density=Real(unit="kg/m3", min=0);
  type Area=Real(unit="m2");
  type Volume=Real(unit="m3");
  type Length=Real(unit="m", min=0);
  type Radius=Real(unit="m", min=0);

또한 시뮬레이션 중인 로드를 설명하기 위해 여러 파라미터를 정의합니다.

  parameter Integer n=10;
  parameter Length L=1.0;
  parameter Radius R=0.1;
  parameter Density rho=2.0;
  parameter ConvectionCoefficient h=2.0;
  parameter ConductionCoefficient k=10;
  parameter SpecificHeat C=10.0;
  parameter Temperature Tamb=300 "Ambient temperature";

다음 선언을 사용하여 정의한 파라미터로 각 섹션의 면적과 체적을 계산할 수 있습니다.

  parameter Area A_c = pi*R^2, A_s = 2*pi*R*L;
  parameter Volume V = A_c*L/n;

마지막으로, 이 문제의 유일한 배열은 각 섹션의 온도입니다(막대의 길이에 따라 실제로 달라지는 유일한 양이므로).

  Temperature T[n];

이것으로 해야 할 모든 선언을 마쳤고, 필요한 방정식을 이제 생각해보겠습니다.먼저 막대의 초기 조건을 지정해야 합니다. T_1(0)=200 , T_n(0)=300 이라고 가정하고 다른 모든 섹션의 초기 온도는 이 두 끝 조건 사이에서 선형으로 보간될 수 있으며, 이는 다음 방정식으로 표현됩니다.

initial equation
  T = linspace(200,300,n);

여기서 linspace 연산자는 200300 사이에서 선형적으로 변하는 n 값의 배열을 만드는 데 사용합니다. 좌변과 우변의 표현이 벡터인 방정식을 포함할 수 있는 상태 공간(State Space) 예제를 상기해보면, 이것은 그러한 방정식의 또 다른 예 인것을 알수 있습니다.

마지막으로 각 섹션의 온도가 시간에 따라 어떻게 변하는지 설명하는 다음 방정식이 있습니다.

equation
  rho*V*C*der(T[1]) = -h*A_s*(T[1]-Tamb)-k*A_c*(T[1]-T[2])/(L/n);
  for i in 2:(n-1) loop
    rho*V*C*der(T[i]) = -h*A_s*(T[i]-Tamb)-k*A_c*(T[i]-T[i-1])/(L/n)-k*A_c*(T[i]-T[i+1])/(L/n);
  end for;
  rho*V*C*der(T[end]) = -h*A_s*(T[end]-Tamb)-k*A_c*(T[end]-T[end-1])/(L/n);

첫 번째 방정식은 1 섹션의 열 균형에 해당하고 마지막 방정식은 n 섹션의 열 균형에 해당하며중간 방정식은 다른 모든 섹션을 포함합니다. end 를 아래 첨자로 사용하는 것을 볼 수 있는데, 주어진 차원에 대한 첨자로 연산하기 위해 표현식이 사용될 때 end 는 해당 차원의 크기를 나타냅니다.이 경우에는 end 를 사용하여 마지막 섹션을 나타냈는데 n 을 사용할 수 있지만, 일반적으로 end 는 차원의 크기가 아직 변수와 연결되지 않은 경우 매우 유용할 수 있습니다.

또한 이 모델에서 for 루프를 사용하는 것을 볼 수 있는데, 이때 루프 인덱스 변수가 값 범위를 반복할 수 있습니다.루프 인덱스 변수는 i 이고 값의 범위는 2 에서 n-1 까지입니다. for 루프의 일반적인 구문은 다음과 같습니다.

for <var> in <range> loop
  // statements
end for;

여기서 <range> 는 값의 벡터이며, 일련의 값을 생성하는 편리한 방법은 범위 연산자 : 를 사용하는 것입니다. 범위 연산자 앞의 값은 시퀀스의 초기 값이고 범위 연산자 뒤의 값은 시퀀스의 최종 값입니다.예를 들어 표현식 5:105, 6, 7, 8, 9 그리고 10 값을 가진 벡터를 생성하며, 여기서 볼 수 있는 것 처럼 범위를 지정하는 데 사용하는 값이 포함 됩니다.

for 루프가 방정식 섹션에서 사용하는 경우, for 루프의 각 반복은 for 루프 내부의 각 방정식에 대해 새로운 방정식을 생성합니다.따라서 경우에는 2n-1 사이의 i 값에 해당하는 n-2 개의 방정식을 생성할 것입니다.

이 모든 것을 종합하면 완전한 모델은 다음과 같습니다.

model Rod_ForLoop "Modeling heat conduction in a rod using a for loop"
  type Temperature=Real(unit="K", min=0);
  type ConvectionCoefficient=Real(unit="W/K", min=0);
  type ConductionCoefficient=Real(unit="W.m-1.K-1", min=0);
  type Mass=Real(unit="kg", min=0);
  type SpecificHeat=Real(unit="J/(K.kg)", min=0);
  type Density=Real(unit="kg/m3", min=0);
  type Area=Real(unit="m2");
  type Volume=Real(unit="m3");
  type Length=Real(unit="m", min=0);
  type Radius=Real(unit="m", min=0);

  constant Real pi = 3.14159;

  parameter Integer n=10;
  parameter Length L=1.0;
  parameter Radius R=0.1;
  parameter Density rho=2.0;
  parameter ConvectionCoefficient h=2.0;
  parameter ConductionCoefficient k=10;
  parameter SpecificHeat C=10.0;
  parameter Temperature Tamb=300 "Ambient temperature";

  parameter Area A_c = pi*R^2, A_s = 2*pi*R*L;
  parameter Volume V = A_c*L/n;

  Temperature T[n];
initial equation
  T = linspace(200,300,n);
equation
  rho*V*C*der(T[1]) = -h*A_s*(T[1]-Tamb)-k*A_c*(T[1]-T[2])/(L/n);
  for i in 2:(n-1) loop
    rho*V*C*der(T[i]) = -h*A_s*(T[i]-Tamb)-k*A_c*(T[i]-T[i-1])/(L/n)-k*A_c*(T[i]-T[i+1])/(L/n);
  end for;
  rho*V*C*der(T[end]) = -h*A_s*(T[end]-Tamb)-k*A_c*(T[end]-T[end-1])/(L/n);
end Rod_ForLoop;

Note

이 모델에서 리터럴 상수로 pi 를 포함했다는 점에 유의해야 합니다. 이 책의 뒷부분에서 일반 상수 를 올바르게 가져오는 방법에 대해 설명 하겠습니다.

이 모델을 시뮬레이션하면 각 절점 온도에 대해 다음과 같은 해가 생성됩니다.

/static/_images/RFL.svg

(initial equation 섹션에서 지정한 대로) 온도가 초기에 선형적으로 분포되어 있다는 부분에 주목해야겠습니다.

대안(Alternatives)

필요한 방정식을 생성할 수 있는 여러 가지 방법이 있음을 밝혔고, 각각은 상황에 따라 고유한 장점과 단점이 있습니다.여러 가능성을 보여주기 위해 가능한 예시를 보여주겠습니다. 가장 이해하기 쉬운 방정식으로 표현하는 방법을 선택하는 것은 모델 개발자에게 달려 있습니다.

방정식을 약간 더 간단하게 만드는 데 사용할 수 있는 배열 기능 중 하나는 배열 내포(array comprehension) 인데,``for`` 루프를 뒤집어 하나의 방정식을 취하고 루프 인덱스 변수의 다른 값에 대해 방정식을 연산해야 한다는 정보를 마지막에 추가하는 형태입니다. 이 예제의 경우 다음과 같이 배열 내포를 사용하여 방정식 섹션을 나타낼 수 있습니다.

equation
  rho*V*C*der(T[1]) = -h*A_s*(T[1]-Tamb)-k*A_c*(T[1]-T[2])/(L/n);
  rho*V*C*der(T[2:n-1]) = {-h*A_s*(T[i]-Tamb)-k*A_c*(T[i]-T[i-1])/(L/n)-k*A_c*(T[i]-T[i+1])/(L/n) for i in 2:(n-1)};
  rho*V*C*der(T[end]) = -h*A_s*(T[end]-Tamb)-k*A_c*(T[end]-T[end-1])/(L/n);

배열 내포를 일부 if 표현식과 결합하여 필요로 하지 않는 경우에 열 균형 수식에서 무효화할 수도 있습니다. equation 섹션을 하나의 (다중 라인) 방정식을 포함하는 지점까지 단순화할 수 있으며, 이러한 경우 좌변과 우변이 같은 크기의 벡터일 때 단일(벡터) 방정식을 사용하여 많은 스칼라 방정식을 나타낼 수 있습니다.이 기능을 사용하여 방정식을 다음과 같이 단순화할 수 있습니다.

equation
  rho*V*C*der(T) = {-h*A_s*(T[i]-Tamb)
                    -(if i==1 then 0 else k*A_c/(L/n)*(T[i]-T[i-1]))
                    -(if i==n then 0 else k*A_c/(L/n)*(T[i]-T[i+1])) for i in 1:n};

이전의 몇 가지 예제에서 모델리카가 벡터 방정식을 지원한다는 사실을 언급 했습니다.이러한 경우 좌변과 우변이 같은 크기의 벡터일 때 단일(벡터) 방정식을 사용하여 많은 스칼라 방정식을 나타낼 수 있습니다.이 기능을 사용하여 방정식을 다음과 같이 단순화할 수 있습니다.

equation
  rho*V*C*der(T[1]) = -h*A_s*(T[1]-Tamb)-k*A_c*(T[1]-T[2])/(L/n);
  rho*V*C*der(T[2:n-1]) = -h*A_s*(T[i]-Tamb)-k*A_c*(T[2:n-1]-T[1:n-2])/(L/n)-k*A_c*(T[2:n-1]-T[3:n])/(L/n);
  rho*V*C*der(T[end]) = -h*A_s*(T[end]-Tamb)-k*A_c*(T[end]-T[end-1])/(L/n);

T 와 같은 벡터 변수에 적용된 첨자 범위가 있는 경우, 결과는 첨자의 값으로 표시된 구성 요소를 포함하는 벡터입니다. 예를 들어, T[2:4] 표현은 {T[2], T[3], T[4]} 와 같습니다. 그리고, 첨자 식이 범위로 지정될 필요가 없습니다. 예를 들어 T[{2,5,9}]{T[2], T[5], T[9]} 와 같습니다.

마지막으로 이러한 방정식을 리팩터링하는 방법을 생각해 보겠습니다.예를 들어 세 가지 추가 벡터 변수를 도입했다고 가정해 보겠습니다.

  Heat Qconv[n];
  Heat Qleft[n];
  Heat Qright[n];

그런 다음 로드의 주변, 이전 섹션 및 다음 섹션으로 손실되는 열을 정의하기 위해 이 두 방정식(다시 벡터 방정식 사용)을 작성할 수 있습니다.

  Qconv = {-h*A_s*(T[i]-Tamb) for i in 1:n};
  Qleft = {(if i==1 then 0 else -k*A_c*(T[i]-T[i-1])/(L/n)) for i in 1:n};
  Qright = {(if i==n then 0 else -k*A_c*(T[i]-T[i+1])/(L/n)) for i in 1:n};

이를 통해 아래 첨자를 포함하지 않는 벡터 방정식을 사용하여 각 섹션의 열 균형을 표현할 수 있습니다.

  rho*V*C*der(T) = Qconv+Qleft+Qright;

결론(Conclusion)

이 섹션에서는 벡터 변수와 벡터 방정식을 사용하여 1차원 열 전달을 나타낼 수 있는 다양한 방법을 살펴보았습니다. 이와 같은 벡터 관련 기능은 다양한 문제 유형에 사용할 수 있습니다. 이 섹션의 목표는 벡터로 작업할 때 개발자가 사용할 수 있는 다양한 옵션을 보여주기 위해 몇 가지 기능을 소개하는 것이었습니다.