ㅡㅇㅂ재ㅔㄹㅈ배렂벫재

잠깐 딴짓했다가 다시 할 기분이 잘 안들었는데 겨우 시작

 

 

유량 다루기 시작 - 먼저 그래프 드로잉 함수부터

plot function은 이름 그대로 함수와 시간 구간 주면 그대로 드로잉 해주는 함수

여기서 사용한 함수는

유체량과 유체흐름률 두개가 있음

유체량은 (t-4)^3 / 64 + 3.3

유체흐름률은 유체량 함수의 도함수 3 * (t - 4)^2 / 64

0 ~ 10초 사이 유체량 함수를 드로잉한 결과는 다음과 같음

import matplotlib.pyplot as plt
import numpy as np

def plot_function(f, tmin, tmax, tlabel=None, xlabel=None, axes=False, **kwargs):
    ts = np.linspace(tmin, tmax, 1000)
    if tlabel:
        plt.xlabel(tlabel, fontsize=18)
    if xlabel:
        plt.ylabel(xlabel, fontsize=18)
    plt.plot(ts, [f(t) for t in ts], **kwargs)
    if axes:
        total_t = tmax-tmin
        plt.plot([tmin-total_t,tmax+total_t/10], [0, 0], c='k', linewidth=1)
        plt.xlim(tmin-total_t/10,tmax+total_t/10)
        xmin, xmax = plt.ylim()
        plt.plot([0, 0], [xmin, xmax], c='k', linewidth=1)
        plt.ylim(xmin, xmax)
def plot_volume(f,tmin,tmax,axes=False,**kwargs):
    plot_function(f, tmin, tmax, tlabel='time (hr)', xlabel='volume (bbl)', axes=axes, **kwargs)
def plot_flow_rate(f, tmin, tmax, axes=False, **kwargs):
    plot_function(f, tmin, tmax, tlabel='time (hr)', xlabel='flow rate(bbl/hr)', axes=axes, **kwargs)

def volume(t):
    return (t-4)**3 / 64 + 3.3
def flow_rate(t):
    return 3 * (t - 4) ** 2 / 64

plot_volume(volume, 0, 10)

 

 

특정 시간에서 유체의 량과 유체 량의 평균 변화를 구해보자

유체량에 대한 함수 volume에다가 시간 4, 9일때 량을 구하면 3.3, 5.2 가 나옴

평균 유체 흐름량 함수를 구현해보면 0.39가 나온다.

 

 

 

def average_flow_rate(v, t1, t2):
    return (v(t2) - v(t1))/(t2 - t1)

print(volume(4))
print(volume(9))
print(average_flow_rate(volume, 4, 9))

 

 

음의 변화율 다루기

아까 구현한 볼륨 함수는 점점 증가하는 형태였으나 이번엔

시간에 따라 내려가도록 구현

0 ~ 4 초사이 평균 흐름율은 -0.8

플로팅 결과는 저렇다

 

def decreasing_volume(t):
    if t < 5:
        return 10 - (t ** 2) / 5
    else:
        return 0.2 * (10 - t) ** 2

print(average_flow_rate(decreasing_volume, 0, 4))
plot_volume(decreasing_volume, 0, 10)

 

 

시컨트 라인 그리기

12시에 오도메트리가 77600 마일인데, 4시 30분에는 77900 마일이 됬다. 평균 속도 변화율은 어떨까?

으악 삼각함수도 잘 모르는데 시컨트라니

잠깐 찾아보니 삼각함수의 역수란다 이게 왜쓰는지 모르겠는데

코사인은 밑변/빗변이니 시컨트는 빗변/밑변 

흐름은 잘 모르겠지만 대충 시컨트 라인은 x1, x2사이 주어진 함수에 대한 직선 방정식을 구하는 함순거같음

 

def secant_line(f, x1, x2):
    def line(x):
        return f(x1) + (x - x1) * (f(x2) - f(x1)) / (x2 - x1)
    return line

def plot_secant(f, x1, x2, color='k'):
    line = secant_line(f, x1, x2)
    plot_function(line,x1,x2,c=color)
    plt.scatter([x1, x2], [f(x1), f(x2)], c=color)

plot_volume(volume, 0, 10)
plot_secant(volume, 4, 8)

 

 

 

 

 

 

구간별 평균 변화율

이번에는 1초 간격 평균 변화율을 구해보자

코드는 여전히 단순

def interval_flow_rate(v, t1, t2, dt):
    return [(t, average_flow_rate(v, t, t+dt)) for t in np.arange(t1, t2, dt)]

interval_flow_rate(volume, 0, 10, 1)

 

 

 

 

구간별 평균 유체 변화율 산점도 그리기

방금 작성한 구간별 평균 변화율로 산점도 드로잉하는 함수

 

def plot_interval_flow_rates(volume, t1, t2, dt):
    series = interval_flow_rate(volume, t1, t2, dt)
    times = [t for (t, _) in series]
    rates = [q for (_, q) in series]
    plt.scatter(times, rates)

plot_interval_flow_rates(volume, 0, 10, 1)

 

 

 

유체 흐름률과 구간별 평균 흐름률 플로팅

유체 흐름률은 유체량 함수의 도함수로 부터 구함

구간별 흐름률은 유체량에서 구간별 평균 변화율로 구함

모양은 비슷하나 후자가 살짝 뒤처짐

 

plot_flow_rate(flow_rate, 0, 10)
plot_interval_flow_rates(volume, 0, 10, 1)

 

 

하지만 구간을 1 -> 1/3으로 줄이면 원 함수에 더 가까워짐

 

