← 강의 페이지 화학공학을 위한 AI 10 / 15

10장 물질수지의 알고리즘화

이번 주의 도구: ⑦ 물질수지 solver

다음 상황을 생각해 보자. 화공양론 과제에 분리 공정 문제가 나왔다. 공급 흐름 하나, 생성물 흐름 둘이라 지난주까지는 식 두 개로 끝났다. 그런데 이번 문제의 흐름도에는 화살표가 하나 더 붙어 있다. 하부 흐름의 절반을 되돌려 공급과 섞는 재순환 배관이다.

미지수를 세어 보니 여섯 개다. 식 여섯 개를 세우고 대입을 시작한다. 20분 뒤, 세 번째 이항에서 부호 하나를 잃어버렸다. 처음부터 다시 푼 값은 아까와 다르고, 어느 쪽이 맞는지 확인할 방법이 없다. 문제를 이해하지 못한 것이 아니다. 식은 전부 맞게 세웠다. 무너진 것은 1차식 여섯 줄을 손으로 관리하는 회계 작업이다.

컴퓨터는 정확히 이 작업을 잘한다. numpy는 여섯 개든 예순 개든 연립선형방정식을 함수 호출 한 번으로 푼다. 남는 질문은 하나다. 그 여섯 줄이 올바른 식이라는 것을 누가 보증하는가. 이 장은 그 보증 절차(경계 긋기, 라벨링, 자유도 분석)를 먼저 익히고, 그다음에야 풀이를 numpy에 넘긴다.

이 장에서 다루는 것

  • 시스템 경계를 긋고 일반 수지식에서 출발해 정상상태 물질수지를 세운다
  • 흐름도 라벨링과 자유도 분석으로 문제의 해결 가능성을 판정한다
  • 재순환·퍼지 구조에서 분기점과 합류점의 회계 규칙을 다룬다
  • 물질수지를 행렬 형태로 변환해 numpy로 풀고 결과를 검증한다
  • 실습에서 학번별 문제로 도구⑦ 물질수지 solver를 완성한다

학습목표 이 장을 마치면 다음을 할 수 있다.

  1. 공정 서술에서 시스템 경계를 긋고 흐름도를 빠짐없이 라벨링할 수 있다.
  2. 미지수와 독립 방정식을 세어 자유도를 계산하고 문제가 풀리는지 판정할 수 있다.
  3. 재순환 시스템에서 분기점·합류점을 공정으로 취급해 자유도 분석을 수행할 수 있다.
  4. 물질수지 연립방정식을 행렬 형태 Ax = b로 변환하고 numpy로 풀 수 있다.
  5. Singular matrix 에러를 자유도 관점에서 진단하고 교정할 수 있다.
  6. solver의 결과를 검증 루틴 3종으로 확인하고 README에 기록할 수 있다.

10.1 시스템 경계와 흐름도 라벨링

물 1 L를 깔때기에 부어 플라스크로 흘려보낸다. 깔때기에 처음 물이 없었고 부은 1 L가 전부 빠져나갔다면, 깔때기에 남은 물은 얼마인가. 답은 0 L다. 이 답은 깔때기의 크기나 벽면의 기울기와 무관하다. 들어간 양과 나온 양만 알면 내부 구조를 몰라도 결론이 나온다.

이 하찮은 예제가 물질수지의 뼈대 전부다. 관심 영역을 정해 두고 그 안팎으로 드나드는 질량을 장부에 적는 계산을 물질수지(material balance)라 한다. 그리고 관심 영역을 둘러싸는 가상의 닫힌 면을 시스템 경계(system boundary)라 한다. 경계를 어디에 긋는가에 따라 같은 공정에서도 전혀 다른 식이 나오는데, 이 선택의 자유를 10.3절에서 재순환 문제를 푸는 데 그대로 쓴다.

경계를 그었으면 장부의 계정은 다섯 개다. 들어온 것, 나간 것, 안에서 생긴 것, 안에서 없어진 것, 그리고 그 결과로 쌓인 것이다. 이를 한 줄로 쓰면 일반 수지식을 얻는다.

축적 = 입력 − 출력 + 생성 − 소멸 (10.1)

생성과 소멸은 화학반응의 몫이다. 이 장에서는 반응이 없는 공정만 다루므로 두 항은 0이다. 여기에 조업 조건이 시간이 지나도 변하지 않는 상태, 곧 정상상태(steady state)를 가정하면 축적도 0이 되어 식은 가장 단순한 형태로 줄어든다.

입력 = 출력 (10.2)

10.1.1 흐름도 라벨링: 문제의 절반

서술형 문제를 받으면 식보다 그림이 먼저다. 문장 속에 흩어진 장치와 흐름을 종이 위의 흐름도로 옮기는 작업을 라벨링이라 부르며, 순서는 다음과 같다.

