finesse.thermal package
Submodules
finesse.thermal.hello_vinet module
Hello-Vinet equations for thermal lenses in cylindrical mirrors. Higher order mode thermal effects are not implemented here. Therefore all the functions return some axially symmetric data.
Equations all based on [37]:
Jean-Yves Vinet, “On Special Optical Modes and Thermal Issues in Advanced Gravitational Wave Interferometric Detectors” Living Review 2009
- finesse.thermal.hello_vinet.eval_p_n_s_numerical(result)
Evaluates a Fourier-Bessel decomposition fit performed with
finesse.thermal.hello_vinet.get_p_n_s_numerical().Returns
- I_rndarray
Irradiance from fit
- finesse.thermal.hello_vinet.get_p_n_s(a, w, n, m, chi, eta_n_s, eta_n_s_sq)
Returns beam intensity overlap coefficients as calculated by Eq 3.33 in [37].
Parameters
- afloat
mirror radius
- wfloat
spot size radius
- n, mint
LG mode order
- chifloat
Reduced radiation constant
- eta_n_sarray_like
2D array with dimensions (n_max, s_max) for the n-th order Bessel and the first s zeros of the Bessel equation 3.11 [37]. See
finesse.thermal.hello_vinet.zeros_of_xjn_1_chi_jn()to compute these.- eta_n_s_sqarray_like
Cached (eta_n_s)^2 values
Notes
This is currently limited to computing only the LG00 mode, higher order modes are still on the todo list.
- finesse.thermal.hello_vinet.get_p_n_s_numerical(I, a, s_max, material, barrel_material=None, n_max=0, T_ext=293.15, root_accuracy=1e-6, newton_cotes_order=2)
Performs a Fourier-Bessel decomposition of some axisymmetric irradiance distribution.
Parameters
- Indarray
Axisymmetric irradiance distribution [Wm^-2], defined from r = 0 -> a. Radial point array is internally inferred from the size of I.
- afloat
mirror radius
- s_maxint
Number of zeros in each Bessel expansion
- materialMaterial
Mirror substrate material, see
finesse.materials- barrel_materialMaterial
Barrel coating material, see
finesse.materials- n_maxint, optional
Number of bessel functions to expand with, typically 0
- T_extfloat, optional
External temperature around mirror
- root_accuracyfloat, optional
Absolute accuracy of root Bessel function root finding
- newton_cotes_weightint, optional
Order of newton-cotes weight for integral
Returns
- rndarray
Radial points [m]
- chi_edgefloat
Reduced thermal constant for barrel surface
- chi_facefloat
Reduced thermal constant for end faces
- p_n_sndarray
Fourier-Bessel coefficients
- eta_n_sndarray
Zeros of Bessel function
- Jn_k_ns_r_andarray
Fourier-Bessel expansion bases
Examples
import finesse.materials import finesse.thermal.hello_vinet as hv import numpy as np import matplotlib.pyplot as plt from scipy.special import eval_hermite
finesse.init_plotting() # aLIGO like test mass substrate material = finesse.materials.FusedSilica a = 0.17 h = 0.2 w = 53e-3 r = np.linspace(0, a, 101) # 5th order hermite radial distribution E = eval_hermite(5, np.sqrt(2)*r/w) * np.exp(-(r/w)**2) I = E*E plt.plot(r, I) # perform Fourier-Bessel decomposition fit = hv.get_p_n_s_numerical(I, a, 10, material) plt.plot(r, hv.eval_p_n_s_numerical(fit), ls=’–’, lw=2, label=’s_max=10’) # perform Fourier-Bessel decomposition fit = hv.get_p_n_s_numerical(I, a, 20, material) plt.plot(r, hv.eval_p_n_s_numerical(fit), ls=’–’, lw=2, label=’s_max=20’) plt.legend() plt.xlabel(“r [m]”) plt.ylabel(“I(r) [Wm^-2]”) plt.title(“Fourier-Bessel decomposition of irradiance”)
Notes
This returns beam intensity overlap coefficients as calculated by Eq 3.15 in [37] for an arbitrary radial intensity distribution. Typically n_max=0 and s_max is chosen for the required fit. The integral is performed using composite Newton-Cotes rule, which by default is set to a Simpsons Rule (order 2) which provides better accuracy when fewer sample points in the intensity are present. Higher orders are not necessarily more accurate as over-fitting from using too high a polynomial order can introduce artifacts.
The resulting fit can be compared using the returned values by passing the tuple of results to
finesse.thermal.hello_vinet.eval_p_n_s_numerical(). Comparing the above to the original intensity will show how accurate the fit is and will determine what s_max and weight ordering you should use. Sharp features in the intensity will not fit well.
- finesse.thermal.hello_vinet.ring_radiator_intensity(r, a, b_c, D_c, P_c)
Calculates the intesity of incident on a mirror surface from an ideally thin ring radiator.
Parameters
- rndarray
Radial points [m]
- afloat
Mirror radius
- b_cfloat
Radius of ring radiator (b_c > D_c) [m]
- D_cfloat
Distance from ring radiator to mirror surface [m]
- P_cfloat
Power emitted by ring [W]
Returns
- I_rndarray(shape=(r.size,))
Radial variation in intensity on mirror from ring.
Notes
Solving equation 4.11 [37]
- finesse.thermal.hello_vinet.substrate_temperatures(data, z, h)
Computes the 2D substrate temperature distribution per Watt of absorbed power in each of the coating and substrate for an arbitrary axisymmetric heating irradiance computed with
finesse.thermal.hello_vinet.get_p_n_s_numerical().Parameters
- datatuple
Irradiance fit data from
finesse.thermal.hello_vinet.get_p_n_s_numerical()- zndarray
Longitudinal points, should sample points between -h/2 and h/2. Sampling outside this region will yield incorrect results.
- hfloat
Longitudinal points
Returns
- T_coatndarray(shape=(z.size, r.size))
2D array of temperature in substrate from coating absorption per watt of power absorbed in coating
- T_bulkndarray(shape=(z.size, r.size))
2D array of temperature throughout substrate from bulk absorption per watt of power absorber through the entire substrate.
Notes
This is using equation 3.20 and 3.25 in [37] for \(\phi=0\).
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.substrate_temperatures_HG00(r, z, a, h, w, material, barrel_material=None, T_ext=293.15, n_max=0, s_max=10, root_accuracy=1e-6)
Computes the 2D substrate temperature distribution per Watt of absorbed power in each of the coating and substrate from a HG00 beam.
Parameters
- rndarray
Radial points
- zndarray
Longitudinal points, should sample points between -h/2 and h/2. Sampling outside this region will yield incorrect results.
- afloat
mirror radius
- hfloat
mirror thickness
- wfloat
spot size radius
- materialMaterial
Mirror substrate material, see
finesse.materials- barrel_materialMaterial
Barrel coating material, see
finesse.materials- T_extfloat, optional
External temperature surrounding mirror
- n_maxint, optional
Maximum Bessel order for expansion
- s_maxint, optional
Maximum number of zeros to compute
- root_accuracyfloat, optional
Accuracy of root finding
Returns
- T_coatndarray(shape=(z.size, r.size))
2D array of temperature in substrate from coating absorption per watt of power absorbed in coating
- T_bulkndarray(shape=(z.size, r.size))
2D array of temperature throughout substrate from bulk absorption per watt of power absorber through the entire substrate.
Notes
This is using equation 3.20 and 3.25 in [37] for \(\phi=0\).
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.substrate_thermal_expansion_depth(data, z, h)
Computes the depth displacements throughout the bulk of an optic due to coating absorption. Displacement is in units of m per absorbed Watts for a custom axisymmetric heating beam, see
finesse.thermal.hello_vinet.get_p_n_s_numerical().Parameters
- datatuple
Irradiance fit data from
finesse.thermal.hello_vinet.get_p_n_s_numerical()- zndarray
Longitudinal points, should sample points between -h/2 and h/2. Sampling outside this region will yield incorrect results.
- hfloat
mirror thickness
Returns
- U_z_coat_per_Wndarray(shape=(z.size, r.size))
D Array of z displacements throughout the substrate per absorbed Watts of HG00 beam in coating
Notes
Solving equation 3.117 and 3.118 in [37]
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.substrate_thermal_expansion_depth_HG00(r, z, a, h, w, material, barrel_material=None, T_ext=293.15, n_max=0, s_max=20, root_accuracy=1e-6)
Computes the depth displacements throughout the bulk of an optic due to coating absorption. Displacement is in units of m per absorbed Watts for a HG00 heating beam.
Parameters
- rndarray
Radial points
- zndarray
Longitudinal points, should sample points between -h/2 and h/2. Sampling outside this region will yield incorrect results.
- afloat
mirror radius
- hfloat
mirror thickness
- wfloat
spot size radius
- materialMaterial
Mirror substrate material, see
finesse.materials- barrel_materialMaterial
Barrel cotaing material, see
finesse.materials- T_extfloat, optional
External temperature surrounding mirror
- n_maxint, optional
Maximum Bessel order for expansion
- s_maxint, optional
Maximum number of zeros to compute
- root_accuracyfloat, optional
Accuracy of root finding
Returns
- U_z_coat_per_Wndarray(shape=(z.size, r.size))
D Array of z displacements throughout the substrate per absorbed Watts of HG00 beam in coating
Notes
Solving equation 3.117 and 3.118 in [37]
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.surface_deformation_coating_heating(data, h)
Computes the depth displacement change of the surface of an optic due to coating absorption. Displacement is in units of m per absorbed Watts for a custom axisymmetric heating profile, see
finesse.thermal.hello_vinet.get_p_n_s_numerical()on how to generate the data for this.Parameters
- datatuple
Irradiance fit data from
finesse.thermal.hello_vinet.get_p_n_s_numerical()- zndarray
Longitudinal points, should sample points between -h/2 and h/2. Sampling outside this region will yield incorrect results.
- hfloat
mirror thickness
Returns
- U_z_coat_per_Wndarray(shape=(r.size.))
Array of z displacements
Notes
Solving equation 3.121 and 3.122 in [37]
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.surface_deformation_coating_heating_HG00(r, a, h, w, material, barrel_material=None, T_ext=293.15, n_max=0, s_max=20, root_accuracy=1e-6)
Computes the depth displacement change of the surface of an optic due to coating absorption. Displacement is in units of m per absorbed Watts for a HG00 heating beam.
Parameters
- rndarray
Radial points
- afloat
mirror radius
- hfloat
mirror thickness
- wfloat
spot size radius
- materialMaterial
Mirror substrate material, see
finesse.materials- barrel_materialMaterial
Barrel cotaing material, see
finesse.materials- T_extfloat, optional
External temperature surrounding mirror
- n_maxint, optional
Maximum Bessel order for expansion
- s_maxint, optional
Maximum number of zeros to compute
- root_accuracyfloat, optional
Accuracy of root finding per Watt of power absorbed in coating
Returns
- U_z_coat_per_Wndarray(shape=(r.size.))
Array of z displacements
Notes
Solving equation 3.121 and 3.122 in [37]
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.surface_deformation_substrate_heating(data, h)
Computes the depth displacement change of the surface of an optic due to bulk absorption from a generic axisymmetric heating profile. Displacement returned is in units of m per absorbed Watts through entire substrate.
The accuracy of this computation decreases as h/a > 1. The substrate modelled must be disk like. The error is more pronounced towards the edge of the substrate.
Parameters
- datatuple
Irradiance fit data from
finesse.thermal.hello_vinet.get_p_n_s_numerical()- hfloat
mirror thickness
Returns
- U_z_bulk_per_Wndarray(shape=(r.size.))
Array of z displacements per watt of absorbed power through entire substrate [1W/h]
Notes
Solving equation 3.165 [37]
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.surface_deformation_substrate_heating_HG00(r, a, h, w, material, barrel_material=None, T_ext=293.15, n_max=0, s_max=20, root_accuracy=1e-6)
Computes the depth displacement change of the surface of an optic due to bulk absorption from a HG00 beam. Displacement returned is in units of m per absorbed Watts through entire substrate.
The accuracy of this computation decreases as h/a > 1. The substrate modelled must be disk like. The error is more pronounced towards the edge of the substrate.
Parameters
- rndarray
Radial points
- afloat
mirror radius
- hfloat
mirror thickness
- wfloat
spot size radius
- materialMaterial
Mirror substrate material, see
finesse.materials- barrel_materialMaterial
Barrel cotaing material, see
finesse.materials- T_extfloat, optional
External temperature surrounding mirror
- n_maxint, optional
Maximum Bessel order for expansion
- s_maxint, optional
Maximum number of zeros to compute
- root_accuracyfloat, optional
Accuracy of root finding
Returns
- U_z_bulk_per_Wndarray(shape=(r.size.))
Array of z displacements per watt of absorbed power through entire substrate [1W/h]
Notes
Solving equation 3.165 [37]
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.thermal_lenses(data, h)
Computes the substrate thermal lens per Watt of absorbed power in each of the coating and substrate for an arbitrary axisymmetric heating irradiance computed with
finesse.thermal.hello_vinet.get_p_n_s_numerical().Parameters
- datatuple
Irradiance fit data from
finesse.thermal.hello_vinet.get_p_n_s_numerical()- hfloat
mirror thickness
Returns
- Z_coatndarray(shape=(r.size,))
Array of optical path difference in bulk from coating absorption per watt of power absorbed in coating
- Z_bulkndarray(shape=(r.size,))
Array of optical path difference in bulk from bulk absorption per watt absorbed through entire substrate [1W/h]
Notes
This is using equation 3.20 and 3.25 in [37] for \(\phi=0\).
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.thermal_lenses_HG00(r, a, h, w, material, barrel_material=None, T_ext=293.15, n_max=0, s_max=20, root_accuracy=1e-6)
Computes the substrate thermal lens per Watt of absorbed power in each of the coating and substrate from a HG00 beam.
Parameters
- rndarray
Radial points
- afloat
mirror radius
- hfloat
mirror thickness
- wfloat
spot size radius
- materialMaterial
Mirror substrate material, see
finesse.materials- barrel_materialMaterial
Barrel cotaing material, see
finesse.materials- T_extfloat, optional
External temperature surrounding mirror
- n_maxint, optional
Maximum Bessel order for expansion
- s_maxint, optional
Maximum number of zeros to compute
- root_accuracyfloat, optional
Accuracy of root finding
Returns
- Z_coatndarray(shape=(r.size,))
Array of optical path difference in bulk from coating absorption per watt of power absorbed in coating
- Z_bulkndarray(shape=(r.size,))
Array of optical path difference in bulk from bulk absorption per watt absorbed through entire substrate [1W/h]
Notes
This is using equation 3.20 and 3.25 in [37] for \(\phi=0\).
Currently only works for n_max == 0.
- finesse.thermal.hello_vinet.zeros_of_xjn_1_chi_jn(double chi, int n_max, int s_max, double accuracy)
Compute the roots of the equation
\[x J_{n+1}(x) - \chi J_{n}(x) = 0 \]which is used throughout the Hello-Vinet thermal equations.
Parameters
- chifloat
Reduced radiation constant
- n_maxint
Max bessel order to compute up to, must be > 0
- s_maxint
Max number of zeros to compute, must be >= 2
- accuracydouble
absolute error on zero finding brentq algorithm
Returns
- eta_n_sarray_like
Array of s_max zeros for the n_max bessel functions
Notes
This is based on the calculations in [37]. The zeros of this function are used in multiple calculations throughout the text.
This algorithm finds the first two zeros of the 0th order bessel function then from there assumes the next zero is approximately the difference between the last two further away.
For higher order bessels, the zeros are always between the zeros of n-1 zeros which can be used as bounds for root finding.
finesse.thermal.reciprocity module
Compute thermo-elastic deformations in optical substrates using reciprocity theorem [42]. This provides a more accurate method to model thermo-elastic deformation of surfaces when the temperature distribution is known throughout a substrate. Reciprocity used here requires finite-element model results for volumetric strain due to a Zernike based force applied to the surface of the substrate. Substrate temperature distributions can then be converted into displacements and overlaps with the volumetric strain calculated. The coefficients of these overlaps then describes the zernike surface decomposition.
Equations all based on [42]:
Modeling thermoelastic distortion of optics using elastodynamic reciprocity Eleanor King, Yuri Levin, David Ottaway, and Peter Veitch Phys. Rev. D 92, 022005 - Published 20 July 2015 https://doi.org/10.1103/PhysRevD.92.022005
The methods here have been adapted from code and work done by Huy Tuong Cao <huy-tuong.cao@LIGO.org>.
- class finesse.thermal.reciprocity.AxisymmetricFEAData(r=None, z=None, V=None, material=None, filepath=None)
Bases:
objectAn object that contains the finite element analysis data required to perform Axisymmetric thermal reciprocity calculations. This data can either be loaded from a numpy npz file that contains the r, z, V, and material data or can be provided directly to the the constructor.
Attributes
- afloat
Radius of optic in meter
- hfloat
Thickness of optic in meter
- rarray_like
1D radial point vector ranging from [0, a] with Nr elements
- zarray_like
1D thickness point vector ranging from [0, h] with Nz elements
- R, Zarray_like
2D meshgrid arrays of self.r, self.z
- Varray_like
An (NV, Nz, Nr) shaped array representing the 2D basis functions for this reciprocity.
- material
finesse.materials.Material An object containing various thermal and mechanical properties for the optic being modelled. Must match the values being used in the finite element model generating self.V.
- property NV
- property Nr
Number of points in the radial vector.
- property Nz
- property dr
- property dz
- finesse.thermal.reciprocity.zernike_coefficients_axisymmetric(data: AxisymmetricFEAData, T)
Compute the Zernike coefficient from temperature substrate profile and volumetric strain. This is for axially symmetric heating profiles and distortions.
Parameters
- data
AxisymmetricFEAData Finite element model data
- Tarray_like
Array of shape (data.Nz, data.Nr) of temperature over the finite element model domain.
Returns
- Z_coeffsarray_like
Array of shape data.NV of Zernike coefficients of the surface
- data
- finesse.thermal.reciprocity.zernike_surface_axisymmetric(data: AxisymmetricFEAData, Z_coeffs)
Reconstruct the surface deformation from Zernike coefficients.
Parameters
- data
AxisymmetricFEAData Finite element model data
- Z_coeffsarray_like
Zernike coefficients in an array of shape data.NV
Returns
- Warray_like
Surface displacement in metres
- data
finesse.thermal.ring_heater module
Ring heater thermal equations for cylindrical mirrors
Equations all based on [38] and [39]:
- finesse.thermal.ring_heater.substrate_deformation_depth(r, z, a, b, c, h, material, barrel_material=None, T_ext=293.15, m_max=10, root_accuracy=1e-12)
Computes the depth displacements throughout the bulk of an optic due to 1W absorption of ring heater. Displacement is in units of m per absorbed Watts.
Parameters
- rarray_like
Radial vector [m]
- z :array_like
Longitudinal points, should sample points between -h/2 and h/2.
- afloat
Mirror radius [m]
- bfloat
Ring heater lower boundary relative to center [m]
- cfloat
Ring heater upper boundary relative to center [m]
- hfloat
Mirror thickness [m]
- material
finesse.materials.Material Mirror substrate material, see
finesse.materials- barrel_material
finesse.materials.Material Barrel coating material, see
finesse.materials- T_extfloat, optional
External temperature surrounding mirror
- m_maxint, optional
Number of zeros to find, i.e. analytic order
- root_accuracy: float, optional
Accuracy of root finding
Returns
- U_z_rh_per_Wndarray(shape=(z.size, r.size))
Array of z displacements throughout the substrate per absorbed Watts of ring heater
Notes
See [39] for derivation of these equations.
- finesse.thermal.ring_heater.substrate_temperature(r, z, a, b, c, h, material, barrel_material=None, T_ext=293.15, m_max=10, root_accuracy=1e-12)
Computes the substrate temperature distribution per Watt absorbed ring heater power.
Parameters
- rarray_like
Radial vector [m]
- zarray_like
Longitudinal vector [m]
- afloat
Mirror radius [m]
- bfloat
Ring heater lower boundary relative to center [m]
- cfloat
Ring heater upper boundary relative to center [m]
- hfloat
Mirror thickness [m]
- material
finesse.materials.Material Mirror substrate material, see
finesse.materials- barrel material:
finesse.materials.Material Barrel coating material, see
finesse.materials- T_extfloat, optional
External temperature surrounding mirror
- m_maxint, optional
Number of zeros to find, i.e. analytic order
- root_accuracy: float, optional
Accuracy of root finding
Returns
- T_rh_per_Warray_like
2D Array of temperature distribution over [r, z]
Notes
Typo for A_m terms in manuscript, sin terms are functions of u_m, not v_m. See [38].
- finesse.thermal.ring_heater.surface_deformation(r, a, b, c, h, material, barrel_material=None, T_ext=293.15, m_max=10, root_accuracy=1e-12)
“Computes the surface thermo-elastic deformation of the HR surface per Watt absorbed ring heater power.
Parameters
- rarray_like
Radial vector [m]
- afloat
Mirror radius [m]
- bfloat
Ring heater lower boundary relative to center [m]
- cfloat
Ring heater upper boundary relative to center [m]
- hfloat
Mirror thickness [m]
- materialMaterial
Mirror substrate material, see
finesse.materials- barrel_materialMaterial
Barrel coating material, see
finesse.materials- T_extfloat, optional
External temperature surrounding mirror
- m_maxint, optional
Number of zeros to find, i.e. analytic order
- root_accuracy: float, optional
Accuracy of root finding
Returns
- U_z_rh_per_Warray_like
1D radial vector of z displacement per Watt of ring heater power
Notes
See [39] for derivation of these equations.
- finesse.thermal.ring_heater.thermal_lens(r, a, b, c, h, material, barrel_material=None, T_ext=293.15, m_max=10, root_accuracy=1e-12)
Computes the substrate thermal lens per Watt absorbed ring heater power.
Parameters
- rarray_like
Radial vector [m]
- afloat
Mirror radius [m]
- bfloat
Ring heater lower boundary relative to center [m]
- cfloat
Ring heater upper boundary relative to center [m]
- hfloat
Mirror thickness [m]
- material
finesse.materials.Material Mirror substrate material, see
finesse.materials- barrel_material
finesse.materials.Material Barrel coating material, see
finesse.materials- T_extfloat, optional
External temperature surrounding mirror
- m_maxint, optional
Number of zeros to find, i.e. analytic order
- root_accuracy: float, optional
Accuracy of root finding
Returns
- Z_rh_per_Warray_like
1D radial vector of optical path difference from propagating through substrate.
Notes
Typo for A_m terms in manuscript, sin terms are functions of u_m, not v_m. See [38].
- finesse.thermal.ring_heater.zeros_u_m(double a, double h, double tau, int m_max, double accuracy)
Compute the roots of the equation
\[u_m - au \cot(u_m h/(2a)) = 0 \]Parameters
- afloat
Mirror radius [m]
- hfloat
Mirror thickness [m]
- taufloat
Reduced radiation constant
- n_maxint
Max bessel order to compute up to
- accuracydouble
absolute error on zero finding brentq algorithm
Returns
- u_marray_like
Array of m_max zeros
- finesse.thermal.ring_heater.zeros_v_m(double a, double h, double tau, int m_max, double accuracy)
Compute the roots of the equation
\[v_m + au tan(v_m h/(2a)) = 0 \]Parameters
- afloat
Mirror radius [m]
- hfloat
Mirror thickness [m]
- taufloat
Reduced radiation constant
- n_maxint
Max bessel order to compute up to
- accuracydouble
absolute error on zero finding brentq algorithm
Returns
- v_marray_like
Array of m_max zeros