├── .gitignore ├── AnalysisRoutines ├── AngularPattern │ └── single_angular_pattern.py ├── Field │ ├── Comparison │ │ ├── monoch_field_periods.py │ │ ├── monoch_field_pmlwlen.py │ │ ├── monoch_field_res.py │ │ ├── monoch_field_res_wleninmed.py │ │ ├── np_monoch_field_empty.py │ │ ├── np_monoch_field_normalization.py │ │ ├── np_monoch_field_periods.py │ │ ├── np_monoch_field_wlen.py │ │ ├── pulse_field_all_bandwidth.py │ │ └── pulse_field_wide_bandwidth.py │ ├── Vacuum │ │ ├── au_mie_field_vacuum_theory_comparison.py │ │ ├── monoch_normalization_plot.py │ │ └── np_monoch_scheme_plots.py │ ├── Water │ │ └── au_mie_field_allwater_theory_comparison.py │ ├── monoch_field_generic_comparison.py │ ├── monoch_field_resolution_wlen_theory.py │ ├── np_monoch_field_generic_comparison.py │ └── pulse_field_generic_comparison.py ├── MaterialsTheory │ ├── epsilon_drude_lorentz_fit.py │ ├── epsilon_exp_meep_data.py │ ├── np_materials_field_theory.py │ └── np_mie_temp_power_theory.py └── Scattering │ ├── Comparison │ ├── au_mie_sphere_courant.py │ ├── au_mie_sphere_diameters.py │ ├── au_mie_sphere_full_comparison.py │ ├── au_mie_sphere_near2far.py │ ├── au_mie_sphere_ram.py │ ├── au_mie_sphere_ram_np.py │ ├── au_mie_sphere_resolution.py │ └── au_mie_sphere_split_chunks.py │ ├── Paper │ ├── au_mie_sphere_paper_diameters_separated.py │ ├── au_mie_sphere_paper_diameters_together.py │ ├── au_mie_sphere_paper_maxres.py │ ├── au_mie_sphere_paper_stfactor.py │ ├── au_mie_sphere_paper_tfcell.py │ └── au_mie_sphere_paper_wlen.py │ ├── Vacuum │ ├── au_mie_sphere_scheme_plots.py │ ├── au_mie_sphere_vacuum_diameters.py │ ├── au_mie_sphere_vacuum_maxres.py │ └── au_mie_sphere_vacuum_parallel_NP.py │ ├── Water │ ├── au_mie_sphere_allwater_cell_time.py │ ├── au_mie_sphere_allwater_courant.py │ ├── au_mie_sphere_allwater_diameters.py │ ├── au_mie_sphere_allwater_empty_r.py │ ├── au_mie_sphere_allwater_flux_r.py │ ├── au_mie_sphere_allwater_flux_r_more_empty.py │ ├── au_mie_sphere_allwater_flux_time.py │ ├── au_mie_sphere_allwater_long_res.py │ ├── au_mie_sphere_allwater_maxres.py │ ├── au_mie_sphere_allwater_pml_wlen.py │ ├── au_mie_sphere_allwater_second_time.py │ ├── au_mie_sphere_allwater_wlen_range_max.py │ └── au_mie_sphere_allwater_wlen_range_min.py │ ├── au_mie_sim_size_theory.py │ └── au_mie_sphere_generic_comparison.py ├── MeepRoutines ├── MoreRoutines │ ├── dipole_angular_pattern.py │ └── np_ellipsoid_scattering.py ├── monoch_field.py ├── np_mie_scattering.py ├── np_monoch_field.py └── pulse_field.py ├── PlotRoutines ├── 3d_simulation_plot.py ├── monoch_field_plot.py ├── np_monoch_field_plot.py ├── np_planewave_cell_plot.py ├── np_pulse_scattering_plot.py └── pulse_field_plot.py ├── README.md ├── ShellRoutines ├── au_mie_test_scattering.sh ├── monoch_field_test.sh ├── np_monoch_field_test.sh └── pulse_field_test.sh ├── SupportFiles ├── DataManagement │ ├── chunks_data_directory_patch.py │ ├── epsilon_theory_riinfo.py │ ├── flux_data_directory_patch.py │ └── norm_data_directory_patch.py ├── Installation │ ├── Test │ │ ├── simple.py │ │ └── simple_serial.py │ ├── conda-pmp-vale-success.txt │ ├── conda-pmp-vale.txt │ ├── conda-pmp.txt │ ├── install_parallel_meep.sh │ ├── mpitest │ ├── mpitest.c │ ├── spack_install_meep.py │ ├── test_mpi │ ├── test_mpi.c │ └── update_parallel_meep.sh ├── MaterialsData │ ├── Ag_JC_ComplexN_RIinfo.txt │ ├── Ag_R_ComplexN_RIinfo.txt │ ├── Au_JC_ComplexN_RIinfo.txt │ └── Au_R_ComplexN_RIinfo.txt └── Pictures │ ├── PyMeepPlasmonics.png │ ├── PyMeepPlasmonicsModules.png │ └── PyMeepPlasmonicsRoutines.png ├── v_analysis.py ├── v_plot.py ├── v_save.py ├── v_utilities.py ├── vmp_analysis.py ├── vmp_materials.py ├── vmp_theory.py └── vmp_utilities.py /.gitignore: -------------------------------------------------------------------------------- 1 | # System directories' database 2 | SystemDirectories.txt 3 | 4 | # Results' Folders 5 | *Results/ 6 | 7 | # Compressed files 8 | *.zip 9 | 10 | # Byte-compiled / optimized / DLL files 11 | __pycache__/ 12 | *.py[cod] 13 | *$py.class 14 | 15 | # C extensions 16 | *.so 17 | 18 | # Distribution / packaging 19 | .Python 20 | build/ 21 | develop-eggs/ 22 | dist/ 23 | downloads/ 24 | eggs/ 25 | .eggs/ 26 | lib/ 27 | lib64/ 28 | parts/ 29 | sdist/ 30 | var/ 31 | wheels/ 32 | pip-wheel-metadata/ 33 | share/python-wheels/ 34 | *.egg-info/ 35 | .installed.cfg 36 | *.egg 37 | MANIFEST 38 | 39 | # PyInstaller 40 | # Usually these files are written by a python script from a template 41 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 42 | *.manifest 43 | *.spec 44 | 45 | # Installer logs 46 | pip-log.txt 47 | pip-delete-this-directory.txt 48 | 49 | # Unit test / coverage reports 50 | htmlcov/ 51 | .tox/ 52 | .nox/ 53 | .coverage 54 | .coverage.* 55 | .cache 56 | nosetests.xml 57 | coverage.xml 58 | *.cover 59 | *.py,cover 60 | .hypothesis/ 61 | .pytest_cache/ 62 | 63 | # Translations 64 | *.mo 65 | *.pot 66 | 67 | # Django stuff: 68 | *.log 69 | local_settings.py 70 | db.sqlite3 71 | db.sqlite3-journal 72 | 73 | # Flask stuff: 74 | instance/ 75 | .webassets-cache 76 | 77 | # Scrapy stuff: 78 | .scrapy 79 | 80 | # Sphinx documentation 81 | docs/_build/ 82 | 83 | # PyBuilder 84 | target/ 85 | 86 | # Jupyter Notebook 87 | .ipynb_checkpoints 88 | 89 | # IPython 90 | profile_default/ 91 | ipython_config.py 92 | 93 | # pyenv 94 | .python-version 95 | 96 | # pipenv 97 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 98 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 99 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 100 | # install all needed dependencies. 101 | #Pipfile.lock 102 | 103 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 104 | __pypackages__/ 105 | 106 | # Celery stuff 107 | celerybeat-schedule 108 | celerybeat.pid 109 | 110 | # SageMath parsed files 111 | *.sage.py 112 | 113 | # Environments 114 | .env 115 | .venv 116 | env/ 117 | venv/ 118 | ENV/ 119 | env.bak/ 120 | venv.bak/ 121 | 122 | # Spyder project settings 123 | .spyderproject 124 | .spyproject 125 | 126 | # Rope project settings 127 | .ropeproject 128 | 129 | # mkdocs documentation 130 | /site 131 | 132 | # mypy 133 | .mypy_cache/ 134 | .dmypy.json 135 | dmypy.json 136 | 137 | # Pyre type checker 138 | .pyre/ 139 | -------------------------------------------------------------------------------- /AnalysisRoutines/Field/Comparison/monoch_field_periods.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Mon Oct 19 14:45:00 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | # Monochromatic planewave field 10 | 11 | from socket import gethostname 12 | if "Nano" in gethostname(): 13 | syshome = "/home/nanofisica/Documents/Vale/PyMeepPlasmonics" 14 | elif "vall" in gethostname(): 15 | syshome = "/home/vall/Documents/Thesis/PyMeepPlasmonics" 16 | else: 17 | raise ValueError("Your PC must be registered at the top of this code") 18 | 19 | import sys 20 | sys.path.append(syshome) 21 | 22 | import imageio as mim 23 | import h5py as h5 24 | import numpy as np 25 | import matplotlib.pyplot as plt 26 | import matplotlib.pylab as plab 27 | from matplotlib.ticker import AutoMinorLocator 28 | import os 29 | import vmp_materials as vml 30 | import vmp_utilities as vmu 31 | import vmp_analysis as vma 32 | import v_plot as vp 33 | import vmp_theory as vmt 34 | import v_save as vs 35 | import v_utilities as vu 36 | 37 | english = False 38 | trs = vu.BilingualManager(english=english) 39 | 40 | #%% PARAMETERS 41 | 42 | # Saving directories 43 | folder = ["Field/Sources/MonochPlanewave/TestPeriods/Vacuum", 44 | "Field/Sources/MonochPlanewave/TestPeriods/Vacuum", 45 | "Field/Sources/MonochPlanewave/TestPeriods/Water", 46 | "Field/Sources/MonochPlanewave/TestPeriods/Water"] 47 | home = vs.get_home() 48 | 49 | # Parameter for the test 50 | test_param_string = "source_center" 51 | test_param_in_series = False 52 | test_param_in_params = True 53 | test_param_position = 0 54 | test_param_label = trs.choose("Wavelength", "Longitud de onda") 55 | 56 | # Sorting and labelling data series 57 | sorting_function = [lambda l : l]*4 58 | series_label = [lambda s : trs.choose(r"Vacuum Centered", r"Vacío centrado"), 59 | lambda s : trs.choose(r"Vacuum Not Centered", r"Vacío no centrado"), 60 | lambda s : trs.choose(r"Water Centered", r"Agua centrado"), 61 | lambda s : trs.choose(r"Water Centered", r"Agua no centrado")] 62 | series_must = ["True", "False"]*2 # leave "" per default 63 | series_mustnt = [""]*4 # leave "" per default 64 | 65 | # Scattering plot options 66 | plot_title_base = trs.choose('Dimnesionless monochromatic wave', 67 | "Onda monocromática adimensional") 68 | series_legend = trs.choose(["Vacuum Centered", "Vacuum Not Centered", 69 | "Water Centered", "Water Not Centered"], 70 | ["Vacío centrado", "Vacío no centrado", 71 | "Agua centrado", "Agua no centrado"]) 72 | series_colors = [plab.cm.Reds, plab.cm.Reds, 73 | plab.cm.Blues, plab.cm.Blues] 74 | series_linestyles = ["solid", "dashed"]*2 75 | plot_make_big = False 76 | plot_file = lambda n : os.path.join(home, "DataAnalysis/Field/Sources/MonochPlanewave/TestPeriods/TestPeriods" + n) 77 | 78 | #%% LOAD DATA 79 | 80 | def file_definer(path): 81 | return lambda s, n : os.path.join(path, s, n) 82 | 83 | path = [os.path.join(home, fold) for fold in folder] 84 | file = [file_definer(pa) for pa in path] 85 | 86 | series = [] 87 | files_line = [] 88 | files_plane = [] 89 | results_line = [] 90 | results_plane = [] 91 | t_line = [] 92 | x_line = [] 93 | t_plane = [] 94 | y_plane = [] 95 | z_plane = [] 96 | params = [] 97 | 98 | # for f, sf, sm, smn in zip(folder, sorting_function, series_must, series_mustnt): 99 | for i in range(len(folder)): 100 | 101 | # path.append( os.path.join(home, f) ) 102 | # file.append( lambda f, s : os.path.join(path[-1], f, s) ) 103 | 104 | series.append( os.listdir(path[i]) ) 105 | series[-1] = vu.filter_by_string_must(series[-1], series_must[i]) 106 | if series_mustnt[i]!="": 107 | series[-1] = vu.filter_by_string_must(series[-1], series_mustnt[i], False) 108 | series[-1] = sorting_function[i](series[-1]) 109 | 110 | files_line.append( [] ) 111 | files_plane.append( [] ) 112 | for s in series[-1]: 113 | files_line[-1].append( h5.File(file[i](s, "Field-Lines.h5"), "r") ) 114 | files_plane[-1].append( h5.File(file[i](s, "Field-Planes.h5"), "r") ) 115 | del s 116 | 117 | results_line.append( [fi["Ez"] for fi in files_line[-1]] ) 118 | results_plane.append( [fi["Ez"] for fi in files_plane[-1]] ) 119 | params.append( [dict(fi["Ez"].attrs) for fi in files_line[-1]] ) 120 | 121 | t_line.append( [np.asarray(fi["T"]) for fi in files_line[-1]] ) 122 | x_line.append( [np.asarray(fi["X"]) for fi in files_line[-1]] ) 123 | 124 | t_plane.append( [np.asarray(fi["T"]) for fi in files_plane[-1]] ) 125 | y_plane.append( [np.asarray(fi["Y"]) for fi in files_plane[-1]] ) 126 | z_plane.append( [np.asarray(fi["Z"]) for fi in files_plane[-1]] ) 127 | 128 | for s, p in zip(series[-1], params[-1]): 129 | try: 130 | f = h5.File(file[-1](s, "Resources.h5")) 131 | p["used_ram"] = np.array(f["RAM"]) 132 | p["used_swap"] = np.array(f["SWAP"]) 133 | p["elapsed_time"] = np.array(f["ElapsedTime"]) 134 | except FileNotFoundError: 135 | f = h5.File(file[-1](s, "RAM.h5")) 136 | p["used_ram"] = np.array(f["RAM"]) 137 | p["used_swap"] = np.array(f["SWAP"]) 138 | p["elapsed_time"] = p["elapsed"] 139 | del p["elapsed"] 140 | # del s, p 141 | del i 142 | 143 | from_um_factor = [] 144 | resolution = [] 145 | resolution_wlen = [] 146 | units = [] 147 | index = [] 148 | wlen = [] 149 | cell_width = [] 150 | pml_width = [] 151 | source_center = [] 152 | period_plane = [] 153 | period_line = [] 154 | until_time = [] 155 | time_period_factor = [] 156 | norm_amplitude = [] 157 | norm_period = [] 158 | sysname = [] 159 | for p in params: 160 | from_um_factor.append( [pi["from_um_factor"] for pi in p] ) 161 | resolution.append( [pi["resolution"] for pi in p] ) 162 | resolution_wlen.append( [pi["resolution_wlen"] for pi in p] ) 163 | units.append( [pi["units"] for pi in p] ) 164 | index.append( [pi["submerged_index"] for pi in p] ) 165 | wlen.append( [pi["wlen"] for pi in p] ) 166 | cell_width.append( [pi["cell_width"] for pi in p] ) 167 | pml_width.append( [pi["pml_width"] for pi in p] ) 168 | source_center.append( [pi["source_center"] for pi in p] ) 169 | period_plane.append( [pi["period_plane"] for pi in p] ) 170 | period_line.append( [pi["period_line"] for pi in p] ) 171 | until_time.append( [pi["until_time"] for pi in p] ) 172 | time_period_factor.append( [pi["time_period_factor"] for pi in p] ) 173 | try: 174 | norm_amplitude.append( [pi["norm_amplitude"] for pi in p] ) 175 | norm_period.append( [pi["norm_period"] for pi in p] ) 176 | requires_normalization = False 177 | except: 178 | requires_normalization = True 179 | sysname.append( [pi["sysname"] for pi in p] ) 180 | del p 181 | 182 | if test_param_in_params: 183 | test_param = [[p[test_param_string] for p in par] for par in params] 184 | else: 185 | test_param = [[vu.find_numbers(s)[test_param_position] for s in ser] for ser in series] 186 | 187 | use_units = np.array(units).any() 188 | 189 | minor_division = [[fum * 1e3 / res for fum, res in zip(frum, reso)] for frum, reso in zip(from_um_factor, resolution)] 190 | try: 191 | width_points = [[int(p["cell_width"] * p["resolution"]) for p in par] for par in params] 192 | effective_width_points = [[(p["cell_width"] - 2 * params["pml_width"]) * p["resolution"] for p in par] for par in params] 193 | except: 194 | width_points = [[2*int((p["pml_width"] + p["empty_width"]) * p["resolution"]) for p in par] for par in params] 195 | effective_width_points = [[2*int(p["empty_width"] * p["resolution"]) for p in par] for par in params] 196 | grid_points = [[wp**3 for wp in wpoints] for wpoints in width_points] 197 | memory_B = [[2 * 12 * gp * 32 for p, gp in zip(par, gpoints)] for par, gpoints in zip(params, grid_points)] # in bytes 198 | 199 | elapsed_time = [[p["elapsed_time"] for p in par] for par in params] 200 | total_elapsed_time = [[sum(p["elapsed_time"]) for p in par] for par in params] 201 | 202 | used_ram = [[np.array(p["used_ram"])/(1024)**2 for p in par] for par in params] 203 | total_used_ram = [[np.sum(used_ram[i][j], axis=1) for j in range(len(series[i]))] for i in range(len(series))] 204 | used_swap = [[p["used_swap"] for p in par] for par in params] 205 | 206 | #%% POSITION RECONSTRUCTION 207 | 208 | t_line_index = [[vma.def_index_function(t_line[i][j]) for j in range(len(series[i]))] for i in range(len(series))] 209 | x_line_index = [[vma.def_index_function(x_line[i][j]) for j in range(len(series[i]))] for i in range(len(series))] 210 | 211 | t_plane_index = [[vma.def_index_function(t_plane[i][j]) for j in range(len(series[i]))] for i in range(len(series))] 212 | y_plane_index = [[vma.def_index_function(y_plane[i][j]) for j in range(len(series[i]))] for i in range(len(series))] 213 | z_plane_index = [[vma.def_index_function(z_plane[i][j]) for j in range(len(series[i]))] for i in range(len(series))] 214 | 215 | x_line_cropped = [[x_line[i][j][:x_line_index[i][j](cell_width[i][j]/2 - pml_width[i][j])+1] for j in range(len(series[i]))] for i in range(len(series))] 216 | x_line_cropped = [[x_line_cropped[i][j][x_line_index[i][j](-cell_width[i][j]/2 + pml_width[i][j]):] for j in range(len(series[i]))] for i in range(len(series))] 217 | 218 | y_plane_cropped = [[y_plane[i][j][:y_plane_index[i][j](cell_width[i][j]/2 - pml_width[i][j])+1] for j in range(len(series[i]))] for i in range(len(series))] 219 | y_plane_cropped = [[y_plane_cropped[i][j][y_plane_index[i][j](-cell_width[i][j]/2 + pml_width[i][j]):] for j in range(len(series[i]))] for i in range(len(series))] 220 | 221 | z_plane_cropped = [[z_plane[i][j][:z_plane_index[i][j](cell_width[i][j]/2 - pml_width[i][j])+1] for j in range(len(series[i]))] for i in range(len(series))] 222 | z_plane_cropped = [[z_plane_cropped[i][j][z_plane_index[i][j](-cell_width[i][j]/2 + pml_width[i][j]):] for j in range(len(series[i]))] for i in range(len(series))] 223 | 224 | #%% DATA EXTRACTION 225 | 226 | source_results = [[vma.get_source_from_line(results_line[i][j], x_line_index[i][j], source_center[i][j]) for j in range(len(series[i]))] for i in range(len(series))] 227 | 228 | if not requires_normalization: 229 | 230 | period_results, amplitude_results = norm_period, norm_amplitude 231 | 232 | else: 233 | 234 | period_results = [[vma.get_period_from_source(source_results[i][j], t_line[i][j])[-1] for j in range(len(series[i]))] for i in range(len(series))] 235 | amplitude_results = [[vma.get_amplitude_from_source(source_results[i][j])[-1] for j in range(len(series[i]))] for i in range(len(series))] 236 | 237 | results_plane = [[np.asarray(results_plane[i][j]) / amplitude_results[i][j] for j in range(len(series[i]))] for i in range(len(series))] 238 | results_line = [[np.asarray(results_line[i][j]) / amplitude_results[i][j] for j in range(len(series[i]))] for i in range(len(series))] 239 | 240 | #%% SHOW SOURCE AND FOURIER USED FOR NORMALIZATION 241 | 242 | colors = [["r"], ["maroon"], ["b"], ["navy"]] 243 | # colors = [sc(np.linspace(0,1,len(s)+2))[2:] 244 | # for sc, s in zip(series_colors, series)] 245 | 246 | plt.figure() 247 | plt.suptitle(plot_title_base) 248 | 249 | lines = [] 250 | for i in range(len(series)): 251 | for j in range(len(series[i])): 252 | l, = plt.plot(t_line[i][j] / period_results[i][j], 253 | source_results[i][j], 254 | label=series_label[i](series[i][j]), 255 | color=colors[i][j]) 256 | lines.append(l) 257 | plt.xlabel(trs.choose("Time in multiples of period", "Tiempo en múltiplos del período")) 258 | plt.ylabel(trs.choose(r"Normalized Electric Field $E_z(y=z=0)$", 259 | r"Campo eléctrico normalizado $E_z(y=z=0)$")) 260 | plt.legend(ncol=2) 261 | 262 | plt.savefig(plot_file("Source.png")) 263 | 264 | fourier = [[np.abs(np.fft.rfft(source_results[i][j] / amplitude_results[i][j])) for j in range(len(series[i]))] for i in range(len(series))] 265 | fourier_freq = [[np.fft.rfftfreq(len(source_results[i][j]), d=period_line[i][j]) for j in range(len(series[i]))] for i in range(len(series))] 266 | if use_units: 267 | fourier_wlen = [[from_um_factor[i][j] * 1e3 / fourier_freq[i][j] for j in range(len(series[i]))] for i in range(len(series))] 268 | else: 269 | fourier_wlen = [[1 / fourier_freq[i][j] for j in range(len(series[i]))] for i in range(len(series))] 270 | 271 | plt.figure() 272 | plt.suptitle(plot_title_base) 273 | 274 | lines = [] 275 | for i in range(len(series)): 276 | for j in range(len(series[i])): 277 | plt.plot(fourier_wlen[i][j], fourier[i][j], 278 | label=series_label[i](series[i][j]), 279 | color=colors[i][j]) 280 | if use_units: 281 | plt.xlabel(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 282 | else: 283 | plt.xlabel(trs.choose("Wavelength [MPu]", "Longitud de onda [uMP]")) 284 | plt.ylabel(trs.choose(r"Electric Field Fourier $\mathcal{F}\;(E_z)$", 285 | r"Transformada del campo eléctrico $\mathcal{F}\;(E_z)$")) 286 | plt.legend(ncol=2) 287 | 288 | plt.savefig(plot_file("SourceFFT.png")) 289 | 290 | if use_units: plt.xlim([350, 850]) 291 | else: plt.xlim([0, 2]) 292 | 293 | plt.savefig(plot_file("SourceFFTZoom.png")) 294 | 295 | #%% 296 | 297 | peaks_index = [[vma.get_peaks_from_source(source_results[i][j]) for j in range(len(series[i]))] for i in range(len(series))] 298 | peaks_heights = [[source_results[i][j][peaks_index[i][j]] for j in range(len(series[i]))] for i in range(len(series))] 299 | peaks_times = [[t_line[i][j][peaks_index[i][j]] for j in range(len(series[i]))] for i in range(len(series))] 300 | 301 | peaks_percentual_variation = [[100 * ( max(peaks_heights[i][j]) - min(peaks_heights[i][j]) ) / min(peaks_heights[i][j]) for j in range(len(series[i]))] for i in range(len(series))] 302 | 303 | plt.figure() 304 | plt.suptitle(plot_title_base) 305 | 306 | lines = [] 307 | for i in range(len(series)): 308 | for j in range(len(series[i])): 309 | l, = plt.plot(t_line[i][j] / period_results[i][j], 310 | source_results[i][j], 311 | label=series_label[i](series[i][j]), 312 | color=colors[i][j]) 313 | l, = plt.plot(t_line[i][j][peaks_index[i][j]] / period_results[i][j], 314 | source_results[i][j][peaks_index[i][j]], "o", 315 | label=series_label[i](series[i][j]), 316 | color=colors[i][j]) 317 | lines.append(l) 318 | plt.xlabel(trs.choose("Time in multiples of period", "Tiempo en múltiplos del período")) 319 | plt.ylabel(trs.choose(r"Normalized Electric Field $E_z(y=z=0)$", 320 | r"Campo eléctrico normalizado $E_z(y=z=0)$")) 321 | plt.legend(ncol=2) 322 | 323 | -------------------------------------------------------------------------------- /AnalysisRoutines/Field/Vacuum/monoch_normalization_plot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Sun Oct 10 01:01:53 2021 5 | 6 | @author: vall 7 | """ 8 | 9 | import imageio as mim 10 | import matplotlib.pyplot as plt 11 | import matplotlib.gridspec as gridspec 12 | import numpy as np 13 | import os 14 | import vmp_utilities as vmu 15 | import vmp_analysis as vma 16 | import v_plot as vp 17 | import v_utilities as vu 18 | 19 | from scipy.signal import find_peaks 20 | from matplotlib import use as use_backend 21 | 22 | vp.set_style() 23 | 24 | #%% PARAMETERS 25 | 26 | series = "ResWlen10" # Para MonochNormalizationPlot 27 | folder = "Field/Sources/MonochPlanewave/TestRes/Not Centered/Vacuum" 28 | 29 | hfield = False 30 | 31 | make_plots = True 32 | make_gifs = True 33 | 34 | english = False 35 | maxnframes = 300 36 | 37 | #%% SETUP 38 | 39 | # Computation 40 | pm = vmu.ParallelManager() 41 | n_processes, n_cores, n_nodes = pm.specs 42 | parallel = pm.parallel 43 | 44 | # Saving directories 45 | sa = vmu.SavingAssistant(series, folder) 46 | 47 | trs = vu.BilingualManager(english=english) 48 | 49 | #%% GET READY TO LOAD DATA 50 | 51 | f = pm.hdf_file(sa.file("Field-Lines.h5"), "r+") 52 | results_line = f["Ez"] 53 | t_line = np.array(f["T"]) 54 | x_line = np.array(f["X"]) 55 | 56 | g = pm.hdf_file(sa.file("Field-Planes.h5"), "r+") 57 | results_plane = g["Ez"] 58 | t_plane = np.array(g["T"]) 59 | y_plane = np.array(g["Y"]) 60 | z_plane = np.array(g["Z"]) 61 | 62 | params = dict(f["Ez"].attrs) 63 | 64 | from_um_factor = params["from_um_factor"] 65 | wlen = params["wlen"] 66 | submerged_index = params["submerged_index"] 67 | 68 | cell_width = params["cell_width"] 69 | pml_width = params["pml_width"] 70 | source_center = params["source_center"] 71 | 72 | until_time = params["until_time"] 73 | period_line = params["period_line"] 74 | period_plane = params["period_plane"] 75 | # period = submerged_index * wlen 76 | 77 | units = params["units"] 78 | try: 79 | norm_amplitude, norm_period = params["norm_amplitude"], params["norm_period"] 80 | requires_normalization = False 81 | except: 82 | requires_normalization = True 83 | 84 | if units: 85 | plot_title_base = trs.choose('Monochromatic wave ', 86 | "Onda monocromática de ") + f' {wlen * from_um_factor * 1e3:.0f} nm' 87 | else: 88 | plot_title_base = trs.choose('Dimnesionless monochromatic wave', 89 | "Onda monocromática adimensional") 90 | 91 | #%% POSITION RECONSTRUCTION 92 | 93 | t_line_index = vma.def_index_function(t_line) 94 | x_line_index = vma.def_index_function(x_line) 95 | 96 | t_plane_index = vma.def_index_function(t_plane) 97 | y_plane_index = vma.def_index_function(y_plane) 98 | z_plane_index = vma.def_index_function(z_plane) 99 | 100 | x_line_cropped = x_line[:x_line_index(cell_width/2 - pml_width)+1] 101 | x_line_cropped = x_line_cropped[x_line_index(-cell_width/2 + pml_width):] 102 | 103 | y_plane_cropped = y_plane[:y_plane_index(cell_width/2 - pml_width)+1] 104 | y_plane_cropped = y_plane_cropped[y_plane_index(-cell_width/2 + pml_width):] 105 | 106 | z_plane_cropped = z_plane[:z_plane_index(cell_width/2 - pml_width)+1] 107 | z_plane_cropped = z_plane_cropped[z_plane_index(-cell_width/2 + pml_width):] 108 | 109 | #%% DATA EXTRACTION 110 | 111 | source_results = vma.get_source_from_line(results_line, x_line_index, source_center) 112 | 113 | if not requires_normalization: 114 | 115 | period_results, amplitude_results = norm_period, norm_amplitude 116 | 117 | else: 118 | 119 | period = vma.get_period_from_source(source_results, t_line)[-1] 120 | amplitude = vma.get_amplitude_from_source(source_results)[-1] 121 | 122 | results_plane = np.asarray(results_plane) / amplitude 123 | results_line = np.asarray(results_line) / amplitude 124 | 125 | results_cropped_line = vma.crop_field_xprofile(results_line, x_line_index, 126 | cell_width, pml_width) 127 | 128 | #%% PEAKS DETECTION 129 | 130 | source_field = source_results 131 | peaks_sep_sensitivity = 0.10 132 | periods_sensitivity = 0.03 133 | amplitude_sensitivity = 0.02 134 | last_stable_periods = 5 135 | 136 | peaks = vma.get_peaks_from_source(source_results, 137 | peaks_sep_sensitivity=peaks_sep_sensitivity, 138 | last_stable_periods=last_stable_periods) 139 | 140 | period_peaks, period = vma.get_period_from_source(source_field, t_line, 141 | peaks_sep_sensitivity=peaks_sep_sensitivity, 142 | periods_sensitivity=periods_sensitivity, 143 | last_stable_periods=last_stable_periods) 144 | 145 | amplitude_peaks, amplitude = vma.get_amplitude_from_source(source_field, 146 | peaks_sep_sensitivity=peaks_sep_sensitivity, 147 | amplitude_sensitivity=amplitude_sensitivity, 148 | last_stable_periods=last_stable_periods) 149 | 150 | #%% PLOT 151 | 152 | plot_for_display = True 153 | 154 | if plot_for_display: use_backend("Agg") 155 | 156 | fig = plt.figure() 157 | if plot_for_display: fig.dpi = 200 158 | 159 | plt.title(plot_title_base) 160 | plt.plot(t_line, source_results, label="Señal") 161 | plt.axhline(color="k", linewidth=0.5) 162 | 163 | plt.xlabel(trs.choose("Time [MPu]", "Tiempo [uMP]")) 164 | plt.ylabel(trs.choose(r"Electric Field $E_z(y=z=0)$ [a.u.]", 165 | r"Campo eléctrico $E_z(y=z=0)$ [u.a.]")) 166 | 167 | plt.plot(t_line[peaks], source_results[peaks], "ok", label=f"Picos detectados con {peaks_sep_sensitivity*100:.0f}%") 168 | 169 | plt.plot(t_line[period_peaks], source_results[period_peaks], "ok", 170 | label=f"Tomado para período con {periods_sensitivity*100:.0f}%", markersize=7, markeredgecolor="r") 171 | 172 | plt.plot(t_line[amplitude_peaks], source_results[amplitude_peaks], "o", color="gold", 173 | label=f"Tomado para amplitud con {amplitude_sensitivity*100:.0f}%", markersize=4, markeredgewidth=1, markeredgecolor="k") 174 | 175 | box = fig.axes[0].get_position() 176 | box_height = box.y1 - box.y0 177 | # box.y1 = box.y1 - .02 * box_height 178 | box.y0 = box.y0 + .25 * box_height 179 | fig.axes[0].set_position(box) 180 | 181 | fig.set_size_inches([6.4 , 6.38]) 182 | 183 | fig.axes[0].legend(loc="lower center", frameon=False, 184 | bbox_to_anchor=(.5,-.5), bbox_transform=fig.axes[0].transAxes) 185 | 186 | plt.savefig("MonochNormalization.png") 187 | 188 | if plot_for_display: use_backend("Qt5Agg") -------------------------------------------------------------------------------- /AnalysisRoutines/Field/monoch_field_resolution_wlen_theory.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Mon Sep 13 12:32:57 2021 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import v_utilities as vu 12 | 13 | #%% 14 | 15 | resolution_wlen = list( range(1,321) ) 16 | resolution_test = [10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 130, 150, 17 | 170, 200, 220, 240, 260, 280, 300, 320] 18 | resolution_index = [resolution_wlen.index(value) for value in resolution_test] 19 | 20 | resolution_wlen = np.array(resolution_wlen) 21 | wlen = np.array( [1]*len(resolution_wlen) ) 22 | resolution = resolution_wlen 23 | from_um_factor = np.array( [1e3]*len(resolution_wlen) ) 24 | time_period_factor = np.array( [10]*len(resolution_wlen) ) 25 | n_period_line = np.array( [100]*len(resolution_wlen) ) 26 | n_period_plane = np.array( [100]*len(resolution_wlen) ) 27 | courant = np.array( [0.5]*len(resolution_wlen) ) 28 | 29 | until_time = time_period_factor * wlen 30 | 31 | period_line = wlen / n_period_line 32 | period_plane = wlen / n_period_plane 33 | 34 | minimum_division_space = 1 / resolution 35 | minimum_division_time = courant / resolution 36 | 37 | t_points_line = until_time / period_line 38 | 39 | round_up_until_time = np.array([vu.round_to_multiple(until_time[k], courant[k]/resolution[k], round_up=True) for k in range(len(resolution_wlen))]) # chosen 40 | round_down_until_time = np.array([vu.round_to_multiple(until_time[k], courant[k]/resolution[k], round_down=True) for k in range(len(resolution_wlen))]) 41 | round_until_time = np.array([vu.round_to_multiple(until_time[k], courant[k]/resolution[k]) for k in range(len(resolution_wlen))]) 42 | 43 | round_up_period_line = np.array([vu.round_to_multiple(period_line[k], courant[k]/resolution[k], round_up=True) for k in range(len(resolution_wlen))]) 44 | round_down_period_line = np.array([vu.round_to_multiple(period_line[k], courant[k]/resolution[k], round_down=True) for k in range(len(resolution_wlen))]) # chosen 45 | round_period_line = np.array([vu.round_to_multiple(period_line[k], courant[k]/resolution[k]) for k in range(len(resolution_wlen))]) 46 | 47 | round_up_period_line = np.array([max(round_up_period_line[k], wlen[k]/n_period_line[k]) for k in range(len(resolution_wlen))]) 48 | round_down_period_line = np.array([max(round_down_period_line[k], wlen[k]/n_period_line[k]) for k in range(len(resolution_wlen))]) 49 | round_period_line = np.array([max(round_period_line[k], wlen[k]/n_period_line[k]) for k in range(len(resolution_wlen))]) 50 | 51 | round_up_t_points_line = np.round( round_up_until_time / round_down_period_line ) # chosen 52 | round_down_t_points_line = np.round( round_down_until_time / round_up_period_line ) 53 | round_t_points_line = np.round( round_down_until_time / round_up_period_line ) 54 | 55 | #%% 56 | 57 | fig, axes = plt.subplots(nrows=3, sharex=True, gridspec_kw={"hspace":0}) 58 | 59 | l1, = axes[0].plot(resolution_wlen, round_until_time, "oC0", alpha=0.3, markersize=8, label="Round") 60 | l2, = axes[0].plot(resolution_wlen, round_up_until_time, "oC1", alpha=0.3, markersize=8, label="Round up") 61 | l3, = axes[0].plot(resolution_wlen, round_down_until_time, "oC2", alpha=0.3, markersize=8, label="Round down") 62 | l4, = axes[0].plot(resolution_wlen[resolution_index], round_up_until_time[resolution_index], "x", color="k", markersize=10, label="Chosen") 63 | l0, = axes[0].plot(resolution_wlen, until_time, "-k", label="Value") 64 | axes[0].set_ylabel("Until time [MPu]") 65 | axes[0].grid() 66 | 67 | lines = [l0, l1, l2, l3, l4] 68 | axes[0].legend(lines, [l.get_label() for l in lines]) 69 | 70 | n1, = axes[1].plot(resolution_wlen, round_period_line, "oC0", alpha=0.3, markersize=8, label="Round") 71 | n2, = axes[1].plot(resolution_wlen, round_up_period_line, "oC1", alpha=0.3, markersize=8, label="Round up") 72 | n3, = axes[1].plot(resolution_wlen, round_down_period_line, "oC2", alpha=0.3, markersize=8, label="Round down") 73 | n5, = axes[1].plot(resolution_wlen, minimum_division_time, "k", linestyle="dashed", label=r"Ref. $\Delta t$") 74 | n4, = axes[1].plot(resolution_wlen[resolution_index], round_down_period_line[resolution_index], "x", color="k", markersize=10, label="Chosen") 75 | n0, = axes[1].plot(resolution_wlen, period_line, "-k", label="Value") 76 | axes[1].set_ylabel("Period line [MPu]") 77 | axes[1].grid() 78 | 79 | new_lines = [n0, n1, n2, n3, n4, n5] 80 | axes[1].legend(new_lines, [n.get_label() for n in new_lines]) 81 | 82 | t1, = axes[2].plot(resolution_wlen, round_t_points_line, "oC0", alpha=0.3, markersize=8, label="Round") 83 | t2, = axes[2].plot(resolution_wlen, round_up_t_points_line, "oC1", alpha=0.3, markersize=8, label="Round up") 84 | t3, = axes[2].plot(resolution_wlen, round_down_t_points_line, "oC2", alpha=0.3, markersize=8, label="Round down") 85 | t4, = axes[2].plot(resolution_wlen[resolution_index], round_up_t_points_line[resolution_index], "x", color="k", markersize=10, label="Chosen") 86 | t0, = axes[2].plot(resolution_wlen, t_points_line, "-k", label="Value") 87 | axes[2].set_ylabel("Number of points in time") 88 | axes[2].grid() 89 | 90 | last_lines = [t0, t1, t2, t3, t4] 91 | axes[2].legend(last_lines, [t.get_label() for t in last_lines]) 92 | 93 | axes[-1].set_xlabel(r"Resolution [points/$\lambda$]") 94 | plt.tight_layout() 95 | -------------------------------------------------------------------------------- /AnalysisRoutines/MaterialsTheory/epsilon_exp_meep_data.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Tue Jul 27 13:59:19 2021 5 | 6 | @author: vall 7 | """ 8 | 9 | import matplotlib.pyplot as plt 10 | import numpy as np 11 | import os 12 | import vmp_materials as vml 13 | import v_save as vs 14 | 15 | home = vs.get_home() 16 | 17 | #%% PARAMETERS 18 | 19 | from_um_factor = 1 20 | 21 | material = "Au" 22 | paper = "JC" 23 | r = 60 24 | submerged_index = 1 25 | 26 | plot_file = lambda n : os.path.join(home, "DataAnalysis/MaterialsPaper", n) 27 | 28 | #%% VARIABLES 29 | 30 | medium = vml.import_medium(material, from_um_factor=from_um_factor, paper=paper) 31 | 32 | freq_range = medium.valid_freq_range 33 | 34 | freqs = np.linspace(*freq_range, 100) 35 | wlens = 1 / freqs # nm 36 | 37 | #%% GET N 38 | 39 | wlen_data_exp, n_data_exp = vml.n_data_from_file(material, paper, "RIinfo") 40 | 41 | n_function_meep = vml.n_function_from_meep(material, paper, from_um_factor) 42 | 43 | n_function_exp = vml.n_function_from_file(material, paper, "RIinfo", from_um_factor) 44 | 45 | #%% PLOT N 46 | 47 | functions = [np.abs, np.real, np.imag] 48 | titles = ["Absolute value", "Real part", "Imaginary part"] 49 | ylabels = [r"|N|", r"Re(N)", r"Im(N)"] 50 | # ylabels = [r"|$\epsilon$|", r"Re($\epsilon$)", r"Im($\epsilon$)"] 51 | long_wlen = [wlen_data_exp, *[1e3 * from_um_factor * wlens]*2] 52 | long_n = [n_data_exp, 53 | np.array([n_function_exp(wl) for wl in wlens]), 54 | np.array([n_function_meep(wl) for wl in wlens])] 55 | labels = ["JC Experimental Data", 56 | "JC Experimental Data Interpolation", 57 | "Meep Drude-Lorentz Model JC Interpolation"] 58 | linestyles = [".", "-", ":"] 59 | colors = ["k", 'k', 'r'] 60 | 61 | nplots = len(functions) 62 | fig = plt.figure(figsize=(nplots*6.4, 6.4), tight_layout=True) 63 | axes = fig.subplots(ncols=nplots) 64 | 65 | max_value = [] 66 | min_value = [] 67 | for ax, f, t, y in zip(axes, functions, titles, ylabels): 68 | for wl, n, l, lst, col in zip(long_wlen, long_n, labels, linestyles, colors): 69 | ax.set_title(t) 70 | ax.plot(wl, f(n), lst, color=col, label=l) 71 | ax.xaxis.set_label_text(rr"Wavelength $\lambda$ [nm]") 72 | ax.yaxis.set_label_text(y) 73 | ax.legend() 74 | ax.set_xlim(min(wlens) * 1e3 * from_um_factor, 75 | max(wlens) * 1e3 * from_um_factor) 76 | max_value.append(max(f(n)[wl < 1e3 * from_um_factor * max(wlens)])) 77 | min_value.append(min(f(n)[wl < 1e3 * from_um_factor * max(wlens)])) 78 | 79 | for ax in axes: ax.set_ylim([min(min_value)-.1*(max(max_value)-min(min_value)), 80 | max(max_value)+.1*(max(max_value)-min(min_value))]) 81 | 82 | vs.saveplot( plot_file(f"N{material}MeepN.png"), overwrite=True ) 83 | 84 | #%% GET EPSILON 85 | 86 | wlen_data_exp, epsilon_data_exp = vml.epsilon_data_from_file(material, 87 | paper, "RIinfo") 88 | 89 | epsilon_function_meep = vml.epsilon_function_from_meep(material, paper, 90 | from_um_factor) 91 | 92 | epsilon_function_exp = vml.epsilon_function_from_file(material, paper, 93 | "RIinfo", from_um_factor) 94 | 95 | #%% PLOT N 96 | 97 | functions = [np.abs, np.real, np.imag] 98 | titles = ["Absolute value", "Real part", "Imaginary part"] 99 | ylabels = [r"|$\epsilon$|", r"Re($\epsilon$)", r"Im($\epsilon$)"] 100 | long_wlen = [wlen_data_exp, *[1e3 * from_um_factor * wlens]*2] 101 | long_epsilon = [epsilon_data_exp, 102 | np.array([epsilon_function_exp(wl) for wl in wlens]), 103 | np.array([epsilon_function_meep(wl) for wl in wlens])] 104 | labels = ["JC Experimental Data", 105 | "JC Experimental Data Interpolation", 106 | "Meep Drude-Lorentz Model JC Interpolation"] 107 | linestyles = [".", "-", ":"] 108 | colors = ["k", 'k', 'r'] 109 | 110 | nplots = len(functions) 111 | fig = plt.figure(figsize=(nplots*6.4, 6.4), tight_layout=True) 112 | axes = fig.subplots(ncols=nplots) 113 | 114 | max_value = [] 115 | min_value = [] 116 | for ax, f, t, y in zip(axes, functions, titles, ylabels): 117 | for wl, eps, l, lst, col in zip(long_wlen, long_epsilon, labels, linestyles, colors): 118 | ax.set_title(t) 119 | ax.plot(wl, f(eps), lst, color=col, label=l) 120 | ax.xaxis.set_label_text(rr"Wavelength $\lambda$ [nm]") 121 | ax.yaxis.set_label_text(y) 122 | ax.legend() 123 | ax.set_xlim(min(wlens) * 1e3 * from_um_factor, 124 | max(wlens) * 1e3 * from_um_factor) 125 | max_value.append(max(f(eps)[wl < 1e3 * from_um_factor * max(wlens)])) 126 | min_value.append(min(f(eps)[wl < 1e3 * from_um_factor * max(wlens)])) 127 | 128 | for ax in axes: ax.set_ylim([min(min_value)-.1*(max(max_value)-min(min_value)), 129 | max(max_value)+.1*(max(max_value)-min(min_value))]) 130 | 131 | vs.saveplot( plot_file(f"Eps{material}MeepN.png"), overwrite=True ) -------------------------------------------------------------------------------- /AnalysisRoutines/MaterialsTheory/np_mie_temp_power_theory.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Mon Apr 26 17:05:09 2021 5 | 6 | Script to work with surface temperature and Gaussian beam power on spherical NP. 7 | 8 | It treats surface temperature increasements due to a focused Gaussian beam 9 | power on a spherical nanoparticle submerged in an isotropic medium. 10 | 11 | - Calculates surface temperature increasement for a given Gaussian beam power 12 | with known central wavelength and beam waist. 13 | - Computes Gaussian beam power for a given surface temperature increasement 14 | with known central wavelength and beam waist 15 | - Returns other laser's required power to produce the same surface temperature 16 | increasement as a reference Gaussian beam when all central wavelengths and 17 | beam waists are known. 18 | 19 | @author: vall 20 | """ 21 | 22 | import numpy as np 23 | import vmp_theory as vmt 24 | import vmp_materials as vml 25 | 26 | #%% PARAMETERS 27 | 28 | # Spherical NP 29 | material = "Au" 30 | paper = "JC" 31 | reference = "RIinfo" 32 | r = 30 # Radius in nm 33 | 34 | # Surrounding medium 35 | surrounding_N = 1.33 # Water complex refractive index, dimensionless 36 | surrounding_kappa = 0.58 # Water thermal conductivity in W/Km 37 | 38 | # Incident Laser 39 | wlen = 532 # Wavelength in nm 40 | P = 0.46 # Power in mW 41 | w0 = 266 # w0 is the Gaussian beam's waist in nm 42 | lasers = [dict(color="Azul", wlen=405, w0=266), 43 | dict(color="Verde", wlen=532, w0=266), 44 | dict(color="Rojo", wlen=642, w0=266)] 45 | 46 | # Surface Temperature 47 | delta_T = 214 # Surface temperature initial increasement caused by the beam in K. 48 | 49 | # Mode 50 | mode = "RefT" # Either 'RefT' or 'RefP' 51 | 52 | #%% 53 | 54 | inner_epsilon_function = vml.epsilon_function(material, paper, reference) 55 | inner_N = np.sqrt(inner_epsilon_function(wlen)) 56 | 57 | sigma_abs = vmt.sigma_abs_Mie(r, wlen, inner_N, surrounding_N) 58 | 59 | estimated_delta_T = vmt.delta_T(P, sigma_abs, w0, r, surrounding_kappa) 60 | 61 | estimated_P = vmt.P(delta_T, sigma_abs, w0, r, surrounding_kappa) 62 | 63 | #%% 64 | 65 | ref_laser = lasers[[l["wlen"] for l in lasers].index(wlen)] 66 | 67 | for l in lasers: 68 | inner_N = np.sqrt(inner_epsilon_function(wlen)) 69 | l["sigma_abs"] = vmt.sigma_abs_Mie(r, l["wlen"], inner_N, surrounding_N) 70 | 71 | ref_laser["P"] = P 72 | for l in lasers: 73 | if l!=ref_laser: 74 | l["P"] = (l["w0"]/ref_laser["w0"])**2 75 | l["P"] = l["P"] * (ref_laser["sigma_abs"]/l["sigma_abs"]) 76 | l["P"] = l["P"] * ref_laser["P"] 77 | 78 | print(f"Para referencia {ref_laser['color'].lower()} con potencia {ref_laser['P']:.3f} mW...") 79 | for l in lasers: 80 | if l!=ref_laser: 81 | print(f">> {l['color']} requiere potencia {round(l['P'],3)} mW") -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Paper/au_mie_sphere_paper_diameters_separated.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.pylab as plab 12 | import os 13 | import PyMieScatt as ps 14 | from vmp_materials import import_medium 15 | import v_save as vs 16 | import v_utilities as vu 17 | 18 | #%% PARAMETERS ALL VACUUM 19 | 20 | # Saving directories 21 | folder = ["AuMieSphere/AuMie/7)Diameters/WLen4560", 22 | "AuMieSphere/AuMie/13)TestPaper/4)PaperJCFit/TestPaperJCFitDiams/AllVac450600"] 23 | home = vs.get_home() 24 | 25 | # Sorting and labelling data series 26 | sorting_function = [vu.sort_by_number, vu.sort_by_number] 27 | series_must = ["Res4", ""] # leave "" per default 28 | series_mustnt = ["", ""] # leave "" per default 29 | series_column = [1, 1] 30 | 31 | # Scattering plot options 32 | plot_title = "Scattering for Au spheres of different diameters and material source in vacuum" 33 | series_colors = [plab.cm.Blues, plab.cm.Reds] 34 | series_label = [lambda s : f"Vacuum R Meep {vu.find_numbers(s)[0]} nm", 35 | lambda s : f"Vacuum JC Meep {vu.find_numbers(s)[0]} nm"] 36 | series_linestyles = ["solid", "solid"] 37 | 38 | theory_label = [lambda s : f"Vacuum R Theory {vu.find_numbers(s)[0]} nm", 39 | lambda s : f"Vacuum JC Theory {vu.find_numbers(s)[0]} nm"] 40 | theory_linestyle = ["dashed", "dashed"] 41 | 42 | plot_make_big = True 43 | plot_file = lambda n : os.path.join(home, "DataAnalysis/PaperDiameters", "AllVacPaperDiameters"+n) 44 | 45 | #%% PARAMETERS ALL WATER 46 | 47 | # Saving directories 48 | folder = ["AuMieMediums/AllWater", 49 | "AuMieSphere/AuMie/13)TestPaper/4)PaperJCFit/TestPaperJCFitDiams/AllWater500650"] 50 | home = vs.get_home() 51 | 52 | # Sorting and labelling data series 53 | sorting_function = [vu.sort_by_number, vu.sort_by_number] 54 | series_must = ["Res4", ""] # leave "" per default 55 | series_mustnt = ["", ""] # leave "" per default 56 | series_column = [1, 1] 57 | 58 | # Scattering plot options 59 | plot_title = "Scattering for Au spheres of different diameters and material source in water" 60 | series_colors = [plab.cm.Purples, plab.cm.Reds] 61 | series_label = [lambda s : f"Water R Meep {vu.find_numbers(s)[0]} nm", 62 | lambda s : f"Water JC Meep {vu.find_numbers(s)[0]} nm"] 63 | series_linestyles = ["solid", "solid"] 64 | 65 | theory_label = [lambda s : f"Water R Theory {vu.find_numbers(s)[0]} nm", 66 | lambda s : f"Water JC Theory {vu.find_numbers(s)[0]} nm"] 67 | theory_linestyle = ["dashed", "dashed"] 68 | 69 | plot_make_big = True 70 | plot_file = lambda n : os.path.join(home, "DataAnalysis/PaperDiameters", "AllWatPaperDiameters"+n) 71 | 72 | #%% LOAD DATA 73 | 74 | path = [] 75 | file = [] 76 | series = [] 77 | data = [] 78 | params = [] 79 | header = [] 80 | 81 | for f, sf, sm, smn in zip(folder, sorting_function, series_must, series_mustnt): 82 | 83 | path.append( os.path.join(home, f) ) 84 | file.append( lambda f, s : os.path.join(path[-1], f, s) ) 85 | 86 | series.append( os.listdir(path[-1]) ) 87 | series[-1] = vu.filter_to_only_directories(series[-1]) 88 | series[-1] = vu.filter_by_string_must(series[-1], sm) 89 | if smn!="": series[-1] = vu.filter_by_string_must(series[-1], smn, False) 90 | series[-1] = sf(series[-1]) 91 | 92 | data.append( [] ) 93 | params.append( [] ) 94 | for s in series[-1]: 95 | data[-1].append(np.loadtxt(file[-1](s, "Results.txt"))) 96 | params[-1].append(vs.retrieve_footer(file[-1](s, "Results.txt"))) 97 | header.append( vs.retrieve_header(file[-1](s, "Results.txt")) ) 98 | 99 | for i in range(len(params[-1])): 100 | if not isinstance(params[-1][i], dict): 101 | params[-1][i] = vu.fix_params_dict(params[-1][i]) 102 | 103 | r = [] 104 | from_um_factor = [] 105 | resolution = [] 106 | paper = [] 107 | index = [] 108 | for p in params: 109 | r.append( [pi["r"] for pi in p] ) 110 | from_um_factor.append( [pi["from_um_factor"] for pi in p] ) 111 | resolution.append( [pi["resolution"] for pi in p] ) 112 | try: 113 | paper.append( [pi["paper"] for pi in p]) 114 | except: 115 | paper.append( ["R" for pi in p] ) 116 | index.append( [] ) 117 | for p in params[-1]: 118 | try: 119 | index[-1].append( p["submerged_index"] ) 120 | except KeyError: 121 | index[-1].append( 1.333 ) 122 | 123 | #%% GET THEORY 124 | 125 | theory = [] # Scattering effiency 126 | for di, ri, fi, resi, ppi, ii in zip(data, r, from_um_factor, resolution, paper, index): 127 | theory.append([]) 128 | for dj, rj, fj, resj, ppij, ij in zip(di, ri, fi, resi, ppi, ii): 129 | wlenj = dj[:,0] # nm 130 | freqj = 1 / wlenj # 1/nm 131 | freqmeepj = (1e3 * fj) / wlenj # Meep units 132 | mediumj = import_medium("Au", from_um_factor=fj, paper=ppij) 133 | theory[-1].append(np.array( 134 | [ps.MieQ(np.sqrt(mediumj.epsilon(fqm)[0,0]*mediumj.mu(fqm)[0,0]), 135 | wl, # Wavelength (nm) 136 | 2*rj*1e3*fj, # Diameter (nm) 137 | nMedium=ij, # Refraction Index of Medium 138 | asDict=True)['Qsca'] 139 | for wl, fq, fqm in zip(wlenj, freqj, freqmeepj)])) 140 | 141 | #%% GET MAX WAVELENGTH 142 | 143 | max_wlen = [] 144 | for d, sc in zip(data, series_column): 145 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 146 | 147 | max_wlen_theory = [] 148 | for t, d in zip(theory, data): 149 | max_wlen_theory.append( [d[i][np.argmax(t[i]), 0] for i in range(len(t))] ) 150 | 151 | max_wlen_diff = [] 152 | for md, mt in zip(max_wlen, max_wlen_theory): 153 | max_wlen_diff.append( [d - t for d,t in zip(md, mt)] ) 154 | 155 | e_max_wlen = [] 156 | for d, sc in zip(data, series_column): 157 | e_max_wlen.append( [ np.mean([ 158 | abs(d[i][np.argmax(d[i][:,sc])-1, 0] - d[i][np.argmax(t[i]), 0]), 159 | abs(d[i][np.argmax(d[i][:,sc])+1, 0] - d[i][np.argmax(t[i]), 0]) 160 | ]) for i in range(len(d)) ] ) 161 | 162 | #%% PLOT NORMALIZED 163 | 164 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 165 | for sc, s in zip(series_colors, series)] 166 | 167 | fig, axes = plt.subplots(2, 1, sharex=True) 168 | fig.suptitle(plot_title) 169 | axes[1].yaxis.tick_right() 170 | axes[1].yaxis.set_label_position("right") 171 | 172 | for ax, s, d, t, p, n, sc, psl, tsl, pc, pls, tls in zip(axes, series, 173 | data, theory, 174 | params, index, 175 | series_column, 176 | series_label, 177 | theory_label, 178 | colors, 179 | series_linestyles, 180 | theory_linestyle): 181 | 182 | for ss, sd, td, sp, nd, spc in zip(s, d, t, p, n, pc): 183 | ax.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 184 | linestyle=pls, color=spc, label=psl(ss)) 185 | ax.plot(sd[:,0], td / max(td), 186 | linestyle=tls, color=spc, label=tsl(ss)) 187 | ax.legend() 188 | ax.grid(True) 189 | ax.xaxis.set_label_text(r"Wavelength $\lambda$ [nm]") 190 | ax.yaxis.set_label_text("Normalized Scattering Cross Section") 191 | if 1.33 <= nd < 1.34: 192 | ax.set_facecolor( np.array([230, 241, 255])/255 ) 193 | # frame = leg.get_frame() 194 | # frame.set_facecolor( np.array([230, 241, 255])/255 ) 195 | 196 | # plt.xlabel(r"Wavelength $\lambda$ [nm]") 197 | # plt.ylabel("Normalized Scattering Cross Section") 198 | if plot_make_big: 199 | mng = plt.get_current_fig_manager() 200 | mng.window.showMaximized() 201 | del mng 202 | fig.tight_layout() 203 | plt.subplots_adjust(hspace=0) 204 | 205 | vs.saveplot(plot_file("AllScattNorm.png"), overwrite=True) 206 | 207 | #%% PLOT EFFIENCIENCY 208 | 209 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 210 | for sc, s in zip(series_colors, series)] 211 | 212 | fig, axes = plt.subplots(2, 1, sharex=True) 213 | fig.suptitle(plot_title) 214 | axes[1].yaxis.tick_right() 215 | axes[1].yaxis.set_label_position("right") 216 | 217 | for ax, s, d, t, p, n, sc, psl, tsl, pc, pls, tls in zip(axes, series, 218 | data, theory, 219 | params, index, 220 | series_column, 221 | series_label, 222 | theory_label, 223 | colors, 224 | series_linestyles, 225 | theory_linestyle): 226 | 227 | for ss, sd, td, sp, nd, spc in zip(s, d, t, p, n, pc): 228 | ax.plot(sd[:,0], sd[:,sc], 229 | linestyle=pls, color=spc, label=psl(ss)) 230 | ax.plot(sd[:,0], td, 231 | linestyle=tls, color=spc, label=tsl(ss)) 232 | ax.legend() 233 | ax.grid(True) 234 | ax.xaxis.set_label_text(r"Wavelength $\lambda$ [nm]") 235 | ax.yaxis.set_label_text("Scattering Efficiency") 236 | if 1.33 <= nd < 1.34: 237 | ax.set_facecolor( np.array([230, 241, 255])/255 ) 238 | # frame = leg.get_frame() 239 | # frame.set_facecolor( np.array([230, 241, 255])/255 ) 240 | 241 | # plt.xlabel(r"Wavelength $\lambda$ [nm]") 242 | # plt.ylabel("Normalized Scattering Cross Section") 243 | if plot_make_big: 244 | mng = plt.get_current_fig_manager() 245 | mng.window.showMaximized() 246 | del mng 247 | fig.tight_layout() 248 | plt.subplots_adjust(hspace=0) 249 | 250 | vs.saveplot(plot_file("AllScattEff.png"), overwrite=True) 251 | 252 | #%% PLOT IN UNITS 253 | 254 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 255 | for sc, s in zip(series_colors, series)] 256 | 257 | fig, axes = plt.subplots(2, 1, sharex=True) 258 | fig.suptitle(plot_title) 259 | axes[1].yaxis.tick_right() 260 | axes[1].yaxis.set_label_position("right") 261 | 262 | for ax, s, d, t, p, n, sc, psl, tsl, pc, pls, tls in zip(axes, series, 263 | data, theory, 264 | params, index, 265 | series_column, 266 | series_label, 267 | theory_label, 268 | colors, 269 | series_linestyles, 270 | theory_linestyle): 271 | 272 | for ss, sd, td, sp, nd, spc in zip(s, d, t, p, n, pc): 273 | ax.plot(sd[:,0], sd[:,sc] * np.pi * (sp['r'] * sp['from_um_factor'] * 1e3)**2, 274 | linestyle=pls, color=spc, label=psl(ss)) 275 | ax.plot(sd[:,0], td * np.pi * (sp['r'] * sp['from_um_factor'] * 1e3)**2, 276 | linestyle=tls, color=spc, label=tsl(ss)) 277 | leg = ax.legend() 278 | ax.grid(True) 279 | ax.xaxis.set_label_text(r"Wavelength $\lambda$ [nm]") 280 | ax.yaxis.set_label_text(r"Scattering Cross Section [nm$^2$]") 281 | if 1.33 <= nd < 1.34: 282 | ax.set_facecolor( np.array([230, 241, 255])/255 ) 283 | # frame = leg.get_frame() 284 | # frame.set_facecolor( np.array([230, 241, 255])/255 ) 285 | 286 | # plt.xlabel(r"Wavelength $\lambda$ [nm]") 287 | # plt.ylabel("Normalized Scattering Cross Section") 288 | if plot_make_big: 289 | mng = plt.get_current_fig_manager() 290 | mng.window.showMaximized() 291 | del mng 292 | fig.tight_layout() 293 | plt.subplots_adjust(hspace=0) 294 | 295 | vs.saveplot(plot_file("AllScatt.png"), overwrite=True) 296 | -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Paper/au_mie_sphere_paper_diameters_together.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.pylab as plab 12 | from matplotlib.ticker import AutoMinorLocator 13 | import os 14 | import PyMieScatt as ps 15 | from vmp_materials import import_medium 16 | import v_save as vs 17 | import v_utilities as vu 18 | 19 | #%% PARAMETERS ALL VACUUM 20 | 21 | marian_folder = "AuMieSphere/AuMie/7)Diameters/Marians" 22 | 23 | # Saving directories 24 | folder = ["AuMieSphere/AuMie/7)Diameters/WLen4560", 25 | "AuMieSphere/AuMie/13)TestPaper/4)PaperJCFit/TestPaperJCFitDiams/AllVac450600", 26 | "AuMieMediums/AllWater", 27 | "AuMieSphere/AuMie/13)TestPaper/4)PaperJCFit/TestPaperJCFitDiams/AllWater500650"] 28 | home = vs.get_home() 29 | 30 | # Sorting and labelling data series 31 | sorting_function = [vu.sort_by_number, vu.sort_by_number, vu.sort_by_number, vu.sort_by_number] 32 | series_must = ["Res4", "", "Res4", ""] # leave "" per default 33 | series_mustnt = ["", "", "", ""] # leave "" per default 34 | series_column = [1, 1, 1, 1] 35 | 36 | # Scattering plot options 37 | plot_title = "Scattering for Au spheres of different diameters and material source" 38 | series_colors = [plab.cm.Blues, plab.cm.Reds, plab.cm.Purples, plab.cm.Greens] 39 | subtitles_label = [lambda s : f"Diameter {vu.find_numbers(s)[0]} nm", 40 | lambda s : f"Diameter {vu.find_numbers(s)[0]} nm", 41 | lambda s : f"Diameter {vu.find_numbers(s)[0]} nm", 42 | lambda s : f"Diameter {vu.find_numbers(s)[0]} nm"] 43 | series_label = ["Vacuum R Meep", "Vacuum JC Meep", "Water R Meep", "Water JC Meep"] 44 | series_linestyles = ["solid", "solid", "solid", "solid"] 45 | 46 | theory_label = ["Vacuum R Theory", "Vacuum JC Theory", "Water R Theory", "Water JC Theory"] 47 | theory_linestyles = ["dashed", "dashed", "dashed", "dashed"] 48 | 49 | plot_make_big = True 50 | plot_file = lambda n : os.path.join(home, "DataAnalysis", "PaperDiameters"+n) 51 | 52 | #%% LOAD DATA 53 | 54 | path = [] 55 | file = [] 56 | series = [] 57 | data = [] 58 | params = [] 59 | header = [] 60 | 61 | for f, sf, sm, smn in zip(folder, sorting_function, series_must, series_mustnt): 62 | 63 | path.append( os.path.join(home, f) ) 64 | file.append( lambda f, s : os.path.join(path[-1], f, s) ) 65 | 66 | series.append( os.listdir(path[-1]) ) 67 | series[-1] = vu.filter_to_only_directories(series[-1]) 68 | series[-1] = vu.filter_by_string_must(series[-1], sm) 69 | if smn!="": series[-1] = vu.filter_by_string_must(series[-1], smn, False) 70 | series[-1] = sf(series[-1]) 71 | 72 | data.append( [] ) 73 | params.append( [] ) 74 | for s in series[-1]: 75 | data[-1].append(np.loadtxt(file[-1](s, "Results.txt"))) 76 | params[-1].append(vs.retrieve_footer(file[-1](s, "Results.txt"))) 77 | header.append( vs.retrieve_header(file[-1](s, "Results.txt")) ) 78 | 79 | for i in range(len(params[-1])): 80 | if not isinstance(params[-1][i], dict): 81 | params[-1][i] = vu.fix_params_dict(params[-1][i]) 82 | 83 | r = [] 84 | from_um_factor = [] 85 | resolution = [] 86 | paper = [] 87 | # index = [] 88 | for p in params: 89 | r.append( [pi["r"] for pi in p] ) 90 | from_um_factor.append( [pi["from_um_factor"] for pi in p] ) 91 | resolution.append( [pi["resolution"] for pi in p] ) 92 | try: 93 | paper.append( [pi["paper"] for pi in p]) 94 | except: 95 | paper.append( ["R" for pi in p] ) 96 | # index.append( [] ) 97 | # for p in params[-1]: 98 | # try: 99 | # index[-1].append( p["submerged_index"] ) 100 | # except KeyError: 101 | # index[-1].append( 1.333 ) 102 | index = [ [*[1]*4] , [*[1]*4], [*[1.33]*4], [*[1.33]*4]] 103 | 104 | #%% GET THEORY 105 | 106 | theory = [] # Scattering effiency 107 | for di, ri, fi, resi, ppi, ii in zip(data, r, from_um_factor, resolution, paper, index): 108 | theory.append([]) 109 | for dj, rj, fj, resj, ppij, ij in zip(di, ri, fi, resi, ppi, ii): 110 | wlenj = dj[:,0] # nm 111 | freqj = 1 / wlenj # 1/nm 112 | freqmeepj = (1e3 * fj) / wlenj # Meep units 113 | mediumj = import_medium("Au", from_um_factor=fj, paper=ppij) 114 | theory[-1].append(np.array( 115 | [ps.MieQ(np.sqrt(mediumj.epsilon(fqm)[0,0]*mediumj.mu(fqm)[0,0]), 116 | wl, # Wavelength (nm) 117 | 2*rj*1e3*fj, # Diameter (nm) 118 | nMedium=ij, # Refraction Index of Medium 119 | asDict=True)['Qsca'] 120 | for wl, fq, fqm in zip(wlenj, freqj, freqmeepj)])) 121 | 122 | #%% LOAD MARIAN'S DATA 123 | 124 | marian_path = os.path.join(home, marian_folder) 125 | marian_file = lambda s : os.path.join(marian_path, s) 126 | 127 | marian_series = os.listdir(marian_path) 128 | 129 | marian_exp_series = vu.filter_by_string_must(marian_series, "exp") 130 | marian_exp_series = vu.filter_by_string_must(marian_exp_series, "glass") 131 | marian_exp_series = vu.sort_by_number(marian_exp_series) 132 | 133 | marian_mie_series = vu.filter_by_string_must(marian_series, "mie") 134 | marian_mie_series = vu.sort_by_number(marian_mie_series) 135 | 136 | marian_exp_data = [] 137 | for s in marian_exp_series: 138 | marian_exp_data.append(np.loadtxt(marian_file(s))) 139 | 140 | marian_mie_data = [] 141 | for s in marian_mie_series: 142 | marian_mie_data.append(np.loadtxt(marian_file(s))) 143 | 144 | #%% GET MAX WAVELENGTH 145 | 146 | max_wlen = [] 147 | for d, sc in zip(data, series_column): 148 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 149 | 150 | max_wlen_theory = [] 151 | for t, d in zip(theory, data): 152 | max_wlen_theory.append( [d[i][np.argmax(t[i]), 0] for i in range(len(t))] ) 153 | 154 | max_wlen_diff = [] 155 | for md, mt in zip(max_wlen, max_wlen_theory): 156 | max_wlen_diff.append( [d - t for d,t in zip(md, mt)] ) 157 | 158 | marian_exp_max = [marian_exp_data[i][np.argmax(marian_exp_data[i][:,1]), 0] for i in range(len(marian_exp_data))] 159 | marian_mie_max = [marian_mie_data[i][np.argmax(marian_mie_data[i][:,1]), 0] for i in range(len(marian_mie_data))] 160 | 161 | marian_wlen_diff = [] 162 | for md in max_wlen: 163 | marian_wlen_diff.append( [d - m for d,m in zip(md, marian_exp_max)] ) 164 | 165 | #%% 166 | 167 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 168 | for sc, s in zip(series_colors, series)] 169 | 170 | fig = plt.figure() 171 | for i in range(len(data)): 172 | for j in range(len(data[i])): 173 | if j==0: label=series_label[i] 174 | else: label=None 175 | plt.plot(max_wlen_diff[i][j], f"{2 * r[i][j] * from_um_factor[i][j] * 1e3:.0f} nm", 176 | '*', markersize=12, color=colors[i][1], label=label) 177 | 178 | plt.grid(True, axis="x", which="minor") 179 | plt.grid(True, axis="x", which="major") 180 | plt.legend(loc="lower right") 181 | plt.xlabel(r"Wavelength difference $\lambda_{MEEP} - \lambda_{MIE}$ [nm]") 182 | plt.title(plot_title) 183 | ax = fig.axes[0] 184 | ax.xaxis.set_minor_locator(AutoMinorLocator()) 185 | plt.show() 186 | fig.set_size_inches([6.4 , 4.07]) 187 | plt.tight_layout() 188 | 189 | vs.saveplot(plot_file("WlenDif.png"), overwrite=True) 190 | 191 | #%% 192 | 193 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 194 | for sc, s in zip(series_colors, series)] 195 | 196 | fig = plt.figure() 197 | for i in range(len(data)): 198 | for j in range(len(data[i])): 199 | if j==0: label=series_label[i] 200 | else: label=None 201 | plt.plot(marian_wlen_diff[i][j], f"{2 * r[i][j] * from_um_factor[i][j] * 1e3:.0f} nm", 202 | '*', markersize=12, color=colors[i][1], label=label) 203 | 204 | plt.grid(True, axis="x", which="minor") 205 | plt.grid(True, axis="x", which="major") 206 | plt.legend(loc="upper center") 207 | plt.xlabel(r"Wavelength difference $\lambda_{MEEP} - \lambda_{EXP}$ [nm]") 208 | plt.title(plot_title) 209 | ax = fig.axes[0] 210 | ax.xaxis.set_minor_locator(AutoMinorLocator()) 211 | plt.show() 212 | fig.set_size_inches([6.4 , 4.07]) 213 | plt.tight_layout() 214 | 215 | vs.saveplot(plot_file("WlenDifMarian.png"), overwrite=True) 216 | 217 | #%% PLOT NORMALIZED VACUUM 218 | 219 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 220 | for sc, s in zip(series_colors, series)] 221 | 222 | fig, axes = plt.subplots(2, 2, sharex=True, sharey=True) 223 | fig.suptitle(plot_title) 224 | 225 | axes = axes.reshape(len(data)) 226 | # for ax, tit in zip(axes, plot_title): 227 | 228 | for i in range(len(data)): 229 | for j in range(len(data[i])): 230 | axes[j].plot(data[i][j][:,0], data[i][j][:,1] / max(data[i][j][:,1]), 231 | linestyle=series_linestyles[i], 232 | color=colors[i][1], 233 | label=series_label[i]) 234 | axes[j].plot(data[i][j][:,0], theory[i][j] / max(theory[i][j]), 235 | linestyle=theory_linestyles[i], 236 | color=colors[i][1], 237 | label=theory_label[i]) 238 | if i==3: 239 | axes[j].plot(marian_exp_data[j][:,0], marian_exp_data[j][:,1], 240 | "-k", label="Experimental Data") 241 | axes[j].set_title(subtitles_label[i](series[i][j])) 242 | axes[j].grid(True) 243 | if j==2 or j==3: 244 | axes[j].xaxis.set_label_text(r"Wavelength $\lambda$ [nm]") 245 | if j==0 or j==2: 246 | axes[j].yaxis.set_label_text("Normalized Scattering") 247 | axes[j].set_xlim(450, 650) 248 | axes[0].legend(ncol=2) 249 | 250 | if plot_make_big: 251 | mng = plt.get_current_fig_manager() 252 | mng.window.showMaximized() 253 | del mng 254 | fig.tight_layout() 255 | plt.subplots_adjust(wspace=0) 256 | 257 | vs.saveplot(plot_file("AllScattNorm.png"), overwrite=True) 258 | -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Paper/au_mie_sphere_paper_stfactor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.pylab as plab 12 | import os 13 | import PyMieScatt as ps 14 | import v_analysis as va 15 | from vmp_materials import import_medium 16 | import v_save as vs 17 | import v_utilities as vu 18 | 19 | #%% PARAMETERS 20 | 21 | # Saving directories 22 | folder = ["AuMieSphere/AuMie/13)TestPaper/4)PaperJCFit/TestSTFactor/AllVac450800"] 23 | home = vs.get_home() 24 | 25 | # Sorting and labelling data series 26 | sorting_function = [lambda l : vu.sort_by_number(l, -2)] 27 | # def special_label(s): 28 | # if "5" in s: 29 | # return "Mie" 30 | # else: 31 | # return "" 32 | series_label = [lambda s : f"Meep factor {vu.find_numbers(s)[-2]}"] 33 | series_must = [""] # leave "" per default 34 | series_mustnt = [""] # leave "" per default 35 | series_column = [1] 36 | 37 | # Scattering plot options 38 | plot_title = "JC Au 103 nm sphere in vacuum" 39 | series_colors = [plab.cm.Reds] 40 | series_linestyles = ["solid"] 41 | plot_make_big = False 42 | plot_file = lambda n : os.path.join(home, "DataAnalysis/PaperSTFactor" + n) 43 | 44 | #%% LOAD DATA 45 | 46 | path = [] 47 | file = [] 48 | series = [] 49 | data = [] 50 | params = [] 51 | header = [] 52 | 53 | for f, sf, sm, smn in zip(folder, sorting_function, series_must, series_mustnt): 54 | 55 | path.append( os.path.join(home, f) ) 56 | file.append( lambda f, s : os.path.join(path[-1], f, s) ) 57 | 58 | series.append( os.listdir(path[-1]) ) 59 | series[-1] = vu.filter_by_string_must(series[-1], sm) 60 | if smn!="": series[-1] = vu.filter_by_string_must(series[-1], smn, False) 61 | series[-1] = sf(series[-1]) 62 | 63 | data.append( [] ) 64 | params.append( [] ) 65 | for s in series[-1]: 66 | data[-1].append(np.loadtxt(file[-1](s, "Results.txt"))) 67 | params[-1].append(vs.retrieve_footer(file[-1](s, "Results.txt"))) 68 | header.append( vs.retrieve_header(file[-1](s, "Results.txt")) ) 69 | 70 | for i in range(len(params[-1])): 71 | if not isinstance(params[-1][i], dict): 72 | params[-1][i] = vu.fix_params_dict(params[-1][i]) 73 | 74 | r = [] 75 | from_um_factor = [] 76 | for par in params: 77 | r.append([p["r"] for p in par]) 78 | from_um_factor.append([p["from_um_factor"] for p in par]) 79 | 80 | #%% LOAD MIE DATA 81 | 82 | from_um_factor = params[0][0]["from_um_factor"] 83 | wlen_range = params[0][0]["wlen_range"] 84 | r = params[0][0]["r"] 85 | index = params[0][0]["submerged_index"] 86 | 87 | medium = import_medium("Au", from_um_factor, paper="JC") 88 | 89 | wlens = data[0][-1][:,0] 90 | freqs = 1e3*from_um_factor/wlens 91 | scatt_eff_theory = [ps.MieQ(np.sqrt(medium.epsilon(f)[0,0]*medium.mu(f)[0,0]), 92 | 1e3*from_um_factor/f, 93 | 2*r*1e3*from_um_factor, 94 | nMedium=index, 95 | asDict=True)['Qsca'] 96 | for f in freqs] 97 | scatt_eff_theory = np.array(scatt_eff_theory) 98 | 99 | #%% GET MAX WAVELENGTH 100 | 101 | max_wlen = [] 102 | for d, sc in zip(data, series_column): 103 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 104 | max_wlen_theory = wlens[np.argmax(scatt_eff_theory)] 105 | 106 | dif_max_wlen = [ml - max_wlen_theory for ml in max_wlen[0]] 107 | 108 | #%% WAVELENGTH MAXIMUM DIFFERENCE VS TIME FACTOR CELL 109 | 110 | second_time_factor = [p["second_time_factor"] for p in params[0]] 111 | 112 | plt.title("Difference in scattering maximum for " + plot_title) 113 | plt.plot(second_time_factor, dif_max_wlen, '.', markersize=12) 114 | plt.grid(True) 115 | plt.legend(["Data", r"Fit $f(r)=a_0 e^{-a_1 r} + a_2$"]) 116 | plt.xlabel("Second time factor") 117 | plt.ylabel("Difference in wavelength $\lambda_{max}^{MEEP}-\lambda_{max}^{MIE}$ [nm]") 118 | vs.saveplot(plot_file("WLenDiff.png"), overwrite=True) 119 | 120 | #%% GET ELAPSED TIME COMPARED 121 | 122 | second_time_factor = [[p["second_time_factor"] for p in par] for par in params] 123 | elapsed_time = [[p["elapsed"] for p in par] for par in params] 124 | total_elapsed_time = [[sum(p["elapsed"]) for p in par] for par in params] 125 | 126 | first_second_time_factor = [] 127 | second_second_time_factor = [] 128 | first_build_time = [] 129 | first_sim_time = [] 130 | second_flux_time = [] 131 | second_build_time = [] 132 | second_sim_time = [] 133 | for enl, stf in zip(elapsed_time, second_time_factor): 134 | first_second_time_factor.append( [] ) 135 | first_build_time.append( [] ) 136 | first_sim_time.append( [] ) 137 | second_second_time_factor.append( [] ) 138 | second_flux_time.append( [] ) 139 | second_build_time.append( [] ) 140 | second_sim_time.append( [] ) 141 | for e, tf in zip(enl, stf): 142 | if len(e)==5: 143 | first_second_time_factor[-1].append( tf ) 144 | second_second_time_factor[-1].append( tf ) 145 | first_build_time[-1].append( e[0] ) 146 | first_sim_time[-1].append( e[1] ) 147 | second_build_time[-1].append( e[2] ) 148 | second_flux_time[-1].append( e[3] ) 149 | second_sim_time[-1].append( e[4] ) 150 | elif len(e)==3: 151 | second_second_time_factor[-1].append( tf ) 152 | second_build_time[-1].append( e[0] ) 153 | second_flux_time[-1].append( e[1] ) 154 | second_sim_time[-1].append( e[2] ) 155 | else: 156 | print(f"Unknown error in second_time_factor {tf} of", stf) 157 | 158 | plt.figure() 159 | plt.title("elapsed total time for simulation of " + plot_title) 160 | for tfc, tot in zip(second_time_factor, total_elapsed_time): 161 | plt.plot(tfc, tot, '.', markersize=12) 162 | plt.legend(["Meep R", "Meep JC"], loc="lower right") 163 | plt.xlabel("Time factor cell") 164 | plt.ylabel("elapsed time [s]") 165 | vs.saveplot(plot_file("ComparedTotTime.png"), overwrite=True) 166 | 167 | plt.figure() 168 | plt.title("elapsed time for simulations of " + plot_title) 169 | plt.plot(first_second_time_factor[0], first_sim_time[0], 'D-', color="C0", label="Sim I") 170 | plt.plot(second_second_time_factor[0], second_sim_time[0], 's-', color="C0", label="Sim II") 171 | plt.xlabel("Time factor cell") 172 | plt.ylabel("elapsed time in simulations [s]") 173 | plt.legend() 174 | plt.savefig(plot_file("ComparedSimTime.png"), bbox_inches='tight') 175 | 176 | plt.figure() 177 | plt.title("elapsed time for building of " + plot_title) 178 | plt.plot(first_second_time_factor[0], first_build_time[0], 'D-', color="C0", label="Sim I") 179 | plt.plot(second_second_time_factor[0], second_build_time[0], 's-', color="C0", label="Sim II") 180 | plt.xlabel("Time factor cell") 181 | plt.ylabel("elapsed time in building [s]") 182 | plt.legend() 183 | plt.savefig(plot_file("ComparedBuildTime.png"), bbox_inches='tight') 184 | 185 | plt.figure() 186 | plt.title("elapsed time for loading flux of " + plot_title) 187 | plt.plot(second_second_time_factor[0], second_flux_time[0], 's-', color="C0", label="Sim II") 188 | plt.xlabel("Time factor cell") 189 | plt.ylabel("elapsed time in loading flux [s]") 190 | plt.savefig(plot_file("ComparedLoadTime.png"), bbox_inches='tight') 191 | 192 | #%% PLOT NORMALIZED 193 | 194 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 195 | for sc, s in zip(series_colors, series)] 196 | 197 | plt.figure() 198 | plt.title("Normalized scattering for " + plot_title) 199 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 200 | series_label, colors, series_linestyles): 201 | 202 | for ss, sd, sp, spc in zip(s, d, p, pc): 203 | if ss!=series[0][0] and ss!="STFactor10.0Res2": 204 | plt.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 205 | linestyle=pls, color=spc, label=psl(ss)) 206 | elif ss=="STFactor10.0Res2": 207 | plt.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 208 | linestyle=pls, color='b', label=psl(ss)) 209 | 210 | plt.plot(wlens, scatt_eff_theory / max(scatt_eff_theory), 211 | linestyle="dashed", color='red', label="Mie Theory") 212 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 213 | plt.ylabel("Normalized Scattering Cross Section") 214 | plt.legend() 215 | if plot_make_big: 216 | mng = plt.get_current_fig_manager() 217 | mng.window.showMaximized() 218 | del mng 219 | vs.saveplot(plot_file("AllScattNorm.png"), overwrite=True) 220 | 221 | #%% PLOT IN UNITS 222 | 223 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 224 | for sc, s in zip(series_colors, series)] 225 | 226 | plt.figure() 227 | plt.title("Scattering for " + plot_title) 228 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 229 | series_label, colors, series_linestyles): 230 | 231 | for ss, sd, sp, spc in zip(s, d, p, pc): 232 | if ss!=series[0][0]: 233 | plt.plot(sd[:,0], sd[:,sc] * np.pi * (sp["r"] * sp["from_um_factor"] * 1e3)**2, 234 | linestyle=pls, color=spc, label=psl(ss)) 235 | 236 | plt.plot(wlens, scatt_eff_theory * np.pi * (sp["r"] * sp["from_um_factor"] * 1e3)**2, 237 | linestyle="dashed", color='red', label="Mie Theory") 238 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 239 | plt.ylabel(r"Scattering Cross Section [nm$^2$]") 240 | plt.legend() 241 | if plot_make_big: 242 | mng = plt.get_current_fig_manager() 243 | mng.window.showMaximized() 244 | del mng 245 | vs.saveplot(plot_file("AllScatt.png"), overwrite=True) 246 | -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Paper/au_mie_sphere_paper_tfcell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.pylab as plab 12 | import os 13 | import PyMieScatt as ps 14 | import v_analysis as va 15 | from vmp_materials import import_medium 16 | import v_save as vs 17 | import v_utilities as vu 18 | 19 | #%% PARAMETERS 20 | 21 | # Saving directories 22 | folder = ["AuMieSphere/AuMie/13)TestPaper/4)PaperJCFit/TestTFCell/AllVac450800"] 23 | home = vs.get_home() 24 | 25 | # Sorting and labelling data series 26 | sorting_function = [lambda l : vu.sort_by_number(l, -2)] 27 | # def special_label(s): 28 | # if "5" in s: 29 | # return "Mie" 30 | # else: 31 | # return "" 32 | series_label = [lambda s : f"Meep factor {vu.find_numbers(s)[-2]}"] 33 | series_must = [""] # leave "" per default 34 | series_mustnt = [""] # leave "" per default 35 | series_column = [1] 36 | 37 | # Scattering plot options 38 | plot_title = "JC Au 103 nm sphere in vacuum" 39 | series_colors = [plab.cm.Reds] 40 | series_linestyles = ["solid"] 41 | plot_make_big = False 42 | plot_file = lambda n : os.path.join(home, "DataAnalysis/PaperTFCell" + n) 43 | 44 | #%% LOAD DATA 45 | 46 | path = [] 47 | file = [] 48 | series = [] 49 | data = [] 50 | params = [] 51 | header = [] 52 | 53 | for f, sf, sm, smn in zip(folder, sorting_function, series_must, series_mustnt): 54 | 55 | path.append( os.path.join(home, f) ) 56 | file.append( lambda f, s : os.path.join(path[-1], f, s) ) 57 | 58 | series.append( os.listdir(path[-1]) ) 59 | series[-1] = vu.filter_by_string_must(series[-1], sm) 60 | if smn!="": series[-1] = vu.filter_by_string_must(series[-1], smn, False) 61 | series[-1] = sf(series[-1]) 62 | 63 | data.append( [] ) 64 | params.append( [] ) 65 | for s in series[-1]: 66 | data[-1].append(np.loadtxt(file[-1](s, "Results.txt"))) 67 | params[-1].append(vs.retrieve_footer(file[-1](s, "Results.txt"))) 68 | header.append( vs.retrieve_header(file[-1](s, "Results.txt")) ) 69 | 70 | for i in range(len(params[-1])): 71 | if not isinstance(params[-1][i], dict): 72 | params[-1][i] = vu.fix_params_dict(params[-1][i]) 73 | 74 | r = [] 75 | from_um_factor = [] 76 | for par in params: 77 | r.append([p["r"] for p in par]) 78 | from_um_factor.append([p["from_um_factor"] for p in par]) 79 | 80 | #%% LOAD MIE DATA 81 | 82 | from_um_factor = params[0][0]["from_um_factor"] 83 | wlen_range = params[0][0]["wlen_range"] 84 | r = params[0][0]["r"] 85 | index = params[0][0]["submerged_index"] 86 | 87 | medium = import_medium("Au", from_um_factor, paper="JC") 88 | 89 | wlens = data[0][-1][:,0] 90 | freqs = 1e3*from_um_factor/wlens 91 | scatt_eff_theory = [ps.MieQ(np.sqrt(medium.epsilon(f)[0,0]*medium.mu(f)[0,0]), 92 | 1e3*from_um_factor/f, 93 | 2*r*1e3*from_um_factor, 94 | nMedium=index, 95 | asDict=True)['Qsca'] 96 | for f in freqs] 97 | scatt_eff_theory = np.array(scatt_eff_theory) 98 | 99 | #%% GET MAX WAVELENGTH 100 | 101 | max_wlen = [] 102 | for d, sc in zip(data, series_column): 103 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 104 | max_wlen_theory = wlens[np.argmax(scatt_eff_theory)] 105 | 106 | dif_max_wlen = [ml - max_wlen_theory for ml in max_wlen[0]] 107 | 108 | #%% WAVELENGTH MAXIMUM DIFFERENCE VS TIME FACTOR CELL 109 | 110 | time_factor_cell = [p["time_factor_cell"] for p in params[0]] 111 | 112 | plt.title("Difference in scattering maximum for " + plot_title) 113 | plt.plot(time_factor_cell, dif_max_wlen, '.', markersize=12) 114 | plt.grid(True) 115 | plt.legend(["Data", r"Fit $f(r)=a_0 e^{-a_1 r} + a_2$"]) 116 | plt.xlabel("Time factor cell") 117 | plt.ylabel("Difference in wavelength $\lambda_{max}^{MEEP}-\lambda_{max}^{MIE}$ [nm]") 118 | vs.saveplot(plot_file("WLenDiff.png"), overwrite=True) 119 | 120 | #%% GET ELAPSED TIME COMPARED 121 | 122 | time_factor_cell = [[p["time_factor_cell"] for p in par] for par in params] 123 | elapsed_time = [[p["elapsed"] for p in par] for par in params] 124 | total_elapsed_time = [[sum(p["elapsed"]) for p in par] for par in params] 125 | 126 | first_time_factor_cell = [] 127 | second_time_factor_cell = [] 128 | first_build_time = [] 129 | first_sim_time = [] 130 | second_flux_time = [] 131 | second_build_time = [] 132 | second_sim_time = [] 133 | for enl, tfc in zip(elapsed_time, time_factor_cell): 134 | first_time_factor_cell.append( [] ) 135 | first_build_time.append( [] ) 136 | first_sim_time.append( [] ) 137 | second_time_factor_cell.append( [] ) 138 | second_flux_time.append( [] ) 139 | second_build_time.append( [] ) 140 | second_sim_time.append( [] ) 141 | for e, tf in zip(enl, tfc): 142 | if len(e)==5: 143 | first_time_factor_cell[-1].append( tf ) 144 | second_time_factor_cell[-1].append( tf ) 145 | first_build_time[-1].append( e[0] ) 146 | first_sim_time[-1].append( e[1] ) 147 | second_build_time[-1].append( e[2] ) 148 | second_flux_time[-1].append( e[3] ) 149 | second_sim_time[-1].append( e[4] ) 150 | elif len(e)==3: 151 | second_time_factor_cell[-1].append( tf ) 152 | second_build_time[-1].append( e[0] ) 153 | second_flux_time[-1].append( e[1] ) 154 | second_sim_time[-1].append( e[2] ) 155 | else: 156 | print(f"Unknown error in time_factor_cell {tf} of", tfc) 157 | 158 | plt.figure() 159 | plt.title("elapsed total time for simulation of " + plot_title) 160 | for tfc, tot in zip(time_factor_cell, total_elapsed_time): 161 | plt.plot(tfc, tot, '.', markersize=12) 162 | plt.legend(["Meep R", "Meep JC"], loc="lower right") 163 | plt.xlabel("Time factor cell") 164 | plt.ylabel("elapsed time [s]") 165 | vs.saveplot(plot_file("ComparedTotTime.png"), overwrite=True) 166 | 167 | plt.figure() 168 | plt.title("elapsed time for simulations of " + plot_title) 169 | plt.plot(first_time_factor_cell[0], first_sim_time[0], 'D-', color="C0", label="Sim I") 170 | plt.plot(second_time_factor_cell[0], second_sim_time[0], 's-', color="C0", label="Sim II") 171 | plt.xlabel("Time factor cell") 172 | plt.ylabel("elapsed time in simulations [s]") 173 | plt.legend() 174 | plt.savefig(plot_file("ComparedSimTime.png"), bbox_inches='tight') 175 | 176 | plt.figure() 177 | plt.title("elapsed time for building of " + plot_title) 178 | plt.plot(first_time_factor_cell[0], first_build_time[0], 'D-', color="C0", label="Sim I") 179 | plt.plot(second_time_factor_cell[0], second_build_time[0], 's-', color="C0", label="Sim II") 180 | plt.xlabel("Time factor cell") 181 | plt.ylabel("elapsed time in building [s]") 182 | plt.legend() 183 | plt.savefig(plot_file("ComparedBuildTime.png"), bbox_inches='tight') 184 | 185 | plt.figure() 186 | plt.title("elapsed time for loading flux of " + plot_title) 187 | plt.plot(second_time_factor_cell[0], second_flux_time[0], 's-', color="C0", label="Sim II") 188 | plt.xlabel("Resolution") 189 | plt.ylabel("elapsed time in loading flux [s]") 190 | plt.savefig(plot_file("ComparedLoadTime.png"), bbox_inches='tight') 191 | 192 | #%% PLOT NORMALIZED 193 | 194 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 195 | for sc, s in zip(series_colors, series)] 196 | 197 | plt.figure() 198 | plt.title("Normalized scattering for " + plot_title) 199 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 200 | series_label, colors, series_linestyles): 201 | 202 | for ss, sd, sp, spc in zip(s, d, p, pc): 203 | if ss!=series[0][0] and ss!="TFCell1.2Res2": 204 | plt.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 205 | linestyle=pls, color=spc, label=psl(ss)) 206 | elif ss=="TFCell1.2Res2": 207 | plt.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 208 | linestyle=pls, color='b', label=psl(ss)) 209 | 210 | plt.plot(wlens, scatt_eff_theory / max(scatt_eff_theory), 211 | linestyle="dashed", color='red', label="Mie Theory") 212 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 213 | plt.ylabel("Normalized Scattering Cross Section") 214 | plt.legend(ncol=2) 215 | if plot_make_big: 216 | mng = plt.get_current_fig_manager() 217 | mng.window.showMaximized() 218 | del mng 219 | vs.saveplot(plot_file("AllScattNorm.png"), overwrite=True) 220 | 221 | #%% PLOT IN UNITS 222 | 223 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 224 | for sc, s in zip(series_colors, series)] 225 | 226 | plt.figure() 227 | plt.title("Scattering for " + plot_title) 228 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 229 | series_label, colors, series_linestyles): 230 | 231 | for ss, sd, sp, spc in zip(s, d, p, pc): 232 | if ss!=series[0][0]: 233 | plt.plot(sd[:,0], sd[:,sc] * np.pi * (sp["r"] * sp["from_um_factor"] * 1e3)**2, 234 | linestyle=pls, color=spc, label=psl(ss)) 235 | 236 | plt.plot(wlens, scatt_eff_theory * np.pi * (sp["r"] * sp["from_um_factor"] * 1e3)**2, 237 | linestyle="dashed", color='red', label="Mie Theory") 238 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 239 | plt.ylabel(r"Scattering Cross Section [nm$^2$]") 240 | plt.legend() 241 | if plot_make_big: 242 | mng = plt.get_current_fig_manager() 243 | mng.window.showMaximized() 244 | del mng 245 | vs.saveplot(plot_file("AllScatt.png"), overwrite=True) 246 | -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Paper/au_mie_sphere_paper_wlen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.pylab as plab 12 | import os 13 | import PyMieScatt as ps 14 | import v_analysis as va 15 | import vmp_materials as vml 16 | import v_save as vs 17 | import v_utilities as vu 18 | 19 | #%% PARAMETERS 20 | 21 | # Saving directories 22 | folder = ["AuMieSphere/AuMie/13)TestPaper/4)PaperJCFit/TestWLenJC/NewTime"] 23 | home = vs.get_home() 24 | 25 | # Sorting and labelling data series 26 | sorting_function = [lambda l : vu.sort_by_number(l, -2)] 27 | # def special_label(s): 28 | # if "5" in s: 29 | # return "Mie" 30 | # else: 31 | # return "" 32 | series_label = [lambda s : f"Meep $\lambda$ Range Max {vu.find_numbers(s)[-2]} nm"] 33 | series_must = [""] # leave "" per default 34 | series_mustnt = [""] # leave "" per default 35 | series_column = [1] 36 | 37 | # Scattering plot options 38 | plot_title = "Scattering for JC Au spheres in vacuum with 103 nm diameter" 39 | series_colors = [plab.cm.Reds] 40 | series_linestyles = ["solid"] 41 | plot_make_big = False 42 | plot_file = lambda n : os.path.join(home, "DataAnalysis/PaperWLenRange" + n) 43 | 44 | #%% LOAD DATA 45 | 46 | path = [] 47 | file = [] 48 | series = [] 49 | data = [] 50 | params = [] 51 | header = [] 52 | 53 | for f, sf, sm, smn in zip(folder, sorting_function, series_must, series_mustnt): 54 | 55 | path.append( os.path.join(home, f) ) 56 | file.append( lambda f, s : os.path.join(path[-1], f, s) ) 57 | 58 | series.append( os.listdir(path[-1]) ) 59 | series[-1] = vu.filter_by_string_must(series[-1], sm) 60 | if smn!="": series[-1] = vu.filter_by_string_must(series[-1], smn, False) 61 | series[-1] = sf(series[-1]) 62 | 63 | data.append( [] ) 64 | params.append( [] ) 65 | for s in series[-1]: 66 | data[-1].append(np.loadtxt(file[-1](s, "Results.txt"))) 67 | params[-1].append(vs.retrieve_footer(file[-1](s, "Results.txt"))) 68 | header.append( vs.retrieve_header(file[-1](s, "Results.txt")) ) 69 | 70 | for i in range(len(params[-1])): 71 | if not isinstance(params[-1][i], dict): 72 | params[-1][i] = vu.fix_params_dict(params[-1][i]) 73 | 74 | r = [] 75 | from_um_factor = [] 76 | for par in params: 77 | r.append([p["r"] for p in par]) 78 | from_um_factor.append([p["from_um_factor"] for p in par]) 79 | 80 | #%% LOAD MIE DATA 81 | 82 | from_um_factor = params[0][0]["from_um_factor"] 83 | wlen_range = params[0][0]["wlen_range"] 84 | r = params[0][0]["r"] 85 | index = params[0][0]["submerged_index"] 86 | 87 | medium = vml.import_medium("Au", from_um_factor, paper="JC") 88 | 89 | wlens = data[0][-1][:,0] 90 | freqs = 1e3*from_um_factor/wlens 91 | scatt_eff_theory = [ps.MieQ(np.sqrt(medium.epsilon(f)[0,0]*medium.mu(f)[0,0]), 92 | 1e3*from_um_factor/f, 93 | 2*r*1e3*from_um_factor, 94 | nMedium=index, 95 | asDict=True)['Qsca'] 96 | for f in freqs] 97 | scatt_eff_theory = np.array(scatt_eff_theory) 98 | 99 | #%% GET MAX WAVELENGTH 100 | 101 | max_wlen = [] 102 | for d, sc in zip(data, series_column): 103 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 104 | max_wlen_theory = wlens[np.argmax(scatt_eff_theory)] 105 | 106 | dif_max_wlen = [ml - max_wlen_theory for ml in max_wlen[0]] 107 | 108 | #%% WAVELENGTH MAXIMUM DIFFERENCE VS WAVELENGTH RANGE MAXIMUM 109 | 110 | wlen_maximum = [vu.find_numbers(s)[-2] for s in series[0]] 111 | 112 | plt.title("Difference in scattering maximum for Au 103 nm sphere in water") 113 | plt.plot(wlen_maximum, dif_max_wlen, '.k', markersize=12) 114 | plt.grid(True) 115 | plt.legend(["Data", r"Fit $f(r)=a_0 e^{-a_1 r} + a_2$"]) 116 | plt.xlabel("Wavelength Range Maximum [nm]") 117 | plt.ylabel("Difference in wavelength $\lambda_{max}^{MEEP}-\lambda_{max}^{MIE}$ [nm]") 118 | vs.saveplot(plot_file("WLenDiff.png"), overwrite=True) 119 | 120 | #%% AVERAGE RESIDUUM VS WAVELENGTH RANGE MAXIMUM 121 | 122 | residuums = [[scatt_eff_theory - d[:,1] for d in dat] for dat in data] 123 | 124 | plt.figure() 125 | for dat, res, ser in zip(data, residuums, series): 126 | for d, rs, s in zip(dat, res, ser): 127 | plt.plot(d[:,0], rs, '.', label=f"Range Max {vu.find_numbers(s)[-2]:.0f} nm") 128 | plt.legend() 129 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 130 | plt.ylabel("Scattering Effienciency Residuum") 131 | 132 | accumulated_residuums = [sum(r) for r in res for res in residuums] 133 | mean_residuums = [np.mean(r) for r in res for res in residuums] 134 | # ¿Cómo comparo estas curvas si tienen amplitudes distintas y recorren rangos distintos de longitud de onda? 135 | 136 | #%% 137 | 138 | norm_residuums = [[scatt_eff_theory/max(scatt_eff_theory) - d[:,1]/max(d[:,1]) for d in dat] for dat in data] 139 | 140 | plt.figure() 141 | for dat, res, ser in zip(data, norm_residuums, series): 142 | for d, r, s in zip(dat, res, ser): 143 | plt.plot(d[:,0], r, '.', label=f"Range Max {vu.find_numbers(s)[-2]:.0f} nm") 144 | plt.legend() 145 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 146 | plt.ylabel("Normalized Scattering Residuum") 147 | 148 | #%% GET ELAPSED TIME 149 | 150 | elapsed_time = [params[0][i]["elapsed"] for i in range(len(data[0]))] 151 | total_elapsed_time = [sum(et) for et in elapsed_time] 152 | 153 | rsq, m, b = va.linear_fit(np.array(wlen_maximum), 154 | np.array(total_elapsed_time), 155 | mb_units=["nm/s","s"]) 156 | 157 | # plt.figure() 158 | plt.title("elapsed total time for simulation of Au 103 nm sphere in water") 159 | # plt.plot(wlen_maximum, total_elapsed_time, '.k', markersize=12) 160 | plt.legend(["Data", r"Fit $f(r)=a_0 \lambda + a_1$"], loc="lower right") 161 | plt.xlabel("Wavelength Range Maximum [nm]") 162 | plt.ylabel("elapsed time [s]") 163 | vs.saveplot(plot_file("TotTime.png"), overwrite=True) 164 | 165 | plt.figure() 166 | plt.title("elapsed time for simulations of Au 103 nm sphere in water") 167 | plt.plot(wlen_maximum, [et[1] for et in elapsed_time], 'D-b', label="Sim I") 168 | plt.plot(wlen_maximum, [et[-1] for et in elapsed_time], 's-b', label="Sim II") 169 | plt.xlabel("Wavelength Range Maximum [nm]") 170 | plt.ylabel("elapsed time in simulations [s]") 171 | plt.legend() 172 | plt.savefig(plot_file("SimTime.png"), bbox_inches='tight') 173 | 174 | plt.figure() 175 | plt.title("elapsed time for building of Au 103 nm sphere in water") 176 | plt.plot(wlen_maximum, [et[0] for et in elapsed_time], 'D-r', label="Sim I") 177 | plt.plot(wlen_maximum, [et[2] for et in elapsed_time], 's-r', label="Sim II") 178 | plt.xlabel("Wavelength Range Maximum [nm]") 179 | plt.ylabel("elapsed time in building [s]") 180 | plt.legend() 181 | plt.savefig(plot_file("BuildTime.png"), bbox_inches='tight') 182 | 183 | plt.figure() 184 | plt.title("elapsed time for loading flux of Au 103 nm sphere in water") 185 | plt.plot(wlen_maximum, [et[3] for et in elapsed_time], 's-m') 186 | plt.xlabel("Wavelength Range Maximum [nm]") 187 | plt.ylabel("elapsed time in loading flux [s]") 188 | plt.savefig(plot_file("LoadTime.png"), bbox_inches='tight') 189 | 190 | #%% PLOT NORMALIZED 191 | 192 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 193 | for sc, s in zip(series_colors, series)] 194 | 195 | plt.figure() 196 | plt.title(plot_title) 197 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 198 | series_label, colors, series_linestyles): 199 | 200 | for ss, sd, sp, spc in zip(s, d, p, pc): 201 | if ss!=series[0][0]: 202 | plt.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 203 | linestyle=pls, color=spc, label=psl(ss)) 204 | 205 | plt.plot(wlens, scatt_eff_theory / max(scatt_eff_theory), 206 | linestyle="dashed", color='red', label="Mie Theory") 207 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 208 | plt.ylabel("Normalized Scattering Cross Section") 209 | plt.legend() 210 | if plot_make_big: 211 | mng = plt.get_current_fig_manager() 212 | mng.window.showMaximized() 213 | del mng 214 | vs.saveplot(plot_file("AllScattNorm.png"), overwrite=True) 215 | 216 | #%% PLOT IN UNITS 217 | 218 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 219 | for sc, s in zip(series_colors, series)] 220 | 221 | plt.figure() 222 | plt.title(plot_title) 223 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 224 | series_label, colors, series_linestyles): 225 | 226 | for ss, sd, sp, spc in zip(s, d, p, pc): 227 | if ss!=series[0][0]: 228 | plt.plot(sd[:,0], sd[:,sc] * np.pi * (sp["r"] * sp["from_um_factor"] * 1e3)**2, 229 | linestyle=pls, color=spc, label=psl(ss)) 230 | 231 | plt.plot(wlens, scatt_eff_theory * np.pi * (sp["r"] * sp["from_um_factor"] * 1e3)**2, 232 | linestyle="dashed", color='red', label="Mie Theory") 233 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 234 | plt.ylabel(r"Scattering Cross Section [nm$^2$]") 235 | plt.legend() 236 | if plot_make_big: 237 | mng = plt.get_current_fig_manager() 238 | mng.window.showMaximized() 239 | del mng 240 | vs.saveplot(plot_file("AllScatt.png"), overwrite=True) 241 | -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Vacuum/au_mie_sphere_vacuum_diameters.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.gridspec as gridspec 11 | import matplotlib.pyplot as plt 12 | import matplotlib.pylab as plab 13 | import os 14 | import v_save as vs 15 | import v_utilities as vu 16 | 17 | english = False 18 | trs = vu.BilingualManager(english=english) 19 | 20 | #%% PARAMETERS 21 | 22 | # Saving directories 23 | folder = ["Scattering/AuSphere/AllVacTest/7)Diameters/WLen4560", 24 | "Scattering/AuSphere/AllVacTest/7)Diameters/WLen4560"] 25 | home = vs.get_home() 26 | 27 | # Sorting and labelling data series 28 | sorting_function = [vu.sort_by_number, vu.sort_by_number] 29 | series_label = [lambda s : f"Meep {vu.find_numbers(s)[0]} nm", 30 | lambda s : f"Mie {vu.find_numbers(s)[0]} nm"] 31 | series_label = [lambda s : trs.choose("MEEP Data", "Datos MEEP") + f" {vu.find_numbers(s)[0]} nm", 32 | lambda s : trs.choose("Mie Theory", "Teoría Mie") + f" {vu.find_numbers(s)[0]} nm",] 33 | series_must = ["SC", "SC"] # leave "" per default 34 | series_column = [1, 2] 35 | 36 | # Scattering plot options 37 | plot_title = trs.choose("Scattering for Au spheres of different diameters in vacuum", 38 | "Dispersión de esferas de Au de diferentes diámetros en vacío") 39 | series_colors = [plab.cm.Reds, plab.cm.Reds] 40 | series_linestyles = ["solid", "dashed"] 41 | plot_make_big = True 42 | plot_file = lambda n : os.path.join(home, "DataAnalysis", n) 43 | 44 | #%% LOAD DATA 45 | 46 | path = [] 47 | file = [] 48 | series = [] 49 | data = [] 50 | params = [] 51 | header = [] 52 | 53 | for f, sf, sm in zip(folder, sorting_function, series_must): 54 | 55 | path.append( os.path.join(home, f) ) 56 | file.append( lambda f, s : os.path.join(path[-1], f, s) ) 57 | 58 | series.append( os.listdir(path[-1]) ) 59 | series[-1] = vu.filter_to_only_directories(series[-1]) 60 | series[-1] = vu.filter_by_string_must(series[-1], sm) 61 | series[-1] = sf(series[-1]) 62 | 63 | data.append( [] ) 64 | params.append( [] ) 65 | for s in series[-1]: 66 | data[-1].append(np.loadtxt(file[-1](s, "Results.txt"))) 67 | params[-1].append(vs.retrieve_footer(file[-1](s, "Results.txt"))) 68 | header.append( vs.retrieve_header(file[-1](s, "Results.txt")) ) 69 | 70 | for i in range(len(params[-1])): 71 | if not isinstance(params[-1][i], dict): 72 | params[-1][i] = vu.fix_params_dict(params[-1][i]) 73 | 74 | # r = [p["r"] for p in params] 75 | # from_um_factor = [p["from_um_factor"] for p in params] 76 | 77 | #%% GET MAX WAVELENGTH 78 | 79 | max_wlen = [] 80 | for d, sc in zip(data, series_column): 81 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 82 | dif_max_wlen = [max_wlen[0][i] - max_wlen[1][i] for i in range(len(data[0]))] 83 | 84 | e_wlen = [] 85 | for d in data: 86 | e_wlen.append( np.mean([ d[i][j, 0] - d[i][j+1, 0] 87 | for j in range(len(d[i])-1) 88 | for i in range(len(d))]) ) 89 | 90 | max_wlen = [] 91 | e_max_wlen = [] 92 | part_max_wlen = [] 93 | for d, sc in zip(data, series_column): 94 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 95 | part_max_wlen.append( [ 96 | [d[i][np.argmax(d[i][:,sc])-1, 0], d[i][np.argmax(d[i][:,sc])+1, 0] ] 97 | for i in range(len(d)) ] ) 98 | e_max_wlen.append( [ np.mean([ 99 | abs(d[i][np.argmax(d[i][:,sc])-1, 0] - d[i][np.argmax(d[i][:,sc]), 0]), 100 | abs(d[i][np.argmax(d[i][:,sc])+1, 0] - d[i][np.argmax(d[i][:,sc]), 0]) 101 | ]) for i in range(len(d)) ] ) 102 | dif_max_wlen = [max_wlen[0][i] - max_wlen[1][i] for i in range(len(data[0]))] 103 | e_dif_max_wlen = [np.mean([e_max_wlen[0][i], e_max_wlen[1][i]]) for i in range(len(data[0]))] 104 | 105 | #%% NORMALIZED PLOT 106 | 107 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 108 | for sc, s in zip(series_colors, series)] 109 | 110 | plt.figure() 111 | plt.title(plot_title) 112 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 113 | series_label, colors, series_linestyles): 114 | 115 | for ss, sd, sp, spc in zip(s, d, p, pc): 116 | plt.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 117 | linestyle=pls, color=spc, label=psl(ss)) 118 | 119 | plt.xlabel(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 120 | plt.ylabel(trs.choose("Normalized Scattering Cross Section", 121 | "Sección eficaz de dispersión normalizada")) 122 | plt.legend() 123 | if plot_make_big: 124 | mng = plt.get_current_fig_manager() 125 | mng.window.showMaximized() 126 | del mng 127 | vs.saveplot(plot_file("AllScatt.png"), overwrite=True) 128 | 129 | #%% NON NORMALIZED PLOT 130 | 131 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 132 | for sc, s in zip(series_colors, series)] 133 | 134 | plt.figure() 135 | plt.title(plot_title) 136 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 137 | series_label, colors, series_linestyles): 138 | 139 | for ss, sd, sp, spc in zip(s, d, p, pc): 140 | plt.plot(sd[:,0], sd[:,sc], 141 | linestyle=pls, color=spc, label=psl(ss)) 142 | 143 | plt.xlabel(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 144 | plt.ylabel(trs.choose("Scattering Efficiency", "Eficacia de Dispersión")) 145 | plt.legend() 146 | if plot_make_big: 147 | mng = plt.get_current_fig_manager() 148 | mng.window.showMaximized() 149 | del mng 150 | vs.saveplot(plot_file("AllScattEf.png"), overwrite=True) 151 | 152 | #%% IN UNITS PLOT 153 | 154 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 155 | for sc, s in zip(series_colors, series)] 156 | 157 | plt.figure() 158 | plt.title(plot_title) 159 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 160 | series_label, colors, series_linestyles): 161 | 162 | for ss, sd, sp, spc in zip(s, d, p, pc): 163 | plt.plot(sd[:,0], sd[:,sc] * np.pi * (sp['r'] * sp['from_um_factor'] * 1e3)**2, 164 | linestyle=pls, color=spc, label=psl(ss)) 165 | 166 | plt.xlabel(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 167 | plt.ylabel(trs.choose("Scattering Cross Section [nm$^2$]", 168 | "Sección eficaz de dispersión [nm$^2$]")) 169 | plt.legend() 170 | if plot_make_big: 171 | mng = plt.get_current_fig_manager() 172 | mng.window.showMaximized() 173 | del mng 174 | vs.saveplot(plot_file("AllScattSec.png"), overwrite=True) 175 | 176 | 177 | #%% ONE HUGE PLOT 178 | 179 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 180 | for sc, s in zip(series_colors, series)] 181 | 182 | fig = plt.figure() 183 | plot_grid = gridspec.GridSpec(ncols=4, nrows=2, hspace=0.5, wspace=0.5, figure=fig) 184 | 185 | main_ax = fig.add_subplot(plot_grid[:,0:2]) 186 | main_ax.set_title(trs.choose("All Diameters", "Todos los diámetros")) 187 | main_ax.xaxis.set_label_text(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 188 | main_ax.yaxis.set_label_text(trs.choose("Normalized Scattering Cross Section", 189 | "Sección eficaz de dispersión normalizada")) 190 | 191 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 192 | series_label, colors, series_linestyles): 193 | 194 | for ss, sd, sp, spc in zip(s, d, p, pc): 195 | main_ax.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 196 | linestyle=pls, color=spc, label=psl(ss)) 197 | main_ax.legend() 198 | 199 | plot_list = [plot_grid[0,2], plot_grid[0,3], plot_grid[1,2], plot_grid[1,3]] 200 | axes_list = [] 201 | for pl in plot_list: 202 | axes_list.append(fig.add_subplot(pl)) 203 | 204 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 205 | series_label, colors, series_linestyles): 206 | for ax, ss, sd, sp, spc in zip(axes_list, s, d, p, pc): 207 | ax.set_title(trs.choose("Diameter", "Diámetro") + 208 | f" {2*sp['r']*sp['from_um_factor']*1e3: 1.0f} nm") 209 | ax.plot(sd[:,0], sd[:,sc] * np.pi * (sp['r'] * sp['from_um_factor'] * 1e3)**2, 210 | linestyle=pls, color=spc, label=psl(ss)) 211 | ax.xaxis.set_label_text(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 212 | ax.yaxis.set_label_text(trs.choose("Scattering Cross Section [nm$^2$]", 213 | "Sección eficaz de dispersión [nm$^2$]")) 214 | 215 | fig.set_size_inches([13.09, 5.52]) 216 | 217 | vs.saveplot(plot_file("AllScattBig.png"), overwrite=True) -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Vacuum/au_mie_sphere_vacuum_maxres.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.pylab as plab 12 | import os 13 | import v_analysis as va 14 | import v_save as vs 15 | import v_utilities as vu 16 | 17 | #%% PARAMETERS 18 | 19 | # Saving directories 20 | folder = ["Scattering/AuSphere/AllVacTest/10)MaxRes/Max103FUMixRes", 21 | "Scattering/AuSphere/AllVacTest/10)MaxRes/Max103FUMixRes"] 22 | home = vs.get_home() 23 | 24 | # Sorting and labelling data series 25 | sorting_function = [lambda ls : vu.sort_by_number(ls, -1), 26 | lambda ls : vu.sort_by_number(ls, -1), ] 27 | series_label = [lambda s : f"Meep Resolution {vu.find_numbers(s)[-1]}", 28 | lambda s : "Mie Theory"] 29 | series_must = ["", ""] # leave "" per default 30 | series_column = [1, 2] 31 | 32 | # Scattering plot options 33 | plot_title = "Scattering for 103 nm Au sphere in vacuum" 34 | series_colors = [plab.cm.Reds, plab.cm.Reds] 35 | series_linestyles = ["solid", "dashed"] 36 | plot_make_big = True 37 | plot_file = lambda n : os.path.join(home, "DataAnalysis", "VacuumMax103FUMixRes"+n) 38 | 39 | #%% LOAD DATA 40 | 41 | path = [] 42 | file = [] 43 | series = [] 44 | data = [] 45 | params = [] 46 | header = [] 47 | 48 | for f, sf, sm in zip(folder, sorting_function, series_must): 49 | 50 | path.append( os.path.join(home, f) ) 51 | file.append( lambda f, s : os.path.join(path[-1], f, s) ) 52 | 53 | series.append( os.listdir(path[-1]) ) 54 | series[-1] = vu.filter_to_only_directories(series[-1]) 55 | series[-1] = vu.filter_by_string_must(series[-1], sm) 56 | series[-1] = sf(series[-1]) 57 | 58 | data.append( [] ) 59 | params.append( [] ) 60 | for s in series[-1]: 61 | data[-1].append(np.loadtxt(file[-1](s, "Results.txt"))) 62 | params[-1].append(vs.retrieve_footer(file[-1](s, "Results.txt"))) 63 | header.append( vs.retrieve_header(file[-1](s, "Results.txt")) ) 64 | 65 | for i in range(len(params[-1])): 66 | if not isinstance(params[-1][i], dict): 67 | params[-1][i] = vu.fix_params_dict(params[-1][i]) 68 | 69 | # r = [p["r"] for p in params] 70 | # from_um_factor = [p["from_um_factor"] for p in params] 71 | 72 | wlens = data[0][0][:,0] 73 | resolution = [vu.find_numbers(s)[-1] for s in series[0]] 74 | elapsed = [p["elapsed"] for p in params[0]] 75 | 76 | def special_label(s): 77 | if str(resolution[-1]) in s: 78 | return "Mie Theory" 79 | else: 80 | return "" 81 | series_label[-1] = special_label 82 | 83 | #%% GET MAX WAVELENGTH 84 | 85 | max_wlen = [] 86 | for d, sc in zip(data, series_column): 87 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 88 | dif_max_wlen = [max_wlen[0][i] - max_wlen[1][i] for i in range(len(data[0]))] 89 | 90 | def exponential_fit(X, A, b, C): 91 | return A * np.exp(-b*X) + C 92 | rsq, parameters = va.nonlinear_fit(np.array(resolution), 93 | np.array(dif_max_wlen), 94 | exponential_fit, 95 | par_units=["nm", "", "nm"]) 96 | 97 | plt.title("Difference in scattering maximum for Au 103 nm sphere in vacuum") 98 | plt.legend(["Data", r"Fit $f(r)=a_0 e^{-a_1 r} + a_2$"]) 99 | plt.xlabel("Resolution") 100 | plt.ylabel("Difference in wavelength $\lambda_{max}^{MEEP}-\lambda_{max}^{MIE}$") 101 | vs.saveplot(plot_file("WLenDiff.png"), overwrite=True) 102 | 103 | #%% GET ELAPSED TIME 104 | 105 | elapsed_time = [params[0][i]["elapsed"] for i in range(len(data[0]))] 106 | total_elapsed_time = [sum(et) for et in elapsed_time] 107 | 108 | def quartic_fit(X, A, b): 109 | return A * (X)**4 + b 110 | rsq, parameters = va.nonlinear_fit(np.array(resolution), 111 | np.array(total_elapsed_time), 112 | quartic_fit, 113 | par_units=["s","s"]) 114 | 115 | plt.title("elapsed time simulation of Au 103 nm sphere in vacuum") 116 | # plt.plot(resolution, total_elapsed_time) 117 | plt.legend(["Data", r"Fit $f(r)=a_0 r^4 + a_1$"], loc="lower right") 118 | plt.xlabel("Resolution") 119 | plt.ylabel("elapsed time [s]") 120 | vs.saveplot(plot_file("TotTime.png"), overwrite=True) 121 | 122 | plt.figure() 123 | plt.title("elapsed time for simulations of Au 103 nm sphere in vacuum") 124 | plt.plot(resolution, [et[1] for et in elapsed_time], 'D-b', label="Sim I") 125 | plt.plot(resolution, [et[-1] for et in elapsed_time], 's-b', label="Sim II") 126 | plt.xlabel("Resolution") 127 | plt.ylabel("elapsed time in simulations [s]") 128 | plt.legend() 129 | plt.savefig(plot_file("SimTime.png"), bbox_inches='tight') 130 | 131 | plt.figure() 132 | plt.title("elapsed time for building of Au 103 nm sphere in vacuum") 133 | plt.plot(resolution, [et[0] for et in elapsed_time], 'D-r', label="Sim I") 134 | plt.plot(resolution, [et[2] for et in elapsed_time], 's-r', label="Sim II") 135 | plt.xlabel("Resolution") 136 | plt.ylabel("elapsed time in building [s]") 137 | plt.legend() 138 | plt.savefig(plot_file("BuildTime.png"), bbox_inches='tight') 139 | 140 | plt.figure() 141 | plt.title("elapsed time for loading flux of Au 103 nm sphere in vacuum") 142 | plt.plot(resolution, [et[3] for et in elapsed_time], 's-m') 143 | plt.xlabel("Resolution") 144 | plt.ylabel("elapsed time in loading flux [s]") 145 | plt.savefig(plot_file("LoadTime.png"), bbox_inches='tight') 146 | 147 | #%% PLOT NORMALIZED 148 | 149 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 150 | for sc, s in zip(series_colors, series)] 151 | 152 | plt.figure() 153 | plt.title(plot_title) 154 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 155 | series_label, colors, series_linestyles): 156 | 157 | for ss, sd, sp, spc in zip(s, d, p, pc): 158 | if ss!=series[0][0]: 159 | plt.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 160 | linestyle=pls, color=spc, label=psl(ss)) 161 | 162 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 163 | plt.ylabel("Normalized Scattering Cross Section") 164 | plt.legend() 165 | if plot_make_big: 166 | mng = plt.get_current_fig_manager() 167 | mng.window.showMaximized() 168 | del mng 169 | vs.saveplot(plot_file("AllScatt.png"), overwrite=True) 170 | 171 | #%% PLOT EFFIENCIENCY 172 | 173 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 174 | for sc, s in zip(series_colors, series)] 175 | 176 | plt.figure() 177 | plt.title(plot_title) 178 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 179 | series_label, colors, series_linestyles): 180 | 181 | for ss, sd, sp, spc in zip(s, d, p, pc): 182 | if ss!=series[0][0]: 183 | plt.plot(sd[:,0], sd[:,sc],# / max(sd[:,sc]), 184 | linestyle=pls, color=spc, label=psl(ss)) 185 | 186 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 187 | plt.ylabel("Scattering Effiency") 188 | plt.legend() 189 | if plot_make_big: 190 | mng = plt.get_current_fig_manager() 191 | mng.window.showMaximized() 192 | del mng 193 | vs.saveplot(plot_file("AllScattEff.png"), overwrite=True) 194 | 195 | #%% PLOT IN UNITS 196 | 197 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 198 | for sc, s in zip(series_colors, series)] 199 | 200 | plt.figure() 201 | plt.title(plot_title) 202 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 203 | series_label, colors, series_linestyles): 204 | 205 | for ss, sd, sp, spc in zip(s, d, p, pc): 206 | if ss!=series[0][0]: 207 | plt.plot(sd[:,0], sd[:,sc] * np.pi * (sp['r'] * sp['from_um_factor'] * 1e3)**2, 208 | linestyle=pls, color=spc, label=psl(ss)) 209 | 210 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 211 | plt.ylabel(r"Scattering Cross Section [nm$^2$]") 212 | plt.legend() 213 | if plot_make_big: 214 | mng = plt.get_current_fig_manager() 215 | mng.window.showMaximized() 216 | del mng 217 | vs.saveplot(plot_file("AllScatt.png"), overwrite=True) -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Vacuum/au_mie_sphere_vacuum_parallel_NP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import os 12 | import v_save as vs 13 | import v_utilities as vu 14 | 15 | #%% PARAMETERS 16 | 17 | # Saving directories 18 | folder = "AuMieSphere/AuMie/8)TestParNP/2nd" 19 | home = vs.get_home() 20 | 21 | nprocesses = np.arange(8) + 1 22 | 23 | #%% LOAD DATA 24 | 25 | path = os.path.join(home, folder) 26 | file = lambda f, s : os.path.join(path, f, s) 27 | 28 | series = os.listdir(path) 29 | series.sort() 30 | 31 | params = [] 32 | for s in series: 33 | params.append(vs.retrieve_footer(file(s, "Results.txt"))) 34 | 35 | params = [vu.fix_params_dict(p) for p in params] 36 | 37 | elapsed = [p["elapsed"] for p in params] 38 | total = np.array([sum(e) for e in elapsed]) 39 | elapsed = np.array(elapsed) 40 | 41 | #%% PLOT 42 | 43 | plt.figure() 44 | # plt.plot(nprocesses, total_0, 'ro-', label="Serie 1") 45 | plt.plot(nprocesses, total, 'bo-', label="Serie 2") 46 | plt.xlabel("Número de subprocesos") 47 | plt.ylabel("Tiempo total (s)") 48 | plt.legend(["Serie 1", "Serie 2"]) 49 | plt.savefig(os.path.join(path, "Total.png"), bbox_inches='tight') 50 | 51 | #%% 52 | 53 | plt.figure() 54 | # plt.plot(nprocesses, elapsed_0[:,1], 's-r', label="Serie 1: Sim I") 55 | # plt.plot(nprocesses, elapsed_0[:,-1], 'o-r', label="Serie 1: Sim II") 56 | plt.plot(nprocesses, elapsed[:,1], 's-b', label="Serie 2: Sim I") 57 | plt.plot(nprocesses, elapsed[:,-1], 'o-b', label="Serie 2: Sim II") 58 | plt.xlabel("Número de subprocesos") 59 | plt.ylabel("Tiempo (s)") 60 | plt.legend() 61 | plt.savefig(os.path.join(path, "Simulations.png"), bbox_inches='tight') 62 | 63 | #%% 64 | 65 | plt.figure() 66 | # plt.plot(nprocesses, elapsed_0[:,0], 's-r', label="Serie 1: Init I") 67 | plt.plot(nprocesses, elapsed[:,0], 's-b', label="Serie 2: Init I") 68 | # plt.plot(nprocesses, elapsed_0[:,2], 'o-r', label="Serie 1: Init II") 69 | plt.plot(nprocesses, elapsed[:,2], 'o-b', label="Serie 2: Init II") 70 | plt.xlabel("Número de subprocesos") 71 | plt.ylabel("Tiempo (s)") 72 | plt.legend() 73 | plt.savefig(os.path.join(path, "Building.png"), bbox_inches='tight') 74 | 75 | #%% 76 | 77 | plt.figure() 78 | # plt.plot(nprocesses, elapsed_0[:,3], 'o-r', label="Serie 1: Load Flux") 79 | plt.plot(nprocesses, elapsed[:,3], 'o-b', label="Serie 2: Load Flux") 80 | plt.xlabel("Número de subprocesos") 81 | plt.ylabel("Tiempo (s)") 82 | plt.legend() 83 | plt.savefig(os.path.join(path, "LoadFlux.png"), bbox_inches='tight') 84 | 85 | #%% 86 | 87 | -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Water/au_mie_sphere_allwater_diameters.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.pylab as plab 12 | import matplotlib.gridspec as gridspec 13 | import os 14 | import PyMieScatt as ps 15 | from vmp_materials import import_medium 16 | import v_save as vs 17 | import v_utilities as vu 18 | import vmp_materials as vml 19 | 20 | english = False 21 | trs = vu.BilingualManager(english=english) 22 | 23 | #%% PARAMETERS 24 | 25 | # Saving directories 26 | folder = ["Scattering/AuSphere/AllWatDiam"] 27 | home = vs.get_home() 28 | 29 | # Sorting and labelling data series 30 | sorting_function = [vu.sort_by_number] 31 | series_must = [""] # leave "" per default 32 | series_mustnt = ["More"] # leave "" per default 33 | series_column = [1] 34 | 35 | # Scattering plot options 36 | plot_title = trs.choose("Scattering for Au spheres of different diameters in water", 37 | "Dispersión de esferas de Au de diferentes diámetros en agua") 38 | series_colors = [plab.cm.Blues] 39 | series_label = [lambda s : trs.choose("MEEP Data", "Datos MEEP") + 40 | f" {vu.find_numbers(s)[0]} nm"] 41 | series_linestyles = ["solid"] 42 | theory_label = lambda s : trs.choose("Mie Theory", "Teoría Mie") + f" {vu.find_numbers(s)[0]} nm" 43 | theory_linestyle = "dashed" 44 | plot_make_big = True 45 | plot_file = lambda n : os.path.join(home, "DataAnalysis", "AllWaterDiameters"+n) 46 | 47 | #%% LOAD DATA 48 | 49 | path = [] 50 | file = [] 51 | series = [] 52 | data = [] 53 | params = [] 54 | header = [] 55 | 56 | for f, sf, sm, smn in zip(folder, sorting_function, series_must, series_mustnt): 57 | 58 | path.append( os.path.join(home, f) ) 59 | file.append( lambda f, s : os.path.join(path[-1], f, s) ) 60 | 61 | series.append( os.listdir(path[-1]) ) 62 | series[-1] = vu.filter_to_only_directories(series[-1]) 63 | series[-1] = vu.filter_by_string_must(series[-1], sm) 64 | if smn!="": series[-1] = vu.filter_by_string_must(series[-1], smn, False) 65 | series[-1] = sf(series[-1]) 66 | 67 | data.append( [] ) 68 | params.append( [] ) 69 | for s in series[-1]: 70 | data[-1].append(np.loadtxt(file[-1](s, "Results.txt"))) 71 | params[-1].append(vs.retrieve_footer(file[-1](s, "Results.txt"))) 72 | header.append( vs.retrieve_header(file[-1](s, "Results.txt")) ) 73 | 74 | for i in range(len(params[-1])): 75 | if not isinstance(params[-1][i], dict): 76 | params[-1][i] = vu.fix_params_dict(params[-1][i]) 77 | 78 | r = [] 79 | from_um_factor = [] 80 | resolution = [] 81 | material = [] 82 | paper = [] 83 | index = [] 84 | for p in params: 85 | r.append( [pi["r"] for pi in p] ) 86 | from_um_factor.append( [pi["from_um_factor"] for pi in p] ) 87 | resolution.append( [pi["resolution"] for pi in p] ) 88 | index.append( [] ) 89 | for p in params[-1]: 90 | try: 91 | index[-1].append( p["submerged_index"] ) 92 | except KeyError: 93 | index[-1].append( 1.333 ) 94 | try: 95 | paper.append( [pi["paper"] for pi in p]) 96 | except: 97 | paper.append( ["R" for pi in p] ) 98 | try: 99 | material.append( [pi["material"] for pi in p] ) 100 | except: 101 | material.append( ["Au" for pi in p] ) 102 | 103 | #%% GET THEORY 104 | 105 | theory = [[vml.sigma_scatt_meep(r[i][j] * from_um_factor[i][j] * 1e3, 106 | material[i][j], paper[i][j], 107 | data[i][j][:,0], # wavelength in nm 108 | surrounding_index=index[i][j], 109 | asEfficiency=True) 110 | for j in range(len(series[i]))] for i in range(len(series))] 111 | 112 | max_wlen_theory = [[ data[i][j][ np.argmax(theory[i][j]) , 0 ] for j in range(len(series[i]))] for i in range(len(series))] 113 | 114 | #%% GET MAX WAVELENGTH 115 | 116 | # def wlen_range(material, surrounding_index): 117 | # if material=="Au": 118 | # if surrounding_index == 1: return (450, 750) 119 | # elif surrounding_index in (1.33, 1.333) : return (550, 850) 120 | # else: 121 | # raise ValueError("Please, expand this function.") 122 | 123 | # max_wlen_theory = [[vml.max_scatt_meep(r[i][j], 124 | # material[i][j], 125 | # paper[i][j], 126 | # wlen_range(material[i][j], 127 | # index[i][j]), 128 | # surrounding_index=index[i][j])[0] for j in range(len(series[i]))] for i in range(len(series))] 129 | 130 | max_wlen = [] 131 | for d, sc in zip(data, series_column): 132 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 133 | 134 | e_max_wlen = [] 135 | for d, t, sc in zip(data, theory, series_column): 136 | e_max_wlen.append( [ np.mean([ 137 | abs(d[i][np.argmax(d[i][:,sc])-1, 0] - d[i][np.argmax(t[i]), 0]), 138 | abs(d[i][np.argmax(d[i][:,sc])+1, 0] - d[i][np.argmax(t[i]), 0]) 139 | ]) for i in range(len(d)) ] ) 140 | dif_max_wlen = [max_wlen[0][i] - max_wlen_theory[0][i] for i in range(len(data[0]))] 141 | 142 | #%% PLOT NORMALIZED 143 | 144 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 145 | for sc, s in zip(series_colors, series)] 146 | 147 | plt.figure() 148 | plt.title(plot_title) 149 | for i in range(len(series)): 150 | for j in range(len(series[i])): 151 | plt.plot(data[i][j][:,0], 152 | data[i][j][:,series_column[i]] / max(data[i][j][:,series_column[i]]), 153 | linestyle=series_linestyles[i], color=colors[i][j], 154 | label=series_label[i](series[i][j])) 155 | plt.plot(data[i][j][:,0], 156 | theory[i][j] / max(theory[i][j]), 157 | linestyle=theory_linestyle, color=colors[i][j], 158 | label=theory_label(series[i][j])) 159 | 160 | plt.xlabel(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 161 | plt.ylabel(trs.choose("Normalized Scattering Cross Section", 162 | "Sección eficaz de dispersión normalizada")) 163 | plt.legend() 164 | if plot_make_big: 165 | mng = plt.get_current_fig_manager() 166 | mng.window.showMaximized() 167 | del mng 168 | vs.saveplot(plot_file("AllScattNorm.png"), overwrite=True) 169 | 170 | #%% PLOT EFFIENCIENCY 171 | 172 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 173 | for sc, s in zip(series_colors, series)] 174 | 175 | plt.figure() 176 | plt.title(plot_title) 177 | for i in range(len(series)): 178 | for j in range(len(series[i])): 179 | plt.plot(data[i][j][:,0], 180 | data[i][j][:,series_column[i]], 181 | linestyle=series_linestyles[i], color=colors[i][j], 182 | label=series_label[i](series[i][j])) 183 | plt.plot(data[i][j][:,0], 184 | theory[i][j], 185 | linestyle=theory_linestyle, color=colors[i][j], 186 | label=theory_label(series[i][j])) 187 | 188 | plt.xlabel(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 189 | plt.ylabel(trs.choose("Scattering Efficiency", "Eficacia de Dispersión")) 190 | plt.legend() 191 | if plot_make_big: 192 | mng = plt.get_current_fig_manager() 193 | mng.window.showMaximized() 194 | del mng 195 | vs.saveplot(plot_file("AllScattEff.png"), overwrite=True) 196 | 197 | #%% PLOT IN UNITS 198 | 199 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 200 | for sc, s in zip(series_colors, series)] 201 | 202 | plt.figure() 203 | plt.title(plot_title) 204 | for i in range(len(series)): 205 | for j in range(len(series[i])): 206 | plt.plot(data[i][j][:,0], 207 | data[i][j][:,series_column[i]] * np.pi * (r[i][j] * from_um_factor[i][j] * 1e3)**2, 208 | linestyle=series_linestyles[i], color=colors[i][j], 209 | label=series_label[i](series[i][j])) 210 | plt.plot(data[i][j][:,0], 211 | theory[i][j] * np.pi * (r[i][j] * from_um_factor[i][j] * 1e3)**2, 212 | linestyle=theory_linestyle, color=colors[i][j], 213 | label=theory_label(series[i][j])) 214 | 215 | plt.xlabel(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 216 | plt.ylabel(trs.choose("Scattering Cross Section [nm$^2$]", 217 | "Sección eficaz de dispersión [nm$^2$]")) 218 | plt.legend() 219 | if plot_make_big: 220 | mng = plt.get_current_fig_manager() 221 | mng.window.showMaximized() 222 | del mng 223 | vs.saveplot(plot_file("AllScatt.png"), overwrite=True) 224 | 225 | #%% ONE HUGE PLOT 226 | 227 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 228 | for sc, s in zip(series_colors, series)] 229 | 230 | fig = plt.figure() 231 | plot_grid = gridspec.GridSpec(ncols=4, nrows=2, hspace=0.5, wspace=0.5, figure=fig) 232 | 233 | main_ax = fig.add_subplot(plot_grid[:,0:2]) 234 | main_ax.set_title(trs.choose("All Diameters", "Todos los diámetros")) 235 | main_ax.xaxis.set_label_text(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 236 | main_ax.yaxis.set_label_text(trs.choose("Normalized Scattering Cross Section", 237 | "Sección eficaz de dispersión normalizada")) 238 | 239 | for i in range(len(series)): 240 | for j in range(len(series[i])): 241 | main_ax.plot(data[i][j][:,0], 242 | data[i][j][:,series_column[i]] / max(data[i][j][:,series_column[i]]), 243 | linestyle=series_linestyles[i], color=colors[i][j], 244 | label=series_label[i](series[i][j])) 245 | main_ax.plot(data[i][j][:,0], 246 | theory[i][j] / max(theory[i][j]), 247 | linestyle=theory_linestyle, color=colors[i][j], 248 | label=theory_label(series[i][j])) 249 | main_ax.legend() 250 | 251 | plot_list = [[plot_grid[0,2], plot_grid[0,3], plot_grid[1,2], plot_grid[1,3]]] 252 | axes_list = [[ fig.add_subplot(pl) for pl in plot_list[0] ]] 253 | 254 | for i in range(len(series)): 255 | for j in range(len(series[i])): 256 | axes_list[i][j].set_title(trs.choose("Diameter", "Diámetro") + 257 | f" {2 * r[i][j] * from_um_factor[i][j] * 1e3: 1.0f} nm") 258 | axes_list[i][j].plot(data[i][j][:,0], 259 | data[i][j][:,series_column[i]] * np.pi * (r[i][j] * from_um_factor[i][j] * 1e3)**2, 260 | linestyle=series_linestyles[i], color=colors[i][j], 261 | label=series_label[i](series[i][j])) 262 | axes_list[i][j].plot(data[i][j][:,0], 263 | theory[i][j] * np.pi * (r[i][j] * from_um_factor[i][j] * 1e3)**2, 264 | linestyle=theory_linestyle, color=colors[i][j], 265 | label=theory_label(series[i][j])) 266 | axes_list[i][j].xaxis.set_label_text(r"Longitud de onda $\lambda$ [nm]") 267 | axes_list[i][j].yaxis.set_label_text("Sección eficaz [nm$^2$]") 268 | axes_list[i][j].xaxis.set_label_text(trs.choose(r"Wavelength $\lambda$ [nm]", r"Longitud de onda $\lambda$ [nm]")) 269 | axes_list[i][j].yaxis.set_label_text(trs.choose("Scattering Cross Section [nm$^2$]", 270 | "Sección eficaz de dispersión [nm$^2$]")) 271 | 272 | fig.set_size_inches([13.09, 5.52]) 273 | 274 | vs.saveplot(plot_file("AllScattBig.png"), overwrite=True) -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Water/au_mie_sphere_allwater_flux_time.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.pylab as plab 12 | import os 13 | import PyMieScatt as ps 14 | from vmp_materials import import_medium 15 | import v_save as vs 16 | import v_utilities as vu 17 | 18 | #%% PARAMETERS 19 | 20 | # Saving directories 21 | folder = "AuMieMediums/AllWaterTest/7)TestFluxTime" 22 | home = vs.get_home() 23 | 24 | # Sorting and labelling data series 25 | sorting_function = lambda l:l 26 | series_must = "" # leave "" per default 27 | series_mustnt = "" # leave "" per default 28 | series_column = 1 29 | 30 | #%% LOAD DATA 31 | # for f, sf, sm, smn in zip(folder, sorting_function, series_must, series_mustnt): 32 | 33 | path = os.path.join(home, folder) 34 | file = lambda f, s : os.path.join(path, f, s) 35 | 36 | series = os.listdir(path) 37 | series = vu.filter_to_only_directories(series) 38 | series = vu.filter_by_string_must(series, series_must) 39 | if series_mustnt!="": series = vu.filter_by_string_must(series, series_mustnt, False) 40 | series = sorting_function(series) 41 | 42 | data = [] 43 | params = [] 44 | for s in series: 45 | data.append(np.loadtxt(file(s, "Results.txt"))) 46 | params.append(vs.retrieve_footer(file(s, "Results.txt"))) 47 | data_header = vs.retrieve_header(file(s, "Results.txt")) 48 | 49 | for i, p in enumerate(params): 50 | if not isinstance(p, dict): 51 | params[i] = vu.fix_params_dict(p) 52 | 53 | midflux = [] 54 | for s in series: 55 | midflux.append(np.loadtxt(file(s, "MidFlux.txt"))) 56 | midflux_header = vs.retrieve_header(file(s, "MidFlux.txt")) 57 | 58 | endflux = [] 59 | for s in series: 60 | endflux.append(np.loadtxt(file(s, "BaseResults.txt"))) 61 | endflux_header = vs.retrieve_header(file(s, "BaseResults.txt")) 62 | 63 | for i, p in enumerate(params): 64 | if not isinstance(p, dict): 65 | params[i] = vu.fix_params_dict(p) 66 | 67 | r = [] 68 | from_um_factor = [] 69 | resolution = [] 70 | index = [] 71 | second_time_factor = [] 72 | until_after_sources = [] 73 | time_factor_cell = [] 74 | for p in params: 75 | r.append( p["r"] ) 76 | from_um_factor.append( p["from_um_factor"] ) 77 | resolution.append( p["resolution"] ) 78 | until_after_sources.append( p["until_after_sources"] ) 79 | second_time_factor.append( p["second_time_factor"] ) 80 | time_factor_cell.append( p["time_factor_cell"] ) 81 | try: 82 | index.append( p["submerged_index"] ) 83 | except KeyError: 84 | index.append( 1.33 ) 85 | 86 | # print(until_after_sources[0] == until_after_sources[1] / (2*1.33)) 87 | 88 | #%% PLOT MIDFLUX 89 | 90 | freqs = [mf[:,0] for mf in midflux] 91 | 92 | ylims = [] 93 | for mflux in midflux: 94 | yl = (np.min(mflux[:,1:]), np.max(mflux[:,1:])) 95 | # print(yl) 96 | yl = (yl[0] - .1*(yl[1]-yl[0]), 97 | yl[1]+.1*(yl[1]-yl[0])) 98 | # print(yl) 99 | ylims.append(yl) 100 | ylims = (np.min(ylims), np.max(ylims)) 101 | 102 | linestyles = ["-c", ":k"] 103 | 104 | fig, ax = plt.subplots(3, 2, sharex=True) 105 | fig.subplots_adjust(hspace=0, wspace=.05) 106 | for a in ax[:,1]: 107 | a.yaxis.tick_right() 108 | a.yaxis.set_label_position("right") 109 | for a, h in zip(np.reshape(ax, 6), midflux_header[1:]): 110 | a.set_ylabel(h) 111 | 112 | for mflux, frqs, fum, ls in zip(midflux, freqs, from_um_factor, linestyles): 113 | for mf, a in zip(mflux[:,1:].T, np.reshape(ax, 6)): 114 | a.plot(1e3*fum/frqs, mf, ls) 115 | a.set_ylim(*ylims) 116 | ax[-1,0].set_xlabel(r"Wavelength $\lambda$ [nm]") 117 | ax[-1,1].set_xlabel(r"Wavelength $\lambda$ [nm]") 118 | 119 | a.legend(["Old Time", "New Time"]) 120 | 121 | # plt.savefig(file("MidFlux.png")) 122 | 123 | #%% PLOT FINAL FLUX 124 | 125 | freqs = [ef[:,0] for ef in endflux] 126 | 127 | ylims = [] 128 | for eflux in endflux: 129 | yl = (np.min(eflux[:,2:8]), np.max(eflux[:,2:8])) 130 | # print(yl) 131 | yl = (yl[0] - .05*(yl[1]-yl[0]), 132 | yl[1]+.05*(yl[1]-yl[0])) 133 | # print(yl) 134 | ylims.append(yl) 135 | ylims = (np.min(ylims), np.max(ylims)) 136 | 137 | linestyles = ["-c", ":k"] 138 | 139 | fig, ax = plt.subplots(3, 2, sharex=True) 140 | fig.subplots_adjust(hspace=0, wspace=.05) 141 | for a in ax[:,1]: 142 | a.yaxis.tick_right() 143 | a.yaxis.set_label_position("right") 144 | for a, h in zip(np.reshape(ax, 6), endflux_header[2:8]): 145 | a.set_ylabel(h) 146 | 147 | for eflux, frqs, fum, ls in zip(endflux, freqs, from_um_factor, linestyles): 148 | for ef, a in zip(eflux[:,2:8].T, np.reshape(ax, 6)): 149 | a.plot(1e3*fum/frqs, ef, ls) 150 | a.set_ylim(*ylims) 151 | ax[-1,0].set_xlabel(r"Wavelength $\lambda$ [nm]") 152 | ax[-1,1].set_xlabel(r"Wavelength $\lambda$ [nm]") 153 | 154 | a.legend(["Old Time", "New Time"]) 155 | 156 | # plt.savefig(file("EndFlux.png")) 157 | 158 | #%% PLOT SCATTERING 159 | 160 | wlens = [d[:,0] for d in data] 161 | 162 | ylims = [] 163 | for d, fum, rd in zip(data, from_um_factor, r): 164 | yl = (np.min(d[:,1]), np.max(d[:,1])) 165 | # print(yl) 166 | yl = (yl[0] - .05*(yl[1]-yl[0]), 167 | yl[1]+.05*(yl[1]-yl[0])) 168 | # print(yl) 169 | ylims.append(np.array(yl) * np.pi * (fum * rd * 1e3)**2 ) 170 | ylims = (np.min(ylims), np.max(ylims)) 171 | 172 | linestyles = ["-c", ":k"] 173 | 174 | plt.figure() 175 | for wl, d, rd, fum, ls in zip(wlens, data, r, from_um_factor, linestyles): 176 | plt.plot(wl, d[:,1] * np.pi * (fum * rd * 1e3)**2, ls) 177 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 178 | plt.ylabel(r"Scattering Cross Section [nm$^2$]") 179 | plt.ylim(*ylims) 180 | plt.legend(["Old Time", "New Time"]) 181 | 182 | # plt.savefig(file("Scattering.png")) -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/Water/au_mie_sphere_allwater_maxres.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Nov 11 12:24:04 2020 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.pylab as plab 12 | import os 13 | import PyMieScatt as ps 14 | import v_analysis as va 15 | from vmp_materials import import_medium 16 | import v_save as vs 17 | import v_utilities as vu 18 | 19 | #%% PARAMETERS 20 | 21 | # Saving directories 22 | folder = ["AuMieMediums/AllWaterMaxRes/AllWaterMax80Res"] 23 | home = vs.get_home() 24 | 25 | # Sorting and labelling data series 26 | sorting_function = [lambda l : vu.sort_by_number(l, -1)] 27 | # def special_label(s): 28 | # if "5" in s: 29 | # return "Mie" 30 | # else: 31 | # return "" 32 | series_label = [lambda s : f"Meep Resolution {vu.find_numbers(s)[-1]}"] 33 | series_must = [""] # leave "" per default 34 | series_mustnt = ["15"] # leave "" per default 35 | series_column = [1] 36 | 37 | # Scattering plot options 38 | plot_title = "Scattering for Au spheres in water with 103 nm diameter" 39 | series_colors = [plab.cm.Blues] 40 | series_linestyles = ["solid"] 41 | plot_make_big = True 42 | plot_file = lambda n : os.path.join(home, "DataAnalysis/AllWaterMax80FU20Res" + n) 43 | 44 | #%% LOAD DATA 45 | 46 | path = [] 47 | file = [] 48 | series = [] 49 | data = [] 50 | params = [] 51 | header = [] 52 | 53 | for f, sf, sm, smn in zip(folder, sorting_function, series_must, series_mustnt): 54 | 55 | path.append( os.path.join(home, f) ) 56 | file.append( lambda f, s : os.path.join(path[-1], f, s) ) 57 | 58 | series.append( os.listdir(path[-1]) ) 59 | series[-1] = vu.filter_by_string_must(series[-1], sm) 60 | if smn!="": series[-1] = vu.filter_by_string_must(series[-1], smn, False) 61 | series[-1] = sf(series[-1]) 62 | 63 | data.append( [] ) 64 | params.append( [] ) 65 | for s in series[-1]: 66 | data[-1].append(np.loadtxt(file[-1](s, "Results.txt"))) 67 | params[-1].append(vs.retrieve_footer(file[-1](s, "Results.txt"))) 68 | header.append( vs.retrieve_header(file[-1](s, "Results.txt")) ) 69 | 70 | for i in range(len(params[-1])): 71 | if not isinstance(params[-1][i], dict): 72 | params[-1][i] = vu.fix_params_dict(params[-1][i]) 73 | 74 | # r = [p["r"] for p in params] 75 | # from_um_factor = [p["from_um_factor"] for p in params] 76 | 77 | #%% LOAD MIE DATA 78 | 79 | from_um_factor = params[0][0]["from_um_factor"] 80 | wlen_range = params[0][0]["wlen_range"] 81 | r = params[0][0]["r"] 82 | index = params[0][0]["submerged_index"] 83 | 84 | medium = import_medium("Au", from_um_factor) 85 | 86 | wlens = data[0][0][:,0] 87 | freqs = 1e3*from_um_factor/wlens 88 | scatt_eff_theory = [ps.MieQ(np.sqrt(medium.epsilon(f)[0,0]*medium.mu(f)[0,0]), 89 | 1e3*from_um_factor/f, 90 | 2*r*1e3*from_um_factor, 91 | nMedium=index, 92 | asDict=True)['Qsca'] 93 | for f in freqs] 94 | scatt_eff_theory = np.array(scatt_eff_theory) 95 | 96 | #%% GET MAX WAVELENGTH 97 | 98 | max_wlen = [] 99 | for d, sc in zip(data, series_column): 100 | max_wlen.append( [d[i][np.argmax(d[i][:,sc]), 0] for i in range(len(d))] ) 101 | max_wlen_theory = wlens[np.argmax(scatt_eff_theory)] 102 | 103 | dif_max_wlen = [ml - max_wlen_theory for ml in max_wlen[0]] 104 | 105 | resolution = [vu.find_numbers(s)[-1] for s in series[0]] 106 | 107 | def exponential_fit(X, A, b, C): 108 | return A * np.exp(-b*X) + C 109 | 110 | # First value is wrong 111 | resolution_fit = resolution[1:] 112 | dif_max_wlen_fit = dif_max_wlen[1:] 113 | 114 | rsq, parameters = va.nonlinear_fit(np.array(resolution_fit), 115 | np.array(dif_max_wlen_fit), 116 | exponential_fit, 117 | par_units=["nm", "", "nm"]) 118 | 119 | plt.title("Difference in scattering maximum for Au 103 nm sphere in water") 120 | plt.legend(["Data", r"Fit $f(r)=a_0 e^{-a_1 r} + a_2$"]) 121 | plt.xlabel("Resolution") 122 | plt.ylabel("Difference in wavelength $\lambda_{max}^{MEEP}-\lambda_{max}^{MIE}$") 123 | vs.saveplot(plot_file("WLenDiff.png"), overwrite=True) 124 | 125 | #%% GET ELAPSED TIME 126 | 127 | elapsed_time = [params[0][i]["elapsed"] for i in range(len(data[0]))] 128 | total_elapsed_time = [sum(et) for et in elapsed_time] 129 | 130 | def quartic_fit(X, A, b): 131 | return A * (X)**4 + b 132 | rsq, parameters = va.nonlinear_fit(np.array(resolution), 133 | np.array(total_elapsed_time), 134 | quartic_fit, 135 | par_units=["s","s"]) 136 | 137 | plt.title("elapsed total time for simulation of Au 103 nm sphere in water") 138 | # plt.plot(resolution, total_elapsed_time) 139 | plt.legend(["Data", r"Fit $f(r)=a_0 r^4 + a_1$"], loc="lower right") 140 | plt.xlabel("Resolution") 141 | plt.ylabel("elapsed time [s]") 142 | vs.saveplot(plot_file("TotTime.png"), overwrite=True) 143 | 144 | plt.figure() 145 | plt.title("elapsed time for simulations of Au 103 nm sphere in water") 146 | plt.plot(resolution, [et[1] for et in elapsed_time], 'D-b', label="Sim I") 147 | plt.plot(resolution, [et[-1] for et in elapsed_time], 's-b', label="Sim II") 148 | plt.xlabel("Resolution") 149 | plt.ylabel("elapsed time in simulations [s]") 150 | plt.legend() 151 | plt.savefig(plot_file("SimTime.png"), bbox_inches='tight') 152 | 153 | plt.figure() 154 | plt.title("elapsed time for building of Au 103 nm sphere in water") 155 | plt.plot(resolution, [et[0] for et in elapsed_time], 'D-r', label="Sim I") 156 | plt.plot(resolution, [et[2] for et in elapsed_time], 's-r', label="Sim II") 157 | plt.xlabel("Resolution") 158 | plt.ylabel("elapsed time in building [s]") 159 | plt.legend() 160 | plt.savefig(plot_file("BuildTime.png"), bbox_inches='tight') 161 | 162 | plt.figure() 163 | plt.title("elapsed time for loading flux of Au 103 nm sphere in water") 164 | plt.plot(resolution, [et[3] for et in elapsed_time], 's-m') 165 | plt.xlabel("Resolution") 166 | plt.ylabel("elapsed time in loading flux [s]") 167 | plt.savefig(plot_file("LoadTime.png"), bbox_inches='tight') 168 | 169 | #%% PLOT NORMALIZED 170 | 171 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 172 | for sc, s in zip(series_colors, series)] 173 | 174 | plt.figure() 175 | plt.title(plot_title) 176 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 177 | series_label, colors, series_linestyles): 178 | 179 | for ss, sd, sp, spc in zip(s, d, p, pc): 180 | if ss!=series[0][0]: 181 | plt.plot(sd[:,0], sd[:,sc] / max(sd[:,sc]), 182 | linestyle=pls, color=spc, label=psl(ss)) 183 | 184 | plt.plot(wlens, scatt_eff_theory / max(scatt_eff_theory), 185 | linestyle="dashed", color='red', label="Mie Theory") 186 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 187 | plt.ylabel("Normalized Scattering Cross Section") 188 | plt.legend() 189 | if plot_make_big: 190 | mng = plt.get_current_fig_manager() 191 | mng.window.showMaximized() 192 | del mng 193 | vs.saveplot(plot_file("AllScattNorm.png"), overwrite=True) 194 | 195 | #%% PLOT EFFIENCIENCY 196 | 197 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 198 | for sc, s in zip(series_colors, series)] 199 | 200 | plt.figure() 201 | plt.title(plot_title) 202 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 203 | series_label, colors, series_linestyles): 204 | 205 | for ss, sd, sp, spc in zip(s, d, p, pc): 206 | if ss!=series[0][0]: 207 | plt.plot(sd[:,0], sd[:,sc],# / max(sd[:,sc]), 208 | linestyle=pls, color=spc, label=psl(ss)) 209 | 210 | plt.plot(wlens, scatt_eff_theory,# / max(scatt_eff_theory), 211 | linestyle="dashed", color='red', label="Mie Theory") 212 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 213 | plt.ylabel("Scattering Effiency") 214 | plt.legend() 215 | if plot_make_big: 216 | mng = plt.get_current_fig_manager() 217 | mng.window.showMaximized() 218 | del mng 219 | vs.saveplot(plot_file("AllScattEff.png"), overwrite=True) 220 | 221 | #%% PLOT IN UNITS 222 | 223 | colors = [sc(np.linspace(0,1,len(s)+3))[3:] 224 | for sc, s in zip(series_colors, series)] 225 | 226 | plt.figure() 227 | plt.title(plot_title) 228 | for s, d, p, sc, psl, pc, pls in zip(series, data, params, series_column, 229 | series_label, colors, series_linestyles): 230 | 231 | for ss, sd, sp, spc in zip(s, d, p, pc): 232 | if ss!=series[0][0]: 233 | plt.plot(sd[:,0], sd[:,sc] * np.pi * (r * from_um_factor * 1e3)**2, 234 | linestyle=pls, color=spc, label=psl(ss)) 235 | 236 | plt.plot(wlens, scatt_eff_theory * np.pi * (r * from_um_factor * 1e3)**2, 237 | linestyle="dashed", color='red', label="Mie Theory") 238 | plt.xlabel(r"Wavelength $\lambda$ [nm]") 239 | plt.ylabel(r"Scattering Cross Section [nm$^2$]") 240 | plt.legend() 241 | if plot_make_big: 242 | mng = plt.get_current_fig_manager() 243 | mng.window.showMaximized() 244 | del mng 245 | vs.saveplot(plot_file("AllScatt.png"), overwrite=True) 246 | -------------------------------------------------------------------------------- /AnalysisRoutines/Scattering/au_mie_sim_size_theory.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Sat Jul 24 11:32:22 2021 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | from matplotlib import cm 12 | 13 | #%% 14 | 15 | r = 51.5 16 | wlen_range_min = 450 17 | wlen_range_max = 600 18 | from_um_factor = 10e-3 19 | pml_wlen_factor = 0.38 20 | air_r_factor = 0.5 21 | time_factor_cell = 1.2 22 | second_time_factor = 10 23 | 24 | #%% 25 | 26 | def resolution_int(wlen_range_min): 27 | 28 | resolution = 8 * from_um_factor * 1e3 / wlen_range_min # 8 29 | # resolution = max( resolution, 5 * from_um_factor / r ) 30 | resolution = int( max([1, resolution]) ) 31 | 32 | return resolution 33 | 34 | def width_points_int(wlen_range_min, wlen_range_max): 35 | 36 | resolution = resolution_int(wlen_range_min) 37 | 38 | pml_width = pml_wlen_factor * wlen_range_max # 0.5 * max(wlen_range) 39 | air_width = air_r_factor * r # 0.5 * max(wlen_range) 40 | 41 | pml_width = pml_width / (1e3 * from_um_factor) 42 | air_width = pml_width / (1e3 * from_um_factor) 43 | 44 | pml_width = pml_width - pml_width%(1/resolution) 45 | air_width = air_width - air_width%(1/resolution) 46 | 47 | cell_width = 2 * (pml_width + air_width + r) 48 | cell_width = cell_width - cell_width%(1/resolution) 49 | 50 | return resolution * cell_width 51 | 52 | def width_points_array(wlen_range_min, wlen_range_max): 53 | 54 | width_points = [] 55 | 56 | for wmin in wlen_range_min: 57 | 58 | width_points.append([]) 59 | 60 | for wmax in wlen_range_max: 61 | 62 | width_points[-1].append( width_points_int(wmin, wmax) ) 63 | 64 | width_points = np.array(width_points).T 65 | 66 | return width_points 67 | 68 | #%% 69 | 70 | def points_int(wlen_range_min, wlen_range_max): 71 | 72 | return width_points_int(wlen_range_min, wlen_range_max)**3 73 | 74 | def points_array(wlen_range_min, wlen_range_max): 75 | 76 | return np.power( width_points_array(wlen_range_min, wlen_range_max) , 3) 77 | 78 | #%% 79 | 80 | wlen_range_min = np.linspace(250, 500, 100) 81 | wlen_range_max = np.linspace(600, 850, 100) 82 | 83 | width_points_surface = width_points_array(wlen_range_min, wlen_range_max) 84 | 85 | wlen_range_min, wlen_range_max = np.meshgrid(wlen_range_min, wlen_range_max) 86 | 87 | #%% 88 | 89 | fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) 90 | 91 | surf = ax.plot_surface(wlen_range_min, 92 | wlen_range_max, 93 | width_points_surface, 94 | cmap=cm.coolwarm, 95 | linewidth=0, antialiased=False) 96 | 97 | ax.set_xlabel(r"$\lambda_{min}$ [nm]") 98 | ax.set_ylabel(r"$\lambda_{max}$ [nm]") 99 | ax.set_zlabel("Points per grid side") 100 | np.power(np.array([2,3]),2) 101 | #%% 102 | 103 | wlen_range_min = np.linspace(250, 500, 100) 104 | wlen_range_max = np.linspace(600, 850, 100) 105 | 106 | points_surface = points_array(wlen_range_min, wlen_range_max) 107 | 108 | wlen_range_min, wlen_range_max = np.meshgrid(wlen_range_min, wlen_range_max) 109 | 110 | #%% 111 | 112 | fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) 113 | 114 | surf = ax.plot_surface(wlen_range_min, 115 | wlen_range_max, 116 | points_surface, 117 | cmap=cm.coolwarm, 118 | linewidth=0, antialiased=False) 119 | 120 | ax.set_xlabel(r"$\lambda_{min}$ [nm]") 121 | ax.set_ylabel(r"$\lambda_{max}$ [nm]") 122 | ax.set_zlabel("Points in grid") 123 | -------------------------------------------------------------------------------- /PlotRoutines/3d_simulation_plot.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Visualization of a 3D structure defined inside a sim.Simulation instance 4 | 5 | See also 6 | -------- 7 | Meep Tutorial: Visualizing 3D structures 8 | """ 9 | 10 | import meep as mp 11 | import numpy as np 12 | import matplotlib.pyplot as plt 13 | #from mayavi import mlab 14 | import math 15 | 16 | #%% DEFAULT SIMULATION 17 | # Do not run this if you have your own simulation defined 18 | 19 | cell_size = mp.Vector3(2,2,2) 20 | 21 | # A hexagon is defined as a prism with six vertices centered on the origin 22 | vertices = [mp.Vector3(-1,0), 23 | mp.Vector3(-0.5,math.sqrt(3)/2), 24 | mp.Vector3(0.5,math.sqrt(3)/2), 25 | mp.Vector3(1,0), 26 | mp.Vector3(0.5,-math.sqrt(3)/2), 27 | mp.Vector3(-0.5,-math.sqrt(3)/2)] 28 | 29 | geometry = [mp.Prism(vertices, height=1.0, material=mp.Medium(index=3.5)), 30 | mp.Cone(radius=1.0, radius2=0.1, height=2.0, material=mp.air)] 31 | 32 | sim = mp.Simulation(resolution=50, 33 | cell_size=cell_size, 34 | geometry=geometry) 35 | 36 | #%% STEPS TO GET DATA FROM SIMULATION 37 | 38 | sim.init_sim() 39 | 40 | x, y, z, *more = sim.get_array_metadata() # (x,y,z,w) = sim.get_array_metadata() 41 | # Returns coordinates and interpolation weights of the fields :) 42 | del more 43 | 44 | eps_data = sim.get_epsilon() 45 | 46 | #%% 3D VISUALIZATION VIA MAYABI SUGGESTED BY MEEP 47 | 48 | #s = mlab.contour3d(eps_data, colormap="YlGnBu") 49 | #mlab.show() 50 | 51 | #%% 3D SLICED VISUALIZATION VIA MATPLOTLIB 52 | 53 | n_slices = 3 54 | 55 | x0 = x[int(len(x)/2)] 56 | y0 = y[int(len(y)/2)] 57 | z0 = z[int(len(z)/2)] 58 | 59 | i_x0 = int(eps_data.shape[0]/2) 60 | i_y0 = int(eps_data.shape[1]/2) 61 | i_z0 = int(eps_data.shape[2]/2) 62 | 63 | titles = ["X=X0", "Y=Y0", "Z=Z0"] 64 | eps_slices = [eps_data[i_x0, :, :], eps_data[:, i_y0, :], eps_data[:, :, i_z0]] 65 | 66 | x_plot = [y, x, x] 67 | x_labels = ["Y", "X", "X"] 68 | y_plot = [z, z, y] 69 | y_labels = ["Z", "Z", "Y"] 70 | 71 | cmlims = (np.min(eps_slices), np.max(eps_slices)) 72 | cmlims = (cmlims[0]-.1*(cmlims[1]-cmlims[0]), 73 | cmlims[1]+.1*(cmlims[1]-cmlims[0])) 74 | 75 | nplots = n_slices 76 | fig, axes = plt.subplots(1, n_slices) 77 | fig.subplots_adjust(hspace=0.5, wspace=.5) 78 | fig.set_figheight = 6.4 79 | fig.set_figwidth = n_slices * 6.4 80 | plt.show() 81 | 82 | for ax, tl in zip(axes, titles): 83 | ax.yaxis.tick_right() 84 | ax.yaxis.set_label_position("right") 85 | ax.set_ylabel(tl) 86 | 87 | for ax, xp, yp, eps, tl, xl, yl in zip(axes, x_plot, y_plot, eps_slices, 88 | titles, x_labels, y_labels): 89 | ax.imshow(eps.T, interpolation='spline36', cmap='RdBu', 90 | vmin=cmlims[0], vmax=cmlims[1]) 91 | ax.axis("off") 92 | ax.xaxis.set_label_text(xl) 93 | ax.yaxis.set_label_text(yl) 94 | -------------------------------------------------------------------------------- /PlotRoutines/np_planewave_cell_plot.py: -------------------------------------------------------------------------------- 1 | """ 2 | Plot of a single spherical NP cell under incidence of a planewave source. 3 | 4 | See also 5 | -------- 6 | Routines/monoch_field 7 | Routines/np_monoch_field 8 | """ 9 | 10 | import matplotlib.pyplot as plt 11 | import numpy as np 12 | import vmp_utilities as vmu 13 | import v_plot as vp 14 | import v_utilities as vu 15 | 16 | vp.set_style() 17 | 18 | #%% PARAMETERS 19 | 20 | """ 21 | series = "DTest532" 22 | folder = "Field/NPMonoch/AuSphere/VacWatTest/DefinitiveTest/Vacuum" 23 | 24 | with_line = True 25 | with_plane = True 26 | with_flux_box = False 27 | with_nanoparticle = True 28 | 29 | english = False 30 | """ 31 | 32 | #%% 33 | 34 | def plot_np_planewave_cell(params, series, folder, 35 | with_line=False, with_plane=False, 36 | with_flux_box=False, with_flux_walls=False, 37 | with_nanoparticle=False, 38 | english=False): 39 | 40 | #%% SETUP 41 | 42 | # Saving directories 43 | sa = vmu.SavingAssistant(series, folder) 44 | 45 | trs = vu.BilingualManager(english=english) 46 | 47 | """ 48 | import h5py as h5 49 | 50 | f = h5.File(sa.file("Field-Lines.h5"), "r+") 51 | params = dict(f["Ez"].attrs) 52 | """ 53 | 54 | """ 55 | import v_save as vs 56 | 57 | params = vs.retrieve_footer(sa.file("Results.txt")) 58 | """ 59 | 60 | #%% DATA EXTRACTION 61 | 62 | from_um_factor = params["from_um_factor"] 63 | try: 64 | units = params["units"] 65 | except: 66 | units = True 67 | 68 | cell_width = params["cell_width"] 69 | pml_width = params["pml_width"] 70 | 71 | try: 72 | r = params["r"] 73 | material = params["material"] 74 | except: 75 | r = 0 76 | material = "none" 77 | with_nanoparticle = False 78 | 79 | try: 80 | wlen = params["wlen"] 81 | except: 82 | wlen_range = params["wlen_range"] 83 | wlen_center = np.mean(wlen_range) 84 | wlen_width = float(np.diff(wlen_range)) 85 | source_center = params["source_center"] 86 | 87 | submerged_index = params["submerged_index"] 88 | surface_index = params["surface_index"] 89 | try: 90 | overlap = params["overlap"] 91 | except: 92 | overlap = 0 93 | 94 | try: 95 | flux_box_size = params["flux_box_size"] 96 | except: 97 | flux_box_size = 0 98 | with_flux_box = False 99 | 100 | try: 101 | flux_wall_positions = params["flux_wall_positions"] 102 | except: 103 | flux_wall_positions = [] 104 | with_flux_walls = False 105 | 106 | #%% PLOT 107 | 108 | fig, ax = plt.subplots() 109 | ax.grid(False) 110 | 111 | # PML borders 112 | pml_out_square = plt.Rectangle((-cell_width/2, -cell_width/2), 113 | cell_width, cell_width, 114 | fill=False, edgecolor="m", linestyle="dashed", 115 | hatch='/', 116 | zorder=-20, 117 | label=trs.choose("PML borders", "Bordes PML")) 118 | pml_inn_square = plt.Rectangle((-cell_width/2+pml_width, 119 | -cell_width/2+pml_width), 120 | cell_width - 2*pml_width, cell_width - 2*pml_width, 121 | facecolor="white", edgecolor="m", 122 | linestyle="dashed", linewidth=1, zorder=-10) 123 | 124 | # Surrounding medium 125 | if submerged_index != 1: 126 | surrounding_square = plt.Rectangle((-cell_width/2, -cell_width/2), 127 | cell_width, cell_width, 128 | color="blue", alpha=.1, zorder=-6, 129 | label=trs.choose(fr"Medium $n$={submerged_index}", 130 | fr"Medio $n$={submerged_index}")) 131 | 132 | # Surface medium 133 | if surface_index != submerged_index: 134 | surface_square = plt.Rectangle((r - overlap, -cell_width/2), 135 | cell_width/2 - r + overlap, 136 | cell_width, 137 | edgecolor="navy", hatch=r"\\", 138 | fill=False, zorder=-3, 139 | label=trs.choose(fr"Surface $n$={surface_index}", 140 | fr"Superficie $n$={surface_index}")) 141 | # Nanoparticle 142 | if with_nanoparticle: 143 | if material=="Au": 144 | circle_color = "gold" 145 | elif material=="Ag": 146 | circle_color="darkgrey" 147 | else: 148 | circle_color="peru" 149 | circle = plt.Circle((0,0), r, color=circle_color, linewidth=1, alpha=.4, 150 | zorder=0, label=trs.choose(f"{material} Nanoparticle", 151 | f"Nanopartícula de {material}")) 152 | 153 | # Source 154 | ax.vlines(source_center, -cell_width/2, cell_width/2, 155 | color="r", linestyle="dashed", zorder=5, 156 | label=trs.choose("Planewave Source", "Fuente de ondas plana")) 157 | 158 | # Sampling line 159 | if with_line: 160 | ax.hlines(0, -cell_width/2, cell_width/2, 161 | color="blue", linestyle=":", zorder=7, # limegreen 162 | label=trs.choose("Sampling Line", "Línea de muestreo")) 163 | 164 | # Sampling plane 165 | if with_plane: 166 | ax.vlines(0, -cell_width/2, cell_width/2, 167 | color="blue", linestyle="dashed", zorder=7, 168 | label=trs.choose("Sampling Plane", "Plano de muestreo")) 169 | 170 | # Flux box 171 | if with_flux_box: 172 | flux_square = plt.Rectangle((-flux_box_size/2, -flux_box_size/2), 173 | flux_box_size, flux_box_size, 174 | linewidth=1, edgecolor="limegreen", linestyle="dashed", 175 | fill=False, zorder=10, 176 | label=trs.choose("Flux box", "Caja de flujo")) 177 | 178 | # Flux wall 179 | if with_flux_walls: 180 | for flux_x in flux_wall_positions: 181 | l = ax.vlines(flux_x, -cell_width/2+pml_width, cell_width/2-pml_width, 182 | color="limegreen", linestyle="dashed", zorder=10) 183 | l.set_label(trs.choose("Flux walls", "Paredes de flujo")) 184 | 185 | if with_nanoparticle: ax.add_patch(circle) 186 | if submerged_index!=1: ax.add_patch(surrounding_square) 187 | if surface_index!=submerged_index and surface_index!=1: ax.add_patch(surface_square) 188 | if with_flux_box: ax.add_patch(flux_square) 189 | ax.add_patch(pml_out_square) 190 | ax.add_patch(pml_inn_square) 191 | 192 | # General configuration 193 | box = ax.get_position() 194 | box.x0 = box.x0 - .26 * (box.x1 - box.x0) 195 | # box.x1 = box.x1 - .05 * (box.x1 - box.x0) 196 | box.y1 = box.y1 + .10 * (box.y1 - box.y0) 197 | ax.set_position(box) 198 | plt.legend(bbox_to_anchor=trs.choose( (1.53, 0.5), (1.60, 0.5) ), 199 | loc="center right", frameon=False) 200 | 201 | fig.set_size_inches(7.5, 4.8) 202 | ax.set_aspect("equal") 203 | plt.xlim(-cell_width/2, cell_width/2) 204 | plt.ylim(-cell_width/2, cell_width/2) 205 | plt.xlabel(trs.choose(r"Position $X$ [MPu]", r"Posición $X$ [uMP]")) 206 | plt.ylabel(trs.choose(r"Position $Z$ [MPu]", r"Posición $Z$ [uMP]")) 207 | 208 | if units: 209 | plt.annotate(trs.choose(f"1 MPu = {from_um_factor * 1e3:.0f} nm", 210 | f"1 uMP = {from_um_factor * 1e3:.0f} nm"), 211 | (5, 5), xycoords='figure points') 212 | try: 213 | plt.annotate(fr"$\lambda$ = {wlen * from_um_factor * 1e3:.0f} nm", 214 | (350, 5), xycoords='figure points', color="r") 215 | except: 216 | plt.annotate(fr"$\lambda_0$ = {wlen_center * from_um_factor * 1e3:.0f} nm" + 217 | ", " + 218 | fr"$\Delta\lambda$ = {wlen_width * from_um_factor * 1e3:.0f} nm", 219 | (345, 5), xycoords='figure points', color="r") 220 | else: 221 | plt.annotate(trs.choose(r"1 MPu = $\lambda$", 222 | r"1 uMP = $\lambda$"), 223 | (5, 5), xycoords='figure points') 224 | try: 225 | plt.annotate(fr"$\lambda$ = {wlen * from_um_factor * 1e3:.2f} " + 226 | trs.choose("MPu", "uMP"), 227 | (350, 5), xycoords='figure points', color="r") 228 | except: 229 | plt.annotate(fr"$\lambda_0$ = {wlen_center * from_um_factor * 1e3:.2f} " + 230 | trs.choose("MPu", "uMP") + ", " + 231 | fr"$\Delta\lambda$ = {wlen_width * from_um_factor * 1e3:.2f} " + 232 | trs.choose("MPu", "uMP"), 233 | (345, 5), xycoords='figure points', color="r") 234 | 235 | if with_nanoparticle or material=="none": 236 | plt.savefig(sa.file("SimBox.png")) 237 | else: 238 | plt.savefig(sa.file("SimBoxNorm.png")) 239 | -------------------------------------------------------------------------------- /PlotRoutines/pulse_field_plot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Analysis of single run of planewave pulse of Gaussian frequency profile. 5 | 6 | See also 7 | -------- 8 | Routines/pulse_field 9 | """ 10 | 11 | import imageio as mim 12 | import matplotlib.pyplot as plt 13 | import matplotlib.pylab as plab 14 | import matplotlib.gridspec as gridspec 15 | import numpy as np 16 | import os 17 | import vmp_utilities as vmu 18 | import vmp_analysis as vma 19 | import v_plot as vp 20 | import v_utilities as vu 21 | 22 | vp.set_style() 23 | 24 | #%% PARAMETERS 25 | 26 | """ 27 | series = "TestPulseField" 28 | folder = "Test" 29 | 30 | hfield = False 31 | 32 | make_plots = True 33 | make_gifs = False 34 | 35 | english = False 36 | maxnframes = 300 37 | """ 38 | 39 | #%% 40 | 41 | def plots_pulse_field(series, folder, units=False, hfield=False, 42 | make_plots=True, make_gifs=False, 43 | english=False, maxnframes=300): 44 | 45 | #%% SETUP 46 | 47 | # Computation 48 | pm = vmu.ParallelManager() 49 | n_processes, n_cores, n_nodes = pm.specs 50 | parallel = pm.parallel 51 | 52 | # Saving directories 53 | sa = vmu.SavingAssistant(series, folder) 54 | 55 | trs = vu.BilingualManager(english=english) 56 | 57 | #%% EXIT IF NOTHING TO BE DONE 58 | 59 | if not make_plots and not make_gifs: 60 | return 61 | 62 | #%% GET READY TO LOAD DATA 63 | 64 | f = pm.hdf_file(sa.file("Field-Lines.h5"), "r+") 65 | results_line = f["Ez"] 66 | t_line = np.array(f["T"]) 67 | x_line = np.array(f["X"]) 68 | 69 | if hfield: 70 | fh = pm.hdf_file(sa.file("Field-HLines.h5"), "r+") 71 | results_hline = f["Ez"] 72 | 73 | data = np.loadtxt(sa.file("Results.txt")) 74 | flux_wlens = data[:,0] 75 | flux_intensity = data[:,1:] 76 | 77 | params = dict(f["Ez"].attrs) 78 | 79 | from_um_factor = params["from_um_factor"] 80 | wlen_range = params["wlen_range"] 81 | submerged_index = params["submerged_index"] 82 | 83 | cell_width = params["cell_width"] 84 | pml_width = params["pml_width"] 85 | source_center = params["source_center"] 86 | 87 | until_after_sources = params["until_after_sources"] 88 | period_line = params["period_line"] 89 | flux_wall_positions = params["flux_wall_positions"] 90 | n_flux_walls = params["n_flux_walls"] 91 | 92 | units = params["units"] 93 | 94 | #%% PLOT CONFIGURATION 95 | 96 | if units: 97 | plot_title_base = trs.choose('Planewave pulse with ', 98 | "Pulso de frentes de onda plano con ") 99 | plot_title_base += r"$\lambda_0$ = " 100 | plot_title_base += f'{np.mean(wlen_range) * from_um_factor * 1e3:.0f} nm, ' 101 | plot_title_base += r"$\Delta\lambda$ = " 102 | plot_title_base += f'{float(np.diff(wlen_range)) * from_um_factor * 1e3:.0f} nm ' 103 | else: 104 | plot_title_base = trs.choose('Planewave pulse with ', 105 | "Pulso de frentes de onda plano con ") 106 | plot_title_base += r"$\Delta\lambda$ = " 107 | plot_title_base += f'{float(np.diff(wlen_range)) * from_um_factor * 1e3:.2f} ' 108 | plot_title_base += trs.choose("MPu", "uMP") 109 | 110 | #%% POSITION RECONSTRUCTION 111 | 112 | t_line_index = vma.def_index_function(t_line) 113 | x_line_index = vma.def_index_function(x_line) 114 | 115 | x_line_cropped = x_line[:x_line_index(cell_width/2 - pml_width)+1] 116 | x_line_cropped = x_line_cropped[x_line_index(-cell_width/2 + pml_width):] 117 | 118 | #%% DATA EXTRACTION 119 | 120 | source_results = vma.get_source_from_line(results_line, x_line_index, source_center) 121 | 122 | walls_results = [results_line[x_line_index(fx),:] for fx in flux_wall_positions] 123 | 124 | results_cropped_line = vma.crop_field_xprofile(results_line, x_line_index, 125 | cell_width, pml_width) 126 | 127 | flux_max_intensity = [np.max(flux_intensity[:,k]) for k in range(n_flux_walls)] 128 | 129 | #%% SHOW SOURCE AND FOURIER 130 | 131 | if make_plots and pm.assign(0): 132 | 133 | plt.figure() 134 | plt.title(plot_title_base) 135 | plt.plot(t_line, source_results) 136 | plt.xlabel(trs.choose(r"Time $T$ [MPu]", r"Tiempo $T$ [uMP]")) 137 | plt.ylabel(trs.choose(r"Electric Field $E_z(y=z=0)$ [au]", 138 | r"Campo eléctrico $E_z(y=z=0)$ [ua]")) 139 | 140 | plt.savefig(sa.file("Source.png")) 141 | 142 | fourier = np.abs(np.fft.rfft(source_results)) 143 | fourier_freq = np.fft.rfftfreq(len(source_results), d=period_line) 144 | if units: 145 | fourier_wlen = from_um_factor * 1e3 / fourier_freq 146 | else: 147 | fourier_wlen = 1 / fourier_freq 148 | fourier_max_wlen = fourier_wlen[ np.argmax(fourier) ] 149 | 150 | plt.figure() 151 | plt.title(plot_title_base) 152 | plt.plot(fourier_wlen, fourier) 153 | 154 | if units: 155 | plt.xlabel(trs.choose(r"Wavelength $\lambda$ [nm]", 156 | r"Longitud de onda $\lambda$ [nm]")) 157 | else: 158 | plt.xlabel(trs.choose(r"Wavelength $\lambda/n$ [$\lambda$]", 159 | r"Longitud de onda $\lambda/n$ [$\lambda$]")) 160 | plt.ylabel(trs.choose(r"Electric Field Fourier $\mathcal{F}\;(E_z)$ [ua]", 161 | r"Transformada del campo eléctrico $\mathcal{F}\;(E_z)$ [ua]")) 162 | 163 | if units: 164 | plt.annotate(trs.choose(f"Maximum at {fourier_max_wlen:.2f} nm", 165 | f"Máximo en {fourier_max_wlen:.2f} nm"), 166 | (5, 5), xycoords='figure points') 167 | else: 168 | plt.annotate(trs.choose(fr"Maximum at {fourier_max_wlen:.2f} $\lambda$", 169 | fr"Máximo en {fourier_max_wlen:.2f} $\lambda$"), 170 | (5, 5), xycoords='figure points') 171 | 172 | plt.savefig(sa.file("SourceFFT.png")) 173 | 174 | if units: plt.xlim([350, 850]) 175 | else: plt.xlim([0, 2]) 176 | 177 | plt.savefig(sa.file("SourceFFTZoom.png")) 178 | 179 | #%% SHOW FLUX 180 | 181 | if make_plots and pm.assign(1): 182 | 183 | colors = plab.cm.Greens(np.linspace(0,1,n_flux_walls+2)[2:]) 184 | 185 | plt.figure() 186 | for k in range(n_flux_walls): 187 | plt.plot(flux_wlens, flux_intensity[:,k], color=colors[k], 188 | alpha=0.7, linewidth=2) 189 | 190 | if units: 191 | plt.xlabel(trs.choose(r"Wavelength $\lambda$ [nm]", 192 | r"Longitud de onda $\lambda$ [nm]")) 193 | else: 194 | plt.xlabel(trs.choose(r"Wavelength $\lambda/n$ [$\lambda$]", 195 | r"Longitud de onda $\lambda/n$ [$\lambda$]")) 196 | plt.ylabel(trs.choose(r"Electromagnetic Flux $P(\lambda)$ [au]", 197 | r"Flujo electromagnético $P(\lambda)$ [ua]")) 198 | 199 | if units: 200 | plt.legend([f"x = {fw * 1e3 * from_um_factor:0f} nm" for fw in flux_wall_positions]) 201 | else: 202 | plt.legend([fr"x = {fw * 1e3 * from_um_factor:.2f} $\lambda$" for fw in flux_wall_positions]) 203 | 204 | plt.savefig(sa.file("Flux.png")) 205 | 206 | plt.figure() 207 | plt.plot(flux_wall_positions, flux_max_intensity, "o-") 208 | plt.axvline(linewidth=1, color="k") 209 | plt.axvline(-cell_width/2 + pml_width, color="k", linestyle="dashed") 210 | plt.axvline(cell_width/2 - pml_width, color="k", linestyle="dashed") 211 | 212 | plt.xlabel(trs.choose("Position $X$ [MPu]", "Posición $X$ [uMP]")) 213 | plt.ylabel(trs.choose(r"Electromagnetic Flux Maximum $P_{max}(\lambda)$ [au]", 214 | r"Máximo flujo electromagnético $P_{max}(\lambda)$ [ua]")) 215 | 216 | plt.savefig(sa.file("FluxMaximum.png")) 217 | 218 | #%% SHOW FIELD AT FLUX WALL 219 | 220 | if make_plots and pm.assign(0): 221 | 222 | colors = plab.cm.Greens(np.linspace(0,1,n_flux_walls+2)[2:]) 223 | 224 | plt.figure() 225 | for k in range(n_flux_walls): 226 | plt.plot(t_line, walls_results[k], color=colors[k], 227 | alpha=0.7, linewidth=2) 228 | 229 | plt.xlabel(trs.choose(r"Time $T$ [MPu]", r"Tiempo $T$ [uMP]")) 230 | plt.ylabel(trs.choose(r"Electric Field $E_z(y=z=0)$ [au]", 231 | r"Campo eléctrico $E_z(y=z=0)$ [ua]")) 232 | 233 | if units: 234 | plt.legend([f"x = {fw * 1e3 * from_um_factor:0f} nm" for fw in flux_wall_positions]) 235 | else: 236 | plt.legend([fr"x = {fw * 1e3 * from_um_factor:.2f} $\lambda$" for fw in flux_wall_positions]) 237 | 238 | plt.savefig(sa.file("FluxWallField.png")) 239 | 240 | #%% SHOW X AXIS FIELD 241 | 242 | if make_plots and pm.assign(1): 243 | 244 | plt.figure() 245 | T, X = np.meshgrid(t_line, x_line_cropped) 246 | plt.contourf(T, X, results_cropped_line, 100, cmap='RdBu') 247 | # for fx in flux_wall_positions: 248 | # plt.axhline(fx, color="limegreen", alpha=0.4, linewidth=2.5) 249 | plt.axhline(color="k", linewidth=1) 250 | plt.xlabel(trs.choose("Time [MPu]", "Tiempo [uMP]")) 251 | plt.ylabel(trs.choose("Position $X$ [MPu]", "Posición $X$ [uMP]")) 252 | plt.grid(False) 253 | 254 | plt.savefig(sa.file("CroppedXAxis.png")) 255 | 256 | plt.figure() 257 | T, X = np.meshgrid(t_line, x_line) 258 | plt.contourf(T, X, results_line, 100, cmap='RdBu') 259 | # for fx in flux_wall_positions: 260 | # plt.axhline(fx, color="limegreen", alpha=0.4, linewidth=2.5) 261 | plt.axhline(color="k", linewidth=1) 262 | plt.axhline(-cell_width/2 + pml_width, color="k", linestyle="dashed") 263 | plt.axhline(cell_width/2 - pml_width, color="k", linestyle="dashed") 264 | plt.xlabel(trs.choose("Time [MPu]", "Tiempo [uMP]")) 265 | plt.ylabel(trs.choose("Position $X$ [MPu]", "Posición $X$ [uMP]")) 266 | plt.grid(False) 267 | 268 | plt.savefig(sa.file("XAxis.png")) 269 | 270 | #%% MAKE LINES GIF 271 | 272 | if make_gifs and pm.assign(0): 273 | 274 | # What should be parameters 275 | nframes = min(maxnframes, results_line.shape[-1]) 276 | frames_index = np.linspace(0, results_line.shape[-1]-1, nframes) 277 | frames_index = [int(round(i)) for i in frames_index] 278 | 279 | # Animation base 280 | fig = plt.figure() 281 | ax = plt.subplot() 282 | lims = (np.min(results_line), np.max(results_line)) 283 | 284 | def make_pic_line(k): 285 | ax.clear() 286 | 287 | ax.plot(x_line, results_line[...,k], linewidth=2) 288 | plt.axvline(-cell_width/2 + pml_width, color="k", linestyle="dashed") 289 | plt.axvline(cell_width/2 - pml_width, color="k", linestyle="dashed") 290 | plt.axhline(0, color="k", linewidth=1) 291 | 292 | plt.xlabel(trs.choose("Position $X$ [MPu]", "Position $X$ [uMP]")) 293 | plt.ylabel(trs.choose(r"Electric Field $E_z(y=z=0)$", 294 | r"Campo eléctrico $E_z(y=z=0)$")) 295 | plt.xlim(min(x_line), max(x_line)) 296 | if units: 297 | plt.annotate(trs.choose(f"1 MPu = {from_um_factor * 1e3:.0f} nm", 298 | f"1 uMP = {from_um_factor * 1e3:.0f} nm"), 299 | (355, 9), xycoords='figure points') # 50, 300 300 | else: 301 | plt.annotate(trs.choose(r"1 MPu = $\lambda_0$", 302 | r"1 uMP = $\lambda_0$"), 303 | (355, 9), xycoords='figure points') # 50, 310 304 | ax.text(0, -.11, trs.choose(f'Time: {t_line[k]:.1f} MPu', 305 | f'Tiempo: {t_line[k]:.1f} uMP'), 306 | transform=ax.transAxes) 307 | plt.ylim(*lims) 308 | 309 | plt.show() 310 | return ax 311 | 312 | def make_gif_line(gif_filename): 313 | pics = [] 314 | for ik, k in enumerate(frames_index): 315 | ax = make_pic_line(k) 316 | plt.savefig('temp_pic.png') 317 | pics.append(mim.imread('temp_pic.png')) 318 | print(str(ik+1)+'/'+str(nframes)) 319 | mim.mimsave(gif_filename+'.gif', pics, fps=5) 320 | os.remove('temp_pic.png') 321 | print('Saved gif') 322 | 323 | make_gif_line(sa.file("AxisX=0")) 324 | plt.close(fig) 325 | # del fig, ax, lims, nframes_step, nframes, call_series, label_function 326 | 327 | #%% 328 | 329 | f.close() 330 | if hfield: fh.close() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyMeepPlasmonics 2 | 3 | Free and open-source code package designed to perform PyMEEP FDTD simulations applied to Plasmonics. 4 | 5 | ## About 6 | 7 | `PyMeepPlasmonics` is a freely accesible FDTD-MEEP implementation that contains code modules and routine scripts that allow for serial and parallel Plasmonics simulations to be run both in personal computers and clusters. 8 | 9 |