마지막 항목이 함정이다. 질량과 달리 부피에는 대부분의 경우 보존 법칙이 없다. 부피 유량이 주어지면 밀도를 곱해 질량 유량으로 환산한 뒤에 수지식에 넣어야 하며, "부피 보존" 식을 세우면 그 시점에서 답이 틀어진다.

미지수를 세는 규칙도 여기서 정해진다. 성분이 C개인 스트림의 독립 미지수는 C개다. 질량분율 C−1개와 총유량 1개다. 분율의 합이 1이므로 마지막 분율은 나머지에서 자동으로 정해지지만, 총유량은 분율만으로는 알 수 없기 때문이다.

예제 10.1-1 설탕물 혼합기

문제 설탕 질량분율 0.20인 설탕물 100 kg/h(스트림 1)와 0.80인 설탕물 50 kg/h(스트림 2)를 혼합기에서 섞는다. 정상상태에서 출구 스트림 3의 유량과 설탕 분율을 구하라.

풀이 전략 성분이 둘(설탕, 물)이므로 독립 수지는 두 개다. 총괄수지와 설탕 수지를 쓰기로 한다. 이 정도 규모는 손계산 영역이다. AI를 부를 일이 아니다.

계산 총괄수지(식 10.2): ṁ3 = 100 + 50 = 150 kg/h. 설탕 수지: 스트림 1이 100 × 0.20 = 20 kg/h, 스트림 2가 50 × 0.80 = 40 kg/h를 들여오므로 출구 설탕 유량은 60 kg/h.

답: ṁ3 = 150 kg/h, x설탕,3 = 60/150 = 0.40

  • 단위 체크: 모든 항이 kg/h로 식 (10.2)와 일치
  • 대조값: 혼합물 분율은 두 입력 분율 사이에 있어야 한다. 0.20 < 0.40 < 0.80으로 통과
  • 극한값: 스트림 2 유량 → 0이면 x설탕,3 → 0.20으로 수렴해야 한다. 식에 0을 대입하면 그대로 재현된다

분석 성분이 C개면 독립 수지도 C개다. 총괄수지를 쓰면 성분 수지 하나를 대신할 수 있을 뿐, 식이 하나 늘어나는 것이 아니다. 이 사실은 다음 절의 자유도 계산과 10.4절의 특이 행렬 에러에 그대로 이어진다. 스트림 2의 분율을 0.5로 바꿔 극한 검증을 한 번 더 해 보라.

스스로 점검 (해답은 권말)

  1. 성분 3개짜리 스트림 하나의 독립 미지수는 몇 개인가?
  2. 정상상태이지만 반응이 있는 계라면 식 (10.1)에서 어떤 항이 살아남는가?

10.2 자유도 분석: 풀리는 문제인지 먼저 판정한다

식을 다 세우고 연립을 반쯤 풀고 나서야 "안 풀리는 문제였다"를 아는 것은 가장 늦은 발견이다. 계산을 시작하기 전에 미지수 개수와 독립 방정식 개수를 세어 비교하면 풀리는 문제인지 미리 알 수 있다. 이 차이를 자유도(degree of freedom, DOF)라 한다.

DOF = 미지수 개수 − 독립 방정식 개수 (10.3)

판정은 세 갈래다. 자유도가 0이면 미지수를 유한한 해로 결정할 수 있는 적정지정(well-defined) 문제다. 0보다 크면 정보가 모자라는 과소지정(underspecified), 0보다 작으면 정보가 남거나 서로 모순일 수 있는 과잉지정(overspecified)이다.

표 10-1 자유도 판정과 대응
DOF판정대응
0적정지정(풀 수 있다)풀이 계획 수립으로 진행
> 0과소지정(정보 부족)추가 측정·사양 확보, 또는 타당한 가정 도입
< 0과잉지정(정보 과잉)중복 정보 통합, 가정 제거, 모순 여부 점검

방정식으로 셀 수 있는 것은 성분별 수지만이 아니다. 분리 효율 같은 공정 사양, 조성 사이의 관계식, 문제 서술이 주는 추가 정보도 모두 방정식 한 건으로 친다. 단, 서로 독립일 때만 센다. "들어온 A의 60 %가 스트림 2로 간다"와 "A의 40 %가 스트림 3으로 간다"는 같은 정보의 앞뒷면이므로 한 건이다.

이 판정을 포함한 풀이 절차 전체가 화공양론 교재(Felder & Rousseau)가 정식화한 체계적 풀이 프로토콜이다. 순서는 흐름도 작성 → 라벨링 → 자유도 분석 → 풀이 계획 수립 → 계산이다. 이 다섯 단계는 그 자체로 하나의 알고리즘이며, 이 장의 제목에 있는 "알고리즘화"는 numpy 이전에 여기서 시작한다. 코드로 옮기는 것은 마지막 두 단계뿐이고, 앞의 세 단계는 사람의 몫으로 남는다.

