diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/AnsysWorkflows.iml b/.idea/AnsysWorkflows.iml new file mode 100644 index 00000000..039314de --- /dev/null +++ b/.idea/AnsysWorkflows.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 00000000..105ce2da --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..c76d81ab --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..0395b48d --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/maxwell2d-lumerical/.gitignore b/maxwell2d-lumerical/.gitignore new file mode 100644 index 00000000..e6d35e74 --- /dev/null +++ b/maxwell2d-lumerical/.gitignore @@ -0,0 +1 @@ +outputs \ No newline at end of file diff --git a/maxwell2d-lumerical/GC_Opt.lsf b/maxwell2d-lumerical/GC_Opt.lsf new file mode 100644 index 00000000..ed5df0a1 --- /dev/null +++ b/maxwell2d-lumerical/GC_Opt.lsf @@ -0,0 +1,301 @@ +# This script file builds the simulation file for the apodized grating coupler, GC +# entirely using script commands, with the goal to focus the output laser beam at a specific distance. Objects are added to the simulation file +# using the specific add commands. Then the script reads the coordinates of the nodal points calculated from Maxwell +# and sets the 5th solution as the target distance of the foccused beam. An optimization is created based on the define FoM in the analysis group & uses as +# as optimization parameters, the pitch, the etch depth and the minimum duty cycle of the GC. + +clear; +switchtolayout; + +selectall; deleteall; # select and delete all objects to make sure we start with a clean project file +setprofile = 0; # not add the profile monitor for the first run; 1 to set this monitor +um=1e-6; + +#################################### add simulation region/mesh/source ############################## +addfdtd; +set("simulation time", 3000e-15); # the unit is second +set("dimension", "2D"); +set("x",16*um); +set("y",-0.75*um); +set("z",0*um); +set("x span", 48*um); +set("y span", 3.5*um); +set("mesh accuracy", 2); + +addmode; #addsource +set("injection axis","x"); +set("x",-3*um); +set("y",-1*um); +set("y span",1*um); +set("z",0); +set("z span",1.14*um); +set("wavelength start", 1550e-9); +set("wavelength stop", 1550e-9); + +adddftmonitor; #addmonitor +set("name","near_field"); +set("monitor type",6); +set("x",24e-6); set("x span",60e-6); +set("y",0.7e-6); +set("z",0e-6); set("z span",15.85e-6); + +############################################ Define geometry ############################################## +# add structures + + +########### Scripted part of the Structure Group ########### +addstructuregroup; # add an apodised grating +set("name","GC_2D"); +set("x",0); # sets the x position + +set("y",-1.1*um); + +set("z",0*um); +adduserprop("index",0,2); +adduserprop("sidewall_angle",0,90); +adduserprop("duty cycle",0,0.8); +adduserprop("n_uniform_gratings",0,1); +adduserprop("dc_min",0,0.476); +adduserprop("dc_uniform",0,0.85); +adduserprop("n_apodized_gratings",0,30); +adduserprop("target length",0,50); +adduserprop("h total",2,0.3*um); +adduserprop("etch depth",2,0.3*um); +adduserprop("input length",2,10*um); +adduserprop("output length",2,80*um); +adduserprop("pitch_uniform",2,0.761*um); +adduserprop("material",5,""); +set('script',' + +deleteall; +fill_width_uniform = pitch_uniform*dc_uniform; +etch_width_uniform = pitch_uniform*(1-dc_uniform); + + +etch_width_apod = linspace(dc_uniform, dc_min, n_apodized_gratings); + +n_periods = ceil(%target length%/pitch_uniform); +fill_width = pitch_uniform*dc_uniform; +etch_width = pitch_uniform*(1-dc_uniform); +L = n_periods*pitch_uniform + etch_width; +sidewall_angle_rad = (90-sidewall_angle)*pi/180; + + +if(%etch depth% > %h total%) { + %etch depth% = %h total%; +} + +# input waveguide +vtx = [-%input length%,%h total%;0,%h total%;%h total%*tan(sidewall_angle_rad),0;-%input length%-%h total%*tan(sidewall_angle_rad),0]; # microns +addpoly; +set("name","input waveguide"); +set("vertices", vtx); +set("x", 0); +set("y", 0); +set("material",material); +if(get("material")=="") +{ set("index",index); } +set("override mesh order from material database", 1); +set("mesh order", 3); + +# lower layer below grating +if(%etch depth% < %h total%) { + addrect; + set("name","lower layer"); + set("x min",-%input length%); + set("x max",%output length%); + set("y min",0); + set("y max",%h total%-%etch depth%); + set("material",material); + if(get("material")=="") + { set("index",index); } +} + +#add grating +for(i=1:(n_uniform_gratings+n_apodized_gratings)){ + + if (i<=n_uniform_gratings){ + vtx = [pitch_uniform*(i-1)+etch_width_uniform,%h total%;pitch_uniform*i,%h total%;pitch_uniform*i+%etch depth%*tan(sidewall_angle_rad),%h total%-%etch depth%;pitch_uniform*(i-1)+etch_width_uniform-%etch depth%*tan(sidewall_angle_rad),%h total%-%etch depth%]; # microns + addpoly; + set("name","grating"); + set("vertices", vtx); + set("x", 0); + set("y", 0); + set("material",material); + if(get("material")=="") + { set("index",index); } + }else{ + + ew = pitch_uniform*(1-etch_width_apod(i-n_uniform_gratings)); + vtx = [pitch_uniform*(i-1)+ew,%h total%;pitch_uniform*i,%h total%;pitch_uniform*i+%etch depth%*tan(sidewall_angle_rad),%h total%-%etch depth%;pitch_uniform*(i-1)+ew-%etch depth%*tan(sidewall_angle_rad),%h total%-%etch depth%]; # microns + addpoly; + set("name","grating"); + set("vertices", vtx); + set("x", 0); + set("y", 0); + set("material",material); + if(get("material")=="") + { set("index",index); } + } + +} + +selectall; + +set("z",0); +set("z span",1e-6); + +'); + + + + +addrect; # add +set("name","cladding"); +set("x",19.5*um); # sets the x position +set("x span",121*um); # sets the x position +set("y",-0.3*um); +set("y span",1.6*um); +set("z",0*um); +set("z span",1*um); +set("material", "SiO2 (Glass) - Palik"); # material name has to be exact +set("override mesh order from material database", true); +set("mesh order", 5); # material name has to be exact + +# add structures +addrect; # add a +set("name","BOx"); +set("x",19.5*um); # sets the x position +set("x span",121*um); # sets the x position +set("y",-1.55*um); +set("y span",0.9*um); +set("z",0*um); +set("z span",1*um); +set("material", "SiO2 (Glass) - Palik"); # material name has to be exact +#set("override mesh order from material database", true); +#set("mesh order", 5); # material name has to be exact + +# add structures +addrect; # add a +set("name","Substrate"); +set("x",19.5*um); # sets the x position +set("x span",121*um); # sets the x position +set("y",-6*um); +set("y span",8*um); +set("z",0*um); +set("z span",1*um); +set("material", "SiO2 (Glass) - Palik"); # material name has to be exact +set("override mesh order from material database", true); +set("mesh order", 1); # material name has to be exact + +## Read Data from ASCII file ## +cd(filedirectory(currentscriptname)); +M=readdata("legend.txt"); +Mselect=M(5,1)*1e-6; + +################Analysis Group####################### + ## Figure of Merit --- Focus Beam ## +############################################## +addanalysisgroup; +set("name","FoM_beam"); +set("x", 0); +set("y", 0); +set("z", 0); + +addanalysisresult("FoM"); +addanalysisprop("Mselect",2,M(5,1)*um); +########### Scripted part of the Analysis Group ########### + +set('analysis script',' + +# Define far field position vector + +x=linspace(-40-06,-5e-06,800); +y=linspace(Mselect-5e-06,Mselect+5e-06,800); + +# Do far field projection +E_H_far=farfieldexact2d("nearfield_profile",x,y,{"field":"E and H"}); +E_far = E_H_far.E; +H_far = E_H_far.H; + + +Ex=E_far(:,:,:,:,1); +Ey=E_far(:,:,:,:,2); +Ez=E_far(:,:,:,:,3); + +Hx=H_far(:,:,:,:,1); +Hy=H_far(:,:,:,:,2); +Hz=H_far(:,:,:,:,3); + +E2_far=(pinch(abs(Ex)))^2+(pinch(abs(Ey)))^2+(pinch(abs(Ez)))^2; +H2_far=(pinch(abs(Hx)))^2+(pinch(abs(Hy)))^2+(pinch(abs(Hz)))^2; + +#FoM=integrate(E2_far,1:2,x,y); + +ind2 = find(y,Mselect); +A=pinch(E2_far,2,ind2); +FoM=max(A); + +'); + +adddftmonitor; +set("name","nearfield_profile"); +set("monitor type",6); # 2D y-normal +set("x",26*um); +set("x span",65*um); +set("y",0.7*um); +set("z",0); +addtogroup("FoM_beam"); + +########################## Save model ######################## + +save("Testsim"); + +########################## add Optimization sweep ######################## + +addsweep(1); +setsweep("optimization", "name", "Intensity"); +setsweep("Intensity", "Type", "Maximize"); +setsweep("Intensity", "algorithm", "Particle Swarm"); +setsweep("Intensity", "maximum generations", 5); +setsweep("Intensity", "generation size", 8); +setsweep("Intensity", "tolerance", 0); + +# define the grating pitch size +para1 = struct; +para1.Parameter = "::model::GC_2D::pitch_uniform"; +para1.Type = "Length"; +para1.Min = 0.7e-6; +para1.Max = 0.9e-6; +para1.Units = "microns"; +addsweepparameter("Intensity", para1); + +# define the grating etch depth +para2 = struct; +para2.Parameter = "::model::GC_2D::etch depth"; +para2.Type = "Length"; +para2.Min = 0.1e-6; +para2.Max = 0.3e-6; +para2.Units = "microns"; +addsweepparameter("Intensity", para2); + +para3 = struct; +para3.Parameter = "::model::GC_2D::dc_min"; +para3.Type = "Number"; +para3.Min = 0.1; +para3.Max = 0.6; +para3.Units = "microns"; +addsweepparameter("Intensity", para3); + +# define figure of merit +result_1 = struct; +result_1.Name = "new_result"; +result_1.Result = "::model::FoM_beam::FoM"; +result_1.Optimize = true; + +# add the figure of merits R & T to the optimization +addsweepresult("Intensity", result_1); +save("Testsim"); +## run optimization +runsweep("Intensity"); + diff --git a/maxwell2d-lumerical/GC_farfield.lsf b/maxwell2d-lumerical/GC_farfield.lsf new file mode 100644 index 00000000..d0a21c8a --- /dev/null +++ b/maxwell2d-lumerical/GC_farfield.lsf @@ -0,0 +1,104 @@ +## This script calculates the E and H component of the grating coupler +## and calculates the properties of the focused beam. + +clear; +# Define far field position vector + +num=500; # number of points +x = linspace(-80e-6,50e-6,num); +y = linspace(1e-6,400e-6,2*num); + +# Do far field projection + +E_H_far=farfieldexact2d("near_field",x,y,{"field":"E and H"}); +E_far = E_H_far.E; +H_far = E_H_far.H; + +# Extract electric & magnetic components from the E_H_far dataset + +Ex=E_far(:,:,:,:,1); +Ey=E_far(:,:,:,:,2); +Ez=E_far(:,:,:,:,3); + +Hx=H_far(:,:,:,:,1); +Hy=H_far(:,:,:,:,2); +Hz=H_far(:,:,:,:,3); + +E2_far=(pinch(abs(Ex)))^2+(pinch(abs(Ey)))^2+(pinch(abs(Ez)))^2; +H2_far=(pinch(abs(Hx)))^2+(pinch(abs(Hy)))^2+(pinch(abs(Hz)))^2; +image(x*1e6,y*1e6, E2_far,"x-coordinate (um)","y-coordinate (um)","|E|^2"); + + +cd(filedirectory(currentscriptname)); +## Read Data from ASCII file ## + M=readdata("legend.txt"); + Mselect=M(5,1)*1e-6; + +# farfield along x axis +E3_z = farfieldexact2d('near_field',x,Mselect); +E3_z = pinch(sum(abs(E3_z)^2,3)); +plot(x*1e6,E3_z,'x (um)','|E|^2 (V^2/m^2)','Line projection at y='+num2str(floor(Mselect*1e6),"%2d")+'um','linewidth=2'); +legend(""); + +# find FWHM along x axis +ind1 = find(E3_z,max(E3_z)); +xmax = x(ind1); +indR1 = find(E3_z,E3_z(ind1)/2); +if ( ind1indR2 ) { + indR2= ind2 + (ind2-indR2); + } +indL2 = abs(ind2-(abs(indR2-ind2))); +FWHM_Y=abs(y(indR2)-y(indL2)); + +##Calculate deviation between actual and target coordinates of the trap ## +#Get the length of the properties +nx = length(x); +ny = length(y); +#Get the intensity values +e2 = E2_far; +#Get the maximum intensity value +indexE2_far = find(e2, max(e2)); +#Create the grids that will be used to extract the actual position values +X = meshgridx(x,y); +Y = meshgridy(x,y); +?Mselect; +Mactual=Y(indexE2_far); +RelVal=(abs(Mselect-Mactual)/Mactual); + +# Print geometric properties in the code editor +select("Substrate"); +Material = get("material"); +select("BOx"); +BOX = get("material"); +select("GC_2D"); +GC_period = get("pitch_uniform"); +GC_etch = get("etch depth"); +GC_DCmin = get("dc_min"); + + + + + + + + + + + + diff --git a/maxwell2d-lumerical/IonTrapM2D_lum_2025.py b/maxwell2d-lumerical/IonTrapM2D_lum_2025.py new file mode 100644 index 00000000..913ffb10 --- /dev/null +++ b/maxwell2d-lumerical/IonTrapM2D_lum_2025.py @@ -0,0 +1,309 @@ +# Copyright (C) 2024 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# # Maxwell2D - Simplified IonTrap Modelling +# +# Description: +# +# First step of a multi-tool workflow: Maxwell 2D model to identify electric field node in Ion Trap +# 1. Set up the Maxwell 2D Parametric Model +# 2. Identify the Electric Field Node Point for Each Design Point +# 3. Export the Node Coordinates for the subsequent Lumerical Step +# 4. Launch the Lumerical Scripts +# +# Keywords: **Ion Trap**, **Electrostatic** + +# ## Perform imports and define constants +# +# Perform required imports. + +import os +import sys +import tempfile +import time + +sys.path.append("C:\\Program Files\\Lumerical\\v251\\api\\python\\") +sys.path.append(os.path.dirname(__file__)) # Current directory +my_path = r"D:/2025/17_IonTrap/PyAnsys_GC_test/" # Directory where Lumerical Scripts are stored +my_node_filename = "NodePositionTable.tab" +my_node_filename_lum = "legend.txt" + +from PIL import Image +import ansys.aedt.core +import lumapi + +# Define constants. + +AEDT_VERSION = "2025.1" +NUM_CORES = 4 +NG_MODE = False # Open AEDT UI when it is launched. + +# ## Create temporary directory +# + +temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") + +# ## Launch AEDT and application +# + +project_name = os.path.join(temp_folder.name, "IonTrapMaxwell.aedt") +m2d = ansys.aedt.core.Maxwell2d( + project=project_name, + design="01_IonTrap_3binary2D", + solution_type="Electrostatic", + version=AEDT_VERSION, + non_graphical=NG_MODE, + new_desktop=True, +) +m2d.modeler.model_units = "um" + +# ## Preprocess +# +# Initialize dictionaries for design variables + +geom_params = { + "div": str(73 / 41), + "w_rf": "41um", + "w_dc": "41um*div", + "w_cut": "4um", + "metal_thickness": "1um", + "offset_glass": "50um", + "glass_thickness": "10um", + "x_dummy": "2um", + "y_dummy": "300um", +} + +# Define variables from dictionaries + +for k, v in geom_params.items(): + m2d[k] = v + +# Create Design Geometry + +dc = m2d.modeler.create_rectangle( + origin=["-w_dc/2", "-metal_thickness/2", "0"], + sizes=["w_dc", "metal_thickness", 0], + name="DC", + material="aluminum", +) +# dc.color = (0, 0, 255) # rgb + +gnd = m2d.modeler.create_rectangle( + origin=["-(w_dc/2+w_cut+w_rf+offset_glass)", "-(metal_thickness/2+glass_thickness)", "0"], + sizes=["2*(w_dc/2+w_cut+w_rf+offset_glass)", "-metal_thickness", 0], + name="gnd", + material="aluminum", +) + +rf = m2d.modeler.create_rectangle( + origin=["-(w_dc/2+w_cut+w_rf)", "-metal_thickness/2", "0"], + sizes=["w_rf", "metal_thickness", 0], + name="RF", + material="aluminum", +) + +sub_glass = m2d.modeler.create_rectangle( + origin=["-(w_dc/2+w_cut+w_rf+offset_glass)", "-metal_thickness/2", "0"], + sizes=["2*(w_dc/2+w_cut+w_rf+offset_glass)", "-glass_thickness", 0], + name="RF", + material="glass", +) + +ins = m2d.modeler.create_rectangle( + origin=["-(w_dc/2+w_cut)", "-metal_thickness/2", "0"], + sizes=["w_cut", "metal_thickness", 0], + name="ins", + material="vacuum", +) + +# Create dummy objects for mesh, center_line for Post Processing and Region + +dummy = m2d.modeler.create_rectangle( + origin=["0", "metal_thickness/2", "0"], + sizes=["-x_dummy", "y_dummy", 0], + name="dummy", + material="vacuum", +) + +region = m2d.modeler.create_region( + pad_value=[100, 0, 100, 0], pad_type="Absolute Offset", name="Region" +) +center_line = m2d.modeler.create_polyline( + points=[["0", "metal_thickness/2", "0"], ["0", "metal_thickness/2+300um", "0"]], + name="center_line", +) + +# Define Excitations + +m2d.assign_voltage(assignment=gnd.id, amplitude=0, name="ground") +m2d.assign_voltage(assignment=dc.id, amplitude=0, name="V_dc") +m2d.assign_voltage(assignment=rf.id, amplitude=1, name="V_rf") + +# Define Mesh Settings +# for good quality results, please uncomment the following mesh operations lines +# m2d.mesh.assign_length_mesh( +# assignment=center_line.id, +# maximum_length=1e-7, +# maximum_elements=None, +# name="center_line_0.1um", +# ) +# m2d.mesh.assign_length_mesh( +# assignment=dummy.name, maximum_length=2e-6, maximum_elements=1e6, name="dummy_2um" +# ) +# m2d.mesh.assign_length_mesh( +# assignment=ins.id, +# maximum_length=8e-7, +# inside_selection=False, +# maximum_elements=1e6, +# name="ins_0.8um", +# ) +# m2d.mesh.assign_length_mesh( +# assignment=[dc.id, rf.id], +# maximum_length=5e-6, +# inside_selection=False, +# maximum_elements=1e6, +# name="dc_5um", +# ) +# m2d.mesh.assign_length_mesh( +# assignment=gnd.id, +# maximum_length=1e-5, +# inside_selection=False, +# maximum_elements=1e6, +# name="gnd_10um", +# ) + +# Duplicate structures and assignments to complete the model + +m2d.modeler.duplicate_and_mirror( + assignment=[rf.id, dummy.id, ins.id], + origin=["0", "0", "0"], + vector=["-1", "0", "0"], + duplicate_assignment=True, +) + +# Create, validate, and analyze setup + +setup_name = "MySetupAuto" +setup = m2d.create_setup(name=setup_name) +setup.props["PercentError"] = 0.1 +setup.update() +m2d.validate_simple() +m2d.analyze_setup(name=setup_name, use_auto_settings=False, cores=NUM_CORES) + +# Create parametric sweep + +# keeping w_rf constant, we recompute the w_dc values from the desired ratios w_rf/w_dc + +div_sweep_start = 1.4 +div_sweep_stop = 2 +sweep = m2d.parametrics.add( + variable="div", + start_point=div_sweep_start, + end_point=div_sweep_stop, + step=0.2, + variation_type="LinearStep", + name="w_dc_sweep", +) +add_points = [1, 1.3] +[ + sweep.add_variation(sweep_variable="div", start_point=p, variation_type="SingleValue") + for p in add_points +] +sweep["SaveFields"] = True +sweep.analyze(cores=NUM_CORES) + +# + +# ## Postprocess +# +# Create the Ey expression in the PyAEDT Advanced Field Calculator +# Due to the symmetric nature of this specific geometry, the electric field +# node will be located along the center line. The electric field node is the +# point where the Ey will be zero and can be found directly by Maxwell post +# processing features + +e_line = m2d.post.fields_calculator.add_expression(calculation="e_line", assignment=None) +my_plots = m2d.post.fields_calculator.expression_plot( + calculation="e_line", assignment="center_line", names=[e_line] +) +my_plots[1].edit_x_axis_scaling(min_scale="20um", max_scale="280um") +my_plots[1].update_trace_in_report( + my_plots[1].get_solution_data().expressions, variations={"div": ["All"]}, context="center_line" +) +my_plots[1].add_cartesian_y_marker("0") +my_plots[1].add_trace_characteristics( + "XAtYVal", arguments=["0"], solution_range=["Full", "20", "280"] +) +my_plots[1].export_table_to_file(my_plots[1].plot_name, my_path + "//" + my_node_filename, "Legend") + +# ## Release AEDT + +m2d.save_project() +m2d.release_desktop() + +# ## Edit the outputted file to be read in by Lumerical +new_line = [] +with open(my_path + my_node_filename, "r", encoding="utf-8") as f: + lines = f.readlines() +new_line.append(lines[0]) +for line in lines[1:]: + new_line.append(line.split("\t")[0]) + new_line.append("\n" + line.split("\t")[1].lstrip()) +with open(my_path + my_node_filename_lum, "w", encoding="utf-8") as f: + for line in new_line: + f.write(line) + +# ## Start the Lumerical Process + +GC0 = lumapi.FDTD(my_path + "GC_Opt.lsf") # run the first script: Build geometry & Run optimization +Gc1 = lumapi.FDTD(my_path + "Readata.lsf") +print( + "Optimize for the Nodal point located", + str(Gc1.getv("T5")), + "um, above the linearly apodized grating coupler", +) +Gc2 = lumapi.FDTD(my_path + "Testsim_Intensity_best_solution") # Run the optimized design +Gc2.save(my_path + "GC_farfields_calc") +Gc2.run() +Gc2.feval(my_path + "GC_farfield.lsf") # run the second script for calculating plots +print("Target focal distance of output laser beam, (um) :", str(Gc2.getv("Mselect") * 1000000)) +print( + "Actual focal distance for the optimised geometry, (um) :", str(Gc2.getv("Mactual") * 1000000) +) +print("Relative error:", str(Gc2.getv("RelVal") * 100), "(%)") +print("FWHM of vertical direction at focus, (um) ", str(Gc2.getv("FWHM_X") * 1000000)) +print("FWHM of horizontal direction at focus, (um) ", str(Gc2.getv("FWHM_Y") * 1000000)) +print("Substrate material :", str(Gc2.getv("Material"))) + +print("Waveguide etch depth, (nm) ", str(Gc2.getv("GC_etch") * 1000000000)) +print("Grating period (P), (nm) ", str(Gc2.getv("GC_period") * 1000000000)) +print("Grating minimum duty cycle:", str(Gc2.getv("GC_DCmin"))) + +Grating_Schema = Image.open(my_path + "img_001.jpg") + +# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. +time.sleep(3) + +# ## Clean up +# + +temp_folder.cleanup() diff --git a/maxwell2d-lumerical/README.rst b/maxwell2d-lumerical/README.rst new file mode 100644 index 00000000..0dc866b5 --- /dev/null +++ b/maxwell2d-lumerical/README.rst @@ -0,0 +1,4 @@ +Maxwell2D and Lumerical +======================= + +Below is an example of a geometry and meshing workflow PyAEDT and Lumerical APIS diff --git a/maxwell2d-lumerical/Readata.lsf b/maxwell2d-lumerical/Readata.lsf new file mode 100644 index 00000000..ecc62f52 --- /dev/null +++ b/maxwell2d-lumerical/Readata.lsf @@ -0,0 +1,6 @@ +cd(filedirectory(currentscriptname)); +## Read Data from ASCII file ## + M=readdata("legend.txt"); + + + T1=M(1,1); T2=M(2,1); T3=M(3,1); T4=M(4,1); T5=M(5,1); T6=M(6,1); T7=M(7,1); \ No newline at end of file diff --git a/maxwell2d-lumerical/img_001.jpg b/maxwell2d-lumerical/img_001.jpg new file mode 100644 index 00000000..a243ad07 Binary files /dev/null and b/maxwell2d-lumerical/img_001.jpg differ diff --git a/maxwell2d-lumerical/requirements_25.1.txt b/maxwell2d-lumerical/requirements_25.1.txt new file mode 100644 index 00000000..d4012b38 --- /dev/null +++ b/maxwell2d-lumerical/requirements_25.1.txt @@ -0,0 +1,2 @@ +.pyaedt [all]==0.17.3 +.PIL \ No newline at end of file