plot_flow_rate(flow_rate, 0, 10)
plot_interval_flow_rates(volume, 0, 10, 1/3)

 

 

감소 하는 함수의 구간별 평균 흐름율 플로팅하면 이럼

plot_interval_flow_rates(decreasing_volume, 0, 10, 0.5)

 

직선의 경우 구간별 평균 흐름률

def linear_volume_function(t):
    return 5 * t + 3

plot_interval_flow_rates(linear_volume_function, 0, 10, 0.25)

 

 

 

유체량의 평균 변화율은 1에 가까워질수록 어떻게 될까?

아까 구현한 평균 유체 변화율로 1에 가까워지게 해보면 특정 값에 점점 가까워진다.

print(average_flow_rate(volume, 0.5, 1.5))
print(average_flow_rate(volume, 0.9, 1.1))
print(average_flow_rate(volume, 0.99, 1.01))
print(average_flow_rate(volume, 0.999, 1.001))
print(average_flow_rate(volume, 0.9999, 1.0001))

 

 

 

 

 

 

 

시컨트 라인과 탄젠트

계속 시컨트 시컨트하길래 잠깐 딴데 찾아보니 이렇게 설명한다

시컨트라인은 곡선 두 점 지나는 선

접선은 곡선의 한점을 지나는 선

https://ko.strephonsays.com/chord-and-vs-secant-and-vs-tangent-1750

 

 

 

순간 변화율 함수 구현하기

아깐 평균 변화율 구간을 1을 중심으로 좁힘으로서 특정 수에 수렴하는 것을 봤는데

이번에는 아예 순간변화율을 구하는 함수 구현됨

먼저 톨레랑스 용인도? 얼마까지 에러 봐줄래 하는 변수를 잡아줌

디폴트로 디지트 6했으니 10 ^ -6까지 오차는 용인한다.

h = 1로 놓고 위아래 1차이와 평균 변화율 구함

2 * digit 그러니까 12회 까지 반복수행하는대 오차가 10 ^-6 보다 크지않으면 반올림하고 반환

루프마다 h는 1/10배로 줄어듬

def instantaneous_flow_rate(v, t, digits=6):
    tolerance = 10 ** (-digits)
    h = 1
    approx = average_flow_rate(v, t-h, t+h)
    for i in range(0, 2 * digits):
        h = h / 10
        next_approx = average_flow_rate(v, t-h, t+h)
        if abs(next_approx - approx) < tolerance:
            return round(next_approx, digits)
        else:
            approx = next_approx
    raise Exception("derivative did not converge")

instantaneous_flow_rate(volume, 1)

 

 

 

 

구현한 순간 변화율 함수가 옳은지 플로팅 해보기

먼저 기존에 볼륨 도함수인 변화율 함수 플로팅

이번엔 순간 변화율 구하는 함수에 볼륨 함수를 집어넣은 뒤 플로팅

둘다 동일함

 

 

def get_flow_rate_function(v):
    def flow_rate_function(t):
        return instantaneous_flow_rate(volume, t)
    return flow_rate_function

plot_function(flow_rate, 0, 10)

plot_function(get_flow_rate_function(volume),0,10)

 

 

짧은 시간 동안 유체량 변화 정도 

1초 동안 유체량 변화 정도 계산시  0.1875나 실제로는 1.09가 나온다.

대신 구간을 1초 대신 0.01로 줄여보면 0.001875 실제로는 0.00186으로

구간을 좁히면 실제 값에 근사하게 나옴

 

def small_volume_change(q, t, dt):
    return q(t) * dt

print(small_volume_change(flow_rate, 2, 1))
print(volume(3) - volume(2))
print("#######")
print(small_volume_change(flow_rate, 2, 0.01))
print(volume(2.01) - volume(2))

 

 

 

볼륨 변화량 구하기

계속 유체라고 했는데 변수 명 그대로 볼륨이라고 해야겠다.

0 ~ 10 초간 0.1초 간격으로 볼륨 변화량을 합치면 4.3289가 나온다.

하지만 실제 볼륨10, 볼륨0으로 구해보면 4.375가 뜬다.

이번엔 구간을 0.0001로 줄이면 4.3749로 실제 값에 가까워짐

def volume_change(q, t1, t2, dt):
    return (sum(small_volume_change(q, t, dt) for t in np.arange(t1, t2, dt)))

print(volume_change(flow_rate, 0, 10, 0.1))
print(volume(10) - volume(0))
print(volume_change(flow_rate, 0, 10, 0.0001))

 

 

볼륨 플로팅하기

이번엔 실제 볼륨 함수와 근사화한 볼륨 함수를 플로팅함

볼륨 함수 근사화는 아까 구현한 볼륨 변화 사용

근사시 구간을 0.5로 해서 좀 안맞아보이긴 한데 거의 비슷하게 나오긴 함

 

근사 구간을 0.1로하면 아까 보다 원함수에 가까워짐

 

구간을 0.01로 더 줄이면 더가까워짐

def approximate_volume(q, v0, dt, T):
    return v0 + volume_change(q, 0, T, dt)

def approximate_volume_function(q, v0, dt):
    def volume_function(T):
        return approximate_volume(q, v0, dt, T)
    return volume_function

plot_volume(approximate_volume_function(flow_rate, 2.3, 0.5), 0, 10)
plot_volume(volume, 0, 10)



plot_volume(approximate_volume_function(flow_rate, 2.3, 0.1), 0, 10)
plot_volume(volume, 0, 10)




plot_volume(approximate_volume_function(flow_rate, 2.3, 0.01), 0, 10)
plot_volume(volume, 0, 10)

 

 

 

 

 

+ Recent posts