AI 협업 사이클: 이번 장의 훈련 블록
  1. 문제 정의
  2. 분해: 경계·라벨링·자유도 분석 (이 장의 주 훈련 블록)
  3. 프롬프트
  4. 생성 코드 읽기
  5. 테스트
  6. 화공 검증: 질량 보존·대조값·극한값 (이 장의 보조 훈련 블록)

10.2.1 다중 유닛 시스템의 자유도

장치가 여러 개면 유닛마다 자유도 분석을 한 뒤 합산한다. 그리고 두 장치 사이를 잇는 중간 스트림의 변수 개수를 합계에서 뺀다. 중간 스트림은 나가는 장치에서 한 번, 들어가는 장치에서 한 번, 두 번 세어졌기 때문이다. 이렇게 얻은 수가 시스템 전체의 자유도다.

자유도가 0으로 판정되면 풀이 계획은 기계적으로 나온다. 자유도가 0인 유닛(또는 유닛 조합)을 찾아 그 미지수를 먼저 계산하고, 계산된 값을 기지수로 바꿔 나머지 유닛의 자유도를 다시 센다. 어딘가가 새로 0이 되면 거기를 풀고, 구하려는 값이 전부 나올 때까지 반복한다.

예제 10.2-1 분리기의 자유도 분석

문제 A 50 %(질량), B 50 %인 혼합물 100 kg/h가 분리기에 들어간다. 분리기는 들어온 A의 60 %와 B의 50 %를 상부 스트림 2로, 나머지를 하부 스트림 3으로 보낸다. 이 문제가 풀리는지 판정하고, 풀린다면 두 출구의 유량과 A 분율을 구하라.

풀이 전략 먼저 라벨링부터 한다. 미지수는 ṁ2, xA2, ṁ3, xA3의 넷이다. 다음으로 자유도를 세고, 그다음에야 계산이다.

계산 쓸 수 있는 독립 방정식은 성분 수지 2개(A, B)다. 추가 정보는 "A의 60 %가 스트림 2로" 1건과 "B의 50 %가 스트림 2로" 1건으로 합계 2건이다. 40 %/50 %가 스트림 3으로 간다는 서술은 독립 정보가 아니므로 세지 않는다. 따라서 DOF = 4 − 2 − 2 = 0, 적정지정이다.

계산은 짧다. 스트림 2의 A는 0.6 × 50 = 30 kg/h, B는 0.5 × 50 = 25 kg/h. 스트림 3은 나머지인 A 20 kg/h, B 25 kg/h.

답: ṁ2 = 55 kg/h, xA2 = 30/55 = 0.545, ṁ3 = 45 kg/h, xA3 = 20/45 = 0.444

  • 단위 체크: 유량 kg/h, 분율 무차원으로 일관
  • 대조값: 출구 합 55 + 45 = 100 kg/h = 공급으로 총괄 질량 보존 통과
  • 극한값: 분리 사양이 A 100 %/B 0 %라면 스트림 2는 순수 A(xA2 = 1)가 되어야 한다. 식에 대입하면 그대로 나온다

분석 이 예제의 교훈은 계산이 아니라 정보 세기다. 자유도 분석에서 가장 흔한 실수는 같은 정보를 두 번 세거나(과잉으로 오판) 사양을 빠뜨리는 것(과소로 오판)이다. 분리 사양을 "A의 70 %"로 바꿔 결과가 어떻게 움직이는지 다시 계산해 보라.

생각해보기 과잉지정은 항상 나쁜가? 센서가 달린 실제 공정에서는 측정값이 방정식보다 많은 상황이 오히려 기회다. 남는 식에 측정값을 넣어 보면 측정이 서로 맞는지 검사할 수 있다. 이 성질을 공정 진단에 활용할 방법을 두 가지 제안해 보라. (최종 시험 주제 예시의 "물질수지 정합성 검사"가 바로 이것이다.)

스스로 점검 (해답은 권말)

  1. 유닛 두 개가 중간 스트림 하나(성분 2개)로 연결되어 있다. 유닛별 DOF 합이 3이면 시스템 DOF는 얼마인가?
  2. "스트림 2와 3의 조성이 같다"는 조건은 자유도 분석에서 무엇으로 세는가?

10.3 재순환과 퍼지: 되돌아오는 흐름의 회계