10 | PyMeepPlasmonics Logo 11 |

12 | 13 | `PyMeepPlasmonics` allows to perform **Finite-Differences Time-Domain (FDTD) simulations**, where a certain domain is discretized both in space and time in order to simulate the electromagnetic response in time by advancing step-by-step the electromagnetic field evaluated in each and every position or node. It uses a free and open-source FDTD implementation called **MIT Electromagnetic Propagation (MEEP)**. [MEEP](https://meep.readthedocs.io/en/latest/) has been cited in many scientific publications and it holds a Python library that offers great flexibility and versatibility while allowing users to create customized scripts and routines. 14 | 15 | `PyMeepPlasmonics` aims to apply PyMEEP FDTD simulations to the nanoscale and it is particularly focused in studying the optical properties of metallic nanoparticles (NPs). It has four fully equiped routines that configure and perform simulations to extract, analyse and save data both in time-domain (direct electromagnetic field calculations) and in frequency domain (indirect scattering cross section calculations). 16 | 17 |

18 | PyMeepPlasmonics Routines 19 |

20 | 21 | In order to build these routines, several code modules are used, each and every one of them highly documented. By calling functions from these modules and combining them with other famous scientific packages such as `numpy` or `matplotlib`, `PyMeepPlasmonics` should be able to present you with a whole spectrum of possibilities that will help you build your own Plasmonics or Nanophysics simulations. 22 | 23 |

24 | PyMeepPlasmonics Modules 25 |

26 | 27 | ## Installation 28 | 29 | ### Ubuntu 30 | 31 | A series of simple instructions can be followed to install the required packages in Ubuntu 20.04 LTS or any newer Ubuntu OS. 32 | 33 | The steps are slightly different whether you intend to run MEEP simulations using serial execution or parallel execution. If you have not decided yet, by following the instructions below you can actually have two Anaconda environments installed at the same time, one intended for serial execution and the other one for parallel execution. 34 | 35 | #### Serial execution 36 | 37 | - First, install the [Miniconda](https://docs.anaconda.com/anaconda/install/linux/) distribution. 38 | - You might need to activate Anaconda from an Ubuntu terminal by using the command `conda init`. 39 | - You can then create a Conda environment for MEEP using the command `conda create -n mp -c conda-forge pymeep`. 40 | - To start using the environment you will need to activate it by using `conda activate mp`. 41 | - Additional packages you might want to install using `conda install` or `pip install` include `h5py` for HDF files management, `resource` for monitoring resources such as RAM consumption and `imageio` for making gifs. 42 | - It might also come in handy installing Spyder for interactive serial execution and it is highly recommended to install `click` for console serial execution. 43 | 44 | #### Parallel execution 45 | 46 | - First, install the [Miniconda](https://docs.anaconda.com/anaconda/install/linux/) distribution. 47 | - You might need to activate Anaconda from an Ubuntu terminal by using the command `conda init`. 48 | - You can then create a Conda environment for MEEP using the command `conda create -n pmp -c conda-forge pymeep=*=mpi_mpich_*`. 49 | - To start using the environment you will need to activate it by using `conda activate pmp`. 50 | - Additional packages you might want to install using `conda install` or `pip install` include `h5py` for HDF files management, `resource` for monitoring resources such as RAM consumption and `imageio` for making gifs. 51 | - It is highly recommended to install `click` for parallel serial execution. 52 | 53 | ### Windows 54 | 55 | As required by MEEP, an Ubuntu OS will be necessary, so if you wish to work in Windows you will need a virtual machine or similar. Up to date, only Ubuntu has been used to execute `PyMeepPlasmonics` simulations, so saddly you will need to find out how to install it yourself. 56 | 57 | ## Usage 58 | 59 | First, you need to configure your system's setup. The suggested way to do this is to use the automatic setup provided by `PyMeepPlasmonics`. To do this, you will need to follow these steps: 60 | 61 | - Open a terminal and go to your repository's directory by running `cd my\route\to\PyMeepPlasmonics`. 62 | - Activate the Anaconda environment by using a line such as `conda activate mp` (serial) or `conda activate pmp` (parallel). 63 | - Call the module `v_save` as an executable file by using the command `python v_save.py`. 64 | - Follow the instructions in the screen: 65 | - First, indicate a nickname for your current PC and system. 66 | - Then, make sure the detected route to the repository is correct. 67 | - Finally, choose a path to a folder where the results will be saved. 68 | - A configuration file named "SystemDirectories.txt" will have been created at your repository's folder and you will be ready to go. 69 | 70 | Once you have finished, you will be able to open, inspect and execute those scripts that are already created to perform FDTD-MEEP Plasmonics simulations. Hopefully they will provide you with the results you are looking for. If not, they will surely provide you with enough examples to build your own simulation :) 71 | 72 | ## Licence 73 | 74 | Free open-source code developed as part of a Master Thesis Project in Physics. 75 | 76 | ***FDTD Applications To The Nanoscale: Photonics & Plasmonics Through MEEP*** 77 | 78 | Development by Valeria R. Pais, [DF, FCEyN, UBA](https://sitio.df.uba.ar/es/) 79 | 80 | Direction by Prof. Dr. Fernando D. Stefani, [Applied Nanophysics Group, CIBION, CONICET](https://stefani-lab.ar/) 81 | 82 | -------------------------------------------------------------------------------- /ShellRoutines/au_mie_test_scattering.sh: -------------------------------------------------------------------------------- 1 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -res 2 --from-um-factor 10e-3 -s "FluxR0.30Res2" -f "AuMieMediums/AllWaterTest/9)BoxDimensions/FluxR" -r 51.5 -pp "R" --wlen-range "np.array([500,650])" --index 1.33 --flux-r-factor 0.3 2 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -res 2 --from-um-factor 10e-3 -s "AirR06.5Res2" -f "AuMieMediums/AllWaterTest/9)BoxDimensions/AirR" -r 51.5 -pp "R" --wlen-range "np.array([500,650])" --index 1.33 --air-r-factor 6.5 3 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -res 2 --from-um-factor 10e-3 -s "PMLWlen0.95Res2" -f "AuMieMediums/AllWaterTest/9)BoxDimensions/PMLWlen" -r 51.5 -pp "R" --wlen-range "np.array([500,650])" --index 1.33 -pml 0.95 4 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -res 2 --from-um-factor 10e-3 -s "WLenMax700Res2" -f "AuMieMediums/AllWaterTest/9)BoxDimensions/WLenMax" -r 51.5 -pp "R" --wlen-range "np.array([500,700])" --index 1.33 5 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -res 2 --from-um-factor 10e-3 -s "WLenMin500Res2" -f "AuMieMediums/AllWaterTest/9)BoxDimensions/WLenMin" -r 51.5 -pp "R" --wlen-range "np.array([500,650])" --index 1.33 6 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -res 2 --from-um-factor 10e-3 -s "TFCell0.2Res2" -f "AuMieSphere/AuMie/13)TestPaper/4)PaperJCFit/TestTFCell/AllVac450650" -r 51.5 -pp "JC" --wlen-range "np.array([450,650])" --time-factor-cell 0.2 7 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -res 2 --from-um-factor 10e-3 -s "STFactor01.0Res2" -f "AuMieSphere/AuMie/13)TestPaper/4)PaperJCFit/TestSTFactor/AllVac450650" -r 51.5 -pp "JC" --wlen-range "np.array([450,650])" --second-time-factor 1 8 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -res 2 --from-um-factor 10e-3 -s "Courant0.50Res2" -f "AuMieMediums/AllWaterTest/6)Courant/500to700" -r 51.5 -pp "R" --wlen-range "np.array([500,700])" --courant .5 --index 1.33 9 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -res 2 --from-um-factor 10e-3 -s "RefRRes2" -f "AuMieMediums/AllWaterTest/9)BoxDimensions/RefIdeal/3)NewRef" -r 51.5 -pp "R" --wlen-range "np.array([500,650])" --index 1.33 10 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -f "Test/TestChunks" -s "AllWatChunksEvenlyFalseNP6" -res 2 --split-chunks-evenly False --index 1.33 --wlen-range "[500, 650]" 11 | ############ 12 | #python ./AuMieSphere/u_au_mie_scattering.py --parallel False -f "Test/TestRAM" -s "TestRAMConsole" -res 2 --wlen-range "[450, 600]" --load-flux False 13 | #mpirun --use-hwthread-cpus -np 1 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 1 --parallel True -f "Test/TestRAM" -s "TestRAMParallel1" -res 2 --load-flux False 14 | #mpirun --use-hwthread-cpus -np 2 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 2 --parallel True -f "Test/TestRAM" -s "TestRAMParallel2" -res 2 --load-flux False 15 | #mpirun --use-hwthread-cpus -np 3 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 3 --parallel True -f "Test/TestRAM" -s "TestRAMParallel3" -res 2 --load-flux False 16 | #mpirun --use-hwthread-cpus -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestRAM" -s "TestRAMParallel4" -res 2 --load-flux False 17 | #mpirun --use-hwthread-cpus -np 5 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 5 --parallel True -f "Test/TestRAM" -s "TestRAMParallel5" -res 2 --load-flux False 18 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -f "Test/TestRAM" -s "TestRAMParallel6" -res 2 --load-flux False 19 | #mpirun --use-hwthread-cpus -np 7 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 7 --parallel True -f "Test/TestRAM" -s "TestRAMParallel7" -res 2 --load-flux False 20 | #mpirun --use-hwthread-cpus -np 8 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 8 --parallel True -f "Test/TestRAM" -s "TestRAMParallel8" -res 2 --load-flux False 21 | ############# 22 | #mpirun --use-hwthread-cpus -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestRAM" -s "AllVacRes2" -res 2 --wlen-range "[450, 600]" --load-flux False 23 | #mpirun --use-hwthread-cpus -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestRAM" -s "AllWatRes2" -res 2 --wlen-range "[500, 650]" --index 1.33 --load-flux False 24 | #mpirun --use-hwthread-cpus -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestRAM" -s "AllVacRes3" -res 3 --wlen-range "[450, 600]" --load-flux False 25 | #mpirun --use-hwthread-cpus -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestRAM" -s "AllWatRes3" -res 3 --wlen-range "[500, 650]" --index 1.33 --load-flux False 26 | #mpirun --use-hwthread-cpus -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestRAM" -s "AllVacRes4" -res 4 --wlen-range "[450, 600]" --load-flux False 27 | #mpirun --use-hwthread-cpus -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestRAM" -s "AllWatRes4" -res 4 --wlen-range "[500, 650]" --index 1.33 --load-flux False 28 | ############ 29 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -f "Test/TestRAM" -s "AllVacNear2FarTrueRes2" -res 2 --near2far True --wlen-range "[450, 600]" --load-flux False 30 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -f "Test/TestRAM" -s "AllVacNear2FarFalseRes2" -res 2 --near2far False --wlen-range "[450, 600]" --load-flux False 31 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -f "Test/TestRAM" -s "AllWatNear2FarTrueRes2" -res 2 --near2far True --wlen-range "[500, 650]" --index 1.33 --load-flux False --flux-r-factor 0.3 32 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -f "Test/TestRAM" -s "AllWatNear2FarFalseRes2" -res 2 --near2far False --wlen-range "[500, 650]" --index 1.33 --load-flux False --flux-r-factor 0.3 33 | ############## 34 | #mpirun --use-hwthread-cpus -np 6 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 6 --parallel True -f "Test/TestRAM" -s "TestSWAP" -res 4 35 | #mpirun --use-hwthread-cpus -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestRAM" -s "TestSWAP" -res 4 36 | ############## 37 | #mpirun --use-hwthread-cpus -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestNP4" -s "TestHWThreadsTrue" -res 2 --load-flux False 38 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --parallel True -f "Test/TestNP4" -s "TestHWThreadsFalse" -res 2 --load-flux False 39 | ############# 40 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --material "Ag" --wlen-range "[350, 500]" -res 4 -s "SilverRes4" -f "Test/TestSilver" 41 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --material "Ag" --wlen-range 350 500 -r 30 -res 2 -s "SilverDiam60Res2" -f "Test/TestSilver" 42 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -np 4 --material "Ag" --paper "JC" --wlen-range 350 500 -res 5 -s "SilverJCRes5" -f "Test/TestSilver" 43 | ############# 44 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -nc 4 -res 4 -s "Over00" -f "Test/TestGlass/OverlapRes4" --wlen-range 500 700 --index 1.33 --surface-index 1.54 45 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -nc 4 -res 4 -s "Over20" -f "Test/TestGlass/OverlapRes4" --wlen-range 500 700 --index 1.33 --surface-index 1.54 --overlap 20 46 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -nc 4 -res 4 -s "Over10" -f "Test/TestGlass/OverlapRes4" --wlen-range 500 700 --index 1.33 --surface-index 1.54 --overlap 10 47 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -nc 4 -res 4 -s "Over25" -f "Test/TestGlass/OverlapRes4" --wlen-range 500 700 --index 1.33 --surface-index 1.54 --overlap 25 48 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -nc 4 -res 4 -s "Over15" -f "Test/TestGlass/OverlapRes4" --wlen-range 500 700 --index 1.33 --surface-index 1.54 --overlap 15 49 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -nc 4 -res 4 -s "Over05" -f "Test/TestGlass/OverlapRes4" --wlen-range 500 700 --index 1.33 --surface-index 1.54 --overlap 5 50 | ############ DO I ADD OVERLAP IN THIS RESOLUTION RUN? 51 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -nc 4 --from-um-factor 20e-3 -res 8 -s "GlassRes8" -f "Test/TestGlass/TestGlassRes" --wlen-range "[500, 700]" --index 1.33 --surface-index 1.54 52 | ########## 53 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/10)TimeFactors/TimeFactorCell" -s "TFC0.7" -res 2 --wlen-range 500 650 --index 1.33 --time-factor-cell 0.7 54 | ########## 55 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/PMLWlen" -s "PMLWlen0.33Res2" -res 2 --wlen-range 500 650 --index 1.33 --pml-wlen-factor 0.33 56 | ######### 57 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/AirR" -s "AirR03.0Res2" -res 2 --wlen-range 500 650 --index 1.33 --empty-r-factor 3 58 | ######### 59 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/FluxR" -s "FluxR0.05Res2" -res 2 --wlen-range 500 650 --index 1.33 --flux-r-factor 0.05 60 | ######### 61 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/10)TimeFactors/SecondTimeFactor" -s "STF03Res2" -res 2 --wlen-range 500 650 --index 1.33 --second-time-factor 3 62 | ######### 63 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/Courant/Vac450600" -s "Courant0.60Res2" -res 2 --wlen-range 450 600 --courant .6 --load-flux False 64 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/Courant/500650" -s "Courant0.60Res2" -res 2 --wlen-range 500 650 --courant .6 --load-flux False --index 1.33 65 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/Courant/Vac450600" -s "Courant0.65Res2" -res 2 --wlen-range 500 650 --courant .65 --load-flux False 66 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/Courant/Vac450600" -s "Courant0.55Res2" -res 2 --wlen-range 450 600 --courant .55 --load-flux False 67 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/Courant/500650" -s "Courant0.55Res2" -res 2 --wlen-range 500 650 --courant .55 --load-flux False --index 1.33 68 | #mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/Courant/500650" -s "Courant0.65Res2" -res 2 --wlen-range 450 600 --courant .65 --load-flux False --index 1.33 69 | ####### 70 | mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/AirR" -s "AirR00.0Res2" -res 2 --wlen-range 500 650 --index 1.33 --empty-r-factor 0 71 | mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/AirR" -s "AirR01.0Res2" -res 2 --wlen-range 500 650 --index 1.33 --empty-r-factor 1 72 | mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/AirR" -s "AirR01.5Res2" -res 2 --wlen-range 500 650 --index 1.33 --empty-r-factor 1.5 73 | mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/AirR" -s "AirR02.5Res2" -res 2 --wlen-range 500 650 --index 1.33 --empty-r-factor 2.5 74 | mpirun -np 4 python -m mpi4py ./AuMieSphere/u_au_mie_scattering.py -f "Scattering/AuSphere/AllWatTest/9)BoxDimensions/AirR" -s "AirR03.5Res2" -res 2 --wlen-range 500 650 --index 1.33 --empty-r-factor 3.5 75 | -------------------------------------------------------------------------------- /ShellRoutines/np_monoch_field_test.sh: -------------------------------------------------------------------------------- 1 | ### Test Periods 2 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -r 30 --wlen 405 --index 1 --time-period-factor 30 --folder "Field/NPMonoch/AuSphere/VacWatTest/TestPeriods/Vacuum" -s "VacNewPeriods405" -res 3 3 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -r 30 --wlen 405 --index 1.33 --time-period-factor 30 --folder "Field/NPMonoch/AuSphere/VacWatTest/TestPeriods/Water" -s "WatNewPeriods405" -res 3 4 | 5 | ### First Results WLen 6 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 405 --index 1 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Vacuum" -s "Norm405Res3" --time-period-factor 20 7 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Vacuum" -s "Norm532Res3" --time-period-factor 20 8 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 642 --index 1 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Vacuum" -s "Norm642Res3" --time-period-factor 20 9 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 405 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Water" -s "Norm405Res3" --time-period-factor 20 10 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Water" -s "Norm532Res3" --time-period-factor 20 11 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 642 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Water" -s "Norm642Res3" --time-period-factor 20 12 | 13 | ### Heavy Results WLen 14 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 405 --index 1 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Vacuum" -s "Norm405Res5" --time-period-factor 20 15 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 532 --index 1 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Vacuum" -s "Norm532Res5" --time-period-factor 20 16 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 642 --index 1 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Vacuum" -s "Norm642Res5" --time-period-factor 20 17 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 405 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Water" -s "Norm405Res5" --time-period-factor 20 18 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Water" -s "Norm532Res5" --time-period-factor 20 19 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 642 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatField/TestWLen/Water" -s "Norm642Res5" --time-period-factor 20 20 | 21 | ### Check empty-r-factor 22 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty532Res3ERF1.0" --time-period-factor 20 --empty-r-factor 1.0 23 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty532Res3ERF1.5" --time-period-factor 20 --empty-r-factor 1.5 24 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty532Res3ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 25 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty532Res3ERF2.5" --time-period-factor 20 --empty-r-factor 2.5 26 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty532Res3ERF3.0" --time-period-factor 20 --empty-r-factor 3.0 27 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty532Res3ERF3.5" --time-period-factor 20 --empty-r-factor 3.5 28 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty532Res3ERF4.0" --time-period-factor 20 --empty-r-factor 4.5 29 | 30 | # Check empty in all wlens 31 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 405 --index 1 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Vacuum " -s "Empty405Res3ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 32 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 532 --index 1 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Vacuum" -s "Empty532Res3ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 33 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 642 --index 1 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Vacuum" -s "Empty642Res3ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 34 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 405 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty405Res3ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 35 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 3 -r 30 -wl 642 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty642Res3ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 36 | 37 | #mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 405 --index 1 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Vacuum" -s "Empty405Res5ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 38 | mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 532 --index 1 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Vacuum" -s "Empty532Res5ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 39 | mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 642 --index 1 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Vacuum" -s "Empty642Res5ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 40 | mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 405 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty405Res5ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 41 | mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 532 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty532Res5ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 42 | mpirun -np 4 python -m mpi4py AuMieSphere/u_np_monoch_field.py -res 5 --courant 0.25 -r 30 -wl 642 --index 1.33 -f "Field/NPMonoch/AuSphere/VacWatTest/TestEmpty/Water" -s "Empty642Res5ERF2.0" --time-period-factor 20 --empty-r-factor 2.0 43 | -------------------------------------------------------------------------------- /ShellRoutines/pulse_field_test.sh: -------------------------------------------------------------------------------- 1 | #### 2 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.13 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.13EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 3 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.18 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.18EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 4 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.23 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.23EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 5 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.28 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.28EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 6 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.33 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.33EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 7 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.43 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.43EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 8 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.48 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.48EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 9 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.3 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.30EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 10 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.38 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.38EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 11 | #### 12 | #mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1 --pml-wlen-factor 0.13 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestVacPML0.13EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 13 | #### 14 | mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1 --pml-wlen-factor 0.15 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestVacPML0.15EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 15 | mpirun -np 4 python -m mpi4py Sources/u_pulse_field.py --resolution-wlen 10 --index 1.33 --pml-wlen-factor 0.15 --empty-wlen-factor 2 --time-factor-cell 1.35 --wlen-range 0.85 1.15 --units False -s "TestWatPML0.15EF2" -f "Field/Sources/PulsePlanewave/6)TestPulse/085115/Res10" 16 | -------------------------------------------------------------------------------- /SupportFiles/DataManagement/chunks_data_directory_patch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Jun 23 14:34:26 2021 5 | 6 | @author: vall 7 | """ 8 | 9 | import vmp_utilities as vmu 10 | import v_save as vs 11 | import h5py as h5 12 | import numpy as np 13 | import os 14 | 15 | sysname = vs.get_sys_name() 16 | syshome = vs.get_sys_home() 17 | home = vs.get_home() 18 | 19 | #%% 20 | 21 | chunks_file = os.path.join(home, "ChunksData/ChunksDataDirectory.txt") 22 | 23 | chunks_dir = vs.retrieve_footer(chunks_file) 24 | 25 | #%% 26 | 27 | data_files = chunks_dir["path"] 28 | 29 | found_files = [] 30 | found_params = [] 31 | for df in data_files: 32 | try: 33 | found_params.append(vs.retrieve_footer(os.path.join(df, "Results.txt"))) 34 | found_files.append(df) 35 | except: 36 | print("No file found at ", df) 37 | print(f"Only found {100*len(found_files)/len(data_files):.2f}% of the files") 38 | 39 | #%% 40 | 41 | resolution = np.array([chunks_dir["resolution"]]) 42 | from_um_factor = np.array(chunks_dir["from_um_factor"]) 43 | cell_width = np.array(chunks_dir["cell_width"]) 44 | pml_width = np.array(chunks_dir["pml_width"]) 45 | air_r_width = cell_width - 2*pml_width 46 | 47 | r = air_r_width/3 48 | r_nm = r * from_um_factor * 1e3 49 | 50 | typical_d_nm = np.array([48, 64, 80, 103, 120]) 51 | typical_r_nm = typical_d_nm / 2 52 | 53 | index = [] 54 | r_nm_reconstructed = [] 55 | for r_nm_i in r_nm: 56 | index.append( np.argmin(abs(typical_r_nm - r_nm_i)) ) 57 | r_nm_reconstructed.append( typical_r_nm[index[-1]] ) 58 | 59 | r_reconstructed = r_nm_reconstructed / (from_um_factor*1e3) 60 | r_reconstructed[-8:] = np.array([5.15]*8) 61 | 62 | flux_box_size = 2*r_reconstructed 63 | flux_box_size[-8:] = np.array(chunks_dir["flux_box_size"][-8:]) 64 | 65 | chunks_dir["flux_box_size"] = list(flux_box_size) 66 | 67 | #%% 68 | 69 | keys = list(chunks_dir.keys()) 70 | n = len(chunks_dir[keys[0]]) 71 | 72 | #%% 73 | 74 | chunks_dir["n_cores"] = [] 75 | for i in range(n): 76 | chunks_dir["n_cores"].append( min([4, chunks_dir["n_processes"][i]]) ) 77 | 78 | #%% 79 | 80 | submerged_index = [] 81 | surface_index = [] 82 | for nsubm, nsurf in zip(chunks_dir["submerged_index"], chunks_dir["surface_index"]): 83 | if nsurf == 1 and nsubm != 1: 84 | nsurf = nsubm 85 | submerged_index.append(nsubm) 86 | surface_index.append(nsurf) 87 | 88 | chunks_dir["submerged_index"] = submerged_index 89 | chunks_dir["surface_index"] = surface_index 90 | 91 | #%% 92 | 93 | index = [] 94 | for i in range(len(chunks_dir["path"])-1): 95 | if chunks_dir["path"][i+1] != chunks_dir["path"][i]: 96 | index.append(i) 97 | 98 | #%% 99 | 100 | new_chunks_dir = {} 101 | for key, values_list in chunks_dir.items(): 102 | chunks_dir[key] = [values_list[i] for i in index] 103 | 104 | #%% 105 | 106 | differences = [] 107 | for k, v_list in chunks_dir.items(): 108 | if v_list[-1] != v_list[-2]: 109 | differences.append(k) 110 | 111 | f0 = h5.File(os.path.join(home, "ChunksData", chunks_dir["chunks_path"][-2], "Layout.h5"), "r") 112 | ff = h5.File(os.path.join(home, "ChunksData", chunks_dir["chunks_path"][-1], "Layout.h5"), "r") 113 | 114 | #%% 115 | 116 | for k in keys: 117 | chunks_dir[k] = chunks_dir[k][:-1] 118 | 119 | #%% 120 | 121 | vs.savetxt(chunks_file, np.array([]), footer=chunks_dir, overwrite=True) 122 | 123 | #%% 124 | 125 | blank_chunks_dir = {} 126 | blank_chunks_dir["chunks_path"] = [] 127 | for k in vmu.chunks_key_params: blank_chunks_dir[k] = [] 128 | blank_chunks_dir["path"] = [] 129 | 130 | vs.savetxt(os.path.join(home, "ChunksData/ChunksDataDirBlank.txt"), 131 | np.array([]), footer=blank_chunks_dir, overwrite=True) -------------------------------------------------------------------------------- /SupportFiles/DataManagement/epsilon_theory_riinfo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Mon Jul 19 14:19:04 2021 5 | 6 | @author: vall 7 | """ 8 | 9 | import numpy as np 10 | import v_save as vs 11 | import os 12 | 13 | syshome = vs.get_sys_home() 14 | 15 | #%% 16 | 17 | name = "Ag_R_ComplexN_RIinfo" 18 | paper = "A. D. Rakić, A. B. Djurišic, J. M. Elazar, and M. L. Majewski. Optical properties of metallic films for vertical-cavity optoelectronic devices, Appl. Opt. 37, 5271-5283 (1998)" 19 | reference = "https://refractiveindex.info/?shelf=main&book=Ag&page=Rakic-LD" 20 | 21 | #%% 22 | 23 | file = lambda name : os.path.join(syshome, "SupportFiles", "MaterialsData", name) 24 | 25 | data = np.loadtxt(file(name + ".csv"), 26 | skiprows=1, 27 | delimiter=",") 28 | 29 | data[:,0] = data[:,0] * 1000 # from um to nm 30 | 31 | #%% 32 | 33 | header = [r"Wavelength $\lambda$ [nm]", "n", "k"] 34 | 35 | footer = {"paper": paper, 36 | "wlen_range": [min(data[:,0]), max(data[:,0])], 37 | "reference": reference} 38 | 39 | vs.savetxt(file(name + ".txt"), data, footer=footer, header=header) 40 | -------------------------------------------------------------------------------- /SupportFiles/DataManagement/flux_data_directory_patch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Jun 23 14:34:26 2021 5 | 6 | @author: vall 7 | """ 8 | 9 | import vmp_utilities as vmu 10 | import v_save as vs 11 | import numpy as np 12 | import os 13 | 14 | sysname = vs.get_sys_name() 15 | syshome = vs.get_sys_home() 16 | home = vs.get_home() 17 | 18 | #%% 19 | 20 | flux_file = os.path.join(home, "FluxData/FluxDataDirectory.txt") 21 | 22 | flux_dir = vs.retrieve_footer(flux_file) 23 | 24 | #%% 25 | 26 | data_files = flux_dir["path"] 27 | 28 | found_files = [] 29 | found_params = [] 30 | for df in data_files: 31 | try: 32 | found_params.append(vs.retrieve_footer(os.path.join(df, "Results.txt"))) 33 | found_files.append(df) 34 | except: 35 | print("No file found at ", df) 36 | print(f"Only found {100*len(found_files)/len(data_files):.2f}% of the files") 37 | 38 | #%% 39 | 40 | resolution = np.array([flux_dir["resolution"]]) 41 | from_um_factor = np.array(flux_dir["from_um_factor"]) 42 | cell_width = np.array(flux_dir["cell_width"]) 43 | pml_width = np.array(flux_dir["pml_width"]) 44 | air_r_width = cell_width - 2*pml_width 45 | 46 | r = air_r_width/3 47 | r_nm = r * from_um_factor * 1e3 48 | 49 | typical_d_nm = np.array([48, 64, 80, 103, 120]) 50 | typical_r_nm = typical_d_nm / 2 51 | 52 | index = [] 53 | r_nm_reconstructed = [] 54 | for r_nm_i in r_nm: 55 | index.append( np.argmin(abs(typical_r_nm - r_nm_i)) ) 56 | r_nm_reconstructed.append( typical_r_nm[index[-1]] ) 57 | 58 | r_reconstructed = r_nm_reconstructed / (from_um_factor*1e3) 59 | r_reconstructed[-8:] = np.array([5.15]*8) 60 | 61 | flux_box_size = 2*r_reconstructed 62 | flux_box_size[-8:] = np.array(flux_dir["flux_box_size"][-8:]) 63 | 64 | flux_dir["flux_box_size"] = list(flux_box_size) 65 | 66 | #%% 67 | 68 | keys = list(flux_dir.keys()) 69 | n = len(flux_dir[keys[0]]) 70 | 71 | #%% 72 | 73 | last_five = {} 74 | for k in flux_dir.keys(): 75 | last_five[k] = flux_dir[k][-5:] 76 | 77 | #%% 78 | 79 | flux_dir["n_cores"] = [] 80 | for i in range(n): 81 | flux_dir["n_cores"].append( min([4, flux_dir["n_processes"][i]]) ) 82 | 83 | flux_dir["n_nodes"] = [1]*n 84 | flux_dir["split_chunks_evenly"] = [True]*n 85 | flux_dir["near2far"] = [False]*n 86 | 87 | #%% 88 | 89 | del flux_dir["displacement"] 90 | 91 | flux_dir["overlap"] = [0]*n 92 | 93 | r = [*[51.5]*12, 24, 32, 40, *[51.5]*n][:n] 94 | r = [r[i] / (1e3 * flux_dir["from_um_factor"][i]) for i in range(n)] 95 | flux_dir["flux_box_size"] = [2 * r[i] for i in range(n)] 96 | 97 | #%% 98 | 99 | backup = dict(**flux_dir) 100 | 101 | for k in keys: 102 | flux_dir[k] = [*flux_dir[k][:32], *flux_dir[k][33:]] 103 | 104 | #%% 105 | 106 | submerged_index = [] 107 | surface_index = [] 108 | for nsubm, nsurf in zip(flux_dir["submerged_index"], flux_dir["surface_index"]): 109 | if nsurf == 1 and nsubm != 1: 110 | nsurf = nsubm 111 | submerged_index.append(nsubm) 112 | surface_index.append(nsurf) 113 | 114 | flux_dir["submerged_index"] = submerged_index 115 | flux_dir["surface_index"] = surface_index 116 | 117 | #%% 118 | 119 | vs.savetxt(flux_file, np.array([]), footer=flux_dir, overwrite=True) 120 | 121 | #%% 122 | 123 | blank_flux_file = {} 124 | blank_flux_file["flux_path"] = [] 125 | for k in vmu.midflux_key_params: blank_flux_file[k] = [] 126 | blank_flux_file["path"] = [] 127 | 128 | vs.savetxt(os.path.join(home, "FluxData/FluxDataDirBlank.txt"), 129 | np.array([]), footer=blank_flux_file, overwrite=True) -------------------------------------------------------------------------------- /SupportFiles/DataManagement/norm_data_directory_patch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Wed Jun 23 14:34:26 2021 5 | 6 | @author: vall 7 | """ 8 | 9 | import vmp_utilities as vmu 10 | import v_save as vs 11 | import numpy as np 12 | import os 13 | 14 | sysname = vs.get_sys_name() 15 | syshome = vs.get_sys_home() 16 | home = vs.get_home() 17 | 18 | #%% 19 | 20 | norm_file = os.path.join(home, "FieldData/FieldDataDirectory.txt") 21 | 22 | norm_dir = vs.retrieve_footer(norm_file) 23 | 24 | #%% 25 | 26 | keys = list(norm_dir.keys()) 27 | n = len(norm_dir[keys[0]]) 28 | 29 | #%% 30 | 31 | for k in keys: 32 | norm_dir[k] = norm_dir[k][-1:] 33 | 34 | #%% 35 | 36 | vs.savetxt(norm_file, np.array([]), footer=norm_dir, overwrite=True) 37 | 38 | #%% 39 | 40 | blank_norm_file = {} 41 | blank_norm_file["norm_path"] = [] 42 | for k in vmu.normfield_key_params: blank_norm_file[k] = [] 43 | blank_norm_file["path"] = [] 44 | 45 | vs.savetxt(os.path.join(home, "FieldData/FieldDataDirBlank.txt"), 46 | np.array([]), footer=blank_norm_file, overwrite=True) -------------------------------------------------------------------------------- /SupportFiles/Installation/Test/simple.py: -------------------------------------------------------------------------------- 1 | import h5py as h5 2 | from mpi4py import MPI 3 | 4 | #comm = MPI.COMM_WORLD 5 | #rank = comm.Get_rank() 6 | rank = MPI.COMM_WORLD.rank 7 | 8 | if rank==0: print(f"Got to load modules and start instance of mpi4py with rank {rank}") 9 | 10 | #f = h5.File("/nfs/home/vpais/PyMeepResults/TestParallel.h5", "w", driver="mpio", comm=comm) 11 | f = h5.File("/nfs/home/vpais/PyMeepResults/TestParallel.h5", "w", driver="mpio", comm=MPI.COMM_WORLD) 12 | 13 | if rank==0: print("Got to open file") 14 | 15 | f["hey"] = [2021,9,19,11,50,0] 16 | 17 | if rank==0: print("Got to save data in new dataset hey") 18 | 19 | f.close() 20 | 21 | if rank==0: print("Got to close file") 22 | -------------------------------------------------------------------------------- /SupportFiles/Installation/Test/simple_serial.py: -------------------------------------------------------------------------------- 1 | import h5py as h5 2 | 3 | print("Got to load module") 4 | 5 | f = h5.File("/nfs/home/vpais/PyMeepResults/TestSerial.h5", "w") 6 | 7 | print("Got to open file") 8 | 9 | f["hey"] = [2,1,1,1] 10 | 11 | print("Got to save data in new dataset hey") 12 | 13 | f.close() 14 | 15 | print("Got to close file") 16 | -------------------------------------------------------------------------------- /SupportFiles/Installation/install_parallel_meep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # /usr/bin/pyvenv/pmp/lib # For Python 4 | # /usr/local/lib/mpi/bin <3 For MPI 5 | # ./configure --prefix=/usr/local/lib/pmeep # Where I would like to have installed meep 6 | 7 | set -e 8 | 9 | RPATH_FLAGS="-Wl,-rpath,/usr/local/lib:/usr/lib/x86_64-linux-gnu/hdf5/openmpi:/usr/bin/pyvenv/pmp/lib:/usr/local/lib/mpi/lib" 10 | MY_LDFLAGS="-L/usr/local/lib -L/usr/lib/x86_64-linux-gnu/hdf5/openmpi -L/usr/bin/pyvenv/pmp/lib -L/usr/local/lib/mpi/lib ${RPATH_FLAGS}" 11 | MY_CPPFLAGS="-I/usr/local/include -I/usr/include/hdf5/openmpi -I/usr/bin/pyvenv/pmp/include -I/usr/local/lib/mpi/include" 12 | 13 | sudo apt-get update 14 | 15 | # If building on Ubuntu 18.04LTS, replace libpng16-dev with libpng-dev, 16 | # and libpython3.5-dev with libpython3-dev. 17 | sudo apt-get -y install build-essential 18 | sudo apt-get -y install gfortran 19 | sudo apt-get -y install libblas-dev 20 | sudo apt-get -y install liblapack-dev 21 | sudo apt-get -y install libgmp-dev 22 | sudo apt-get -y install swig 23 | sudo apt-get -y install libgsl-dev 24 | sudo apt-get -y install autoconf 25 | sudo apt-get -y install pkg-config 26 | sudo apt-get -y install libpng-dev # libpng16-dev \ 27 | # sudo apt-get -y install git 28 | sudo apt-get -y install guile-3.0-dev # guile-2.0-dev \ 29 | sudo apt-get -y install libfftw3-dev 30 | sudo apt-get -y install libhdf5-openmpi-dev 31 | sudo apt-get -y install hdf5-tools 32 | sudo apt-get -y install libpython3-dev # libpython3.5-dev \ 33 | sudo apt-get -y install python3-pip 34 | sudo apt-get -y install cmake 35 | 36 | #mkdir -p ~/Documents/Thesis/ThesisInstall 37 | 38 | # cd ~/install 39 | # git clone https://github.com/NanoComp/harminv.git 40 | # cd harminv/ 41 | # sh autogen.sh --enable-shared 42 | # make && sudo make install 43 | 44 | cd ~/Documents/Thesis/ThesisInstall 45 | git clone https://github.com/NanoComp/libctl.git 46 | cd libctl/ 47 | sh autogen.sh --enable-shared 48 | make && sudo make install 49 | 50 | cd ~/Documents/Thesis/ThesisInstall 51 | git clone https://github.com/NanoComp/h5utils.git 52 | cd h5utils/ 53 | sh autogen.sh CC=mpicc LDFLAGS="${MY_LDFLAGS}" CPPFLAGS="${MY_CPPFLAGS}" 54 | make && sudo make install 55 | 56 | # cd ~/Documents/Thesis/ThesisInstall 57 | # git clone https://github.com/NanoComp/mpb.git 58 | # cd mpb/ 59 | # sh autogen.sh --enable-shared CC=mpicc LDFLAGS="${MY_LDFLAGS}" CPPFLAGS="${MY_CPPFLAGS}" --with-hermitian-eps 60 | # make && sudo make install 61 | 62 | cd ~/Documents/Thesis/ThesisInstall 63 | git clone https://github.com/HomerReid/libGDSII.git 64 | cd libGDSII/ 65 | sh autogen.sh 66 | make && sudo make install 67 | 68 | # The next line is only required on Ubuntu 16.04 69 | # sudo pip3 install --upgrade pip 70 | 71 | pip3 install --user --no-cache-dir mpi4py 72 | pip3 install --user Cython==0.29.16 73 | export HDF5_MPI="ON" 74 | pip3 install --user --no-binary=h5py h5py 75 | pip3 install --user autograd 76 | pip3 install --user scipy 77 | pip3 install --user matplotlib>3.0.0 78 | pip3 install --user ffmpeg 79 | 80 | cd ~/Documents/Thesis/ThesisInstall 81 | git clone git://github.com/stevengj/nlopt.git 82 | cd nlopt/ 83 | cmake -DPYTHON_EXECUTABLE=/usr/bin/python3 && make && sudo make install 84 | 85 | cd ~/Documents/Thesis/ThesisInstall 86 | # git clone https://github.com/NanoComp/meep.git --branch "v1.20.0" # had already run this line 87 | cd meep/ 88 | # Open autogen and change line to ./configure --enable-maintainer-mode "$@" --prefix=/usr/bin/pyvenv/pmp 89 | sh autogen.sh --enable-shared --with-mpi --with-openmp PYTHON=python3 LDFLAGS="${MY_LDFLAGS}" CPPFLAGS="${MY_CPPFLAGS}" 90 | make && sudo make install 91 | -------------------------------------------------------------------------------- /SupportFiles/Installation/mpitest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xInfty/PyMeepPlasmonics/ba526137978fc700dbfa652fecabcec99f4f74ad/SupportFiles/Installation/mpitest -------------------------------------------------------------------------------- /SupportFiles/Installation/mpitest.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Usage: 3 | * mpicc mpitest.c -o mpitest 4 | * mpirun -np 2 -H `hostname` ./mpitest 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | int rank, size, h_len; 13 | char hostname[MPI_MAX_PROCESSOR_NAME]; 14 | MPI_Init(&argc, &argv); 15 | 16 | // get rank of this proces 17 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 18 | // get total process number 19 | MPI_Comm_size(MPI_COMM_WORLD, &size); 20 | 21 | MPI_Get_processor_name(hostname, &h_len); 22 | printf("Start! rank:%d size: %d at %s\n", rank, size,hostname); 23 | //do something 24 | printf("Done! rank:%d size: %d at %s\n", rank, size,hostname); 25 | 26 | MPI_Finalize(); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /SupportFiles/Installation/spack_install_meep.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013-2021 Lawrence Livermore National Security, LLC and other 2 | # Spack Project Developers. See the top-level COPYRIGHT file for details. 3 | # 4 | # SPDX-License-Identifier: (Apache-2.0 OR MIT) 5 | 6 | from spack import * 7 | 8 | 9 | class Meep(AutotoolsPackage): 10 | """Meep (or MEEP) is a free finite-difference time-domain (FDTD) simulation 11 | software package developed at MIT to model electromagnetic systems.""" 12 | 13 | homepage = "http://ab-initio.mit.edu/wiki/index.php/Meep" 14 | url = "https://github.com/NanoComp/meep/releases/download/v1.19.0/meep-1.19.0.tar.gz" 15 | # "http://ab-initio.mit.edu/meep/meep-1.3.tar.gz" 16 | list_url = "http://ab-initio.mit.edu/meep/old" 17 | 18 | version('1.19.0', sha256='5a73e719b274017015e9e7994b7a7a11139d4eb6') 19 | version('1.3', sha256='564c1ff1b413a3487cf81048a45deabfdac4243a1a37ce743f4fcf0c055fd438') 20 | version('1.2.1', sha256='f1f0683e5688d231f7dd1863939677148fc27a6744c03510e030c85d6c518ea5') 21 | version('1.1.1', sha256='7a97b5555da1f9ea2ec6eed5c45bd97bcd6ddbd54bdfc181f46c696dffc169f2') 22 | 23 | variant('harminv', default=True, description='Enable Harminv support') 24 | variant('guile', default=True, description='Enable Guile support') 25 | variant('libgdsii', default=False, description='Enable libGDSII support') 26 | 27 | # depends_on('python') 28 | depends_on('libctl@4.0:') 29 | depends_on('mpi') 30 | depends_on('hdf5+mpi') 31 | depends_on('blas', when='+harminv') 32 | depends_on('lapack', when='+harminv') 33 | depends_on('harminv', when='+harminv') 34 | depends_on('guile', when='+guile') 35 | depends_on('libgdsii', when='+libgdsii') 36 | 37 | def configure_args(self): 38 | spec = self.spec 39 | 40 | config_args = [ 41 | '--enable-shared', 42 | '--with-libctl={0}'.format(join_path(spec['libctl'].prefix.share, 43 | 'libctl')), 44 | '--with-mpi', 45 | '--with-hdf5' 46 | ] 47 | 48 | if '+harminv' in spec: 49 | config_args.append('--with-blas={0}'.format( 50 | spec['blas'].prefix.lib)) 51 | config_args.append('--with-lapack={0}'.format( 52 | spec['lapack'].prefix.lib)) 53 | else: 54 | config_args.append('--without-blas') 55 | config_args.append('--without-lapack') 56 | 57 | return config_args 58 | 59 | def check(self): 60 | spec = self.spec 61 | 62 | # aniso_disp test fails unless installed with harminv 63 | # near2far test fails unless installed with gsl 64 | if '+harminv' in spec and '+gsl' in spec: 65 | # Most tests fail when run in parallel 66 | # 2D_convergence tests still fails to converge for unknown reasons 67 | make('check', parallel=False) 68 | -------------------------------------------------------------------------------- /SupportFiles/Installation/test_mpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xInfty/PyMeepPlasmonics/ba526137978fc700dbfa652fecabcec99f4f74ad/SupportFiles/Installation/test_mpi -------------------------------------------------------------------------------- /SupportFiles/Installation/test_mpi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char** argv) { 5 | 6 | MPI_Init(NULL, NULL); // initialize MPI environment 7 | int world_size; // number of processes 8 | MPI_Comm_size(MPI_COMM_WORLD, &world_size); 9 | 10 | int world_rank; // the rank of the process 11 | MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 12 | 13 | char processor_name[MPI_MAX_PROCESSOR_NAME]; // gets the name of the processor 14 | int name_len; 15 | MPI_Get_processor_name(processor_name, &name_len); 16 | 17 | printf("Hello world from processor %s, rank %d out of %d processors\n", 18 | processor_name, world_rank, world_size); 19 | 20 | MPI_Finalize(); // finish MPI environment 21 | } 22 | -------------------------------------------------------------------------------- /SupportFiles/Installation/update_parallel_meep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # /usr/bin/pyvenv/pmp/lib # For Python 4 | # /usr/local/lib/mpi/bin <3 For MPI 5 | # ./configure --prefix=/usr/local/lib/pmeep # Where I would like to have installed meep 6 | 7 | 8 | set -e 9 | 10 | RPATH_FLAGS="-Wl,-rpath,/usr/local/lib:/usr/lib/x86_64-linux-gnu/hdf5/openmpi:/usr/bin/pyvenv/pmp/lib:/usr/local/lib/mpi/lib" 11 | MY_LDFLAGS="-L/usr/local/lib -L/usr/lib/x86_64-linux-gnu/hdf5/openmpi -L/usr/bin/pyvenv/pmp/lib -L/usr/local/lib/mpi/lib ${RPATH_FLAGS}" 12 | MY_CPPFLAGS="-I/usr/local/include -I/usr/include/hdf5/openmpi -I/usr/bin/pyvenv/pmp/include -I/usr/local/lib/mpi/include" 13 | 14 | # sudo apt-get update 15 | 16 | # If building on Ubuntu 18.04LTS, replace libpng16-dev with libpng-dev, 17 | # and libpython3.5-dev with libpython3-dev. 18 | #sudo apt-get -y install \ 19 | # build-essential \ 20 | # gfortran \ 21 | # libblas-dev \ # Supossedly only for harminv 22 | # liblapack-dev \ # Supossedly only for harminv 23 | # libgmp-dev \ 24 | # swig \ 25 | # libgsl-dev \ 26 | # autoconf \ 27 | # pkg-config \ 28 | # libpng16-dev \ 29 | # git \ 30 | # guile-2.0-dev \ 31 | # libfftw3-dev \ 32 | # libhdf5-openmpi-dev \ 33 | # hdf5-tools \ 34 | # libpython3.5-dev \ 35 | # python3-pip \ 36 | # cmake \ 37 | 38 | mkdir -p ~/install 39 | 40 | # cd ~/install 41 | # git clone https://github.com/NanoComp/harminv.git 42 | # cd harminv/ 43 | # sh autogen.sh --enable-shared 44 | # make && sudo make install 45 | 46 | #cd ~/install 47 | #git clone https://github.com/NanoComp/libctl.git 48 | #cd libctl/ 49 | #sh autogen.sh --enable-shared 50 | #make && sudo make install 51 | 52 | #cd ~/install 53 | #git clone https://github.com/NanoComp/h5utils.git 54 | #cd h5utils/ 55 | #sh autogen.sh CC=mpicc LDFLAGS="${MY_LDFLAGS}" CPPFLAGS="${MY_CPPFLAGS}" 56 | #make && sudo make install 57 | 58 | # cd ~/install 59 | # git clone https://github.com/NanoComp/mpb.git 60 | # cd mpb/ 61 | # sh autogen.sh --enable-shared CC=mpicc LDFLAGS="${MY_LDFLAGS}" CPPFLAGS="${MY_CPPFLAGS}" --with-hermitian-eps 62 | # make && sudo make install 63 | 64 | # cd ~/install 65 | # git clone https://github.com/HomerReid/libGDSII.git 66 | # cd libGDSII/ 67 | # sh autogen.sh 68 | # make && sudo make install 69 | 70 | # The next line is only required on Ubuntu 16.04 71 | # sudo pip3 install --upgrade pip 72 | 73 | # pip3 install --user --no-cache-dir mpi4py 74 | # pip3 install --user Cython==0.29.16 75 | export HDF5_MPI="ON" 76 | # pip3 install --user --no-binary=h5py h5py 77 | # pip3 install --user autograd 78 | # pip3 install --user scipy 79 | # pip3 install --user matplotlib>3.0.0 80 | # pip3 install --user ffmpeg 81 | 82 | #cd ~/install 83 | #git clone git://github.com/stevengj/nlopt.git 84 | #cd nlopt/ 85 | #cmake -DPYTHON_EXECUTABLE=/usr/bin/python3 && make && sudo make install 86 | 87 | cd ~/install 88 | git clone https://github.com/NanoComp/meep.git 89 | cd meep/ 90 | sh autogen.sh --enable-shared --with-mpi --with-openmp PYTHON=python3 LDFLAGS="${MY_LDFLAGS}" CPPFLAGS="${MY_CPPFLAGS}" 91 | make && sudo make install 92 | -------------------------------------------------------------------------------- /SupportFiles/MaterialsData/Ag_JC_ComplexN_RIinfo.txt: -------------------------------------------------------------------------------- 1 | # Wavelength [nm] n k 2 | 1.879000000000000057e+02 1.070000000000000062e+00 1.211999999999999966e+00 3 | 1.915999999999999943e+02 1.100000000000000089e+00 1.231999999999999984e+00 4 | 1.953000000000000114e+02 1.120000000000000107e+00 1.254999999999999893e+00 5 | 1.993000000000000114e+02 1.139999999999999902e+00 1.276999999999999913e+00 6 | 2.033000000000000114e+02 1.149999999999999911e+00 1.296000000000000041e+00 7 | 2.073000000000000114e+02 1.179999999999999938e+00 1.312000000000000055e+00 8 | 2.119000000000000057e+02 1.199999999999999956e+00 1.324999999999999956e+00 9 | 2.164000000000000057e+02 1.219999999999999973e+00 1.336000000000000076e+00 10 | 2.214000000000000057e+02 1.250000000000000000e+00 1.342000000000000082e+00 11 | 2.262000000000000171e+02 1.260000000000000009e+00 1.344000000000000083e+00 12 | 2.313000000000000114e+02 1.280000000000000027e+00 1.356999999999999984e+00 13 | 2.370999999999999943e+02 1.280000000000000027e+00 1.366999999999999993e+00 14 | 2.426000000000000227e+02 1.300000000000000044e+00 1.377999999999999892e+00 15 | 2.490000000000000000e+02 1.310000000000000053e+00 1.389000000000000012e+00 16 | 2.550999999999999943e+02 1.330000000000000071e+00 1.393000000000000016e+00 17 | 2.616000000000000227e+02 1.350000000000000089e+00 1.387000000000000011e+00 18 | 2.688999999999999773e+02 1.379999999999999893e+00 1.372000000000000108e+00 19 | 2.761000000000000227e+02 1.409999999999999920e+00 1.330999999999999961e+00 20 | 2.843999999999999773e+02 1.409999999999999920e+00 1.264000000000000012e+00 21 | 2.923999999999999773e+02 1.389999999999999902e+00 1.161000000000000032e+00 22 | 3.008999999999999773e+02 1.340000000000000080e+00 9.639999999999999680e-01 23 | 3.106999999999999886e+02 1.129999999999999893e+00 6.159999999999999920e-01 24 | 3.204000000000000341e+02 8.100000000000000533e-01 3.920000000000000151e-01 25 | 3.315000000000000000e+02 1.700000000000000122e-01 8.289999999999999591e-01 26 | 3.425000000000000000e+02 1.400000000000000133e-01 1.141999999999999904e+00 27 | 3.541999999999999886e+02 1.000000000000000056e-01 1.419000000000000039e+00 28 | 3.678999999999999773e+02 7.000000000000000666e-02 1.657000000000000028e+00 29 | 3.815000000000000000e+02 5.000000000000000278e-02 1.864000000000000101e+00 30 | 3.973999999999999773e+02 5.000000000000000278e-02 2.069999999999999840e+00 31 | 4.133000000000000114e+02 5.000000000000000278e-02 2.274999999999999911e+00 32 | 4.305000000000000000e+02 4.000000000000000083e-02 2.462000000000000188e+00 33 | 4.509000000000000341e+02 4.000000000000000083e-02 2.657000000000000028e+00 34 | 4.713999999999999773e+02 5.000000000000000278e-02 2.869000000000000217e+00 35 | 4.959000000000000341e+02 5.000000000000000278e-02 3.092999999999999972e+00 36 | 5.208999999999999773e+02 5.000000000000000278e-02 3.323999999999999844e+00 37 | 5.486000000000000227e+02 5.999999999999999778e-02 3.585999999999999854e+00 38 | 5.820999999999999091e+02 5.000000000000000278e-02 3.858000000000000096e+00 39 | 6.168000000000000682e+02 5.999999999999999778e-02 4.152000000000000135e+00 40 | 6.595000000000000000e+02 5.000000000000000278e-02 4.482999999999999652e+00 41 | 7.045000000000000000e+02 4.000000000000000083e-02 4.838000000000000078e+00 42 | 7.560000000000000000e+02 2.999999999999999889e-02 5.241999999999999993e+00 43 | 8.211000000000000227e+02 4.000000000000000083e-02 5.727000000000000313e+00 44 | 8.920000000000000000e+02 4.000000000000000083e-02 6.312000000000000277e+00 45 | 9.840000000000000000e+02 4.000000000000000083e-02 6.991999999999999993e+00 46 | 1.088000000000000000e+03 4.000000000000000083e-02 7.794999999999999929e+00 47 | 1.216000000000000000e+03 8.999999999999999667e-02 8.827999999999999403e+00 48 | 1.393000000000000000e+03 1.300000000000000044e-01 1.009999999999999964e+01 49 | 1.610000000000000000e+03 1.499999999999999944e-01 1.184999999999999964e+01 50 | 1.937000000000000000e+03 2.399999999999999911e-01 1.408000000000000007e+01 51 | # paper="P. B. Johnson and R. W. Christy. Optical constants of the noble metals, Phys. Rev. B 6, 4370-4379 (1972)", wlen_range=[187.9, 1937.0], reference="https://refractiveindex.info/?shelf=main&book=Ag&page=Johnson", 52 | -------------------------------------------------------------------------------- /SupportFiles/MaterialsData/Au_JC_ComplexN_RIinfo.txt: -------------------------------------------------------------------------------- 1 | # Wavelength [nm] n k 2 | 1.879000000000000057e+02 1.280000000000000027e+00 1.187999999999999945e+00 3 | 1.915999999999999943e+02 1.320000000000000062e+00 1.203000000000000069e+00 4 | 1.953000000000000114e+02 1.340000000000000080e+00 1.225999999999999979e+00 5 | 1.993000000000000114e+02 1.330000000000000071e+00 1.250999999999999890e+00 6 | 2.033000000000000114e+02 1.330000000000000071e+00 1.276999999999999913e+00 7 | 2.073000000000000114e+02 1.300000000000000044e+00 1.304000000000000048e+00 8 | 2.119000000000000057e+02 1.300000000000000044e+00 1.350000000000000089e+00 9 | 2.164000000000000057e+02 1.300000000000000044e+00 1.387000000000000011e+00 10 | 2.214000000000000057e+02 1.300000000000000044e+00 1.427000000000000046e+00 11 | 2.262000000000000171e+02 1.310000000000000053e+00 1.459999999999999964e+00 12 | 2.313000000000000114e+02 1.300000000000000044e+00 1.497000000000000108e+00 13 | 2.370999999999999943e+02 1.320000000000000062e+00 1.536000000000000032e+00 14 | 2.426000000000000227e+02 1.320000000000000062e+00 1.576999999999999957e+00 15 | 2.490000000000000000e+02 1.330000000000000071e+00 1.631000000000000005e+00 16 | 2.550999999999999943e+02 1.330000000000000071e+00 1.687999999999999945e+00 17 | 2.616000000000000227e+02 1.350000000000000089e+00 1.749000000000000110e+00 18 | 2.688999999999999773e+02 1.379999999999999893e+00 1.802999999999999936e+00 19 | 2.761000000000000227e+02 1.429999999999999938e+00 1.846999999999999975e+00 20 | 2.843999999999999773e+02 1.469999999999999973e+00 1.868999999999999995e+00 21 | 2.923999999999999773e+02 1.489999999999999991e+00 1.877999999999999892e+00 22 | 3.008999999999999773e+02 1.530000000000000027e+00 1.889000000000000012e+00 23 | 3.106999999999999886e+02 1.530000000000000027e+00 1.893000000000000016e+00 24 | 3.204000000000000341e+02 1.540000000000000036e+00 1.897999999999999909e+00 25 | 3.315000000000000000e+02 1.479999999999999982e+00 1.883000000000000007e+00 26 | 3.425000000000000000e+02 1.479999999999999982e+00 1.870999999999999996e+00 27 | 3.541999999999999886e+02 1.500000000000000000e+00 1.866000000000000103e+00 28 | 3.678999999999999773e+02 1.479999999999999982e+00 1.895000000000000018e+00 29 | 3.815000000000000000e+02 1.459999999999999964e+00 1.933000000000000052e+00 30 | 3.973999999999999773e+02 1.469999999999999973e+00 1.951999999999999957e+00 31 | 4.133000000000000114e+02 1.459999999999999964e+00 1.957999999999999963e+00 32 | 4.305000000000000000e+02 1.449999999999999956e+00 1.947999999999999954e+00 33 | 4.509000000000000341e+02 1.379999999999999893e+00 1.913999999999999924e+00 34 | 4.713999999999999773e+02 1.310000000000000053e+00 1.848999999999999977e+00 35 | 4.959000000000000341e+02 1.040000000000000036e+00 1.832999999999999963e+00 36 | 5.208999999999999773e+02 6.199999999999999956e-01 2.080999999999999961e+00 37 | 5.486000000000000227e+02 4.299999999999999933e-01 2.455000000000000071e+00 38 | 5.820999999999999091e+02 2.899999999999999800e-01 2.862999999999999989e+00 39 | 6.168000000000000682e+02 2.099999999999999922e-01 3.271999999999999797e+00 40 | 6.595000000000000000e+02 1.400000000000000133e-01 3.697000000000000064e+00 41 | 7.045000000000000000e+02 1.300000000000000044e-01 4.102999999999999758e+00 42 | 7.560000000000000000e+02 1.400000000000000133e-01 4.541999999999999815e+00 43 | 8.211000000000000227e+02 1.600000000000000033e-01 5.083000000000000185e+00 44 | 8.920000000000000000e+02 1.700000000000000122e-01 5.663000000000000256e+00 45 | 9.840000000000000000e+02 2.200000000000000011e-01 6.349999999999999645e+00 46 | 1.088000000000000000e+03 2.700000000000000178e-01 7.150000000000000355e+00 47 | 1.216000000000000000e+03 3.499999999999999778e-01 8.144999999999999574e+00 48 | 1.393000000000000000e+03 4.299999999999999933e-01 9.519000000000000128e+00 49 | 1.610000000000000000e+03 5.600000000000000533e-01 1.121000000000000085e+01 50 | 1.937000000000000000e+03 9.200000000000000400e-01 1.377999999999999936e+01 51 | # paper="P. B. Johnson and R. W. Christy. Optical constants of the noble metals, Phys. Rev. B 6, 4370-4379 (1972)", wlen_range=[188, 1937], material="Au", reference="https://refractiveindex.info/?shelf=main&book=Au&page=Johnson", 52 | -------------------------------------------------------------------------------- /SupportFiles/Pictures/PyMeepPlasmonics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xInfty/PyMeepPlasmonics/ba526137978fc700dbfa652fecabcec99f4f74ad/SupportFiles/Pictures/PyMeepPlasmonics.png -------------------------------------------------------------------------------- /SupportFiles/Pictures/PyMeepPlasmonicsModules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xInfty/PyMeepPlasmonics/ba526137978fc700dbfa652fecabcec99f4f74ad/SupportFiles/Pictures/PyMeepPlasmonicsModules.png -------------------------------------------------------------------------------- /SupportFiles/Pictures/PyMeepPlasmonicsRoutines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xInfty/PyMeepPlasmonics/ba526137978fc700dbfa652fecabcec99f4f74ad/SupportFiles/Pictures/PyMeepPlasmonicsRoutines.png -------------------------------------------------------------------------------- /v_plot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | This module contains tools for plotting with customized style. 5 | 6 | The functions contained right now are... 7 | 8 | set_style : function 9 | Gives PyMeepPlasmonics thesis style to a figure. 10 | add_style : function 11 | Gives style to figures to include in Latex PDF files. 12 | add_subplot_axes : function 13 | Adds a sub-set of axes inside an existing set of axes. 14 | 15 | @author: Vall 16 | """ 17 | 18 | #%% 19 | 20 | from matplotlib import rcParams, ticker 21 | import matplotlib.pyplot as plt 22 | 23 | #%% CUSTOMIZATION OPTIONS 24 | 25 | def set_style(): 26 | """Gives PyMeepPlasmonics thesis style to a figure.""" 27 | 28 | plt.rcParams.update({'text.usetex': False, 29 | 'font.family':'serif', 30 | 'font.sans-serif': ['MS Reference Sans Serif', 'sans-serif'], 31 | 'mathtext.fontset': 'cm', # Computer Modern 32 | 'font.weight':500, 33 | 'figure.titlesize':13, 34 | 'axes.titlesize':12, 35 | 'axes.labelsize':11, 36 | 'legend.fontsize':11, 37 | 'xtick.labelsize':10, 38 | 'ytick.labelsize':10, 39 | 'xtick.minor.visible':True, 40 | 'ytick.minor.visible':True, 41 | 'grid.alpha':0.4, 42 | 'axes.grid':True, 43 | 'xtick.color':'b0b0b0', 44 | 'ytick.color':'b0b0b0', 45 | 'xtick.labelcolor':'black', 46 | 'ytick.labelcolor':'black', 47 | 'legend.frameon':False, 48 | 'legend.framealpha':0, 49 | 'lines.markersize':8 50 | }) 51 | 52 | def add_style(figure_id=None, new_figure=False, **kwargs): 53 | """Gives style to figures to include in Latex PDF files. 54 | 55 | This function... 56 | ...increases font size; 57 | ...increases linewidth; 58 | ...increases markersize; 59 | ...gives format to axis ticks if specified; 60 | ...stablishes new figure dimensions if specified; 61 | ...activates grid. 62 | 63 | Parameters 64 | ---------- 65 | figure_id : int, optional 66 | ID of the figure where the text will be printed. 67 | If none is given, the current figure is taken as default. 68 | new_figure=False : bool, optional 69 | Indicates whether to make a new figure or not when 70 | figure_id=None. 71 | 72 | Other Parameters 73 | ---------------- 74 | xaxisformat : format-like str, optional. 75 | Used to update x axis ticks format; i.e.: '%.2e' 76 | yaxisformat : format-like str, optional. 77 | Used to update y axis ticks format; i.e.: '%.2e' 78 | dimensions: list with length 4, optional. 79 | Used to update plot dimensions: [xmin, xmax, ymin, ymax]. Each 80 | one should be a number expressed as a fraction of current 81 | dimensions. 82 | 83 | See Also 84 | -------- 85 | matplotlib.pyplot.axis 86 | matplotlib.pyplot.gcf 87 | 88 | """ 89 | 90 | if figure_id is not None: 91 | fig = plt.figure(figure_id) 92 | elif new_figure: 93 | fig = plt.figure() 94 | else: 95 | fig = plt.gcf() 96 | 97 | try: 98 | ax = fig.axes 99 | ax[0] 100 | except IndexError: 101 | ax = [plt.axes()] 102 | 103 | kwargs_default = dict( 104 | fontsize=12, 105 | linewidth=3, 106 | markersize=6, 107 | dimensions=[1.15,1.05,1,1], 108 | tight_layout=True, 109 | grid=False, 110 | xaxisformat=None, 111 | yaxisformat=None) 112 | 113 | kwargs = {key:kwargs.get(key, value) 114 | for key, value in kwargs_default.items()} 115 | 116 | rcParams.update({'font.size': kwargs['fontsize']}) 117 | rcParams.update({'lines.linewidth': kwargs['linewidth']}) 118 | rcParams.update({'lines.markersize': kwargs['markersize']}) 119 | for a in ax: 120 | box = a.get_position() 121 | a.set_position([kwargs['dimensions'][0]*box.x0, 122 | kwargs['dimensions'][1]*box.y0, 123 | kwargs['dimensions'][2]*box.width, 124 | kwargs['dimensions'][3]*box.height]) 125 | 126 | if kwargs['xaxisformat'] is not None: 127 | for a in ax: 128 | a.xaxis.set_major_formatter(ticker.FormatStrFormatter( 129 | kwargs['xaxisformat'])) 130 | 131 | if kwargs['yaxisformat'] is not None: 132 | for a in ax: 133 | a.yaxis.set_major_formatter(ticker.FormatStrFormatter( 134 | kwargs['yaxisformat'])) 135 | 136 | for a in ax: 137 | a.grid(kwargs['grid']) 138 | 139 | fig.tight_layout = kwargs['tight_layout'] 140 | 141 | plt.show() 142 | 143 | #%% 144 | 145 | def add_subplot_axes(ax, rect): 146 | """Adds a sub-set of axes inside an existing set of axes. 147 | 148 | This function was taken from StackOverflow on September 2021. 149 | https://stackoverflow.com/questions/17458580/embedding-small-plots-inside-subplots-in-matplotlib 150 | 151 | Parameters 152 | ---------- 153 | ax : plt.Axes or plt.AxesSubplot instance 154 | The currently existing set of axes. 155 | rect : list or iterable of length 4 156 | The desired dimensions for the new sub-set of axes: [x, y, width, height] 157 | 158 | Returns 159 | ------- 160 | subax : plt.AxesSubplot instance 161 | The newly created sub-set of axes. 162 | """ 163 | 164 | 165 | fig = ax.figure #plt.gcf() 166 | box = ax.get_position() 167 | width = box.width 168 | height = box.height 169 | 170 | inax_position = ax.transAxes.transform(rect[0:2]) 171 | transFigure = fig.transFigure.inverted() 172 | infig_position = transFigure.transform(inax_position) 173 | x = infig_position[0] 174 | y = infig_position[1] 175 | width *= rect[2] 176 | height *= rect[3] 177 | 178 | subax = fig.add_axes([x,y,width,height]) 179 | x_labelsize = subax.get_xticklabels()[0].get_size() 180 | y_labelsize = subax.get_yticklabels()[0].get_size() 181 | x_labelsize *= rect[2]**0.5 182 | y_labelsize *= rect[3]**0.5 183 | subax.xaxis.set_tick_params(labelsize=x_labelsize) 184 | subax.yaxis.set_tick_params(labelsize=y_labelsize) 185 | 186 | return subax --------------------------------------------------------------------------------