16_混合

16 混合

在之前的章节,我们学习了如何模拟咖啡冷却的过程 ,只要我们知道咖啡初始温度,空气温度,和冷却速率(r)我们就能预测咖啡在规定时间冷却了多少,但是,一般而言,我们是不知道冷却速率(r)的,我们可以通过数据进行估测它,只要给出初始温度和最终温度,以及时间,我们就可以通过测试和纠错来算出r。在这一章,我们就通过 二分法来测出 r

16.1 计算根

ModSim 里提供了一个方法叫 root_bisect 来求非线性方程的根,比如你想算:

f(x) = (x − 1)(x − 2)(x − 3)

那么就可以算出x=1,x=2,x=3 这些事方程的根(默认计算f(x) = 0 的值)

下面我就用一个例子来解释一下如何用这个函数:

#首先自己定义一函数,待会算这个函数的根
def func(x):
    return (x-1) * (x-2) * (x-3)
#下面就是使用求根函数,两个参数,一个参数是我们的要求根的方程,
#第二是限制根的范围,指定我们要算哪个范围的根
#此函数是用二分法来算,用1.5 和2.5 的中间值 x2 作为func的参数
#得到一个数,如果大于0就把x2-1.5作为新的范围进行迭代(反之则x2-2.5)直到算出值
res = root_bisect(func, [1.5, 2.5])
print(res.root)

下面我们如何用 root_bisect() 函数类估测我们的 r 呢?

首先我们得定义一个函数,这个函数的输入是我们要算的r,我们再测出一个粗略的r所在的范围,然后让root_bisect() 来迭代计算

#这个函数通过给定的r 计算预测温度,和实际温度做比较(做差)作为输出 
#然后让root_bisect()计算r
def error_func1(r):
    system = make_system(T_init=90, r=r, volume=300, t_end=30)
    results = run_simulation(system, update_func)
    T_final = get_last_value(results.T)
    return T_final - 70

定义好我们的方程(函数) 就是求方程的跟啦(r) 下面就是用root_bisect() 来求根

#首先我们得粗略算出r所在区间,作者 把0.01带入 得到值是2.3℃(正)所以需要把 r调大
error_func1(r=0.01)

#把0.02带入得 -10.9℃ (负)  所以区间就定好了,r真实值在0.01到0.02之间 
#剩下的就可以交给root_bisect()啦
error_func1(r=0.02)

#通过函数求得我们的r_coffe 的值为0.012
res = root_bisect(error_func1, [0.01, 0.02])
r_coffee = res.root

通过同样的方法计算 r_milk 的值

16_1.png

图16.1: 咖啡与牛奶的随时间变化的温度

16.2 混合液体(牛奶和咖啡)

下面我们混合两个液体(牛奶和咖啡),混合液体的温度取决于混合的材料,并且我们假设没有化学反应或者其他因素来影响温度,我们的热量是守恒的。

如果第一个液体的温度是 T1 第二个液体的温度是 T2 ,混合后的温度是 T ,那么与第一个液体进行的热量交换是 C1(T - T1) ,同理,与第二个液体进行的热量交换是 C2(T - T2) , C1 和 C2 是两个液体的比热容(热质量),根据热量守恒,两个交换的热量相加应该为0,如下:

C_1(T − T_1) + C_2(T − T_2) = 0

下面我们把 T 提取出来:

T =( C_1T_1 + C_2T_2 )/ ( C_1 + C_2 )

如果我们知道液体的密度和体积以及比热容cp,那么我们就可以算出来热质量C:

C = ρV c

如果液体有相同的比热容和密度,那么我们就可以得到以下式子(v1 v2 是两个液体的体积):

T = (V_1T_1 + V_2T_2 )/(V_1 + V_2)

下面就是对混合系统的模拟了:

def mix(system1, system2):
    #判断两个系统的结束时间,确认是否相同,如果不相同就返回错误并且终止运行其他代码
    assert system1.t_end == system2.t_end
    #分别赋值两个系统的体积
    V1, V2 = system1.volume, system2.volume
    #分别赋值两个系统的温度
    T1, T2 = system1.temp, system2.temp
    #混合后的体积和温度
    V_mix = V1 + V2
    T_mix = (V1 * T1 + V2 * T2) / V_mix
    #返回一个新的系统,温度为混合后的温度,体积为混合后的体积
    return make_system( T_init=T_mix,
                        r=system1.r,
                        volume=V_mix,
                        t_end=30)

主义我们的mix()函数要求我们的两个系统的温度有 temp变量,并且是已经更新过的温度,我用了这个函数:

def run_and_set(system):
    #更新温度
    results = run_simulation(system, update_func)
    system.temp = get_last_value(results.T)
    #返回的是对象
    return results

现在我们有了所有我们需要的东西!

16.3 先混合还是后混合?

首先我先创建两个对象来代表咖啡和奶油

#注意两者的冷却时间都是一样的,是30(分钟)
#咖啡
coffee = make_system(T_init=90, r=r_coffee,volume=300, t_end=30)
#奶油
milk = make_system(T_init=5, r=r_milk, volume=50, t_end=30)

先混合:

mix_first = mix(coffee, milk)
mix_results = run_and_set(mix_first)
#先混合 得到混合后冷却得到的温度是61.4℃