분리가 한 번에 충분하지 않으면 덜 분리된 흐름을 공급 쪽으로 되돌려 다시 통과시킨다. 이렇게 공정 출구의 일부를 상류로 되돌리는 흐름을 재순환(recycle)이라 한다. 재순환이 붙으면 흐름도에 새 교차점이 두 개 생긴다. 스트림이 갈라지는 지점을 분기점(splitting point), 신선 공급과 재순환 흐름이 만나는 지점을 합류점(recombination point)이라 한다.

스트림 1 ──▶ [합류점] ──▶ ┌────────┐ ──▶ 스트림 2 (상부 생성물)
(신선 공급)      ▲   스트림 4 │ 분리기 │
                │            └────────┘
                │                 │ 스트림 3 (하부)
                │                 ▼
                └──────────── [분기점] ──▶ 스트림 6 (하부 생성물)
                  스트림 5 (재순환)
  
그림 10-1 재순환이 있는 분리 공정의 스트림 번호. 이 번호 체계를 10.4절의 예제까지 그대로 쓴다.

재순환 시스템의 회계 규칙은 세 가지다. 첫째, 분기점과 합류점도 자유도 분석에서는 하나의 공정으로 센다. 다른 어디에서도 세어지지 않는 미지수를 갖기 때문이다. 둘째, 분기점에서 갈라진 두 흐름은 조성이 같다. 이 조성 동일 조건이 방정식 1건이 되고, 분기비(얼마를 되돌리는가)가 주어지면 또 1건이 된다. 셋째, 합류점에서는 이런 추가 방정식이 나오지 않는다. 조성이 다른 두 흐름이 섞이므로 출구 조성은 수지를 풀어야 나온다.

둘째 규칙에는 함정이 하나 붙어 있다. 자유도 분석이 끝나기 전에는 갈라진 두 흐름의 조성을 같은 변수로 라벨링하지 마라. 같다고 적어 버리는 순간 그 정보를 이미 써 버린 것이라, 방정식 수를 셀 때 이중으로 세거나 빠뜨리기 쉽다. 미지수는 미지수대로 두고, 정보는 정보대로 세는 것이 안전하다.

풀이 계획에서는 10.1절의 경계 선택이 그대로 쓰인다. 경계를 시스템 전체에 그은 총괄수지(overall balance)를 세우면 재순환 스트림은 경계를 드나들지 않으므로 식에서 아예 사라진다. 재순환의 조성이 미지수일 때 이 요령 하나가 계산량을 크게 줄이며, 재순환 문제는 대개 총괄수지에서 출발하는 것이 좋다.

그림 10-1의 시스템(성분 2개)에 10.2절의 다중 유닛 절차를 적용해 보자. 합류점은 미지수 6 − 수지 2 = 4 DOF, 분리기는 미지수 6 − 수지 2 − 분리 사양 2 = 2 DOF, 분기점은 미지수 6 − 수지 2 − 조성 동일 1 − 분기비 1 = 2 DOF다. 신선 공급이 지정되면 합류점은 4가 아닌 2 DOF가 되고, 세 교차점의 합 2 + 2 + 2에서 중간 스트림 변수 6을 빼면 시스템 자유도는 0이다. 문제는 풀린다. 손으로 풀면 대입이 여러 겹이지만, 10.4절에서 행렬로 한 번에 처리한다.

10.3.1 퍼지: 루프의 배출구

재순환 루프에서 일부를 계 밖으로 뽑아 버리는 흐름을 퍼지(purge)라 한다. 반응 공정에서 원료에 섞여 들어온 비활성 성분은 반응으로도 분리로도 없어지지 않아 루프를 돌며 쌓이는데, 퍼지는 이 축적을 막는 배출구 역할을 한다. 수지 회계의 관점에서 퍼지는 분기점이 하나 늘어나는 것과 같다. 10.4절의 행렬에 행이 몇 줄 더해질 뿐, 새 이론은 필요 없다. 반응이 얽힌 퍼지의 정량 설계는 화공양론 수업의 몫으로 남긴다.

생각해보기 재순환 비율을 올리면 분리는 공짜로 좋아지는가? 직관으로 먼저 답을 적어 두고, 예제 10.4-1을 푼 뒤 돌아와 자신의 답을 채점해 보라.

10.4 연립선형방정식의 행렬 표현과 numpy 풀이

수지식을 코드로 넘기기 전에 미지수 선택부터 손봐야 한다. (총유량, 분율) 쌍을 미지수로 쓰면 식마다 ṁ2xA2 같은 곱이 나타난다. 미지수끼리의 곱은 1차식이 아니므로, 이대로는 이 절의 도구를 쓸 수 없다.

해법은 미지수를 바꿔 잡는 것이다. 스트림 속 한 성분의 질량 유량을 통째로 하나의 미지수로 잡은 것을 성분 유량(component flow rate)이라 한다. 스트림 2의 A 성분 유량을 A2라 쓰면 ṁ2xA2가 곱이 아니라 A2 하나가 되고, 무반응 물질수지는 전부 미지수의 덧셈과 상수배만 남는다. 이런 방정식을 선형(linear) 방정식이라 하며, 여러 개를 묶은 것이 연립선형방정식이다.

