大功率激光器广泛用于各种领域当中,例如激光切割、焊接、钻孔等应用中。由于镜头材料的体吸收或表面膜层带来的吸收效应,将导致在光学系统中由于激光能量吸收所产生的影响也显而易见,大功率激光器系统带来的激光能量加热会降低此类光学系统的性能。为了确保焦距稳定性和激光光束的尺寸和质量,有必要对这种效应进行建模。在本系列的 5 篇文章中,我们将对激光加热效应进行仿真,包括由于镜头材料温度升高而引起的折射率变化,以及由机械应力和热弹性效应造成的结构变形。
在本文中,我们将在OpticStudio中打开完整的光机系统,准备记录光束穿过镜头和反射镜时被吸收的激光功率。随后,我们使用可以导入到FEA软件的格式来导出此数据。打开附件中的 ‘system_NSC_2022.zar’ 文件。
在使用如下所示设置运行光线追迹后,吸收的通量数据将存储在探测器中,并且可通过ZOS-API进行使用和取回。
任何物体作为探测器(‘Object is Detector’)的表面上辐照度都可以在实体(Shaded)模型中直观地显示。
而且体探测器内部的吸收通量可以在探测器查看器中进行查看。
ZOS-API 作为一种有助于自动化运行数据导出流程的强大工具。在下一部分中,我们将演示如何使用ZOS-API脚本来取回探测器上存储的通量数据,并对输出进行配置,以符合您FEA软件的输入要求。如果您不熟悉ZOS-API,请参阅 ZOS-API – Zemax入门(https://www.zemax.com/blogs/free-tutorials/getting-started-with-zos-api)了解完整指南和技巧提示,以充分发挥其功能优势。
在OpticStudio中,不同类型的探测器能够存储不同类型的数据。下表总结了我们从FEA分析所使用的每种探测器中抽取的数据类型。
探测器类型 | 数据类型 | 辐射单位 | 能量单位 |
矩形探测器 | 辐射照度 | 瓦/平方米 | 焦耳/平方米 |
瓦/平方厘米 | 焦耳/平方厘米 |
瓦/平方毫米 | 焦耳/平方毫米 |
瓦/平方英尺 | 焦耳/平方英尺 |
瓦/平方英寸 | 焦耳/平方英寸 |
辐射强度 | 瓦/球面度 | 焦耳/球面度 |
辉度 | 瓦/球面度-平方米 | 焦耳/球面度-平方米 |
体探测器 | 入射通量 | 瓦 | 吸收通量/体积 |
吸收通量 | 瓦 | 焦耳 |
吸收通量/体积 | 瓦/立方米 | 焦耳/立方米 |
瓦/立方厘米 | 焦耳/立方厘米 |
瓦/立方毫米 | 焦耳/立方毫米 |
瓦/立方英尺 | 焦耳/立方英尺 |
瓦/立方英寸 | 焦耳/立方英寸 |
物体作为探测器 | 入射通量 | 瓦/平方米 | 焦耳/平方米 |
瓦/平方厘米 | 焦耳/平方厘米 |
瓦/平方毫米 | 焦耳/平方毫米 |
瓦/平方英尺 | 焦耳/平方英尺 |
吸收通量 | 瓦/平方英寸 | 焦耳/平方英寸 |
下方表格中总结了可从各种探测器中获取并用于 FEA 分析的数据类型:
探测器类型 | 像素形状 | 数据类型 | 辐射学 单位 | ZOS-API 语句 |
矩形探测器 | 矩形 | 辐照度 | 瓦/ 平方厘米 | bool | GetDetectorData (int ObjectNumber, int pixel, int Data(=2), out double Value) |
体探测器 | 矩形体积 | 吸收通量/体积 | 瓦/ 立方厘米 | bool | GetDetectorData (int ObjectNumber, int pixel, int Data(=2), out double Value) |
物体作为探测器 | 三角形 | 吸收通量 | 瓦/ 平方厘米 | double | AbsorbedIrradiance [get] |
|
本例中使用的 FEA 软件是 Ansys Mechanical,它可以将吸收通量数据作为外部热源导入,以用于热模拟。导入数据所需的格式如下:
X Y Z AbsorbedData
X、 Y、Z 是每个像素中心的全局坐标,而 AbsorbedData 是上面列出的数据类型的值。
请注意,当从 “探测器查看器” 窗口检查吸收通量数据时,针对 “物体作为探测器” 选项数据尽快在 “文本” 选项卡中进行查看。“文本” 选项卡将显示每个三角形像素的 “通量” 和 “辐照度” 值的文本列表。X、Y 和 Z 值是每个像素中心的局部坐标。在 STOP 分析过程中,适合使用一个统一的全局坐标系。如果要在全局坐标中导出数据,则需要进行适当的坐标转换。
我们创建了自动运行这个流程,用于取回、格式排版和导出数据的Python脚本,如文章附件 ‘ExportAbsorbedFlux.py’。以下章节内容将解释该部分代码的具体意义。
计算旋转矩阵
首先,我们需要确定系统中每个物体的旋转矩阵。如果未勾选 “物体属性…类型…使用全局 XYZ 旋转顺序” 选项,则使用以下公式计算物体的旋转矩阵,其中 A、B 和 C 是 NSCE 中列出的倾斜 X、Y、Z 角度。
相反,如果勾选了 “使用全局 XYZ 旋转顺序” 选项,则物体的旋转矩阵取决于:
以上计算将在 rotation_matrix 函数中得到定义:
将局部坐标转换为全局坐标
将物体局部坐标转换为全局坐标的公式形式可以表达为如下形式:
其中,g 下标表示全局坐标,o 表示偏移,l 表示局部物体坐标。R11、R12…R33 是物体旋转矩阵 R 的分量。
以上计算将在 convert_to_global 函数中得到定义:
计算局部坐标并取回吸收通量数值
对于 “物体作为探测器” 选项而言:
局部坐标将通过以下代码的各鳞甲像素循环形式进行计算:
detector.CurrentFace = j
position_1 = detector.GetVertex(0, 0.0, 0.0, 0.0)
position_2 = detector.GetVertex(1, 0.0, 0.0, 0.0)
position_3 = detector.GetVertex(2, 0.0, 0.0, 0.0)
x_position = (position_1[1] + position_2[1] + position_3[1])/3
y_position = (position_1[2] + position_2[2] + position_3[2])/3
z_position = (position_1[3] + position_2[3] + position_3[3])/3value = detector.AbsorbedIrradiance
position_1、position_2、position_3 代表各三角形像素的三个顶点。
bool GetVertex (int vertexNumber, out double X, out double Y, out double Z)
GetVertex 方法将用于取回指定顶点的 X、Y、Z 坐标值。之后,该三角形中心的坐标值将得到计算。
对于矩形探测器和体探测器而言,局部坐标将通过以下代码中的矩形像素/矩形体积像素循环中得到计算。
# Detector Rectanglelocal_x = ((j % pixelsX) - ((pixelsX - 1) / 2)) * (widthX / pixelsX)
local_y = (((j // pixelsX) % pixelsX) - ((pixelsY - 1) / 2)) * (widthY / pixelsY)
local_z = 0.0
value = TheNCE.GetDetectorData(i + 1, j + 1, 2, 0.0)[1]
# Detector Volumelocal_x = ((j % voxelsX) - ((voxelsX - 1) / 2)) * (widthX / voxelsX)
local_y = (((j // voxelsX) % voxelsY) - ((voxelsY - 1) / 2)) * (widthY / voxelsY)
local_z = ((j // (voxelsX * voxelsY)) - ((voxelsZ - 1) / 2)) * (widthZ / voxelsZ)
value = TheNCE.GetDetectorData(i + 1, j + 1, 2, 0.0)[1]
对吸收的数据进行逐像素数据取回,其中 i 表示物体序号的循环,j 表示像素序号的循环。参考的本地坐标系位于该物体的中心,在决定如何循环并依据从像素到像素顺序获取数据时,应注意探测器的像素编号。对于每种探测器类型,可以在 OpticStudio 帮助文件条目中查看探测器的像素编号注释。
将局部坐标转换为全局坐标并获取结果
将提前创建空的数据阵列,例如 ‘detectorData’ 将用于存放局部坐标以及探测器数据,‘global_detectorData’ 将用于存放全局坐标以及探测器数据:
detectorData = []
global_detectorData = []
局部数据将作为各探测器像素循环计算的附加项:
detectorData.append([local_x, local_y, local_z, float(value)])
***终,各探测器具有局部坐标的阵列将转换为具有全局坐标的数据阵列:
detectorData.append([local_x, local_y, local_z, float(value)])
如何使用 Python 代码
该代码将结合 OpticStudio 的交互扩展形式 (Interactive Extension) 运行。
首先打开非序列模式镜头文件,运行光线追迹,勾选使用偏振(‘Use Polarization’)。
点击编程……交互式扩展(Click Programming…Interactive Extension),然后在Python IDE 中运行 ExportAbsorbedFlux.py 代码。
数据将保存为代码中指定的文件夹下的 txt 文件。在运行代码的过程中将显示附加数据的状态:
我们已经成功仿真了激光光束穿过光学系统时的吸收情况,并生成了吸收通量数据的文件。该数据与完整光机系统的模型相结合,可以为 FEA 工具中的结构分析和热分析提供输入。在下一篇文章中,我们将演示如何使用 STAR 模块获得结构分析和热分析的输出,并导入到 OpticStudio 中。