用Python API啟動(dòng)Lumerical的仿真軟件時(shí),建立了兩者環(huán)境之間的聯(lián)系,彼此的工作空間不共享,而是在變量傳遞過(guò)程中創(chuàng)建一個(gè)相同的副本,根據(jù)getv( )和put( )函數(shù)中定義的轉(zhuǎn)換類型來(lái)進(jìn)行前傳和后傳。2020a R4版本將典型傳輸速率提高至約為300MBs,并將傳輸數(shù)據(jù)所需的內(nèi)存開(kāi)銷減少[1],提高了數(shù)據(jù)傳輸?shù)男?,但?dāng)數(shù)據(jù)量傳輸量非常大的時(shí)候,數(shù)據(jù)傳遞的規(guī)律仍顯得很重要。
Lumerical和Python中的數(shù)據(jù)類型對(duì)應(yīng)如下:
Lumerical | Python |
---|
String | string |
Real | float |
Complex | np.array |
Matrix | np.array |
Cell array | list |
Struct | dictionary |
Dataset | dictionary |
仿真過(guò)程中,經(jīng)常會(huì)從監(jiān)視器中提取各種數(shù)據(jù)類型的結(jié)果,并進(jìn)一步進(jìn)行傳遞、數(shù)據(jù)處理、作圖等操作。接下來(lái)針對(duì)大家使用Python API進(jìn)行仿真或提取結(jié)果時(shí),常涉及到的數(shù)據(jù)類型進(jìn)行總結(jié):
1. 原始數(shù)據(jù)(Raw Data)
從運(yùn)行過(guò)的仿真工程中的監(jiān)視器結(jié)果中,可以直接訪問(wèn)原始數(shù)據(jù),這些數(shù)據(jù)在 Lumerical中以矩陣的形式存在,將其傳遞到Python環(huán)境時(shí),將作為numpy數(shù)組返回。矩陣各維度的長(zhǎng)度將與相關(guān)參數(shù)的長(zhǎng)度一致,與監(jiān)視器在各個(gè)維度上的監(jiān)測(cè)點(diǎn)個(gè)數(shù)有關(guān)。
屬性:數(shù)據(jù)集中實(shí)際數(shù)據(jù),例如,電場(chǎng)分量Ex、Ey、Ez是場(chǎng)分布監(jiān)視器的屬性。
參數(shù):數(shù)據(jù)集的相關(guān)位置向量。例如,位置x、y、z和頻率f可以是場(chǎng)剖面監(jiān)視器的參數(shù)。
用getdata( )函數(shù)可以獲取監(jiān)視器的原始數(shù)據(jù),注意與getresult( )區(qū)分,得到數(shù)據(jù)后可以用Python的squeeze( )函數(shù),或者Lumerical的pinch( )函數(shù)來(lái)刪除單個(gè)元素的維度,調(diào)整結(jié)果矩陣的形式。
以下是一個(gè)簡(jiǎn)單的Python API控制Lumerical FDTD進(jìn)行仿真,并提取數(shù)據(jù)回到Python的例子:
with?lumapi.FDTD()?as?fdtd:
????fdtd.addfdtd(dimension='2D',?x=0.0e-9,?y=0.0e-9,?x_span=3.0e-6,?y_span=1.0e-6)
????fdtd.addgaussian(name?=?'source',?x=0.,?y=-0.4e-6,?injection_axis='y',?waist_radius_w0=0.2e-6,?wavelength_start=0.5e-6,?wavelength_stop=0.6e-6)
????fdtd.addring(?x=0.0e-9,?y=0.0e-9,?z=0.0e-9,?inner_radius=0.1e-6,?outer_radius=0.2e-6,?index=2.0)
????fdtd.addmesh(dx=10.0e-9,?dy=10.0e-9,?x=0.,?y=0.,?x_span=0.4e-6,?y_span=0.4e-6)
????fdtd.addtime(name='time',?x=0.0e-9,?y=0.0e-9)
????fdtd.addprofile(name='profile',?x=0.,?x_span=3.0e-6,?y=0.)?
????#?Dict?ordering?is?not?guaranteed,?so?if?there?properties?dependant?on?other?properties?an?ordered?dict?is?necessary
????#?In?this?case?'override?global?monitor?settings'?must?be?true?before?'frequency?points'?can?be?set????
????props?=?OrderedDict([('name',?'power'),
????????????????????????('override?global?monitor?settings',?True),
????????????????????????('x',?0.),('y',?0.4e-6),('monitor?type',?'linear?x'),
????????????????????????('frequency?points',?10.0)])
????fdtd.addpower(properties=props)??
????fdtd.save('fdtd_file.fsp')
????fdtd.run()
????#Return?raw?E?field?data
????Ex?=?fdtd.getdata('profile','Ex')
????f?=?fdtd.getdata('profile','f')
????x?=?fdtd.getdata('profile','x')
????y?=?fdtd.getdata('profile','y')
????
print('Frequency?field?profile?data?Ex?is?type',?type(Ex),'?with?shape',?str(Ex.shape?))
print('Frequency?field?profile?data?f?is?type',?type(f),?'with?shape',?str(f.shape?))
print('Frequency?field?profile?data?x?is?type',?type(x),?'with?shape',?str(x.shape?))
print('Frequency?field?profile?data?y?is?type',?type(y),?'with?shape',?str(y.shape?))
Python程序設(shè)置了光源、環(huán)形結(jié)構(gòu)、網(wǎng)格、監(jiān)視器等,最終返回相應(yīng)結(jié)果的維度,如下圖所示,可以直接用Python對(duì)數(shù)據(jù)進(jìn)行進(jìn)一步處理、出圖。
數(shù)據(jù)集是互相相關(guān)的結(jié)果,打包在Lumerical中,可以輕松地可視化或訪問(wèn),主要包含三種直線數(shù)據(jù)集:
其中,Nx, Ny, Nz為坐標(biāo)向量的長(zhǎng)度,Np為參數(shù)長(zhǎng)度。正如本節(jié)之前提到的,如果數(shù)據(jù)集中參數(shù)的維度比較小,例如二維或一維,那么很多個(gè)維度的長(zhǎng)度將為1,這時(shí)就需要使用Lumerical的pinch( )函數(shù)來(lái)刪掉多余的單元素維度。非結(jié)構(gòu)化空間數(shù)據(jù)集情況類似,但包含了網(wǎng)格點(diǎn)的連通性屬性,作為空間屬性,廣泛用于有限元求解器CHARGE、HEAT、FEEM和DGTD。
傳遞給python環(huán)境的空間數(shù)據(jù)集將被轉(zhuǎn)換為字典,字典中的鍵(keys)與各種屬性和參數(shù)相關(guān)聯(lián)。由于屬性是矩陣,它們將轉(zhuǎn)換為numpy數(shù)組。此外,它們將有一個(gè)特殊的元數(shù)據(jù)標(biāo)簽'Lumerical_dataset',當(dāng)執(zhí)行往返傳遞時(shí),可以保留它們的結(jié)構(gòu)。使用 getresult( )方法獲取返回的數(shù)據(jù)集:
with?lumapi.FDTD('fdtd_file.fsp')?as?fdtd:???
????#返回兩種維度不同的數(shù)據(jù)集
????T,?time?=?fdtd.getresult('power',?'T'),?fdtd.getresult('time','E')
????#創(chuàng)建一個(gè)非結(jié)構(gòu)化數(shù)據(jù)集
????fdtd.eval('x?=?[0;1;2];y?=?[0;sqrt(3);0];z?=?[0;0;0];C?=?[1,3,2];ds?=?unstructureddataset(x,y,z,C);')
????ds?=?fdtd.getv('ds')
????
print('Transmission?result?T?is?type',?type(T),'?with?keys',?str(T.keys())?)
print('Time?monitor?result?E?is?type',?type(time),'?with?keys',?str(time.keys())?)
print('Unstructured?dataset?is?type',?type(ds),'?with?keys',?str(ds.keys())?)
返回結(jié)果:
參考:
[1]https://optics.ansys.com/hc/en-us/articles/360041401434-Passing-Data-Python-API