선형 연립방정식은 표준형이 있다. 계수만 뽑아 정사각 표로 모은 것을 계수 행렬(coefficient matrix) A, 미지수를 세로로 쌓은 것을 벡터 x, 우변 상수를 벡터 b라 하면 연립 전체가 한 줄이 된다.

Ax = b (10.4)

numpy가 푸는 것이 정확히 이 형태다. 작은 3원 연립으로 손을 먼저 풀어 보자.

코드 10-1 numpy로 3원 연립선형방정식 풀기
import numpy as np

# 연립방정식 (Kreyszig, Advanced Engineering Mathematics 9판, 7.3절 예제)
#   x1 -  x2 +   x3 = 0
#       10*x2 + 25*x3 = 90
# 20*x1 + 10*x2        = 80
A = np.array([[ 1, -1,  1],
              [ 0, 10, 25],
              [20, 10,  0]])
b = np.array([0, 90, 80])

x = np.linalg.solve(A, b)   # 해 벡터
print(x)
[2. 4. 2.]

해가 나왔다. 그런데 이 해가 정말 방정식을 만족하는지 코드로 검증하려다 보면 첫 함정을 만난다.

코드 10-2 해의 검증: 부동소수점 함정
print(A @ x)            # A와 x의 행렬곱 — b와 같아야 한다
print(A @ x == b)       # 원소별 비교
print(np.allclose(A @ x, b))  # 허용 오차 안에서의 비교
[2.66453526e-15 9.00000000e+01 8.00000000e+01]
[False  True  True]
True

첫 성분은 0이어야 하는데 2.7 × 10−15가 나왔고, 그래서 원소별 비교의 첫 칸이 False다. 컴퓨터의 실수 연산에는 이 정도의 오차가 항상 붙는다. 따라서 수치 해의 등호 검증에는 == 대신 허용 오차 안 비교인 np.allclose를 쓴다. 검증 루틴을 코드로 옮길 때의 표준 관례다.

예제 10.4-1 재순환 분리 공정을 numpy로 풀기

문제 그림 10-1의 공정에서 신선 공급(스트림 1)은 100 kg/h, A 50 %(질량)다. 분리기는 들어온 A의 60 %와 B의 50 %를 스트림 2로 보낸다. 스트림 3의 절반이 재순환된다(분기비 0.5). 상부 생성물(스트림 2)과 하부 생성물(스트림 6)의 유량과 A 분율을 구하라.

풀이 전략 10.3절에서 이 시스템의 자유도가 0임을 확인했으므로 바로 풀이 계획이다. 미지수는 성분 유량 여섯 개 x = [A2, B2, A3, B3, A4, B4]로 잡는다. 재순환(스트림 5)과 하부 생성물(스트림 6)은 분기비 규칙(각각 스트림 3의 절반)으로 후처리하면 되므로 미지수에서 뺀다. 식은 성분 i = A, B에 대해 세 묶음이다.

합류점: i4 − 0.5 i3 = 50 (10.5)

분리 사양: A2 = 0.6 A4, B2 = 0.5 B4 (10.6)

분리기 수지: i2 + i3 = i4 (10.7)

식 여섯 개에 미지수 여섯 개다. 행렬 조립은 AI에게 맡기고, 행별 대조와 검증은 직접 한다.

recycle 있는 분리 공정 물질수지야. 성분 A, B 두 개. 신선 공급 100 kg/h에 A가 50%. 분리기는 들어온 A의 60%를 스트림 2로, B의 50%를 스트림 2로 보내. 스트림 3의 절반이 재순환돼서 공급이랑 합쳐져. 미지수를 성분 유량 [A2, B2, A3, B3, A4, B4] 순서로 잡고 numpy로 풀게 계수 행렬이랑 b 벡터 만들어줘. 각 행이 어느 장치의 어떤 수지인지 한국어 주석 달아줘.

코드 10-3 재순환 분리 공정의 행렬 조립 (AI 생성)
import numpy as np

# 미지수 x = [A2, B2, A3, B3, A4, B4]  # 전부 kg/h (성분 유량)
A_mat = np.array([
    [0, 0, -0.5,  0,    1,    0  ],  # 합류점 A 수지: A4 - 0.5*A3 = 50
    [0, 0,  0,   -0.5,  0,    1  ],  # 합류점 B 수지: B4 - 0.5*B3 = 50
    [1, 0,  0,    0,   -0.6,  0  ],  # 분리 사양 A: A2 = 0.6*A4
    [0, 1,  0,    0,    0,   -0.5],  # 분리 사양 B: B2 = 0.5*B4
    [1, 0,  1,    0,   -1,    0  ],  # 분리기 A 수지: A2 + A3 = A4
    [0, 1,  0,    1,    0,   -1  ],  # 분리기 B 수지: B2 + B3 = B4
])
b = np.array([50, 50, 0, 0, 0, 0])   # kg/h (신선 공급의 성분 유량)