后混合:

coffee_results = run_and_set(coffee)
milk_results = run_and_set(milk)
mix_last = mix(coffee, milk)
#先各自放置30分钟再混合得到的温度是 63.1℃

显然 后混合效果好一些,咖啡温度也高1.7℃!

16.4 优化

过30分钟再添加牛奶比立即添加牛奶要好一些,但是可能有更好的选择,下面我用新的函数来调节添加牛奶的时间,让T_add 作为参数

def run_and_mix(t_add, t_total):
    #咖啡  
    coffee = make_system(T_init=90, r=r_coffee,volume=300, t_end=t_add)
    coffee_results = run_and_set(coffee)
    #牛奶
    milk = make_system(T_init=5, r=r_milk,volume=50, t_end=t_add)
    milk_results = run_and_set(milk)
    #混合
    mixture = mix(coffee, milk)
    #可以看到 混合液体冷却的温度是: 总温度-我们尝试加牛奶的温度
    mixture.t_end = t_total - t_add
    results = run_and_set(mixture)
    return mixture.temp

t_add =0 时 表示立即添加牛奶(也就是混合液最后得到温度:61.4℃),t_end = 30表示最后添加牛奶(也就是混合液体最终温度为:63.1℃),下面我们尝试不同的添加牛奶时间,来看看什么时间添加会好一些:

sweep = SweepSeries()
    #表示0到30之间选择了11次(numpy.linespace()函数中表示11个)
    for t_add in linspace(0, 30, 11):
        sweep[t_add] = run_and_mix(t_add, 30)

得到的结果作图得到如下图:

16_2.png

图16.2:以牛奶加入的时间为变量最终的温度曲线

图片横纵表是我们添加牛奶的时机,可见在最后添加牛奶是最好的!

16.5 分析

用牛顿冷却定律来求解是不太合理的,我们可以用微分方程来求解:

\frac {dT}{dt} = -r(T-T_{env})

一般求解如下:

T(t) = C_1 exp(−rt) + T_{env}

特解:T(0) = Tinit

T_{env} + (−T_{env} + T_{init}) exp(−rt)

现在我们可以用观测的数据来计算估测我们的参数 r, 如果T(tend) = Tend 我们可以把tend 和Tend带入到特解了 来求出我们的 r , 公式如下:
r = \frac{1}{t_{end}}log(\frac{T_{init}-T_{env}}{T_{end}-T_{env}})

我们让 tend = 30 , Tend = 70 ,Tinit = 90 ,Tenv = 22 我们就可以计算出估测 r 为 0.0116

接下来我们可以用下面的方程来计算出 我们的时间序列:

def run_analysis(system):
    T_env, r = system.T_env, system.r
    T_init = system.init.T
    #numpy.linspace(num = 50)缺省为50
    ts = linspace(0, system.t_end)
    T_array = T_env + (T_init - T_env) * exp(-r * ts)
    return TimeFrame(T_array, index=ts, columns=['T'])

这个函数类似于run_simulation 它把System当做参数,然后返回TimeFrame作为结果

因为linerange返回的是Numpy 矩阵, T_array也是Numpy矩阵,为了让run_simulation()里的数据格式一致,我们把它放到 TimeFrame , 下面是代码:

#之前计算得到r
r_coffee2 = 0.0116
coffee2 = make_system(T_init=90, r=r_coffee2,volume=300, t_end=30)
results = run_analysis(coffee2)

最终温度是70℃,我建议您先阅读chap16.ipynb 然后自己下载数据,进行实践一下,这有助于您的学习和更深刻的了解!

本书的中文翻译由南开大学医学院智能医学工程专业2018级、2019级的师生完成,方便后续学生学习《Python仿真建模》课程。翻译人员(排名不分前后):薛淏源、金钰、张雯、张莹睿、赵子雨、李翀、慕振墺、许靖云、李文硕、尹瀛寰、沈纪辰、迪力木拉、樊旭波、商嘉文、赵旭、连煦、杨永新、樊一诺、刘志鑫、彭子豪、马碧婷、吴晓玲、常智星、陈俊帆、高胜寒、韩志恒、刘天翔、张艺潇、刘畅。

整理校订由刘畅完成,如果您发现有翻译不当或者错误,请邮件联系changliu@nankai.edu.cn

本书中文版不用于商业用途,供大家自由使用。

未经允许,请勿转载。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • 我的图书馆 留言交流 2000个最常用的英语单词 2016-05-15酴羰骀璺 2000个最常用的英语单词 (英语...
    Mr_Wang92阅读 646评论 0 0
  • 一、什么是泵? 泵是输送液体或使液体增压的机械。它将原动机的机械能或其他外部能量传送给液体,使液体能量增加。 泵主...
    简史青年阅读 541评论 0 1
  • 首先介绍下自己的背景: 我11年左右入市到现在,也差不多有4年时间,看过一些关于股票投资的书籍,对于巴菲特等股神的...
    瞎投资阅读 5,722评论 3 8
  • ![Flask](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAW...
    极客学院Wiki阅读 7,241评论 0 3
  • 不知不觉易趣客已经在路上走了快一年了,感觉也该让更多朋友认识知道易趣客,所以就谢了这篇简介,已做创业记事。 易趣客...
    Physher阅读 3,414评论 1 2