Multi-objective BO: OPV light-intensity dependant JV fits with SIMsalabim (real data)
This notebook is a demonstration of how to fit light-intensity dependent JV curves with drift-diffusion models using the SIMsalabim package.
[1]:
# Import necessary libraries
import warnings, os, sys, shutil
# remove warnings from the output
os.environ["PYTHONWARNINGS"] = "ignore"
warnings.filterwarnings(action='ignore', category=FutureWarning)
warnings.filterwarnings(action='ignore', category=UserWarning)
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from numpy.random import default_rng
from scipy import constants
import torch, copy, uuid
import pySIMsalabim as sim
from pySIMsalabim.experiments.JV_steady_state import *
import ax, logging
from ax.utils.notebook.plotting import init_notebook_plotting, render
init_notebook_plotting() # for Jupyter notebooks
try:
from optimpv import *
from optimpv.axBOtorch.axUtils import *
except Exception as e:
sys.path.append('../') # add the path to the optimpv module
from optimpv import *
from optimpv.axBOtorch.axUtils import *
[INFO 08-13 18:09:30] ax.utils.notebook.plotting: Injecting Plotly library into cell. Do not overwrite or delete cell.
[INFO 08-13 18:09:30] ax.utils.notebook.plotting: Please see
(https://ax.dev/tutorials/visualizations.html#Fix-for-plots-that-are-not-rendering)
if visualizations are not rendering.
Get the experimental data
[2]:
# Set the session path for the simulation and the input files
session_path = os.path.join(os.path.join(os.path.abspath('../'),'SIMsalabim','SimSS'))
input_path = os.path.join(os.path.join(os.path.join(os.path.abspath('../'),'Data','simsalabim_test_inputs','JVrealOPV')))
simulation_setup_filename = 'simulation_setup_PM6_L8BO.txt'
simulation_setup = os.path.join(session_path, simulation_setup_filename)
# path to the layer files defined in the simulation_setup file
l1 = 'ZnO.txt'
l2 = 'PM6_L8BO.txt'
l3 = 'BM_HTL.txt'
l1 = os.path.join(input_path, l1 )
l2 = os.path.join(input_path, l2 )
l3 = os.path.join(input_path, l3 )
# copy this files to session_path
force_copy = True
if not os.path.exists(session_path):
os.makedirs(session_path)
for file in [l1,l2,l3,simulation_setup_filename]:
file = os.path.join(input_path, os.path.basename(file))
if force_copy or not os.path.exists(os.path.join(session_path, os.path.basename(file))):
shutil.copyfile(file, os.path.join(session_path, os.path.basename(file)))
else:
print('File already exists: ',file)
# Show the device structure
fig = sim.plot_band_diagram(simulation_setup, session_path)
dev_par, layers = sim.load_device_parameters(session_path, simulation_setup, run_mode = False)
SIMsalabim_params = {}
for layer in layers:
SIMsalabim_params[layer[1]] = sim.ReadParameterFile(os.path.join(session_path,layer[2]))
L_active_Layer = float(SIMsalabim_params['l2']['L'])
# Load the JV data
# Gfracs = [0.1,0.5,1.0] # Fractions of the generation rate to simulate (None if you want only one light intensity as define in the simulation_setup file)
# import JV data
df = pd.read_csv(os.path.join(input_path, 'JV_PM6_L8BO.dat'), sep=' ')
# X = vext,gfrac columns
X = df[['Vext','Gfrac']].values
y = df[['Jext']].values.reshape(-1)
# same order of the Gfrac as they appear in the data
Gfracs = pd.unique(df['Gfrac'])
# Gfracs = np.unique(df[['Gfrac']].values)
print(f'Gfracs = {Gfracs}')
X_1sun = df[['Vext','Gfrac']].values[df['Gfrac'] == 1.0]
y_1sun = df[['Jext']].values[df['Gfrac'] == 1.0].reshape(-1)
# get 1sun Jsc as it will help narrow down the range for Gehp
Jsc_1sun = np.interp(0.0, X_1sun[:,0], y_1sun)
minJ = np.min(y_1sun)
q = constants.value(u'elementary charge')
G_ehp_calc = abs(Jsc_1sun/(q*L_active_Layer))
G_ehp_max = abs(minJ/(q*L_active_Layer))
# get Voc
Voc_1sun = np.interp(0.0, y_1sun, X_1sun[:,0])
print(f'Voc_1sun = {Voc_1sun} V')
# Filter some data
Vmin = -0.1
Jmax = abs(Jsc_1sun)
idx = np.where((X[:,0] > Vmin) & (y < Jmax))
y = y[idx]
X = X[idx]
# get the data for each Gfrac with will be used in the different agents later
X1 = X[X[:,1] == Gfracs[0]]
y1 = y[X[:,1] == Gfracs[0]]
X2 = X[X[:,1] == Gfracs[1]]
y2 = y[X[:,1] == Gfracs[1]]
X3 = X[X[:,1] == Gfracs[2]]
y3 = y[X[:,1] == Gfracs[2]]
# plot the data for each Gfrac
plt.figure(figsize=(10,10))
viridis = plt.get_cmap('viridis', len(Gfracs))
for i, Gfrac in enumerate(Gfracs):
plt.plot(X[X[:,1] == Gfrac][:,0], y[X[:,1] == Gfrac], '-', label = f'Gfrac = {Gfrac}', color = viridis(i))
plt.grid()
plt.xlabel('Voltage [V]')
plt.ylabel('Current density [A m$^{-2}$]')
plt.legend()
plt.show()

Gfracs = [1. 0.1 0.5]
Voc_1sun = 0.8613743287822753 V

Define the parameters for the simulation
[3]:
params = [] # list of parameters to be optimized
mun = FitParam(name = 'l2.mu_n', value = 7e-8, bounds = [1e-9,1e-6], log_scale = True, value_type = 'float', fscale = None, rescale = False, display_name=r'$\mu_n$', unit='m$^2$ V$^{-1}$s$^{-1}$', axis_type = 'log', force_log = True)
params.append(mun)
mup = FitParam(name = 'l2.mu_p', value = 5e-8, bounds = [1e-9,1e-6], log_scale = True, value_type = 'float', fscale = None, rescale = False, display_name=r'$\mu_p$', unit=r'm$^2$ V$^{-1}$s$^{-1}$', axis_type = 'log', force_log = True)
params.append(mup)
bulk_tr = FitParam(name = 'l2.N_t_bulk', value = 1e20, bounds = [1e16,8e22], log_scale = True, value_type = 'float', fscale = None, rescale = False, display_name=r'$N_{T}$', unit=r'm$^{-3}$', axis_type = 'log', force_log = True)
params.append(bulk_tr)
preLangevin = FitParam(name = 'l2.preLangevin', value = 1e-2, bounds = [1e-3,1], log_scale = True, value_type = 'float', fscale = None, rescale = False, display_name=r'$\gamma_{pre}$', unit=r'', axis_type = 'log', force_log = True)
params.append(preLangevin)
R_series = FitParam(name = 'R_series', value = 1e-4, bounds = [1e-6,1e-2], log_scale = True, value_type = 'float', fscale = None, rescale = False, display_name=r'$R_{series}$', unit=r'$\Omega$ m$^2$', axis_type = 'log', force_log = False)
params.append(R_series)
R_shunt = FitParam(name = 'R_shunt', value = 1e1, bounds = [1e-2,1e2], log_scale = True, value_type = 'float', fscale = None, rescale = False, display_name=r'$R_{shunt}$', unit=r'$\Omega$ m$^2$', axis_type = 'log', force_log = False)
params.append(R_shunt)
G_ehp = FitParam(name = 'l2.G_ehp', value = G_ehp_calc, bounds = [G_ehp_calc*0.95,G_ehp_max*1.05], log_scale = False, value_type = 'float', fscale = None, rescale = False, display_name=r'$G_{ehp}$', unit=r'm$^{-3}$ s$^{-1}$', axis_type = 'linear', force_log = False)
params.append(G_ehp)
# save the original parameters for later
params_orig = copy.deepcopy(params)
Run the optimization
[4]:
# Define the Agent and the target metric/loss function
from optimpv.DDfits.JVAgent import JVAgent
metric = 'nrmse' # can be 'nrmse', 'mse', 'mae'
loss = 'linear' # can be 'linear', 'huber', 'soft_l1'
threshold = 0.05 # need this to get a reference point for the hypervolume calculation
jv_main = JVAgent(params, X, y, session_path, simulation_setup, parallel = True, max_jobs = 3, metric = metric, loss = loss) # agent with ALL the light intensities, not necessary for the MOO but useful later
# The agents below need to add a different name for each agent otherwise they will overwrite each other in the jv.run_Ax output dictionary
jv1 = JVAgent(params, X1, y1, session_path, simulation_setup, parallel = True, max_jobs = 1, metric = metric, loss = loss, threshold=threshold,name='Gfrac1') # agent with Gfrac 1
jv2 = JVAgent(params, X2, y2, session_path, simulation_setup, parallel = True, max_jobs = 1, metric = metric, loss = loss, threshold=threshold,name='Gfrac2') # agent with Gfrac 2
jv3 = JVAgent(params, X3, y3, session_path, simulation_setup, parallel = True, max_jobs = 1, metric = metric, loss = loss, threshold=threshold,name='Gfrac3') # agent with Gfrac 3
[5]:
from optimpv.axBOtorch.axBOtorchOptimizer import axBOtorchOptimizer
from botorch.acquisition.multi_objective.logei import qLogExpectedHypervolumeImprovement
from ax.adapter.transforms.standardize_y import StandardizeY
from ax.adapter.transforms.unit_x import UnitX
from ax.adapter.transforms.remove_fixed import RemoveFixed
from ax.adapter.transforms.log import Log
from ax.generators.torch.botorch_modular.utils import ModelConfig
from ax.generators.torch.botorch_modular.surrogate import SurrogateSpec
from gpytorch.kernels import MaternKernel
from gpytorch.kernels import ScaleKernel
from botorch.models import SingleTaskGP
model_gen_kwargs_list = None
parameter_constraints = None
model_kwargs_list = [{},{},{"torch_device":torch.device("cuda" if torch.cuda.is_available() else "cpu"),'botorch_acqf_class':qLogExpectedHypervolumeImprovement,'transforms':[RemoveFixed, Log,UnitX, StandardizeY],'surrogate_spec':SurrogateSpec(model_configs=[ModelConfig(botorch_model_class=SingleTaskGP,covar_module_class=ScaleKernel, covar_module_options={'base_kernel':MaternKernel(nu=2.5, ard_num_dims=len(params))})])}]
optimizer = axBOtorchOptimizer(params = params, agents = [jv1,jv2,jv3], models = ['CENTER','SOBOL','BOTORCH_MODULAR'],n_batches = [1,1,10], batch_size = [1,10,2], ax_client = None, max_parallelism = 100, model_kwargs_list = model_kwargs_list, model_gen_kwargs_list = model_gen_kwargs_list, name = 'ax_opti',parameter_constraints = parameter_constraints,)
[6]:
optimizer.optimize() # run the optimization with ax
[INFO 08-13 18:09:31] optimpv.axBOtorchOptimizer: Trial 0 with parameters: {'l2.mu_n': -7.5, 'l2.mu_p': -7.5, 'l2.N_t_bulk': 19.451544993495972, 'l2.preLangevin': -1.5, 'R_series': 0.0001, 'R_shunt': 1.0, 'l2.G_ehp': 1.4669272681272731e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 0 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.13334896922864783), 'Gfrac2_JV_nrmse_linear': np.float64(0.08254634225523515), 'Gfrac3_JV_nrmse_linear': np.float64(0.11049013404965334)} and parameters: {'l2.mu_n': -7.5, 'l2.mu_p': -7.5, 'l2.N_t_bulk': 19.451544993495972, 'l2.preLangevin': -1.5, 'R_series': 0.0001, 'R_shunt': 1.0, 'l2.G_ehp': 1.4669272681272731e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 1 with parameters: {'l2.mu_n': -7.487566986121237, 'l2.mu_p': -6.286150937899947, 'l2.N_t_bulk': 21.077922106036834, 'l2.preLangevin': -2.51336507499218, 'R_series': 5.8498769227713524e-05, 'R_shunt': 0.01610212424771596, 'l2.G_ehp': 1.3980302796022572e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 2 with parameters: {'l2.mu_n': -8.767879217863083, 'l2.mu_p': -8.223654940724373, 'l2.N_t_bulk': 16.825483778023063, 'l2.preLangevin': -1.4102639285847545, 'R_series': 0.0036132872832182047, 'R_shunt': 51.05918350102587, 'l2.G_ehp': 1.5171129522488657e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 3 with parameters: {'l2.mu_n': -7.90431893337518, 'l2.mu_p': -6.849244264885783, 'l2.N_t_bulk': 21.76933169613836, 'l2.preLangevin': -2.2116903299465775, 'R_series': 0.00027804338148928673, 'R_shunt': 7.613954580060508, 'l2.G_ehp': 1.4451258581689775e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 4 with parameters: {'l2.mu_n': -6.565481308847666, 'l2.mu_p': -8.787022165954113, 'l2.N_t_bulk': 19.21484815802554, 'l2.preLangevin': -0.2178038600832224, 'R_series': 1.7000973642142542e-06, 'R_shunt': 0.23716372197456007, 'l2.G_ehp': 1.4700396522431865e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 5 with parameters: {'l2.mu_n': -6.338317349553108, 'l2.mu_p': -7.1641351114958525, 'l2.N_t_bulk': 17.41491614109903, 'l2.preLangevin': -0.7236263556405902, 'R_series': 8.78603136275188e-06, 'R_shunt': 0.08736550657400785, 'l2.G_ehp': 1.4266324813443568e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 6 with parameters: {'l2.mu_n': -7.6655266815796494, 'l2.mu_p': -8.331916965544224, 'l2.N_t_bulk': 20.06378128285764, 'l2.preLangevin': -1.7293039038777351, 'R_series': 0.0005384705498376531, 'R_shunt': 27.70327092585164, 'l2.G_ehp': 1.491397408827677e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 7 with parameters: {'l2.mu_n': -8.257998246699572, 'l2.mu_p': -6.600860109552741, 'l2.N_t_bulk': 18.531030873937958, 'l2.preLangevin': -1.0252781677991152, 'R_series': 0.0018485145075870086, 'R_shunt': 1.4041470822563349, 'l2.G_ehp': 1.3795585746203186e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 8 with parameters: {'l2.mu_n': -6.9660591976717114, 'l2.mu_p': -7.768734276294708, 'l2.N_t_bulk': 22.87784417086586, 'l2.preLangevin': -2.9217869052663445, 'R_series': 1.144423062529783e-05, 'R_shunt': 0.4373717181190632, 'l2.G_ehp': 1.5384936146794804e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 9 with parameters: {'l2.mu_n': -6.769544108770788, 'l2.mu_p': -6.95305815897882, 'l2.N_t_bulk': 17.731448303948802, 'l2.preLangevin': -1.5697099333629012, 'R_series': 0.006693783844118423, 'R_shunt': 0.11592826228311534, 'l2.G_ehp': 1.4334914836413886e+28}
[INFO 08-13 18:09:32] optimpv.axBOtorchOptimizer: Trial 10 with parameters: {'l2.mu_n': -8.477584613487124, 'l2.mu_p': -8.870759770274162, 'l2.N_t_bulk': 22.120397007198353, 'l2.preLangevin': -0.5139866285026073, 'R_series': 3.992921376426787e-05, 'R_shunt': 3.7134133786983297, 'l2.G_ehp': 1.5046805120459625e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 1 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.17892726422630456), 'Gfrac2_JV_nrmse_linear': np.float64(0.18048961314950498), 'Gfrac3_JV_nrmse_linear': np.float64(0.179697427065233)} and parameters: {'l2.mu_n': -7.487566986121237, 'l2.mu_p': -6.286150937899947, 'l2.N_t_bulk': 21.077922106036834, 'l2.preLangevin': -2.51336507499218, 'R_series': 5.8498769227713524e-05, 'R_shunt': 0.01610212424771596, 'l2.G_ehp': 1.3980302796022572e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 2 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.3425375431603147), 'Gfrac2_JV_nrmse_linear': np.float64(0.16979087877383278), 'Gfrac3_JV_nrmse_linear': np.float64(0.20176696498816724)} and parameters: {'l2.mu_n': -8.767879217863083, 'l2.mu_p': -8.223654940724373, 'l2.N_t_bulk': 16.825483778023063, 'l2.preLangevin': -1.4102639285847545, 'R_series': 0.0036132872832182047, 'R_shunt': 51.05918350102587, 'l2.G_ehp': 1.5171129522488657e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 3 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.29728157788823617), 'Gfrac2_JV_nrmse_linear': np.float64(0.12700887138397926), 'Gfrac3_JV_nrmse_linear': np.float64(0.23023830530385575)} and parameters: {'l2.mu_n': -7.90431893337518, 'l2.mu_p': -6.849244264885783, 'l2.N_t_bulk': 21.76933169613836, 'l2.preLangevin': -2.2116903299465775, 'R_series': 0.00027804338148928673, 'R_shunt': 7.613954580060508, 'l2.G_ehp': 1.4451258581689775e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 4 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.2961223315648388), 'Gfrac2_JV_nrmse_linear': np.float64(0.14736144584406363), 'Gfrac3_JV_nrmse_linear': np.float64(0.21976477235707417)} and parameters: {'l2.mu_n': -6.565481308847666, 'l2.mu_p': -8.787022165954113, 'l2.N_t_bulk': 19.21484815802554, 'l2.preLangevin': -0.2178038600832224, 'R_series': 1.7000973642142542e-06, 'R_shunt': 0.23716372197456007, 'l2.G_ehp': 1.4700396522431865e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 5 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.218948136546223), 'Gfrac2_JV_nrmse_linear': np.float64(0.22082351926456634), 'Gfrac3_JV_nrmse_linear': np.float64(0.21938795815491516)} and parameters: {'l2.mu_n': -6.338317349553108, 'l2.mu_p': -7.1641351114958525, 'l2.N_t_bulk': 17.41491614109903, 'l2.preLangevin': -0.7236263556405902, 'R_series': 8.78603136275188e-06, 'R_shunt': 0.08736550657400785, 'l2.G_ehp': 1.4266324813443568e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 6 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.19216883890029854), 'Gfrac2_JV_nrmse_linear': np.float64(0.10990465531578862), 'Gfrac3_JV_nrmse_linear': np.float64(0.12221326205477198)} and parameters: {'l2.mu_n': -7.6655266815796494, 'l2.mu_p': -8.331916965544224, 'l2.N_t_bulk': 20.06378128285764, 'l2.preLangevin': -1.7293039038777351, 'R_series': 0.0005384705498376531, 'R_shunt': 27.70327092585164, 'l2.G_ehp': 1.491397408827677e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 7 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.32589099944533007), 'Gfrac2_JV_nrmse_linear': np.float64(0.12495303363658125), 'Gfrac3_JV_nrmse_linear': np.float64(0.20080250383108644)} and parameters: {'l2.mu_n': -8.257998246699572, 'l2.mu_p': -6.600860109552741, 'l2.N_t_bulk': 18.531030873937958, 'l2.preLangevin': -1.0252781677991152, 'R_series': 0.0018485145075870086, 'R_shunt': 1.4041470822563349, 'l2.G_ehp': 1.3795585746203186e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 8 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.4748546643986718), 'Gfrac2_JV_nrmse_linear': np.float64(0.1382628794911131), 'Gfrac3_JV_nrmse_linear': np.float64(0.3265755123967553)} and parameters: {'l2.mu_n': -6.9660591976717114, 'l2.mu_p': -7.768734276294708, 'l2.N_t_bulk': 22.87784417086586, 'l2.preLangevin': -2.9217869052663445, 'R_series': 1.144423062529783e-05, 'R_shunt': 0.4373717181190632, 'l2.G_ehp': 1.5384936146794804e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 9 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.4004976596211393), 'Gfrac2_JV_nrmse_linear': np.float64(0.16307469908373295), 'Gfrac3_JV_nrmse_linear': np.float64(0.23313398099987592)} and parameters: {'l2.mu_n': -6.769544108770788, 'l2.mu_p': -6.95305815897882, 'l2.N_t_bulk': 17.731448303948802, 'l2.preLangevin': -1.5697099333629012, 'R_series': 0.006693783844118423, 'R_shunt': 0.11592826228311534, 'l2.G_ehp': 1.4334914836413886e+28}
[INFO 08-13 18:09:35] optimpv.axBOtorchOptimizer: Trial 10 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.49856102937148644), 'Gfrac2_JV_nrmse_linear': np.float64(0.19401116112405478), 'Gfrac3_JV_nrmse_linear': np.float64(0.3421449147789714)} and parameters: {'l2.mu_n': -8.477584613487124, 'l2.mu_p': -8.870759770274162, 'l2.N_t_bulk': 22.120397007198353, 'l2.preLangevin': -0.5139866285026073, 'R_series': 3.992921376426787e-05, 'R_shunt': 3.7134133786983297, 'l2.G_ehp': 1.5046805120459625e+28}
[INFO 08-13 18:09:40] optimpv.axBOtorchOptimizer: Trial 11 with parameters: {'l2.mu_n': -7.64871278572833, 'l2.mu_p': -7.390690603427543, 'l2.N_t_bulk': 19.648824669527205, 'l2.preLangevin': -1.8509989470126311, 'R_series': 0.00025586010461392793, 'R_shunt': 0.8026879056406122, 'l2.G_ehp': 1.463788306103097e+28}
[INFO 08-13 18:09:40] optimpv.axBOtorchOptimizer: Trial 12 with parameters: {'l2.mu_n': -6.8717850108850165, 'l2.mu_p': -7.623948008841699, 'l2.N_t_bulk': 19.53740931905366, 'l2.preLangevin': -0.17933468616360093, 'R_series': 0.0002925662450387275, 'R_shunt': 1.7031780373357064, 'l2.G_ehp': 1.557374110593198e+28}
[INFO 08-13 18:09:41] optimpv.axBOtorchOptimizer: Trial 11 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.12358712981320975), 'Gfrac2_JV_nrmse_linear': np.float64(0.052765254943831504), 'Gfrac3_JV_nrmse_linear': np.float64(0.08595456215635008)} and parameters: {'l2.mu_n': -7.64871278572833, 'l2.mu_p': -7.390690603427543, 'l2.N_t_bulk': 19.648824669527205, 'l2.preLangevin': -1.8509989470126311, 'R_series': 0.00025586010461392793, 'R_shunt': 0.8026879056406122, 'l2.G_ehp': 1.463788306103097e+28}
[INFO 08-13 18:09:41] optimpv.axBOtorchOptimizer: Trial 12 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.27374033320783037), 'Gfrac2_JV_nrmse_linear': np.float64(0.15040682506502287), 'Gfrac3_JV_nrmse_linear': np.float64(0.2139421620691672)} and parameters: {'l2.mu_n': -6.8717850108850165, 'l2.mu_p': -7.623948008841699, 'l2.N_t_bulk': 19.53740931905366, 'l2.preLangevin': -0.17933468616360093, 'R_series': 0.0002925662450387275, 'R_shunt': 1.7031780373357064, 'l2.G_ehp': 1.557374110593198e+28}
[INFO 08-13 18:09:46] optimpv.axBOtorchOptimizer: Trial 13 with parameters: {'l2.mu_n': -8.76807110744148, 'l2.mu_p': -7.240514241701158, 'l2.N_t_bulk': 19.7631322360619, 'l2.preLangevin': -2.23044950097048, 'R_series': 0.00031372987846391994, 'R_shunt': 1.088169768957447, 'l2.G_ehp': 1.451816998938778e+28}
[INFO 08-13 18:09:46] optimpv.axBOtorchOptimizer: Trial 14 with parameters: {'l2.mu_n': -6.9021538141229035, 'l2.mu_p': -6.888439691457291, 'l2.N_t_bulk': 19.81689012027116, 'l2.preLangevin': -1.3448433136392528, 'R_series': 0.00024739114199300125, 'R_shunt': 0.014642944446422262, 'l2.G_ehp': 1.4620951183714428e+28}
[INFO 08-13 18:09:47] optimpv.axBOtorchOptimizer: Trial 13 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.2220785160217458), 'Gfrac2_JV_nrmse_linear': np.float64(0.10139153668100048), 'Gfrac3_JV_nrmse_linear': np.float64(0.13012945586510963)} and parameters: {'l2.mu_n': -8.76807110744148, 'l2.mu_p': -7.240514241701158, 'l2.N_t_bulk': 19.7631322360619, 'l2.preLangevin': -2.23044950097048, 'R_series': 0.00031372987846391994, 'R_shunt': 1.088169768957447, 'l2.G_ehp': 1.451816998938778e+28}
[INFO 08-13 18:09:47] optimpv.axBOtorchOptimizer: Trial 14 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.19917664221463416), 'Gfrac2_JV_nrmse_linear': np.float64(0.18069937340297684), 'Gfrac3_JV_nrmse_linear': np.float64(0.1882481321288729)} and parameters: {'l2.mu_n': -6.9021538141229035, 'l2.mu_p': -6.888439691457291, 'l2.N_t_bulk': 19.81689012027116, 'l2.preLangevin': -1.3448433136392528, 'R_series': 0.00024739114199300125, 'R_shunt': 0.014642944446422262, 'l2.G_ehp': 1.4620951183714428e+28}
[INFO 08-13 18:09:52] optimpv.axBOtorchOptimizer: Trial 15 with parameters: {'l2.mu_n': -7.4475274159433695, 'l2.mu_p': -7.025057707473408, 'l2.N_t_bulk': 19.618740342625358, 'l2.preLangevin': -1.8945562640171925, 'R_series': 0.0002103771639664598, 'R_shunt': 1.5851689465722325, 'l2.G_ehp': 1.4735750895936206e+28}
[INFO 08-13 18:09:52] optimpv.axBOtorchOptimizer: Trial 16 with parameters: {'l2.mu_n': -7.752426590213192, 'l2.mu_p': -8.401964005066981, 'l2.N_t_bulk': 19.701397065852227, 'l2.preLangevin': -1.7999038268617793, 'R_series': 0.007909976012119877, 'R_shunt': 1.1195499937739959, 'l2.G_ehp': 1.3875379690873237e+28}
[INFO 08-13 18:09:53] optimpv.axBOtorchOptimizer: Trial 15 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.12367750479400179), 'Gfrac2_JV_nrmse_linear': np.float64(0.08467514908596312), 'Gfrac3_JV_nrmse_linear': np.float64(0.10361231291415197)} and parameters: {'l2.mu_n': -7.4475274159433695, 'l2.mu_p': -7.025057707473408, 'l2.N_t_bulk': 19.618740342625358, 'l2.preLangevin': -1.8945562640171925, 'R_series': 0.0002103771639664598, 'R_shunt': 1.5851689465722325, 'l2.G_ehp': 1.4735750895936206e+28}
[INFO 08-13 18:09:53] optimpv.axBOtorchOptimizer: Trial 16 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.40794125672887527), 'Gfrac2_JV_nrmse_linear': np.float64(0.17423945714141625), 'Gfrac3_JV_nrmse_linear': np.float64(0.24231023829838022)} and parameters: {'l2.mu_n': -7.752426590213192, 'l2.mu_p': -8.401964005066981, 'l2.N_t_bulk': 19.701397065852227, 'l2.preLangevin': -1.7999038268617793, 'R_series': 0.007909976012119877, 'R_shunt': 1.1195499937739959, 'l2.G_ehp': 1.3875379690873237e+28}
[INFO 08-13 18:09:57] optimpv.axBOtorchOptimizer: Trial 17 with parameters: {'l2.mu_n': -7.847509548194543, 'l2.mu_p': -7.279339584577821, 'l2.N_t_bulk': 19.643011810817857, 'l2.preLangevin': -2.024057810643643, 'R_series': 0.00017869955815835189, 'R_shunt': 1.633714417533566, 'l2.G_ehp': 1.4466205394168166e+28}
[INFO 08-13 18:09:57] optimpv.axBOtorchOptimizer: Trial 18 with parameters: {'l2.mu_n': -7.906269503195217, 'l2.mu_p': -7.299930897464082, 'l2.N_t_bulk': 19.572783831333194, 'l2.preLangevin': -0.3615174802006962, 'R_series': 0.00017950314060671642, 'R_shunt': 0.043080066997367335, 'l2.G_ehp': 1.4990836336838953e+28}
[INFO 08-13 18:09:58] optimpv.axBOtorchOptimizer: Trial 17 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.11321175251530026), 'Gfrac2_JV_nrmse_linear': np.float64(0.042849381379845376), 'Gfrac3_JV_nrmse_linear': np.float64(0.07655401060580475)} and parameters: {'l2.mu_n': -7.847509548194543, 'l2.mu_p': -7.279339584577821, 'l2.N_t_bulk': 19.643011810817857, 'l2.preLangevin': -2.024057810643643, 'R_series': 0.00017869955815835189, 'R_shunt': 1.633714417533566, 'l2.G_ehp': 1.4466205394168166e+28}
[INFO 08-13 18:09:58] optimpv.axBOtorchOptimizer: Trial 18 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.2899758477186021), 'Gfrac2_JV_nrmse_linear': np.float64(0.11960633592067504), 'Gfrac3_JV_nrmse_linear': np.float64(0.2096166352265529)} and parameters: {'l2.mu_n': -7.906269503195217, 'l2.mu_p': -7.299930897464082, 'l2.N_t_bulk': 19.572783831333194, 'l2.preLangevin': -0.3615174802006962, 'R_series': 0.00017950314060671642, 'R_shunt': 0.043080066997367335, 'l2.G_ehp': 1.4990836336838953e+28}
[INFO 08-13 18:10:04] optimpv.axBOtorchOptimizer: Trial 19 with parameters: {'l2.mu_n': -7.902091149601029, 'l2.mu_p': -7.4123662881971715, 'l2.N_t_bulk': 19.20046227949028, 'l2.preLangevin': -2.114935186141352, 'R_series': 0.00016786747540736523, 'R_shunt': 3.67240231147706, 'l2.G_ehp': 1.4260495258380792e+28}
[INFO 08-13 18:10:04] optimpv.axBOtorchOptimizer: Trial 20 with parameters: {'l2.mu_n': -7.871454833957004, 'l2.mu_p': -8.919675896571352, 'l2.N_t_bulk': 19.61463937587879, 'l2.preLangevin': -1.944827696909266, 'R_series': 0.00015132042609487695, 'R_shunt': 4.087953938724685, 'l2.G_ehp': 1.4920303406880362e+28}
[INFO 08-13 18:10:04] optimpv.axBOtorchOptimizer: Trial 19 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.09727230433812399), 'Gfrac2_JV_nrmse_linear': np.float64(0.03939099988096798), 'Gfrac3_JV_nrmse_linear': np.float64(0.0616186143397504)} and parameters: {'l2.mu_n': -7.902091149601029, 'l2.mu_p': -7.4123662881971715, 'l2.N_t_bulk': 19.20046227949028, 'l2.preLangevin': -2.114935186141352, 'R_series': 0.00016786747540736523, 'R_shunt': 3.67240231147706, 'l2.G_ehp': 1.4260495258380792e+28}
[INFO 08-13 18:10:04] optimpv.axBOtorchOptimizer: Trial 20 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.2215287766532427), 'Gfrac2_JV_nrmse_linear': np.float64(0.11547328430261491), 'Gfrac3_JV_nrmse_linear': np.float64(0.1308355452697534)} and parameters: {'l2.mu_n': -7.871454833957004, 'l2.mu_p': -8.919675896571352, 'l2.N_t_bulk': 19.61463937587879, 'l2.preLangevin': -1.944827696909266, 'R_series': 0.00015132042609487695, 'R_shunt': 4.087953938724685, 'l2.G_ehp': 1.4920303406880362e+28}
[INFO 08-13 18:10:10] optimpv.axBOtorchOptimizer: Trial 21 with parameters: {'l2.mu_n': -7.816130553241653, 'l2.mu_p': -7.500457957398744, 'l2.N_t_bulk': 19.21579570247408, 'l2.preLangevin': -2.3188411266199913, 'R_series': 0.0001803349244485284, 'R_shunt': 63.73083613013878, 'l2.G_ehp': 1.4950655829206754e+28}
[INFO 08-13 18:10:10] optimpv.axBOtorchOptimizer: Trial 22 with parameters: {'l2.mu_n': -7.8292383695877685, 'l2.mu_p': -7.4888232802058825, 'l2.N_t_bulk': 19.206821713473936, 'l2.preLangevin': -2.311879041836356, 'R_series': 0.00018012582004255738, 'R_shunt': 0.34497262670363815, 'l2.G_ehp': 1.3749133023443778e+28}
[INFO 08-13 18:10:11] optimpv.axBOtorchOptimizer: Trial 21 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.06695944838058306), 'Gfrac2_JV_nrmse_linear': np.float64(0.042623770851241416), 'Gfrac3_JV_nrmse_linear': np.float64(0.045584401509067)} and parameters: {'l2.mu_n': -7.816130553241653, 'l2.mu_p': -7.500457957398744, 'l2.N_t_bulk': 19.21579570247408, 'l2.preLangevin': -2.3188411266199913, 'R_series': 0.0001803349244485284, 'R_shunt': 63.73083613013878, 'l2.G_ehp': 1.4950655829206754e+28}
[INFO 08-13 18:10:11] optimpv.axBOtorchOptimizer: Trial 22 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.08538788672486643), 'Gfrac2_JV_nrmse_linear': np.float64(0.042180882908346484), 'Gfrac3_JV_nrmse_linear': np.float64(0.05545134280451697)} and parameters: {'l2.mu_n': -7.8292383695877685, 'l2.mu_p': -7.4888232802058825, 'l2.N_t_bulk': 19.206821713473936, 'l2.preLangevin': -2.311879041836356, 'R_series': 0.00018012582004255738, 'R_shunt': 0.34497262670363815, 'l2.G_ehp': 1.3749133023443778e+28}
[INFO 08-13 18:10:18] optimpv.axBOtorchOptimizer: Trial 23 with parameters: {'l2.mu_n': -7.872908581553992, 'l2.mu_p': -7.414152803402538, 'l2.N_t_bulk': 19.279071593879443, 'l2.preLangevin': -2.4846407595731486, 'R_series': 0.00021643283216463675, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:18] optimpv.axBOtorchOptimizer: Trial 24 with parameters: {'l2.mu_n': -7.854786463604267, 'l2.mu_p': -7.5154993796174505, 'l2.N_t_bulk': 19.38320475111198, 'l2.preLangevin': -2.4217605319141633, 'R_series': 0.0001697057234334894, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:18] optimpv.axBOtorchOptimizer: Trial 23 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.06319282482357054), 'Gfrac2_JV_nrmse_linear': np.float64(0.05535281789024131), 'Gfrac3_JV_nrmse_linear': np.float64(0.049467208858117395)} and parameters: {'l2.mu_n': -7.872908581553992, 'l2.mu_p': -7.414152803402538, 'l2.N_t_bulk': 19.279071593879443, 'l2.preLangevin': -2.4846407595731486, 'R_series': 0.00021643283216463675, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:18] optimpv.axBOtorchOptimizer: Trial 24 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.059009685164229136), 'Gfrac2_JV_nrmse_linear': np.float64(0.046645765509249405), 'Gfrac3_JV_nrmse_linear': np.float64(0.04471695186765407)} and parameters: {'l2.mu_n': -7.854786463604267, 'l2.mu_p': -7.5154993796174505, 'l2.N_t_bulk': 19.38320475111198, 'l2.preLangevin': -2.4217605319141633, 'R_series': 0.0001697057234334894, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:26] optimpv.axBOtorchOptimizer: Trial 25 with parameters: {'l2.mu_n': -7.818551752844506, 'l2.mu_p': -7.595629498499626, 'l2.N_t_bulk': 19.27473788139894, 'l2.preLangevin': -2.2644758936997476, 'R_series': 0.0001517760131853893, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:26] optimpv.axBOtorchOptimizer: Trial 26 with parameters: {'l2.mu_n': -7.808639205651634, 'l2.mu_p': -7.5807554459561, 'l2.N_t_bulk': 19.34518402868052, 'l2.preLangevin': -2.3386732430481274, 'R_series': 0.00015378617743811002, 'R_shunt': 100.0, 'l2.G_ehp': 1.3749133023443778e+28}
[INFO 08-13 18:10:26] optimpv.axBOtorchOptimizer: Trial 25 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.06481735529825405), 'Gfrac2_JV_nrmse_linear': np.float64(0.040817749529370596), 'Gfrac3_JV_nrmse_linear': np.float64(0.046114795064273226)} and parameters: {'l2.mu_n': -7.818551752844506, 'l2.mu_p': -7.595629498499626, 'l2.N_t_bulk': 19.27473788139894, 'l2.preLangevin': -2.2644758936997476, 'R_series': 0.0001517760131853893, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:26] optimpv.axBOtorchOptimizer: Trial 26 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.07641348585286342), 'Gfrac2_JV_nrmse_linear': np.float64(0.040069677638038), 'Gfrac3_JV_nrmse_linear': np.float64(0.04930536180738282)} and parameters: {'l2.mu_n': -7.808639205651634, 'l2.mu_p': -7.5807554459561, 'l2.N_t_bulk': 19.34518402868052, 'l2.preLangevin': -2.3386732430481274, 'R_series': 0.00015378617743811002, 'R_shunt': 100.0, 'l2.G_ehp': 1.3749133023443778e+28}
[INFO 08-13 18:10:33] optimpv.axBOtorchOptimizer: Trial 27 with parameters: {'l2.mu_n': -7.777694275493177, 'l2.mu_p': -7.612303119397728, 'l2.N_t_bulk': 19.243172381412492, 'l2.preLangevin': -2.3201685505218435, 'R_series': 0.00013509060107450436, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:33] optimpv.axBOtorchOptimizer: Trial 28 with parameters: {'l2.mu_n': -7.835469951361187, 'l2.mu_p': -7.603379915752399, 'l2.N_t_bulk': 19.32083216217207, 'l2.preLangevin': -2.2033092114934165, 'R_series': 0.00015321009760796894, 'R_shunt': 100.0, 'l2.G_ehp': 1.4740751011562614e+28}
[INFO 08-13 18:10:33] optimpv.axBOtorchOptimizer: Trial 27 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.058727068521386074), 'Gfrac2_JV_nrmse_linear': np.float64(0.035223346897266666), 'Gfrac3_JV_nrmse_linear': np.float64(0.04209200803216535)} and parameters: {'l2.mu_n': -7.777694275493177, 'l2.mu_p': -7.612303119397728, 'l2.N_t_bulk': 19.243172381412492, 'l2.preLangevin': -2.3201685505218435, 'R_series': 0.00013509060107450436, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:33] optimpv.axBOtorchOptimizer: Trial 28 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.0741205678098489), 'Gfrac2_JV_nrmse_linear': np.float64(0.041738647046091974), 'Gfrac3_JV_nrmse_linear': np.float64(0.04902389887579275)} and parameters: {'l2.mu_n': -7.835469951361187, 'l2.mu_p': -7.603379915752399, 'l2.N_t_bulk': 19.32083216217207, 'l2.preLangevin': -2.2033092114934165, 'R_series': 0.00015321009760796894, 'R_shunt': 100.0, 'l2.G_ehp': 1.4740751011562614e+28}
[INFO 08-13 18:10:40] optimpv.axBOtorchOptimizer: Trial 29 with parameters: {'l2.mu_n': -7.757852413253347, 'l2.mu_p': -7.617076160209974, 'l2.N_t_bulk': 19.03994076866327, 'l2.preLangevin': -2.4951481189956684, 'R_series': 9.218874619979018e-05, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:40] optimpv.axBOtorchOptimizer: Trial 30 with parameters: {'l2.mu_n': -7.6474705023545, 'l2.mu_p': -7.722331933464262, 'l2.N_t_bulk': 19.055339962520378, 'l2.preLangevin': -2.4040535411312325, 'R_series': 0.00013658852350279302, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:40] optimpv.axBOtorchOptimizer: Trial 29 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.042962371007618384), 'Gfrac2_JV_nrmse_linear': np.float64(0.025245448500045415), 'Gfrac3_JV_nrmse_linear': np.float64(0.03214760930433182)} and parameters: {'l2.mu_n': -7.757852413253347, 'l2.mu_p': -7.617076160209974, 'l2.N_t_bulk': 19.03994076866327, 'l2.preLangevin': -2.4951481189956684, 'R_series': 9.218874619979018e-05, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[INFO 08-13 18:10:40] optimpv.axBOtorchOptimizer: Trial 30 completed with results: {'Gfrac1_JV_nrmse_linear': np.float64(0.053768849344177326), 'Gfrac2_JV_nrmse_linear': np.float64(0.03291535956648793), 'Gfrac3_JV_nrmse_linear': np.float64(0.03930411644322092)} and parameters: {'l2.mu_n': -7.6474705023545, 'l2.mu_p': -7.722331933464262, 'l2.N_t_bulk': 19.055339962520378, 'l2.preLangevin': -2.4040535411312325, 'R_series': 0.00013658852350279302, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}
[7]:
# get the best parameters and update the params list in the optimizer and the agent
ax_client = optimizer.ax_client # get the ax client
optimizer.update_params_with_best_balance() # update the params list in the optimizer with the best parameters
jv_main.params = optimizer.params # update the params list in the agent with the best parameters
# print the best parameters
print('Best parameters:')
for p in optimizer.params:
print(p.name, 'fitted value:', p.value)
print('\nSimSS command line:')
print(jv_main.get_SIMsalabim_clean_cmd(jv_main.params)) # print the simss command line with the best parameters
Best parameters:
l2.mu_n fitted value: 1.7464155383028927e-08
l2.mu_p fitted value: 2.4150372834152555e-08
l2.N_t_bulk fitted value: 1.0963286629500838e+19
l2.preLangevin fitted value: 0.0031978042914549403
R_series fitted value: 9.218874619979018e-05
R_shunt fitted value: 100.0
l2.G_ehp fitted value: 1.5589412339101684e+28
SimSS command line:
./simss -l2.mu_n 1.7464155383028927e-08 -l2.mu_p 2.4150372834152555e-08 -l2.N_t_bulk 1.0963286629500838e+19 -l2.preLangevin 0.0031978042914549403 -R_series 9.218874619979018e-05 -R_shunt 100.0 -l2.G_ehp 1.5589412339101684e+28
[8]:
# Plot optimization results
data = ax_client.summarize()
all_metrics = optimizer.all_metrics
plt.figure()
plt.plot(np.minimum.accumulate(data[all_metrics]), label="Best value seen so far")
plt.yscale("log")
plt.xlabel("Iteration")
plt.ylabel("Target metric: " + metric + " with " + loss + " loss")
plt.legend()
plt.title("Best value seen so far")
plt.show()

[10]:
import matplotlib
# import itertools
from itertools import combinations
comb = list(combinations(optimizer.all_metrics, 2))
threshold_list = []
for i in range(len(optimizer.agents)):
for j in range(len(optimizer.agents[i].threshold)):
threshold_list.append(optimizer.agents[i].threshold[j])
threshold_comb = list(combinations(threshold_list, 2))
pareto = ax_client.get_pareto_frontier(use_model_predictions=False)
print('Pareto frontier:', pareto)
cm = matplotlib.colormaps.get_cmap('viridis')
df = get_df_from_ax(params, optimizer)
# create pareto df
dum_dic = {}
for eto in pareto:
print(eto[1])
for metr in optimizer.all_metrics:
if metr not in dum_dic.keys():
dum_dic[metr] = []
dum_dic[metr].append(eto[1][metr][0])
df_pareto = pd.DataFrame(dum_dic)
for c,t_c in zip(comb,threshold_comb):
plt.figure(figsize=(10, 10))
plt.scatter(df[c[0]],df[c[1]],c=df.index, cmap=cm, marker='o', s=100) # plot the points with color according to the iteration
cbar = plt.colorbar()
cbar.set_label('Iteration')
sorted_df = df_pareto.sort_values(by=c[0])
plt.plot(sorted_df[c[0]],sorted_df[c[1]],'r')
plt.scatter(t_c[0],t_c[1],c='r', marker='x', s=100) # plot the threshold
plt.xlabel(c[0])
plt.ylabel(c[1])
plt.xscale('log')
plt.yscale('log')
plt.show()
Pareto frontier: [({'l2.mu_n': -7.757852413253347, 'l2.mu_p': -7.617076160209974, 'l2.N_t_bulk': 19.03994076866327, 'l2.preLangevin': -2.4951481189956684, 'R_series': 9.218874619979018e-05, 'R_shunt': 100.0, 'l2.G_ehp': 1.5589412339101684e+28}, {'Gfrac1_JV_nrmse_linear': (np.float64(0.042962371007618384), nan), 'Gfrac2_JV_nrmse_linear': (np.float64(0.025245448500045415), nan), 'Gfrac3_JV_nrmse_linear': (np.float64(0.03214760930433182), nan)}, 29, '29_0')]
{'Gfrac1_JV_nrmse_linear': (np.float64(0.042962371007618384), nan), 'Gfrac2_JV_nrmse_linear': (np.float64(0.025245448500045415), nan), 'Gfrac3_JV_nrmse_linear': (np.float64(0.03214760930433182), nan)}



[11]:
# Plot the density of the exploration of the parameters
# this gives a nice visualization of where the optimizer focused its exploration and may show some correlation between the parameters
plot_dens = True
if plot_dens:
from optimpv.posterior.posterior import *
best_parameters = {}
for p in optimizer.params:
best_parameters[p.name] = p.value
fig_dens, ax_dens = plot_density_exploration(params, optimizer = optimizer, best_parameters = best_parameters, optimizer_type = 'ax')

[12]:
# rerun the simulation with the best parameters
yfit = jv_main.run(parameters={}) # run the simulation with the best parameters
res_dic = jv_main.run_Ax(parameters={})
keys = list(res_dic.keys())
print('Best combined target metric:', res_dic[keys[0]])
viridis = plt.get_cmap('viridis', len(Gfracs))
plt.figure(figsize=(10,10))
linewidth = 2
for idx, Gfrac in enumerate(Gfracs[::-1]):
plt.plot(X[X[:,1]==Gfrac,0],y[X[:,1]==Gfrac],label='Gfrac = '+str(Gfrac),color=viridis(idx),alpha=0.5,linewidth=linewidth)
plt.plot(X[X[:,1]==Gfrac,0],yfit[X[:,1]==Gfrac],label='Gfrac = '+str(Gfrac)+' fit',linestyle='--',color=viridis(idx),linewidth=linewidth)
plt.xlabel('Voltage [V]')
plt.ylabel('Current density [A m$^{-2}$]')
plt.legend()
plt.show()
Best combined target metric: 0.02736767325624443

[13]:
# Clean up the output files (comment out if you want to keep the output files)
sim.clean_all_output(session_path)
sim.delete_folders('tmp',session_path)
# uncomment the following lines to delete specific files
sim.clean_up_output('ZnO',session_path)
sim.clean_up_output('PM6_L8BO',session_path)
sim.clean_up_output('BM_HTL',session_path)
sim.clean_up_output('simulation_setup_PM6_L8BO',session_path)