x = np.linalg.solve(A_mat, b)
print(x)

✔ 여섯 행을 식 (10.5)~(10.7)과 한 행씩 대조했다. 분리 사양 행의 −0.6, −0.5는 우변 항을 이항한 부호다. b의 단위는 전부 kg/h로 일관. 미지수 순서가 프롬프트에서 지정한 순서와 일치.

[37.5        33.33333333 25.         33.33333333 62.5        66.66666667]

성분 유량이 나왔으니 문제가 묻는 총유량과 분율로 되돌리는 후처리가 남았다. 하부 생성물은 스트림 3의 절반이다.

코드 10-4 후처리와 검증
A2, B2, A3, B3, A4, B4 = x
m2  = A2 + B2               # kg/h, 상부 생성물 총유량
xA2 = A2 / m2               # 상부 생성물의 A 질량분율
m6  = 0.5 * (A3 + B3)       # kg/h, 하부 생성물(스트림 3의 절반)
xA6 = 0.5 * A3 / m6         # 하부 생성물의 A 질량분율

print(m2, xA2)              # 70.83..., 0.529...
print(m6, xA6)              # 29.16..., 0.428...
print(m2 + m6)              # 100.0 — 총괄 질량 보존
print(np.allclose(A_mat @ x, b))  # True — 해가 방정식을 만족

답: ṁ2 = 70.8 kg/h, xA2 = 0.53, ṁ6 = 29.2 kg/h, xA6 = 0.429

  • 단위 체크: 계수는 무차원 분율·비율, x와 b는 kg/h이고 식 (10.4) 전체가 kg/h로 일관
  • 대조값: 총괄 질량 70.8 + 29.2 = 100 kg/h = 공급. 교과서 손풀이 값(ṁ4 = 129.17 kg/h, xA4 = 0.484)과 대조했다. 코드에서 A4 + B4 = 129.17, A4/(A4+B4) = 0.484로 일치
  • 극한값: 합류점 행의 −0.5를 0으로 바꾸면(재순환 차단) ṁ2 = 55 kg/h, xA2 = 0.545로 예제 10.2-1의 무재순환 해가 재현된다

분석 재순환의 효과를 읽어 보자. 하부 생성물의 A 분율은 0.444에서 0.429로 내려갔다. 분리가 좋아졌다. 그러나 그 유량은 45에서 29.2 kg/h로 줄었다. 개선에는 대가가 따르며, 물질수지는 그 대가를 정량으로 보여 주는 회계 장부다. 노트북에서 분기비를 0.7로 바꿔 재실행하고, 실습에서는 학번별 분리 사양으로 같은 절차를 반복하라.

스스로 점검 (해답은 권말)

  1. A @ x == b의 원소별 비교가 False를 낼 수 있는 이유를 한 문장으로 설명하라.
  2. 코드 10-3의 다섯째 행 [1, 0, 1, 0, -1, 0]이 표현하는 물질수지를 한국어로 말하라.
  3. 미지수 6개에 독립 방정식 5개짜리 시스템을 np.linalg.solve에 넣으면 무슨 일이 생기는가?

실습 10: 도구⑦ 물질수지 solver (75분)

이번 실습은 75분 타이머로 진행하는 mini practical이며, 종료 후 공개 지목 구술이 있다. 학번별 파라미터 생성기가 배부한 재순환 공정 문제를 받아, 자유도 분석에서 검증 기록까지 한 번에 완주한다.

준비물

  • 스타터 repo(GitHub Classroom 발급)와 학번별 문제 파일. 스트림 표와 분리 사양이 학번마다 다르다.
  • numpy 동작 확인: 터미널에서 python -c "import numpy; print(numpy.__version__)"이 버전을 출력해야 한다.
  • 재사용할 이전 도구: 5주차 도구④ 단위환산 + 물성 조회기의 환산 함수. 문제 파일의 스트림 일부는 lb/h 단위로 주어진다. 행렬에 넣기 전에 kg/h로 정규화해야 한다.

