1. 引言
大学物理课程是高校理工类专业的必修课程,内容涉及经典物理和近代物理两部分,经典物理主要包括力学、热学、电磁学和光学等知识篇章,近代物理部分主要包括狭义相对论和量子力学等内容。而在经典物理教学中,力学知识往往是课程最先引入和研究的部分。课程包含运动学、牛顿定律、动量定理、动量守恒、功能原理、刚体定轴转动、简谐振动、机械波和流体力学等知识。此部分内容承接中学物理的知识基础和思想方法,通过引入数学的微积分和矢量思想,运用高等数学知识阐述和扩展物理概念,可以帮助学生深入理解自然科学规律、求解问题,也为后续的物理知识学习和相关专业课的学习打牢数理基础、锻炼科学思维。
由此可见,大学物理力学教学具有非常重要的现实意义,是整个课程的基础。然而由于传统教学方式的限制,实际教学效果还存在一些不足之处。在目前的教学过程中,教师往往采用讲授法阐述物理概念、公式和定理,此种方法能够将课程重难点及时传授给学生,把握课程进度。但因为教学方法较为单一,教师讲授比例较大,师生互动和学生自己动手实操环节较少,学生的学习兴趣和学习热情未能充分激发,学习注意力容易发生转移和涣散,导致教学效果降低。与此同时,由于课程安排所限以及传统应试考试的需求,教师在课堂上讲授的内容很难兼具深度与广度,课堂和课后实践内容也有所限制,学生对于某些知识点的理解浮于表面、存在偏差,对于某些较难问题的求解思路一知半解,导致无法建立牢固的知识体系,无法将所学知识灵活运用于实际问题。此外,传统大班教学面向数量较多的学生,教师在教学时需要参考学生的平均水平来制定教学大纲、设计教学内容和教学方法,难以顾及全部学生的个体情况,也很难对一些拔尖学生开展个性化教学,具有一定的局限性。
鉴于当前的力学教学情况,针对教学的难点和学习者的学习困境,尝试重构教学过程,将知识获取和思维能力训练有机结合,促进知识的意义建构非常重要[1]。建构主义学习理论认为学习是学习者在与外部环境交互作用的过程中主动地构建内部心理表征的过程,知识是学习者在一定的情境下,利用必要的学习材料和学习资源,通过意义建构的方式获得的。建构主义学习理论强调以学习者为中心,更加强调学习的主观性、社会性和情境性。基于建构理论的指导,在教学过程中将Python程序作为教学的辅助资源,引导学生将被动记忆和实践练习相结合,自主探寻问题的求解思路和求解方案,构建个人的知识思维体系,从而激发主观能动性,提升学习兴趣,具有一定的积极意义。
2. Python软件的功能特性
Python软件诞生于1990年代初期,由荷兰国家数学与计算机科学研究中心的程序员吉多范罗苏姆设计,是一种结合了解释性、编译性、互动性和面向对象的脚本语言。Python语言具有很多优点,其关键字较少、结构较为简单、代码的定义更清晰,非常易于学习和阅读,入门成本较低,维护成本也较低,互动性很强。同时,Python语言具有丰富的可跨平台库,可以被移植到其他平台,可嵌入其他语言程序,这些特定使得Python语言的应用更加广泛。
鉴于其强大的功能特性,目前已有一些将Python程序运用于大学物理课程教学的实例。例如运用Python强大的数据处理功能,对实验数据进行优化拟合,从而提高实验结果精度[2]。以及运用Python的高效计算功能,采用有限差分法快速求解偏微分方程并绘制方程的数值图形[3]。还有使用Python的3D模块VPython对简谐振动合成进行可视化模拟,从而直观展示不同频率不同相位的简谐振动合成情况,直观展示各类李萨如图形[4]。此外,也有将Python运用于网页版物理实验建设工作的例子,利用Python多领域大规模的函数包和基于网页开发的免费、公开、快捷的框架设计,在网页上进行物理实验模拟和建设[5]。
本文基于Python强大的科学计算和可视化功能,探索该软件在大学物理力学教学中的应用。
3. Python科学计算在力学教学中的应用
在大学物理力学的教学过程中,由于部分物理概念和物理公式较为复杂抽象,有一定理解上的困难,同时涉及的数学计算比中学更具难度,导致最终教学效果有所欠缺。例如微分问题、积分问题、及其相关数学概念和应用,其对物理学定量的分析和研究也具有重要意义。例如运动的瞬时速度、瞬时加速度、瞬时功率等概念,均是利用微分的概念进行定义;在求解变力做功问题时,需要先求出力和位移的表达式,再对其点乘的函数进行积分计算;在运用牛顿第二定律的微分形式解决受力问题时,需要运用不同方法求解微分方程。但由于数学逻辑思维的抽象性和公式灵活运用的复杂性,部分学生难以顺利解题。使用Python程序辅助计算,则可以大大提高解题效率,锻炼科学思维。以下以具体问题为例,探讨程序的使用方法。
例1:已知一质点运动方程为
,试求任意
时刻,质点运动的速度和加速度,以及切向加速度和法向加速度。
分析:此问题是经典的求导问题,第一问只需分别对运动方程求一阶和二阶导数即可,第二问需将第一问中的合加速度分解为切向和法向两个分量。由题意写出相应Python程序如下:
from sympy import symbols
from sympy import diff
t,i,j = symbols('t i j')
r = t**3*i + (3*t**2+3)*j
v=diff(r,t)
a=diff(r,t,2)
print(v)
print(a)
第一问可求出
,
,将
由直角坐标系分解到自然坐标系:
vv=(2*t**2)**2+(6*t)**2
at=diff(vv,t)
an=((6*t)**t+6**2-at**2)**(1/2)
print(at)
print(an)
由此可得第二问结果。本题涉及到符号表达式运算,需要引入SymPy库,该库功能强大,包含计算、几何、微积分、统计等各类支持内容,广泛运用于数学、物理、工程等领域。程序中的symbols函数用于创建值不变的全局唯一性符号,diff函数用于求符号表达式的导数,可以自定义求导的自变量和求导阶数。
上题第一问如改成已知速度的表达式
,求解质点的运动方程
,则可以使用求导的逆运算积分来求解:
from sympy import symbols ,integrate
t,i,j = symbols('t i j')
f=3*t**2*i+6*t*j
F=integrate(f,t)
print(F)
可得
,还需初始条件确定常数
和
,代入
时,
,最终可得
。
在运动学问题中,根据位矢、位移、速度、加速度等物理量的定义关系,常见习题中涉及大量的矢量函数求导和积分的问题,此部分内容虽然涉及的数学公式并不复杂,但因为部分学生尚未建立“矢量思维”和“微积分思维”,习惯用中学的简单标量方法计算,在求解过程中容易有所疏漏。借助Python程序的运算功能,可以帮助学生进一步熟悉知识点,更新思维方式,起到较好的入门启蒙作用。
除了积分和求导之外,求解微分方程也是常见的数学物理问题。在大学物理问题中较为常见的有可分离变量的微分方程、一阶齐次微分方程、二阶常系数微分方程、波动方程等等。以下以具体问题为例,展示Python程序的使用方法。
例2:跳水运动员从
高度的高台跳水,水的阻力与运动速度的关系式为
,
为阻力系数,运动员自身的质量为
,试求运动员的入水时间
与水中下落速度
的关系。
分析:将运动员看作质点,从高台跳下到刚刚落到水面的过程中,只受重力作用自由落体。在运动员入水之后,受到自身的重力、浮力、以及水的阻力共同作用,因为人的密度与水接近,重力和浮力的数值所差不多,为简化计算,近似看作两力作用抵消。设运动员刚落入水面时为
时刻,此时运动员入水速度为
。根据牛顿第二定律可得方程:
运用Python程序求解此方程:
from sympy import symbols,Function,dsolve,pprint
m,c,v0=symbols('m c v0')
v=Function('v')
t=symbols('t')
eq=m*v(t).diff(t,1)+c*v(t)*v(t)
pprint(dsolve(eq,v(t)))
pprint(dsolve(eq,v(t),ics={v(0):v0}))
本题主要使用dsolve函数求解微分方程,此函数功能强大,可以求解各类常微分方程。根据数学关系,若用代数方法求解此方程,需先用分离变量法将速度
和时间
分离到等式两边,再代入初始条件进行积分:
可见,运动员入水之后因为水的阻力作用运动速度将会逐渐减慢。如直接对微分方程进行求解,需要一定的计算时间,在细节上可能出错,而运用dsolve函数可批量求解大量较为复杂的方程,只需输入相应的方程等式即可,同时支持数字和符号的运算,可提升运算效率。
4. Python可视化在力学教学中的应用
在物理学习过程中,图表和动画呈现等可视化方式可以帮助学生更加直观透彻地理解知识点,有助于加深记忆和提高学习兴趣。而Python软件拥有非常强大的可视化功能,包含多种功能各异的库,这一特性为物理教学过程提供了强有力的帮助与支持。
在振动与波动这一章节的学习过程中,涉及到简谐振动的合成,包括同方向同频率和不同频率简谐振动的合成、垂直方向同频率和不同频率简谐振动的合成等知识点。在推导过程中,代数解析方法往往涉及较为复杂的三角函数公式计算,步骤较为枯燥抽象,而利用Python交互可视化的特性可以实现振动合成的直观演示,从而帮助学生加深对知识的记忆和理解。以下以一个具体问题为例,展示Python程序的使用方法。
例3:求两个同方向不同频率简谐振动的合成。
尝试运用Python程序求解此问题并展示可交互模块,代码如下:
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
plt.rcParams['font.family'] = ['SimSun']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['xtick.labelsize'] = 9
plt.rcParams['ytick.labelsize'] = 9
plt.rcParams['font.size'] = 9
class HarmonicVibration:
def __init__(self):
self.freq1 = 1.0
self.freq2 = 2.0
self.amp1 = 1.0
self.amp2 = 1.0
self.phase1 = 0
self.phase2 = 0
self.t = np.linspace(0, 10, 1000)
self.fig, self.ax = plt.subplots(figsize=(10, 6))
self.fig.subplots_adjust(bottom=0.25)
self.line1, = self.ax.plot([], [], label='振动1')
self.line2, = self.ax.plot([], [], label='振动2')
self.line3, = self.ax.plot([], [], label='合振动', linewidth=2)
self.ax.set_xlim(0, 10)
self.ax.set_ylim(-3, 3)
self.ax.set_xlabel('时间')
self.ax.set_ylabel('位移')
self.ax.legend()
self.ax.grid(True)
from matplotlib.widgets import Slider
axfreq1 = plt.axes([0.25, 0.1, 0.65, 0.03])
axfreq2 = plt.axes([0.25, 0.05, 0.65, 0.03])
self.freq1_slider = Slider(ax=axfreq1, label='振动1频率',valmin=0.1, valmax=5.0, valinit=self.freq1)
self.freq2_slider = Slider(ax=axfreq2, label='振动2频率',valmin=0.1, valmax=5.0, valinit=self.freq2)
self.freq1_slider.on_changed(self.update)
self.freq2_slider.on_changed(self.update)
self.ani = FuncAnimation(self.fig, self.animate, frames=200,interval=50, blit=True)
def update(self, val):
self.freq1 = self.freq1_slider.val
self.freq2 = self.freq2_slider.val
def animate(self, i):
x1 = self.amp1 * np.cos(2 * np.pi * self.freq1 * self.t + self.phase1)
x2 = self.amp2 * np.cos(2 * np.pi * self.freq2 * self.t + self.phase2)
x3 = x1 + x2
self.line1.set_data(self.t, x1)
self.line2.set_data(self.t, x2)
self.line3.set_data(self.t, x3)
return self.line1, self.line2, self.line3
def show(self):
plt.show()
if __name__ == "__main__":
vibration = HarmonicVibration()
vibration.show()
展示结果如图1所示。Python中的matplotlib库是一个2D绘图库,其功能强大,支持绘制各种图表类型,可实现动态参数调整互动。matplotlib.pyplot子库可设置绘图框架的格式,根据问题设计需要的图表样式,matplotlib.animation.FuncAnimation可用于创建动画,允许通过循环调用一个函数来更新图表,从而实现动态变化效果,matplotlib.widgets可用于生成各类交互按钮和滑块组件。程序首先创建和设定图表框架的基本形式,输入两个同方向不同频率简谐振动函数,并给予初始化参数,将其绑定至滑块事件。随后设置更新情况,计算更新后的曲线数据,并实时动态显示更新后的动画展示效果。通过拖拽两个频率滑块,即可动态展示不同频率的合成情况,以下是某两个不同频率简谐振动合成的效果展示图像。
两个同方向不同频率的简谐振动叠加是力学中的常见问题,为了简单起见,考虑两个振幅相同、角频率分别为
和
两个同方向的振动。由于
不等于
,两个分振动相位差不固定,可以选二者相位相同时为时间零点,使二者初始相位都为零。即设
,
。根据三角公式,两者叠加之后可得合振动方程为:
Figure 1. Synthesis of simple harmonic motions with the same direction but different frequencies
图1. 同方向不同频率简谐振动合成
对于合振动的方程分析可知,如果
,则有
,合振动将围绕
的新的平衡位置以角频率
做简谐振动。若
,情况与之类似;如果
,
和
都较大但二者相差很小时,
随时间做缓慢变化,
随时间变化较快。合振动近似看作是角频率为
,振幅为
的简谐振动。
显然此合成过程需要较为复杂的三角函数运算,合成的结果也较为复杂,涉及抽象的代数分析,具有一定难度,不利于学生直观理解和掌握。运用Python程序的可视化功能可以更加高效、直观地呈现振动合成的结果,并有助于探寻分振动频率对于合振动波形结果的影响。
例4:求解简单非线性振动问题,例如求二阶常微分方程
(杜芬振子)的数值解。
尝试运用Python程序求解数值解并展示图像结果,代码如下:
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
plt.rcParams['font.family'] = ['SimSun']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['xtick.labelsize'] = 9
plt.rcParams['ytick.labelsize'] = 9
plt.rcParams['font.size'] = 9
def duffing_oscillator(t, z, gamma, alpha, beta, F, omega):
x, v = z
dxdt = v
dvdt = -2 * gamma * v - alpha * x - beta * (x ** 3) + F * np.cos(omega * t)
return [dxdt, dvdt]
gamma = 0.1
alpha = -1
beta = 1
F = 0.5
omega = 1
z0 = [1.0, 0.0]
t_span = (0, 100)
t_eval = np.linspace(t_span[0], t_span[1], 10000)
sol = solve_ivp(
fun=lambda t, z: duffing_oscillator(t, z, gamma, alpha, beta, F, omega),
t_span=t_span,
y0=z0,
t_eval=t_eval,
method='RK45')
t = sol.t
x = sol.y[0]
v = sol.y[1]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
ax1.plot(t, x, color='#1f77b4', linewidth=1.5)
ax1.set_xlabel('时间 t (s)', fontsize=9)
ax1.set_ylabel('位移 x (m)', fontsize=9)
ax1.set_title('杜芬振子的位移–时间曲线', fontsize=9, fontweight='bold')
ax1.grid(True, alpha=0.3)
ax2.plot(x, v, color='#ff7f0e', linewidth=1)
ax2.set_xlabel('位移 x (m)', fontsize=9)
ax2.set_ylabel('速度 v (m/s)', fontsize=9)
ax2.set_title('杜芬振子的相图(速度–位移)', fontsize=9, fontweight='bold')
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Figure 2. The displacement-time curve and phase diagram of the Duffin oscillator
图2. 杜芬振子的位移–时间曲线和相图
绘图结果如图2所示,本例主要使用龙格–库塔法求解微分方程的数值解,使用matplotlib库绘制结果图像。龙格–库塔法是一种数值求解常微分方程的高精度方法,其核心思想是用区间内多个点的函数值加权平均逼近导数,利用多步采样和加权组合的方式替代欧拉法的单点近似,可兼顾精度与效率,稳定性强,适用于工程、物理问题中的各类常微分方程。
本例中出现的杜芬阵子是一类典型的非线性受迫振动系统,其方程中的各项参数依次为阻尼系数
,决定振动的衰减程度,线性刚度系数
,非线性刚度系数
,简谐激励振幅
和激励频率
。在求解时利用物理关系先将二阶方程重写为两个一阶方程:
再设定初始条件和时间范围,通过龙格–库塔法求解方程的数值解,其中方程的各项参数可以根据研究问题的不同自主设置,从而有助于直观观察不同参数对于振动效应的影响。此问题如果通过代数方法难以直接求解,借助Python强大的运算功能和直观可视化功能可以更加高效地对问题进行模拟和求解,从而帮助学生更加深刻地理解振动问题。
5. 总结
相比于传统的教学方式,将Python程序引入大学物理力学教学具有很多优势。教学中借助Python强大的科学计算和可视化能力,可以丰富教学内容和方法,更加直观高效地呈现和阐释知识点,帮助加深记忆和理解。也有助于将理论和实践结合,培养和提升学生的动手能力和解决实际问题的能力。同时可以对基础不同的学生开展个性化教学,有利于培优和拔尖训练。
6. 讨论与展望
将Python程序引入力学教学虽具有很多积极意义,但目前也面临一些局限和挑战。一是Python语言的学习需要知识基础和一定时间精力的投入,对于师生的计算机水平提出了较高要求,在课程开展前需进行较多的引导和铺垫。二是能否在有限的课程时间内,合理规划教学内容和方式,将力学知识与程序应用更加有机地融合,使程序工具更好地促进学生对于知识的理解和思维的培养,助力教学效果提升。三是还需进一步推进学科融合教学,促进力学教学与工程专业类课程、计算机应用课程的协同教学,引导学生扩展眼界,培养解决综合实践问题的能力,激发自主学习、自主探究的精神。
在未来的教学中,可以进一步建设更加合理的教学体系,加强不同课程的协同联系,让程序资源更好地辅助书本知识的教学过程,并帮助学生在课前、课中、课后培养更加良好的学习习惯,构建综合知识体系,从而实现更好的教育效果。