十二月九日,周六。期末的阴影如同窗外铅灰色的云层,沉甸甸地压下来。距离学期结束还有不到一个月,各门课程的进度明显加快,作业和项目接踵而至,空气中弥漫着一股“冲刺”前的紧张气息。
清华园的冬天肃穆而安静,法桐的枯枝伸向天空,像一张巨大的、脉络分明的网。寒风刮过,卷起地上零星的落叶和残雪。
许源和徐嘉庆的生活节奏也调整到了“期末模式”。早晨的碰面时间更早了,图书馆待的时间更长了,连食堂吃饭时讨论的话题,也几乎全部围绕着即将到来的期末考试和那些尚未完成的大作业。
徐嘉庆似乎完全从之前的小恙中恢复了过来,甚至比以往更加专注和投入,只是眼下偶尔会浮现淡淡的青色,显示出睡眠时间的压缩。许源看在眼里,除了每天早晨雷打不动地带一杯热豆浆或热牛奶给他,监督他按时吃早饭,也只能在深夜他发来“睡了”的信息时,回一个“早点睡”的叮嘱。
上午,他们在图书馆攻克《计算物理》的期末大作业——一个综合性的数值模拟项目,要求用蒙特卡洛方法模拟“二维伊辛模型”的相变,并计算比热、磁化率等物理量随温度的变化,与理论预测(Onsager严格解)进行比较。
这个项目难度很大,不仅涉及复杂的算法(Metropolis抽样、有限尺寸标度分析),还对编程技巧、数据处理和结果分析提出了很高要求。他们决定合作完成,共同设计算法框架,分工编写和调试核心模块。
徐嘉庆负责设计核心的抽样算法和自旋翻转规则,力求在保证马尔可夫链收敛的前提下提高效率。许源则负责搭建程序整体框架,实现并行计算(以模拟不同尺寸的晶格),并设计数据的可视化输出。
机房里暖气很足,但两人额头都沁出了细密的汗珠。屏幕上,代码行飞速滚动,调试信息不断跳出。他们时而各自沉思,时而低声快速交流。
“这里,用checkerboard分解做并行,边界交换的通信开销会不会太大?” 徐嘉庆指着许源写的一段并行代码。
“试试用非阻塞通信重叠计算和通信?” 许源思考着,“或者,先不考虑大规模并行,把单核优化做到极致,用多线程跑不同尺寸的晶格?”
“可以。但不同尺寸晶格的有限尺寸标度分析,需要仔细设计温度点的选取。” 徐嘉庆在草稿纸上画着不同尺寸晶格的相变区域示意图。
讨论、修改、调试、再讨论……时间在高度集中的思考中飞快流逝。当中午的饥饿感终于将他们的注意力从屏幕上拉回时,已经过了饭点。两人匆匆收拾东西,跑去食堂。
吃完饭,没有休息,又立刻回到机房。下午,程序初步跑通,但结果与理论预期偏差较大,且在相变点附近数值不稳定。
“可能是弛豫时间不够,或者抽样次数不足。” 许源看着屏幕上抖动的磁化曲线。
“也可能是临界慢化,在临界点附近需要更长的马尔可夫链才能达到平衡。” 徐嘉庆调出程序输出的能量自关联函数,眉头紧锁,“得增加热化步数和测量间隔,但计算时间会大大增加。”
“先优化单次模拟的速度,比如用查找表预计算能量变化,用位运算加速自旋邻居求和。” 许源提议。
又是新一轮的代码优化和参数调整。当窗外的天色完全暗下来,机房的灯一盏盏亮起,他们的程序终于跑出了一组相对合理、能清晰看到相变迹象,且与Onsager解定性符合的数据。
虽然离完美还有距离,但基本的物理图像已经呈现出来。两人都长长舒了口气,感到一种混合着巨大疲惫和成就感的复杂情绪。
“剩下的就是完善分析,写报告了。” 许源活动着僵硬的脖颈,保存好所有代码和数据。
“嗯。报告结构可以分模拟方法、结果展示、与理论对比、误差分析和讨论几个部分。” 徐嘉庆一边说,一边已经在笔记本上列起了提纲,条理清晰。
离开机房时,校园里已是一片寂静的夜色,寒风刺骨。他们踩着冻硬的地面,慢慢走回宿舍区,身体疲惫不堪,但精神却因为解决了难题而有些兴奋。
路过小卖部,许源进去买了两罐热咖啡,递了一罐给徐嘉庆。徐嘉庆接过,指尖碰到罐身温热的铝皮,微微一顿,低声说:“谢谢。”