과제

  1. 실습 10.1 스타터 repo를 클론하고 본인 학번의 문제 파일을 열어 스트림 표를 확인하라. (성공 시 장치 목록과 스트림 표, 분리 사양이 보인다) 확인 즉시 첫 커밋을 남겨라.
  2. 실습 10.2 AI를 부르기 전에, 손으로 흐름도를 라벨링하고 자유도 분석을 수행해 README에 표로 기록하라. (완료 기준: 미지수 목록·방정식 목록·DOF 값이 표에 있고 DOF = 0) 이 단계는 사람 몫이다. 여기서 틀리면 뒤의 코드 전부가 틀린다.
  3. 실습 10.3 도구④의 환산 함수를 import해 문제 파일의 모든 유량을 kg/h로 정규화하는 코드를 작성하라. (완료 기준: 정규화된 스트림 표가 출력되고 단위 주석이 달려 있다) 커밋하라.
  4. 실습 10.4 AI에게 행렬 조립 함수 build_system()을 생성시키고, 행별 주석을 식과 대조한 뒤 np.linalg.solve로 풀어라. (완료 기준: 해 벡터가 출력되고, 행 대조 결과를 README에 한 줄 남겼다) 커밋하라.
  5. 실습 10.5 검증 루틴 3종(총괄 질량 보존, np.allclose 잔차 검사, 분기비 → 0 극한에서 무재순환 해 재현)을 코드로 붙여라. (완료 기준: pytest test_solver.py 3개 통과) 커밋하라.

완성 기준 통과/재도전 2단계로 판정한다.

  • pytest test_solver.py 3개 통과(질량 보존 · 무재순환 극한 · 특이 행렬 입력 시 rank 진단 메시지 출력)
  • README에 흐름도 라벨링, DOF 표, 검증 루틴 3종의 결과 기록
  • 학번별 파라미터로 계산한 최종 답(유량·분율) 표
  • 커밋 3회 이상. 단계 완료마다 남긴 커밋 이력이 증거다
막혔는가?
  • 행렬이 안 세워지면: "이 공정의 미지수를 성분 유량으로 잡으면 몇 개인지 세고, 장치별로 쓸 수 있는 독립 방정식을 표로 만들어 줘. 코드는 아직 쓰지 마."라고 물어라. 분해부터 다시 하는 것이다.
  • Singular matrix가 나면: 에러 메시지 전문을 붙여넣고 "이 행렬의 rank를 확인하는 코드와, 어느 행들이 서로 종속인지 찾는 방법을 알려 줘."라고 물어라.
  • 해가 음수 유량이면: "물질수지 해에 음수 유량이 나왔다. 계수 부호가 틀렸을 후보 행 3개를 짚고, 각 행을 원래 수지식과 대조하는 절차를 알려 줘."라고 물어라.

퇴실 전 기록 오늘 만든 것·막힌 것·틀린 것 1건을 위키에 커밋해야 퇴실한다. 이번 주는 위키 마일스톤② 집계 주간이다. 5주차 이후의 커밋 리듬, evergreen 승격, 타 과목 연결이 자동 집계된다. 몰아치기 커밋은 이력에 그대로 드러난다.

요약

  • S 10-1 일반 수지식: 축적 = 입력 − 출력 + 생성 − 소멸. 무반응·정상상태면 입력 = 출력.
  • S 10-2 DOF = 미지수 − 독립 방정식. 0 적정 / 양수 과소지정 / 음수 과잉지정. 다중 유닛은 유닛별 합산 후 중간 스트림 변수를 뺀다.
  • S 10-3 성분 유량을 미지수로 잡으면 물질수지는 Ax = b가 되고, np.linalg.solve(A, b)로 푼 뒤 np.allclose(A @ x, b)로 검증한다.
  • S 10-4 프롬프트 패턴: 미지수 목록과 순서를 지정하고, 행별로 "어느 장치의 어떤 수지인지" 주석을 요구하라. 총괄수지는 방정식이 아니라 검증에 쓴다.
표 10-2 미지수 선택 두 가지의 비교
항목(총유량, 질량분율)성분 유량
식의 형태ṁ·x 곱이 있어 비선형전부 1차식(선형)
numpy 풀이비선형 solver가 필요np.linalg.solve 한 번
물리적 직관분율이 바로 보인다후처리로 분율 환산 필요
권장 용도손계산·작은 문제코드화·다중 유닛·재순환

이 장에서 강해진 것은 AI 협업 사이클의 ② 분해다. 경계 긋기·라벨링·자유도 분석은 AI가 대신해 주지 않는 사람의 단계이고, 이 단계가 어긋나면 numpy도 특이 행렬 에러를 돌려준다. 도구 사다리는 ④ 물성 조회 → ⑤ 증기압 → ⑥ T-xy → ⑦ 물질수지 solver까지 올라왔다. 처음으로 "장치 여러 개"를 다루는 도구가 생겼다.

용어 정리

물질수지(material balance)
시스템 경계를 드나드는 질량을 일반 수지식으로 회계하는 계산.
시스템 경계(system boundary)
수지를 세울 관심 영역을 둘러싸는 가상의 닫힌 면.
정상상태(steady state)
시간이 지나도 계 내부 상태가 변하지 않아 축적이 0인 조업 상태.
자유도(degree of freedom, DOF)
미지수 개수에서 독립 방정식 개수를 뺀 값. 문제의 해결 가능성 판정 기준.
적정지정(well-defined)
자유도가 0이어서 유한한 해를 결정할 수 있는 문제.
과소지정(underspecified)
자유도가 양수인 경우. 정보가 부족해 해가 정해지지 않는 문제.
과잉지정(overspecified)
자유도가 음수인 경우. 정보가 남거나 서로 모순일 수 있는 문제.
재순환(recycle)
공정 출구의 일부를 상류로 되돌려 다시 처리하는 흐름.
분기점(splitting point)
한 스트림이 같은 조성의 여러 흐름으로 갈라지는 지점.
합류점(recombination point)
신선 공급과 재순환처럼 조성이 다른 흐름들이 섞이는 지점.
퍼지(purge)
재순환 루프에서 일부를 계 밖으로 뽑아 성분 축적을 막는 배출 흐름.
총괄수지(overall balance)
경계를 시스템 전체에 그어 세운 수지. 재순환 스트림이 식에서 사라진다.
성분 유량(component flow rate)
스트림 속 한 성분의 질량 유량을 통째로 잡은 미지수. 수지식을 선형으로 만든다.
선형(linear)
미지수의 덧셈과 상수배만으로 이루어진 방정식의 성질.
계수 행렬(coefficient matrix)
연립선형방정식의 계수를 모아 만든 행렬 A.
특이 행렬(singular matrix)
행들이 서로 종속이어서 역행렬이 없고 np.linalg.solve가 실패하는 행렬.

연습문제

Q군: 개념·읽기 (AI 없이 풀 것)

  1. Q10.1 다음 코드의 출력을 실행 없이 예측하라.
    import numpy as np
    A = np.array([[1, 1], [1, -1]])
    b = np.array([10, 2])
    print(np.linalg.solve(A, b))
  2. Q10.2 코드 10-3의 셋째 행 [1, 0, 0, 0, -0.6, 0]이 표현하는 물질수지를 한국어 두 문장으로 설명하라(EiPE). 부호 −0.6이 왜 음수인지 반드시 포함하라.
  3. Q10.3 증발기와 열교환기가 중간 스트림 하나(성분 1개)로 연결된 시스템이 있다. 증발기의 DOF가 2, 열교환기의 DOF가 1일 때 시스템 전체의 DOF를 구하고 판정하라.

P군: 제작·계산 (AI 사용 전제)

  1. P10.1 도구⑦을 확장해 분기비를 인자로 받게 하고, 분기비를 0부터 0.9까지 훑으며 하부 생성물의 A 분율과 유량을 그래프로 그려라(matplotlib). 분기비 = 0 극한이 무재순환 해와 일치함을 그래프에 표시하고 README에 검증 기록을 남겨라.
  2. P10.2 예제 10.4-1의 행렬을 일부러 풀 수 없게 만드는 방법을 두 가지 제시하고, 각각을 코드로 재현해 np.linalg.matrix_rank로 진단하는 리포트를 작성하라. 각 방법이 자유도 관점에서 무엇을 망가뜨렸는지 한 줄씩 설명하라.
  3. P10.3 (도전) 장치 3개와 재순환·퍼지가 있는 공정의 측정 데이터(모든 스트림의 유량·조성)가 주어졌다고 하자. 과잉지정 상태를 역이용해, 측정값이 물질수지를 만족하는지 잔차로 검사하고 어긋난 스트림 후보를 지목하는 정합성 검사기를 설계·구현하라. 최종 시험 주제 예시 ②와 동형의 문제다.

위키 기록 과제 ① 이번 장 핵심 1페이지(#seed): F&R 프로토콜 다섯 단계와 행렬 조립 레시피를 본인의 말로 정리하라. ② "내가 틀렸던 것" 1건: Singular matrix든 부호 실수든, 에러 스크린샷과 원인을 함께 남겨라. ③ 타 과목 연결 1건: 화공양론의 재순환 단원 문제 하나를 도구⑦로 검산한 기록을 링크하라. 이번 주 의미 커밋 1회 이상이 채점 지표다.

물질수지가 "얼마나 흐르는가"의 장부였다면, 11장은 "흐르게 하는 데 무엇이 드는가"를 계산한다. 동시수강 중인 유체역학과 직결되는 레이놀즈 수·마찰손실을 다루고, 도구⑧ 배관 압력강하 계산기를 만들어 Moody 선도 위에 계산점을 찍는다. 이 장에서 익힌 numpy 배열 감각이 그대로 재사용된다.