Fit non ideal diode equation to dark or light JV-curve

This notebook was written to fit dark JV-curves with the non-ideal diode equation below:
For dark:
\[J = J_0\left[\exp\left(-\frac{V-R_s J}{n k_b T}\right)-1\right] + \frac{V-R_s J}{R_{sh}}\]

using the solving method described in Solid-State Electronics 44 (2000) 1861-1864.

For light:

\[J = J_{ph} - J_0\left[\exp\left(-\frac{V-R_s J}{n k_b T}\right)-1\right] - \frac{V-R_s J}{R_{sh}}\]

using the solving method described in Solar Energy Materials & Solar Cells 81 (2004) 269–277.

[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 copy import deepcopy
import torch, copy, uuid
# Ax on the desktop
sys.path.append('../ax')  # add the path to the ax module

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 *
    from optimpv.Diodefits.DiodeAgent import DiodeAgent
    from optimpv.Diodefits.DiodeModel import *
except Exception as e:
    sys.path.append('../') # add the path to the optimpv module
    from optimpv import *
    from optimpv.axBOtorch.axUtils import *
    from optimpv.Diodefits.DiodeAgent import DiodeAgent
    from optimpv.Diodefits.DiodeModel import *

[INFO 08-13 17:12:59] ax.utils.notebook.plotting: Injecting Plotly library into cell. Do not overwrite or delete cell.
[INFO 08-13 17:12:59] ax.utils.notebook.plotting: Please see
    (https://ax.dev/tutorials/visualizations.html#Fix-for-plots-that-are-not-rendering)
    if visualizations are not rendering.

Define the parameters for the simulation

[2]:
params = []

J0 = FitParam(name = 'J0', value = 1e-5, bounds = [1e-6,1e-3], log_scale = True, rescale = False, value_type = 'float', type='range', display_name=r'$J_0$', unit='A m$^{-2}$', axis_type = 'log',force_log=True)
params.append(J0)

n = FitParam(name = 'n', value = 1.5, bounds = [1,2], log_scale = False, value_type = 'float', type='range', display_name=r'$n$', unit='', axis_type = 'linear')
params.append(n)

R_series = FitParam(name = 'R_series', value = 1e-4, bounds = [1e-5,1e-3], log_scale = True, rescale = False, value_type = 'float', type='range', display_name=r'$R_{\text{series}}$', unit=r'$\Omega$ m$^2$', axis_type = 'log',force_log=True)
params.append(R_series)

R_shunt = FitParam(name = 'R_shunt', value = 1e-1, bounds = [1e-2,1e2], log_scale = True, rescale = False, value_type = 'float', type='range', display_name=r'$R_{\text{shunt}}$', unit=r'$\Omega$ m$^2$', axis_type = 'log',force_log=True)
params.append(R_shunt)

# original values
params_orig = copy.deepcopy(params)

Generate some fake data for the dark JV

[3]:
# Create JV to fit
X = np.linspace(0.001,1,100)
y = NonIdealDiode_dark(X, J0.value, n.value, R_series.value, R_shunt.value)

plt.figure(figsize=(10,6))
plt.semilogy(X,y)
plt.xlabel('Voltage [V]')
plt.ylabel('Current density [A m$^{-2}$]')
plt.grid()
plt.show()

../_images/examples_diode_5_0.png

Run the optimization

While very inefficient we first try to fit the data using Bayesian optimization, then we use scipy.optimize.minize to demonstrate the difference in speed and accuracy.

[4]:
# Define the Agent and the target metric/loss function
metric = 'mse' # can be 'nrmse', 'mse', 'mae'
loss = 'soft_l1' # can be 'linear', 'huber', 'soft_l1'
exp_format = 'dark' # can be 'dark', 'light' depending on the type of data you have
use_pvlib = False # if True, use pvlib to calculate the diode model if not use the implementation in DiodeModel.py
tracking_metric = 'mse' # metric to track during the optimization, can be 'nrmse', 'mse', 'mae'
tracking_loss = 'linear'
diode = DiodeAgent(params, X, y, metric = metric, loss = loss, minimize=True,exp_format=exp_format,use_pvlib=use_pvlib,compare_type='log', )#tracking_metric=tracking_metric, tracking_loss=tracking_loss)

First with BO

[5]:
from optimpv.axBOtorch.axBOtorchOptimizer import axBOtorchOptimizer
from botorch.acquisition.logei import qLogNoisyExpectedImprovement
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':qLogNoisyExpectedImprovement,'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))})])}]

# Define the optimizer
optimizer = axBOtorchOptimizer(params = params, agents = diode, models = ['SOBOL','BOTORCH_MODULAR'],n_batches = [1,20], batch_size = [10,2], ax_client = None,  max_parallelism = -1, model_kwargs_list = model_kwargs_list, model_gen_kwargs_list = None, name = 'ax_opti',parallel=False,verbose_logging=True)
[6]:
optimizer.optimize() # run the optimization with ax
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 0 with parameters {'J0': -3.884729, 'n': 1.145922, 'R_series': -3.899989, 'R_shunt': -1.544776}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 1 with parameters {'J0': -5.074858, 'n': 1.754597, 'R_series': -4.074424, 'R_shunt': 1.842121}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 2 with parameters {'J0': -5.926173, 'n': 1.341267, 'R_series': -3.428928, 'R_shunt': -0.153645}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 3 with parameters {'J0': -3.044036, 'n': 1.699877, 'R_series': -4.596297, 'R_shunt': 0.483248}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 4 with parameters {'J0': -3.416914, 'n': 1.417951, 'R_series': -4.373056, 'R_shunt': 0.899646}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 5 with parameters {'J0': -5.553285, 'n': 1.556774, 'R_series': -3.667607, 'R_shunt': -0.729193}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 6 with parameters {'J0': -4.703594, 'n': 1.097545, 'R_series': -4.828781, 'R_shunt': 1.290712}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 7 with parameters {'J0': -4.255981, 'n': 1.986555, 'R_series': -3.129942, 'R_shunt': -1.088123}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 8 with parameters {'J0': -4.490603, 'n': 1.26286, 'R_series': -4.980922, 'R_shunt': -0.767488}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] ax.api.client: Generated new trial 9 with parameters {'J0': -4.561545, 'n': 1.65327, 'R_series': -3.05648, 'R_shunt': 0.59609}using GenerationNode SOBOL.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 0 with parameters: {'J0': -3.884729395620525, 'n': 1.1459221355617046, 'R_series': -3.8999887257814407, 'R_shunt': -1.544775828719139}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 1 with parameters: {'J0': -5.074858085252345, 'n': 1.754597146064043, 'R_series': -4.074423952028155, 'R_shunt': 1.8421208411455154}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 2 with parameters: {'J0': -5.926173163577914, 'n': 1.3412671824917197, 'R_series': -3.42892774567008, 'R_shunt': -0.1536451317369938}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 3 with parameters: {'J0': -3.0440355129539967, 'n': 1.6998773431405425, 'R_series': -4.596297198906541, 'R_shunt': 0.4832477234303951}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 4 with parameters: {'J0': -3.4169137375429273, 'n': 1.4179511535912752, 'R_series': -4.373056288808584, 'R_shunt': 0.8996459767222404}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 5 with parameters: {'J0': -5.553284986875951, 'n': 1.5567737016826868, 'R_series': -3.667606735602021, 'R_shunt': -0.7291929796338081}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 6 with parameters: {'J0': -4.703593544661999, 'n': 1.0975450733676553, 'R_series': -4.828781232237816, 'R_shunt': 1.290711808949709}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 7 with parameters: {'J0': -4.25598113425076, 'n': 1.9865545416250825, 'R_series': -3.1299415957182646, 'R_shunt': -1.088123332709074}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 8 with parameters: {'J0': -4.490603383630514, 'n': 1.2628602162003517, 'R_series': -4.98092165030539, 'R_shunt': -0.7674875259399414}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 9 with parameters: {'J0': -4.561544945463538, 'n': 1.6532696932554245, 'R_series': -3.0564798079431057, 'R_shunt': 0.5960898995399475}
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 0 completed with results: {'diode_dark_mse_soft_l1': 0.6925635875471055} and parameters: {'J0': -3.884729395620525, 'n': 1.1459221355617046, 'R_series': -3.8999887257814407, 'R_shunt': -1.544775828719139}
[INFO 08-13 17:13:00] ax.api.client: Trial 0 marked COMPLETED.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 1 completed with results: {'diode_dark_mse_soft_l1': 2.1396049283159053} and parameters: {'J0': -5.074858085252345, 'n': 1.754597146064043, 'R_series': -4.074423952028155, 'R_shunt': 1.8421208411455154}
[INFO 08-13 17:13:00] ax.api.client: Trial 1 marked COMPLETED.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 2 completed with results: {'diode_dark_mse_soft_l1': 0.37398757775797886} and parameters: {'J0': -5.926173163577914, 'n': 1.3412671824917197, 'R_series': -3.42892774567008, 'R_shunt': -0.1536451317369938}
[INFO 08-13 17:13:00] ax.api.client: Trial 2 marked COMPLETED.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 3 completed with results: {'diode_dark_mse_soft_l1': 0.715303060097924} and parameters: {'J0': -3.0440355129539967, 'n': 1.6998773431405425, 'R_series': -4.596297198906541, 'R_shunt': 0.4832477234303951}
[INFO 08-13 17:13:00] ax.api.client: Trial 3 marked COMPLETED.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 4 completed with results: {'diode_dark_mse_soft_l1': 1.0212519328224294} and parameters: {'J0': -3.4169137375429273, 'n': 1.4179511535912752, 'R_series': -4.373056288808584, 'R_shunt': 0.8996459767222404}
[INFO 08-13 17:13:00] ax.api.client: Trial 4 marked COMPLETED.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 5 completed with results: {'diode_dark_mse_soft_l1': 0.18361584790855812} and parameters: {'J0': -5.553284986875951, 'n': 1.5567737016826868, 'R_series': -3.667606735602021, 'R_shunt': -0.7291929796338081}
[INFO 08-13 17:13:00] ax.api.client: Trial 5 marked COMPLETED.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 6 completed with results: {'diode_dark_mse_soft_l1': 1.6943364196706385} and parameters: {'J0': -4.703593544661999, 'n': 1.0975450733676553, 'R_series': -4.828781232237816, 'R_shunt': 1.290711808949709}
[INFO 08-13 17:13:00] ax.api.client: Trial 6 marked COMPLETED.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 7 completed with results: {'diode_dark_mse_soft_l1': 0.3387730370639912} and parameters: {'J0': -4.25598113425076, 'n': 1.9865545416250825, 'R_series': -3.1299415957182646, 'R_shunt': -1.088123332709074}
[INFO 08-13 17:13:00] ax.api.client: Trial 7 marked COMPLETED.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 8 completed with results: {'diode_dark_mse_soft_l1': 0.7702393365827067} and parameters: {'J0': -4.490603383630514, 'n': 1.2628602162003517, 'R_series': -4.98092165030539, 'R_shunt': -0.7674875259399414}
[INFO 08-13 17:13:00] ax.api.client: Trial 8 marked COMPLETED.
[INFO 08-13 17:13:00] optimpv.axBOtorchOptimizer: Trial 9 completed with results: {'diode_dark_mse_soft_l1': 0.9530855852040596} and parameters: {'J0': -4.561544945463538, 'n': 1.6532696932554245, 'R_series': -3.0564798079431057, 'R_shunt': 0.5960898995399475}
[INFO 08-13 17:13:00] ax.api.client: Trial 9 marked COMPLETED.
[INFO 08-13 17:13:01] ax.api.client: Generated new trial 10 with parameters {'J0': -6.0, 'n': 1.919834, 'R_series': -3.0, 'R_shunt': -0.926087}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:01] ax.api.client: Generated new trial 11 with parameters {'J0': -6.0, 'n': 1.369462, 'R_series': -3.0, 'R_shunt': -1.579391}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:01] optimpv.axBOtorchOptimizer: Trial 10 with parameters: {'J0': -6.0, 'n': 1.919834248339634, 'R_series': -3.0, 'R_shunt': -0.9260871271790718}
[INFO 08-13 17:13:01] optimpv.axBOtorchOptimizer: Trial 11 with parameters: {'J0': -6.0, 'n': 1.3694617677419614, 'R_series': -3.0, 'R_shunt': -1.5793906753848799}
[INFO 08-13 17:13:01] optimpv.axBOtorchOptimizer: Trial 10 completed with results: {'diode_dark_mse_soft_l1': 0.8832589057882836} and parameters: {'J0': -6.0, 'n': 1.919834248339634, 'R_series': -3.0, 'R_shunt': -0.9260871271790718}
[INFO 08-13 17:13:01] ax.api.client: Trial 10 marked COMPLETED.
[INFO 08-13 17:13:01] optimpv.axBOtorchOptimizer: Trial 11 completed with results: {'diode_dark_mse_soft_l1': 0.34777598483818073} and parameters: {'J0': -6.0, 'n': 1.3694617677419614, 'R_series': -3.0, 'R_shunt': -1.5793906753848799}
[INFO 08-13 17:13:01] ax.api.client: Trial 11 marked COMPLETED.
[INFO 08-13 17:13:03] ax.api.client: Generated new trial 12 with parameters {'J0': -5.062306, 'n': 1.377384, 'R_series': -3.149101, 'R_shunt': -0.849147}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:03] ax.api.client: Generated new trial 13 with parameters {'J0': -6.0, 'n': 1.260715, 'R_series': -3.833088, 'R_shunt': -0.997825}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:03] optimpv.axBOtorchOptimizer: Trial 12 with parameters: {'J0': -5.0623057179858755, 'n': 1.3773837699908937, 'R_series': -3.1491006239169197, 'R_shunt': -0.8491465620146699}
[INFO 08-13 17:13:03] optimpv.axBOtorchOptimizer: Trial 13 with parameters: {'J0': -6.0, 'n': 1.2607146021928912, 'R_series': -3.8330879356635257, 'R_shunt': -0.9978250980287651}
[INFO 08-13 17:13:03] optimpv.axBOtorchOptimizer: Trial 12 completed with results: {'diode_dark_mse_soft_l1': 0.11161309377352557} and parameters: {'J0': -5.0623057179858755, 'n': 1.3773837699908937, 'R_series': -3.1491006239169197, 'R_shunt': -0.8491465620146699}
[INFO 08-13 17:13:03] ax.api.client: Trial 12 marked COMPLETED.
[INFO 08-13 17:13:03] optimpv.axBOtorchOptimizer: Trial 13 completed with results: {'diode_dark_mse_soft_l1': 0.0042234773361089495} and parameters: {'J0': -6.0, 'n': 1.2607146021928912, 'R_series': -3.8330879356635257, 'R_shunt': -0.9978250980287651}
[INFO 08-13 17:13:03] ax.api.client: Trial 13 marked COMPLETED.
[INFO 08-13 17:13:04] ax.api.client: Generated new trial 14 with parameters {'J0': -5.793182, 'n': 1.0, 'R_series': -3.527705, 'R_shunt': -0.983161}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:04] ax.api.client: Generated new trial 15 with parameters {'J0': -6.0, 'n': 1.0, 'R_series': -4.270303, 'R_shunt': -1.625068}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:04] optimpv.axBOtorchOptimizer: Trial 14 with parameters: {'J0': -5.793182297304618, 'n': 1.0, 'R_series': -3.5277050265913092, 'R_shunt': -0.9831610850640764}
[INFO 08-13 17:13:04] optimpv.axBOtorchOptimizer: Trial 15 with parameters: {'J0': -6.0, 'n': 1.0, 'R_series': -4.2703027446608495, 'R_shunt': -1.6250677859716243}
[INFO 08-13 17:13:04] optimpv.axBOtorchOptimizer: Trial 14 completed with results: {'diode_dark_mse_soft_l1': 0.21007579465665183} and parameters: {'J0': -5.793182297304618, 'n': 1.0, 'R_series': -3.5277050265913092, 'R_shunt': -0.9831610850640764}
[INFO 08-13 17:13:04] ax.api.client: Trial 14 marked COMPLETED.
[INFO 08-13 17:13:04] optimpv.axBOtorchOptimizer: Trial 15 completed with results: {'diode_dark_mse_soft_l1': 0.6161382294418551} and parameters: {'J0': -6.0, 'n': 1.0, 'R_series': -4.2703027446608495, 'R_shunt': -1.6250677859716243}
[INFO 08-13 17:13:04] ax.api.client: Trial 15 marked COMPLETED.
[INFO 08-13 17:13:05] ax.api.client: Generated new trial 16 with parameters {'J0': -3.0, 'n': 1.683837, 'R_series': -3.0, 'R_shunt': -0.704832}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:05] ax.api.client: Generated new trial 17 with parameters {'J0': -5.707185, 'n': 1.293789, 'R_series': -3.575605, 'R_shunt': -0.920621}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:05] optimpv.axBOtorchOptimizer: Trial 16 with parameters: {'J0': -3.0, 'n': 1.6838367379092807, 'R_series': -3.0, 'R_shunt': -0.7048319580974642}
[INFO 08-13 17:13:05] optimpv.axBOtorchOptimizer: Trial 17 with parameters: {'J0': -5.707185151724669, 'n': 1.2937891685308933, 'R_series': -3.5756052952493924, 'R_shunt': -0.9206213801867411}
[INFO 08-13 17:13:05] optimpv.axBOtorchOptimizer: Trial 16 completed with results: {'diode_dark_mse_soft_l1': 0.18798456479513748} and parameters: {'J0': -3.0, 'n': 1.6838367379092807, 'R_series': -3.0, 'R_shunt': -0.7048319580974642}
[INFO 08-13 17:13:05] ax.api.client: Trial 16 marked COMPLETED.
[INFO 08-13 17:13:05] optimpv.axBOtorchOptimizer: Trial 17 completed with results: {'diode_dark_mse_soft_l1': 0.02229869081473268} and parameters: {'J0': -5.707185151724669, 'n': 1.2937891685308933, 'R_series': -3.5756052952493924, 'R_shunt': -0.9206213801867411}
[INFO 08-13 17:13:05] ax.api.client: Trial 17 marked COMPLETED.
[INFO 08-13 17:13:06] ax.api.client: Generated new trial 18 with parameters {'J0': -3.0, 'n': 2.0, 'R_series': -4.030677, 'R_shunt': -1.137421}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:06] ax.api.client: Generated new trial 19 with parameters {'J0': -3.0, 'n': 2.0, 'R_series': -3.0, 'R_shunt': -2.0}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:06] optimpv.axBOtorchOptimizer: Trial 18 with parameters: {'J0': -3.0, 'n': 2.0, 'R_series': -4.0306768295393525, 'R_shunt': -1.1374214812032053}
[INFO 08-13 17:13:06] optimpv.axBOtorchOptimizer: Trial 19 with parameters: {'J0': -3.0, 'n': 2.0, 'R_series': -3.0, 'R_shunt': -2.0}
[INFO 08-13 17:13:06] optimpv.axBOtorchOptimizer: Trial 18 completed with results: {'diode_dark_mse_soft_l1': 0.038198434340031895} and parameters: {'J0': -3.0, 'n': 2.0, 'R_series': -4.0306768295393525, 'R_shunt': -1.1374214812032053}
[INFO 08-13 17:13:06] ax.api.client: Trial 18 marked COMPLETED.
[INFO 08-13 17:13:06] optimpv.axBOtorchOptimizer: Trial 19 completed with results: {'diode_dark_mse_soft_l1': 0.5551480079765065} and parameters: {'J0': -3.0, 'n': 2.0, 'R_series': -3.0, 'R_shunt': -2.0}
[INFO 08-13 17:13:06] ax.api.client: Trial 19 marked COMPLETED.
[INFO 08-13 17:13:07] ax.api.client: Generated new trial 20 with parameters {'J0': -3.0, 'n': 1.827015, 'R_series': -3.824579, 'R_shunt': -0.826203}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:07] ax.api.client: Generated new trial 21 with parameters {'J0': -3.0, 'n': 2.0, 'R_series': -3.720599, 'R_shunt': -0.678919}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:07] optimpv.axBOtorchOptimizer: Trial 20 with parameters: {'J0': -3.0, 'n': 1.827014671187309, 'R_series': -3.8245793127437677, 'R_shunt': -0.8262034979193897}
[INFO 08-13 17:13:07] optimpv.axBOtorchOptimizer: Trial 21 with parameters: {'J0': -3.0, 'n': 2.0, 'R_series': -3.720598688225505, 'R_shunt': -0.6789193840106758}
[INFO 08-13 17:13:07] optimpv.axBOtorchOptimizer: Trial 20 completed with results: {'diode_dark_mse_soft_l1': 0.08666593865974104} and parameters: {'J0': -3.0, 'n': 1.827014671187309, 'R_series': -3.8245793127437677, 'R_shunt': -0.8262034979193897}
[INFO 08-13 17:13:07] ax.api.client: Trial 20 marked COMPLETED.
[INFO 08-13 17:13:07] optimpv.axBOtorchOptimizer: Trial 21 completed with results: {'diode_dark_mse_soft_l1': 0.053538203133737916} and parameters: {'J0': -3.0, 'n': 2.0, 'R_series': -3.720598688225505, 'R_shunt': -0.6789193840106758}
[INFO 08-13 17:13:07] ax.api.client: Trial 21 marked COMPLETED.
[INFO 08-13 17:13:09] ax.api.client: Generated new trial 22 with parameters {'J0': -3.930319, 'n': 2.0, 'R_series': -4.545879, 'R_shunt': -1.101149}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:09] ax.api.client: Generated new trial 23 with parameters {'J0': -5.295064, 'n': 2.0, 'R_series': -5.0, 'R_shunt': -2.0}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:09] optimpv.axBOtorchOptimizer: Trial 22 with parameters: {'J0': -3.930319002857133, 'n': 2.0, 'R_series': -4.545879489933741, 'R_shunt': -1.1011489798309126}
[INFO 08-13 17:13:09] optimpv.axBOtorchOptimizer: Trial 23 with parameters: {'J0': -5.295063871847459, 'n': 2.0, 'R_series': -5.0, 'R_shunt': -2.0}
[INFO 08-13 17:13:09] optimpv.axBOtorchOptimizer: Trial 22 completed with results: {'diode_dark_mse_soft_l1': 0.05641292050532565} and parameters: {'J0': -3.930319002857133, 'n': 2.0, 'R_series': -4.545879489933741, 'R_shunt': -1.1011489798309126}
[INFO 08-13 17:13:09] ax.api.client: Trial 22 marked COMPLETED.
[INFO 08-13 17:13:09] optimpv.axBOtorchOptimizer: Trial 23 completed with results: {'diode_dark_mse_soft_l1': 0.6052557393578359} and parameters: {'J0': -5.295063871847459, 'n': 2.0, 'R_series': -5.0, 'R_shunt': -2.0}
[INFO 08-13 17:13:09] ax.api.client: Trial 23 marked COMPLETED.
[INFO 08-13 17:13:10] ax.api.client: Generated new trial 24 with parameters {'J0': -3.0, 'n': 2.0, 'R_series': -4.534254, 'R_shunt': -0.849856}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:10] ax.api.client: Generated new trial 25 with parameters {'J0': -3.574239, 'n': 2.0, 'R_series': -4.091532, 'R_shunt': -0.931105}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:10] optimpv.axBOtorchOptimizer: Trial 24 with parameters: {'J0': -3.0, 'n': 2.0, 'R_series': -4.534254340042729, 'R_shunt': -0.8498557473268875}
[INFO 08-13 17:13:10] optimpv.axBOtorchOptimizer: Trial 25 with parameters: {'J0': -3.5742390652880944, 'n': 2.0, 'R_series': -4.091531553464159, 'R_shunt': -0.9311053747134874}
[INFO 08-13 17:13:10] optimpv.axBOtorchOptimizer: Trial 24 completed with results: {'diode_dark_mse_soft_l1': 0.06526154632146053} and parameters: {'J0': -3.0, 'n': 2.0, 'R_series': -4.534254340042729, 'R_shunt': -0.8498557473268875}
[INFO 08-13 17:13:10] ax.api.client: Trial 24 marked COMPLETED.
[INFO 08-13 17:13:10] optimpv.axBOtorchOptimizer: Trial 25 completed with results: {'diode_dark_mse_soft_l1': 0.01872510234208624} and parameters: {'J0': -3.5742390652880944, 'n': 2.0, 'R_series': -4.091531553464159, 'R_shunt': -0.9311053747134874}
[INFO 08-13 17:13:10] ax.api.client: Trial 25 marked COMPLETED.
[INFO 08-13 17:13:12] ax.api.client: Generated new trial 26 with parameters {'J0': -6.0, 'n': 1.2621, 'R_series': -3.526481, 'R_shunt': -0.948499}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:12] ax.api.client: Generated new trial 27 with parameters {'J0': -5.506965, 'n': 1.367174, 'R_series': -3.7761, 'R_shunt': -1.061991}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:12] optimpv.axBOtorchOptimizer: Trial 26 with parameters: {'J0': -6.0, 'n': 1.2621000501787467, 'R_series': -3.52648129014879, 'R_shunt': -0.9484986723774056}
[INFO 08-13 17:13:12] optimpv.axBOtorchOptimizer: Trial 27 with parameters: {'J0': -5.506965070953563, 'n': 1.3671737910056676, 'R_series': -3.7760996873717305, 'R_shunt': -1.0619906995590402}
[INFO 08-13 17:13:12] optimpv.axBOtorchOptimizer: Trial 26 completed with results: {'diode_dark_mse_soft_l1': 0.0274278455352035} and parameters: {'J0': -6.0, 'n': 1.2621000501787467, 'R_series': -3.52648129014879, 'R_shunt': -0.9484986723774056}
[INFO 08-13 17:13:12] ax.api.client: Trial 26 marked COMPLETED.
[INFO 08-13 17:13:12] optimpv.axBOtorchOptimizer: Trial 27 completed with results: {'diode_dark_mse_soft_l1': 0.006677717429455665} and parameters: {'J0': -5.506965070953563, 'n': 1.3671737910056676, 'R_series': -3.7760996873717305, 'R_shunt': -1.0619906995590402}
[INFO 08-13 17:13:12] ax.api.client: Trial 27 marked COMPLETED.
[INFO 08-13 17:13:13] ax.api.client: Generated new trial 28 with parameters {'J0': -6.0, 'n': 1.369726, 'R_series': -3.888307, 'R_shunt': -1.10956}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:13] ax.api.client: Generated new trial 29 with parameters {'J0': -3.0, 'n': 1.0, 'R_series': -3.0, 'R_shunt': -0.023748}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:13] optimpv.axBOtorchOptimizer: Trial 28 with parameters: {'J0': -6.0, 'n': 1.3697263059274718, 'R_series': -3.888306814639223, 'R_shunt': -1.109560221246364}
[INFO 08-13 17:13:13] optimpv.axBOtorchOptimizer: Trial 29 with parameters: {'J0': -3.0, 'n': 1.0, 'R_series': -3.0, 'R_shunt': -0.023748289513747745}
[INFO 08-13 17:13:13] optimpv.axBOtorchOptimizer: Trial 28 completed with results: {'diode_dark_mse_soft_l1': 0.020765757828501652} and parameters: {'J0': -6.0, 'n': 1.3697263059274718, 'R_series': -3.888306814639223, 'R_shunt': -1.109560221246364}
[INFO 08-13 17:13:13] ax.api.client: Trial 28 marked COMPLETED.
[INFO 08-13 17:13:13] optimpv.axBOtorchOptimizer: Trial 29 completed with results: {'diode_dark_mse_soft_l1': 0.5937180914320295} and parameters: {'J0': -3.0, 'n': 1.0, 'R_series': -3.0, 'R_shunt': -0.023748289513747745}
[INFO 08-13 17:13:13] ax.api.client: Trial 29 marked COMPLETED.
[INFO 08-13 17:13:15] ax.api.client: Generated new trial 30 with parameters {'J0': -5.594928, 'n': 1.30689, 'R_series': -3.733611, 'R_shunt': -0.946454}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:15] ax.api.client: Generated new trial 31 with parameters {'J0': -4.403696, 'n': 1.71142, 'R_series': -4.045317, 'R_shunt': -1.200706}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:15] optimpv.axBOtorchOptimizer: Trial 30 with parameters: {'J0': -5.594928310734994, 'n': 1.3068904392117826, 'R_series': -3.7336110971220013, 'R_shunt': -0.9464544561021322}
[INFO 08-13 17:13:15] optimpv.axBOtorchOptimizer: Trial 31 with parameters: {'J0': -4.403696428471269, 'n': 1.711419984028637, 'R_series': -4.045316641780693, 'R_shunt': -1.2007056546483237}
[INFO 08-13 17:13:15] optimpv.axBOtorchOptimizer: Trial 30 completed with results: {'diode_dark_mse_soft_l1': 0.011028140595488622} and parameters: {'J0': -5.594928310734994, 'n': 1.3068904392117826, 'R_series': -3.7336110971220013, 'R_shunt': -0.9464544561021322}
[INFO 08-13 17:13:15] ax.api.client: Trial 30 marked COMPLETED.
[INFO 08-13 17:13:15] optimpv.axBOtorchOptimizer: Trial 31 completed with results: {'diode_dark_mse_soft_l1': 0.025460273110576637} and parameters: {'J0': -4.403696428471269, 'n': 1.711419984028637, 'R_series': -4.045316641780693, 'R_shunt': -1.2007056546483237}
[INFO 08-13 17:13:15] ax.api.client: Trial 31 marked COMPLETED.
[INFO 08-13 17:13:17] ax.api.client: Generated new trial 32 with parameters {'J0': -3.75452, 'n': 1.896255, 'R_series': -4.143721, 'R_shunt': -1.085849}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:17] ax.api.client: Generated new trial 33 with parameters {'J0': -4.64964, 'n': 1.523718, 'R_series': -3.772953, 'R_shunt': -1.071054}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:17] optimpv.axBOtorchOptimizer: Trial 32 with parameters: {'J0': -3.7545198253059695, 'n': 1.8962550661056177, 'R_series': -4.143721119097392, 'R_shunt': -1.0858486843201258}
[INFO 08-13 17:13:17] optimpv.axBOtorchOptimizer: Trial 33 with parameters: {'J0': -4.649639834475527, 'n': 1.5237183243847539, 'R_series': -3.7729528516831, 'R_shunt': -1.0710536838031075}
[INFO 08-13 17:13:17] optimpv.axBOtorchOptimizer: Trial 32 completed with results: {'diode_dark_mse_soft_l1': 0.009008117004678073} and parameters: {'J0': -3.7545198253059695, 'n': 1.8962550661056177, 'R_series': -4.143721119097392, 'R_shunt': -1.0858486843201258}
[INFO 08-13 17:13:17] ax.api.client: Trial 32 marked COMPLETED.
[INFO 08-13 17:13:17] optimpv.axBOtorchOptimizer: Trial 33 completed with results: {'diode_dark_mse_soft_l1': 0.012086086285457487} and parameters: {'J0': -4.649639834475527, 'n': 1.5237183243847539, 'R_series': -3.7729528516831, 'R_shunt': -1.0710536838031075}
[INFO 08-13 17:13:17] ax.api.client: Trial 33 marked COMPLETED.
[INFO 08-13 17:13:19] ax.api.client: Generated new trial 34 with parameters {'J0': -5.219661, 'n': 1.492556, 'R_series': -3.886521, 'R_shunt': -1.227839}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:19] ax.api.client: Generated new trial 35 with parameters {'J0': -3.527967, 'n': 2.0, 'R_series': -4.163491, 'R_shunt': -1.127933}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:19] optimpv.axBOtorchOptimizer: Trial 34 with parameters: {'J0': -5.219660935925669, 'n': 1.4925556211779916, 'R_series': -3.886520705344524, 'R_shunt': -1.2278394830807784}
[INFO 08-13 17:13:19] optimpv.axBOtorchOptimizer: Trial 35 with parameters: {'J0': -3.527967042641243, 'n': 2.0, 'R_series': -4.163491322485223, 'R_shunt': -1.1279325276770389}
[INFO 08-13 17:13:19] optimpv.axBOtorchOptimizer: Trial 34 completed with results: {'diode_dark_mse_soft_l1': 0.030302256536404837} and parameters: {'J0': -5.219660935925669, 'n': 1.4925556211779916, 'R_series': -3.886520705344524, 'R_shunt': -1.2278394830807784}
[INFO 08-13 17:13:19] ax.api.client: Trial 34 marked COMPLETED.
[INFO 08-13 17:13:19] optimpv.axBOtorchOptimizer: Trial 35 completed with results: {'diode_dark_mse_soft_l1': 0.01800052658538487} and parameters: {'J0': -3.527967042641243, 'n': 2.0, 'R_series': -4.163491322485223, 'R_shunt': -1.1279325276770389}
[INFO 08-13 17:13:19] ax.api.client: Trial 35 marked COMPLETED.
[INFO 08-13 17:13:20] ax.api.client: Generated new trial 36 with parameters {'J0': -4.209253, 'n': 1.664538, 'R_series': -3.922854, 'R_shunt': -0.963445}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:20] ax.api.client: Generated new trial 37 with parameters {'J0': -5.843914, 'n': 1.303589, 'R_series': -3.722095, 'R_shunt': -1.087351}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:20] optimpv.axBOtorchOptimizer: Trial 36 with parameters: {'J0': -4.209252955397247, 'n': 1.6645384913597414, 'R_series': -3.922853863357136, 'R_shunt': -0.96344451377895}
[INFO 08-13 17:13:20] optimpv.axBOtorchOptimizer: Trial 37 with parameters: {'J0': -5.843914431477638, 'n': 1.3035892003816183, 'R_series': -3.7220954043772885, 'R_shunt': -1.08735140673692}
[INFO 08-13 17:13:20] optimpv.axBOtorchOptimizer: Trial 36 completed with results: {'diode_dark_mse_soft_l1': 0.0032783056169889413} and parameters: {'J0': -4.209252955397247, 'n': 1.6645384913597414, 'R_series': -3.922853863357136, 'R_shunt': -0.96344451377895}
[INFO 08-13 17:13:20] ax.api.client: Trial 36 marked COMPLETED.
[INFO 08-13 17:13:20] optimpv.axBOtorchOptimizer: Trial 37 completed with results: {'diode_dark_mse_soft_l1': 0.010695869105898037} and parameters: {'J0': -5.843914431477638, 'n': 1.3035892003816183, 'R_series': -3.7220954043772885, 'R_shunt': -1.08735140673692}
[INFO 08-13 17:13:20] ax.api.client: Trial 37 marked COMPLETED.
[INFO 08-13 17:13:23] ax.api.client: Generated new trial 38 with parameters {'J0': -4.093479, 'n': 1.692881, 'R_series': -3.778717, 'R_shunt': -1.076144}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:23] ax.api.client: Generated new trial 39 with parameters {'J0': -4.651111, 'n': 1.568821, 'R_series': -4.026448, 'R_shunt': -1.003091}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:23] optimpv.axBOtorchOptimizer: Trial 38 with parameters: {'J0': -4.093478997588273, 'n': 1.6928806316801013, 'R_series': -3.7787166567810537, 'R_shunt': -1.0761442665352197}
[INFO 08-13 17:13:23] optimpv.axBOtorchOptimizer: Trial 39 with parameters: {'J0': -4.6511109045365595, 'n': 1.5688207835914247, 'R_series': -4.026447754973198, 'R_shunt': -1.0030912199637734}
[INFO 08-13 17:13:23] optimpv.axBOtorchOptimizer: Trial 38 completed with results: {'diode_dark_mse_soft_l1': 0.014846167427391865} and parameters: {'J0': -4.093478997588273, 'n': 1.6928806316801013, 'R_series': -3.7787166567810537, 'R_shunt': -1.0761442665352197}
[INFO 08-13 17:13:23] ax.api.client: Trial 38 marked COMPLETED.
[INFO 08-13 17:13:23] optimpv.axBOtorchOptimizer: Trial 39 completed with results: {'diode_dark_mse_soft_l1': 0.0006473383070897398} and parameters: {'J0': -4.6511109045365595, 'n': 1.5688207835914247, 'R_series': -4.026447754973198, 'R_shunt': -1.0030912199637734}
[INFO 08-13 17:13:23] ax.api.client: Trial 39 marked COMPLETED.
[INFO 08-13 17:13:25] ax.api.client: Generated new trial 40 with parameters {'J0': -4.545953, 'n': 1.497008, 'R_series': -3.806959, 'R_shunt': -0.927644}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:25] ax.api.client: Generated new trial 41 with parameters {'J0': -4.058035, 'n': 1.775045, 'R_series': -4.115447, 'R_shunt': -0.979054}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:25] optimpv.axBOtorchOptimizer: Trial 40 with parameters: {'J0': -4.545953365812609, 'n': 1.4970076114081623, 'R_series': -3.806958706030602, 'R_shunt': -0.9276438913140355}
[INFO 08-13 17:13:25] optimpv.axBOtorchOptimizer: Trial 41 with parameters: {'J0': -4.058034998347488, 'n': 1.7750454653139323, 'R_series': -4.115446541628393, 'R_shunt': -0.9790539701985559}
[INFO 08-13 17:13:25] optimpv.axBOtorchOptimizer: Trial 40 completed with results: {'diode_dark_mse_soft_l1': 0.018930021339803815} and parameters: {'J0': -4.545953365812609, 'n': 1.4970076114081623, 'R_series': -3.806958706030602, 'R_shunt': -0.9276438913140355}
[INFO 08-13 17:13:25] ax.api.client: Trial 40 marked COMPLETED.
[INFO 08-13 17:13:25] optimpv.axBOtorchOptimizer: Trial 41 completed with results: {'diode_dark_mse_soft_l1': 0.001828824207354529} and parameters: {'J0': -4.058034998347488, 'n': 1.7750454653139323, 'R_series': -4.115446541628393, 'R_shunt': -0.9790539701985559}
[INFO 08-13 17:13:25] ax.api.client: Trial 41 marked COMPLETED.
[INFO 08-13 17:13:27] ax.api.client: Generated new trial 42 with parameters {'J0': -4.23617, 'n': 1.656367, 'R_series': -4.030615, 'R_shunt': -1.037711}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:27] ax.api.client: Generated new trial 43 with parameters {'J0': -4.425, 'n': 1.676323, 'R_series': -4.01036, 'R_shunt': -0.997524}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:27] optimpv.axBOtorchOptimizer: Trial 42 with parameters: {'J0': -4.236169743818424, 'n': 1.6563673664840888, 'R_series': -4.030615473986686, 'R_shunt': -1.0377107501459308}
[INFO 08-13 17:13:27] optimpv.axBOtorchOptimizer: Trial 43 with parameters: {'J0': -4.425000245825025, 'n': 1.6763228472006184, 'R_series': -4.010360192351628, 'R_shunt': -0.9975235537677227}
[INFO 08-13 17:13:27] optimpv.axBOtorchOptimizer: Trial 42 completed with results: {'diode_dark_mse_soft_l1': 0.004423223241122987} and parameters: {'J0': -4.236169743818424, 'n': 1.6563673664840888, 'R_series': -4.030615473986686, 'R_shunt': -1.0377107501459308}
[INFO 08-13 17:13:27] ax.api.client: Trial 42 marked COMPLETED.
[INFO 08-13 17:13:27] optimpv.axBOtorchOptimizer: Trial 43 completed with results: {'diode_dark_mse_soft_l1': 0.003634293141145939} and parameters: {'J0': -4.425000245825025, 'n': 1.6763228472006184, 'R_series': -4.010360192351628, 'R_shunt': -0.9975235537677227}
[INFO 08-13 17:13:27] ax.api.client: Trial 43 marked COMPLETED.
[INFO 08-13 17:13:29] ax.api.client: Generated new trial 44 with parameters {'J0': -5.670638, 'n': 1.348897, 'R_series': -3.924821, 'R_shunt': -0.990384}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:29] ax.api.client: Generated new trial 45 with parameters {'J0': -4.505223, 'n': 1.606292, 'R_series': -3.941248, 'R_shunt': -1.034131}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:29] optimpv.axBOtorchOptimizer: Trial 44 with parameters: {'J0': -5.670637976579574, 'n': 1.348897212313223, 'R_series': -3.9248214161047494, 'R_shunt': -0.9903838270678562}
[INFO 08-13 17:13:29] optimpv.axBOtorchOptimizer: Trial 45 with parameters: {'J0': -4.505223361232316, 'n': 1.6062917612670442, 'R_series': -3.941248039549243, 'R_shunt': -1.034131132660141}
[INFO 08-13 17:13:29] optimpv.axBOtorchOptimizer: Trial 44 completed with results: {'diode_dark_mse_soft_l1': 0.0006449324478681184} and parameters: {'J0': -5.670637976579574, 'n': 1.348897212313223, 'R_series': -3.9248214161047494, 'R_shunt': -0.9903838270678562}
[INFO 08-13 17:13:29] ax.api.client: Trial 44 marked COMPLETED.
[INFO 08-13 17:13:29] optimpv.axBOtorchOptimizer: Trial 45 completed with results: {'diode_dark_mse_soft_l1': 0.002170715047169036} and parameters: {'J0': -4.505223361232316, 'n': 1.6062917612670442, 'R_series': -3.941248039549243, 'R_shunt': -1.034131132660141}
[INFO 08-13 17:13:29] ax.api.client: Trial 45 marked COMPLETED.
[INFO 08-13 17:13:31] ax.api.client: Generated new trial 46 with parameters {'J0': -5.184136, 'n': 1.434522, 'R_series': -3.953855, 'R_shunt': -1.014455}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:31] ax.api.client: Generated new trial 47 with parameters {'J0': -3.985566, 'n': 1.791017, 'R_series': -4.029579, 'R_shunt': -0.989327}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:31] optimpv.axBOtorchOptimizer: Trial 46 with parameters: {'J0': -5.18413593236281, 'n': 1.4345220181261285, 'R_series': -3.953855332055963, 'R_shunt': -1.0144553083782677}
[INFO 08-13 17:13:31] optimpv.axBOtorchOptimizer: Trial 47 with parameters: {'J0': -3.9855658226207633, 'n': 1.7910171780984825, 'R_series': -4.029579238561085, 'R_shunt': -0.9893269013080384}
[INFO 08-13 17:13:31] optimpv.axBOtorchOptimizer: Trial 46 completed with results: {'diode_dark_mse_soft_l1': 0.0013895987482648309} and parameters: {'J0': -5.18413593236281, 'n': 1.4345220181261285, 'R_series': -3.953855332055963, 'R_shunt': -1.0144553083782677}
[INFO 08-13 17:13:31] ax.api.client: Trial 46 marked COMPLETED.
[INFO 08-13 17:13:31] optimpv.axBOtorchOptimizer: Trial 47 completed with results: {'diode_dark_mse_soft_l1': 0.0028910272734328224} and parameters: {'J0': -3.9855658226207633, 'n': 1.7910171780984825, 'R_series': -4.029579238561085, 'R_shunt': -0.9893269013080384}
[INFO 08-13 17:13:31] ax.api.client: Trial 47 marked COMPLETED.
[INFO 08-13 17:13:33] ax.api.client: Generated new trial 48 with parameters {'J0': -4.994338, 'n': 1.522348, 'R_series': -4.061595, 'R_shunt': -1.023816}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:33] ax.api.client: Generated new trial 49 with parameters {'J0': -3.679519, 'n': 1.886985, 'R_series': -4.225567, 'R_shunt': -0.956094}using GenerationNode BOTORCH_MODULAR.
[INFO 08-13 17:13:33] optimpv.axBOtorchOptimizer: Trial 48 with parameters: {'J0': -4.994338414467902, 'n': 1.5223479979654044, 'R_series': -4.061594511654757, 'R_shunt': -1.0238163040500252}
[INFO 08-13 17:13:33] optimpv.axBOtorchOptimizer: Trial 49 with parameters: {'J0': -3.6795188002857557, 'n': 1.8869846423577519, 'R_series': -4.225566668628558, 'R_shunt': -0.9560944668278479}
[INFO 08-13 17:13:33] optimpv.axBOtorchOptimizer: Trial 48 completed with results: {'diode_dark_mse_soft_l1': 0.0009340214344093489} and parameters: {'J0': -4.994338414467902, 'n': 1.5223479979654044, 'R_series': -4.061594511654757, 'R_shunt': -1.0238163040500252}
[INFO 08-13 17:13:33] ax.api.client: Trial 48 marked COMPLETED.
[INFO 08-13 17:13:33] optimpv.axBOtorchOptimizer: Trial 49 completed with results: {'diode_dark_mse_soft_l1': 0.0027798879500697815} and parameters: {'J0': -3.6795188002857557, 'n': 1.8869846423577519, 'R_series': -4.225566668628558, 'R_shunt': -0.9560944668278479}
[INFO 08-13 17:13:33] ax.api.client: Trial 49 marked COMPLETED.
[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
diode.params = optimizer.params # update the params list in the agent with the best parameters

# print the best parameters
print('Best parameters:')
for p,po in zip(optimizer.params, params_orig):
    print(p.name, 'fitted value:', p.value, 'original value:', po.value)
Best parameters:
J0 fitted value: 2.1348237387847263e-06 original value: 1e-05
n fitted value: 1.348897212313223 original value: 1.5
R_series fitted value: 0.00011889910455331817 original value: 0.0001
R_shunt fitted value: 0.10223890111035405 original value: 0.1
[8]:
# Plot optimization results
data = ax_client.summarize()
all_metrics = optimizer.all_metrics
tracking_metrics = optimizer.all_tracking_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")

print("Best value seen so far is ", min(data[all_metrics]), "at iteration ", int(data[all_metrics].idxmin()))
plt.show()
Best value seen so far is  diode_dark_mse_soft_l1 at iteration  44
../_images/examples_diode_12_1.png
[9]:
# rerun the simulation with the best parameters
yfit = diode.run(parameters={})

plt.figure(figsize=(10,10))
plt.plot(X,y,label='data')
plt.plot(X,yfit,label='fit',linestyle='--')
plt.xscale('linear')
plt.yscale('log')
plt.xlabel('Applied voltage [V]')
plt.ylabel('Current density [A m$^{-2}$]')
plt.legend()
plt.show()
../_images/examples_diode_13_0.png
[10]:
cards = ax_client.compute_analyses(display=True)
Overview of the Entire Optimization Process

This analysis provides an overview of the entire optimization process. It includes visualizations of the results obtained so far, insights into the parameter and metric relationships learned by the Ax model, diagnostics such as model fit, and health checks to assess the overall health of the experiment.

Results Analysis

Result Analyses provide a high-level overview of the results of the optimization process so far with respect to the metrics specified in experiment design.

Metric Effects: Predicted and observed effects for all arms in the experiment

These pair of plots visualize the metric effects for each arm, with the Ax model predictions on the left and the raw observed data on the right. The predicted effects apply shrinkage for noise and adjust for non-stationarity in the data, so they are more representative of the reproducible effects that will manifest in a long-term validation experiment.

Metric Effects Pair for diode_dark_mse_soft_l1

Modeled Arm Effects on diode_dark_mse_soft_l1

Modeled effects on diode_dark_mse_soft_l1. This plot visualizes predictions of the true metric changes for each arm based on Ax's model. This is the expected delta you would expect if you (re-)ran that arm. This plot helps in anticipating the outcomes and performance of arms based on the model's predictions. Note, flat predictions across arms indicate that the model predicts that there is no effect, meaning if you were to re-run the experiment, the delta you would see would be small and fall within the confidence interval indicated in the plot.

Observed Arm Effects on diode_dark_mse_soft_l1

Observed effects on diode_dark_mse_soft_l1. This plot visualizes the effects from previously-run arms on a specific metric, providing insights into their performance. This plot allows one to compare and contrast the effectiveness of different arms, highlighting which configurations have yielded the most favorable outcomes.

Summary for ax_opti

High-level summary of the `Trial`-s in this `Experiment`

trial_index arm_name trial_status generation_node diode_dark_mse_soft_l1 J0 n R_series R_shunt
0 0 0_0 COMPLETED SOBOL 0.692564 -3.884729 1.145922 -3.899989 -1.544776
1 1 1_0 COMPLETED SOBOL 2.139605 -5.074858 1.754597 -4.074424 1.842121
2 2 2_0 COMPLETED SOBOL 0.373988 -5.926173 1.341267 -3.428928 -0.153645
3 3 3_0 COMPLETED SOBOL 0.715303 -3.044036 1.699877 -4.596297 0.483248
4 4 4_0 COMPLETED SOBOL 1.021252 -3.416914 1.417951 -4.373056 0.899646
5 5 5_0 COMPLETED SOBOL 0.183616 -5.553285 1.556774 -3.667607 -0.729193
6 6 6_0 COMPLETED SOBOL 1.694336 -4.703594 1.097545 -4.828781 1.290712
7 7 7_0 COMPLETED SOBOL 0.338773 -4.255981 1.986555 -3.129942 -1.088123
8 8 8_0 COMPLETED SOBOL 0.770239 -4.490603 1.262860 -4.980922 -0.767488
9 9 9_0 COMPLETED SOBOL 0.953086 -4.561545 1.653270 -3.056480 0.596090
10 10 10_0 COMPLETED BOTORCH_MODULAR 0.883259 -6.000000 1.919834 -3.000000 -0.926087
11 11 11_0 COMPLETED BOTORCH_MODULAR 0.347776 -6.000000 1.369462 -3.000000 -1.579391
12 12 12_0 COMPLETED BOTORCH_MODULAR 0.111613 -5.062306 1.377384 -3.149101 -0.849147
13 13 13_0 COMPLETED BOTORCH_MODULAR 0.004223 -6.000000 1.260715 -3.833088 -0.997825
14 14 14_0 COMPLETED BOTORCH_MODULAR 0.210076 -5.793182 1.000000 -3.527705 -0.983161
15 15 15_0 COMPLETED BOTORCH_MODULAR 0.616138 -6.000000 1.000000 -4.270303 -1.625068
16 16 16_0 COMPLETED BOTORCH_MODULAR 0.187985 -3.000000 1.683837 -3.000000 -0.704832
17 17 17_0 COMPLETED BOTORCH_MODULAR 0.022299 -5.707185 1.293789 -3.575605 -0.920621
18 18 18_0 COMPLETED BOTORCH_MODULAR 0.038198 -3.000000 2.000000 -4.030677 -1.137421
19 19 19_0 COMPLETED BOTORCH_MODULAR 0.555148 -3.000000 2.000000 -3.000000 -2.000000
20 20 20_0 COMPLETED BOTORCH_MODULAR 0.086666 -3.000000 1.827015 -3.824579 -0.826203
21 21 21_0 COMPLETED BOTORCH_MODULAR 0.053538 -3.000000 2.000000 -3.720599 -0.678919
22 22 22_0 COMPLETED BOTORCH_MODULAR 0.056413 -3.930319 2.000000 -4.545879 -1.101149
23 23 23_0 COMPLETED BOTORCH_MODULAR 0.605256 -5.295064 2.000000 -5.000000 -2.000000
24 24 24_0 COMPLETED BOTORCH_MODULAR 0.065262 -3.000000 2.000000 -4.534254 -0.849856
25 25 25_0 COMPLETED BOTORCH_MODULAR 0.018725 -3.574239 2.000000 -4.091532 -0.931105
26 26 26_0 COMPLETED BOTORCH_MODULAR 0.027428 -6.000000 1.262100 -3.526481 -0.948499
27 27 27_0 COMPLETED BOTORCH_MODULAR 0.006678 -5.506965 1.367174 -3.776100 -1.061991
28 28 28_0 COMPLETED BOTORCH_MODULAR 0.020766 -6.000000 1.369726 -3.888307 -1.109560
29 29 29_0 COMPLETED BOTORCH_MODULAR 0.593718 -3.000000 1.000000 -3.000000 -0.023748
30 30 30_0 COMPLETED BOTORCH_MODULAR 0.011028 -5.594928 1.306890 -3.733611 -0.946454
31 31 31_0 COMPLETED BOTORCH_MODULAR 0.025460 -4.403696 1.711420 -4.045317 -1.200706
32 32 32_0 COMPLETED BOTORCH_MODULAR 0.009008 -3.754520 1.896255 -4.143721 -1.085849
33 33 33_0 COMPLETED BOTORCH_MODULAR 0.012086 -4.649640 1.523718 -3.772953 -1.071054
34 34 34_0 COMPLETED BOTORCH_MODULAR 0.030302 -5.219661 1.492556 -3.886521 -1.227839
35 35 35_0 COMPLETED BOTORCH_MODULAR 0.018001 -3.527967 2.000000 -4.163491 -1.127933
36 36 36_0 COMPLETED BOTORCH_MODULAR 0.003278 -4.209253 1.664538 -3.922854 -0.963445
37 37 37_0 COMPLETED BOTORCH_MODULAR 0.010696 -5.843914 1.303589 -3.722095 -1.087351
38 38 38_0 COMPLETED BOTORCH_MODULAR 0.014846 -4.093479 1.692881 -3.778717 -1.076144
39 39 39_0 COMPLETED BOTORCH_MODULAR 0.000647 -4.651111 1.568821 -4.026448 -1.003091
40 40 40_0 COMPLETED BOTORCH_MODULAR 0.018930 -4.545953 1.497008 -3.806959 -0.927644
41 41 41_0 COMPLETED BOTORCH_MODULAR 0.001829 -4.058035 1.775045 -4.115447 -0.979054
42 42 42_0 COMPLETED BOTORCH_MODULAR 0.004423 -4.236170 1.656367 -4.030615 -1.037711
43 43 43_0 COMPLETED BOTORCH_MODULAR 0.003634 -4.425000 1.676323 -4.010360 -0.997524
44 44 44_0 COMPLETED BOTORCH_MODULAR 0.000645 -5.670638 1.348897 -3.924821 -0.990384
45 45 45_0 COMPLETED BOTORCH_MODULAR 0.002171 -4.505223 1.606292 -3.941248 -1.034131
46 46 46_0 COMPLETED BOTORCH_MODULAR 0.001390 -5.184136 1.434522 -3.953855 -1.014455
47 47 47_0 COMPLETED BOTORCH_MODULAR 0.002891 -3.985566 1.791017 -4.029579 -0.989327
48 48 48_0 COMPLETED BOTORCH_MODULAR 0.000934 -4.994338 1.522348 -4.061595 -1.023816
49 49 49_0 COMPLETED BOTORCH_MODULAR 0.002780 -3.679519 1.886985 -4.225567 -0.956094
Insights Analysis

Insight Analyses display information to help understand the underlying experiment i.e parameter and metric relationships learned by the Ax model.Use this information to better understand your experiment space and users.

Top Surfaces Analysis: Parameter sensitivity, slice, and contour plots

The top surfaces analysis displays three analyses in one. First, it shows parameter sensitivities, which shows the sensitivity of the metrics in the experiment to the most important parameters. Subsetting to only the most important parameters, it then shows slice plots and contour plots for each metric in the experiment, displaying the relationship between the metric and the most important parameters.

Sensitivity Analysis for diode_dark_mse_so...

Understand how each parameter affects diode_dark_mse_so... according to a second-order sensitivity analysis.

Slice Plots: Metric effects by parameter value

These plots show the relationship between a metric and a parameter. They show the predicted values of the metric on the y-axis as a function of the parameter on the x-axis while keeping all other parameters fixed at their status_quo value (or mean value if status_quo is unavailable).

R_shunt vs. diode_dark_mse_soft_l1

The slice plot provides a one-dimensional view of predicted outcomes for diode_dark_mse_soft_l1 as a function of a single parameter, while keeping all other parameters fixed at their status_quo value (or mean value if status_quo is unavailable). This visualization helps in understanding the sensitivity and impact of changes in the selected parameter on the predicted metric outcomes.

Contour Plots: Metric effects by parameter values

These plots show the relationship between a metric and two parameters. They show the predicted values of the metric (indicated by color) as a function of the two parameters on the x- and y-axes while keeping all other parameters fixed at their status_quo value (or mean value if status_quo is unavailable).

n, R_shunt vs. diode_dark_mse_soft_l1

The contour plot visualizes the predicted outcomes for diode_dark_mse_soft_l1 across a two-dimensional parameter space, with other parameters held fixed at their status_quo value (or mean value if status_quo is unavailable). This plot helps in identifying regions of optimal performance and understanding how changes in the selected parameters influence the predicted outcomes. Contour lines represent levels of constant predicted values, providing insights into the gradient and potential optima within the parameter space.

n, R_series vs. diode_dark_mse_soft_l1

The contour plot visualizes the predicted outcomes for diode_dark_mse_soft_l1 across a two-dimensional parameter space, with other parameters held fixed at their status_quo value (or mean value if status_quo is unavailable). This plot helps in identifying regions of optimal performance and understanding how changes in the selected parameters influence the predicted outcomes. Contour lines represent levels of constant predicted values, providing insights into the gradient and potential optima within the parameter space.

Diagnostic Analysis

Diagnostic Analyses provide information about the optimization process and the quality of the model fit. You can use this information to understand if the experimental design should be adjusted to improve optimization quality.

Cross Validation for diode_dark_mse_soft_l1

The cross-validation plot displays the model fit for each metric in the experiment. It employs a leave-one-out approach, where the model is trained on all data except one sample, which is used for validation. The plot shows the predicted outcome for the validation set on the y-axis against its actual value on the x-axis. Points that align closely with the dotted diagonal line indicate a strong model fit, signifying accurate predictions. Additionally, the plot includes 95% confidence intervals that provide insight into the noise in observations and the uncertainty in model predictions. A horizontal, flat line of predictions indicates that the model has not picked up on sufficient signal in the data, and instead is just predicting the mean.

Moving on to the scipy optimizer

[11]:
params_scipy = deepcopy(diode.params) # make copies of the parameters
# change the values of params scipy by a random value between the bounds
for param in params_scipy:
    param.value = np.random.uniform(param.bounds[0], param.bounds[1])
    print(f'param: {param.name}, value: {param.value}, bounds: {param.bounds}')

# Create a new agent with the new parameters
# this is needed as the scipy optimizer uses the parameters values as the initial guess for the optimization
diode2 = deepcopy(diode) # make a copy of the agent
diode2.params = params_scipy # set the new parameters

from optimpv.scipyOpti.scipyOptimizer import ScipyOptimizer
scipyOpti = ScipyOptimizer(params=params_scipy, agents=diode2, method='L-BFGS-B', options={}, name='scipy_opti', parallel_agents=True, max_parallelism=os.cpu_count()-1, verbose_logging=True)
param: J0, value: 0.00031185280010773104, bounds: [1e-06, 0.001]
param: n, value: 1.3254674648429738, bounds: [1, 2]
param: R_series, value: 0.0002515367044047746, bounds: [1e-05, 0.001]
param: R_shunt, value: 90.2356625344723, bounds: [0.01, 100.0]
[12]:
scipyOpti.optimize() # run the optimization with scipy
Starting optimization using L-BFGS-B method
Optimization completed with status: CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL
Final objective value: 1.9896528868912355e-11
[12]:
  message: CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL
  success: True
   status: 0
      fun: 1.9896528868912355e-11
        x: [-5.000e+00  1.500e+00 -4.000e+00 -1.000e+00]
      nit: 23
      jac: [-1.776e-07  3.109e-07 -2.132e-06 -3.686e-06]
     nfev: 145
     njev: 29
 hess_inv: <4x4 LbfgsInvHessProduct with dtype=float64>
[13]:
# get the best parameters and update the params list in the optimizer and the agent
diode2.params = scipyOpti.params # update the params list in the agent with the best parameters.append
# print the best parameters
print('Best parameters:')
for p,po in zip(scipyOpti.params, params_orig):
    if p.axis_type == 'log':
        print(p.name, 'fitted value:', '{:.2e}'.format(p.value), 'original value:', '{:.2e}'.format(po.value))
    else:
        print(p.name, 'fitted value:', p.value, 'original value:', po.value)
Best parameters:
J0 fitted value: 1.00e-05 original value: 1.00e-05
n fitted value: 1.5000089782224562 original value: 1.5
R_series fitted value: 1.00e-04 original value: 1.00e-04
R_shunt fitted value: 1.00e-01 original value: 1.00e-01
[14]:
# rerun the simulation with the best parameters
yfit = diode2.run(parameters={})

plt.figure(figsize=(10,10))
plt.plot(X,y,label='data')
plt.plot(X,yfit,label='fit',linestyle='--')
plt.xscale('linear')
plt.yscale('log')
plt.xlabel('Applied voltage [V]')
plt.ylabel('Current density [A m$^{-2}$]')
plt.legend()
plt.show()
../_images/examples_diode_19_0.png

Define the parameters for the simulation for light JV

Now we run only the scipy optimization to fit the light JV-curve.

[15]:
##############################################################################################
# Define the parameters to be fitted
params = []

J0 = FitParam(name = 'J0', value = 1e-6, bounds = [1e-7,1e-4], log_scale = True, rescale = False, value_type = 'float', type='range', display_name=r'$J_0$', unit='A m$^{-2}$', axis_type = 'log',force_log=True)
params.append(J0)

n = FitParam(name = 'n', value = 1.5, bounds = [1,2], log_scale = False, value_type = 'float', type='range', display_name=r'$n$', unit='', axis_type = 'linear')
params.append(n)

R_series = FitParam(name = 'R_series', value = 1e-4, bounds = [1e-5,1e-3], log_scale = True, rescale = False, value_type = 'float', type='range', display_name=r'$R_{\text{series}}$', unit=r'$\Omega$ m$^2$', axis_type = 'log',force_log=True)
params.append(R_series)

R_shunt = FitParam(name = 'R_shunt', value = 1e-1, bounds = [1e-2,1e2], log_scale = True, rescale = False, value_type = 'float', type='range', display_name=r'$R_{\text{shunt}}$', unit=r'$\Omega$ m$^2$', axis_type = 'log',force_log=True)
params.append(R_shunt)

Jph = FitParam(name = 'Jph', value = 200, bounds = [150,250], log_scale = False, rescale = False, value_type = 'float', type='range', display_name=r'$J_{\text{ph}}$', unit='A m$^{-2}$', axis_type = 'linear')
params.append(Jph)

# original values
params_orig_light = copy.deepcopy(params)
[16]:
# Create JV to fit
X_light = np.linspace(0.001,0.8,100)
y_light = NonIdealDiode_light(X_light, J0.value, n.value, R_series.value, R_shunt.value, Jph.value)

plt.figure(figsize=(10,6))
plt.plot(X_light,y_light)
plt.xlabel('Voltage [V]')
plt.ylabel('Current density [A m$^{-2}$]')

[16]:
Text(0, 0.5, 'Current density [A m$^{-2}$]')
../_images/examples_diode_22_1.png

Run the optimization

[17]:
# Define the agents
metric = 'nrmse' # can be 'nrmse', 'mse', 'mae'
loss = 'linear' # can be 'linear', 'huber', 'soft_l1'
exp_format = 'light' # can be 'dark', 'light' depending on the type of data you have
use_pvlib = False # if True, use pvlib to calculate the diode model if not use the implementation in DiodeModel.py
compare_logs = False # if True, compare the logs of the diode model with the data which is preferable when doing dark fitting

diode_light = DiodeAgent(params, X_light, y_light, metric = metric, loss = loss, minimize=True,exp_format=exp_format,use_pvlib=False,compare_type='linear')
[18]:
params_scipy_light = deepcopy(diode_light.params) # make copies of the parameters
# change the values of params scipy by a random value between the bounds
for param in params_scipy_light:
    param.value = np.random.uniform(param.bounds[0], param.bounds[1])
    print(f'param: {param.name}, value: {param.value}, bounds: {param.bounds}')

# Create a new agent with the new parameters
# this is needed as the scipy optimizer uses the parameters values as the initial guess for the optimization
diode2_light = deepcopy(diode_light) # make a copy of the agent
diode2_light.params = params_scipy_light # set the new parameters

from optimpv.scipyOpti.scipyOptimizer import ScipyOptimizer
scipyOpti_light = ScipyOptimizer(params=params_scipy_light, agents=diode2_light, method='L-BFGS-B', options={'maxiter':int(1e5),'ftol':1e-13,'xtol':1e-10}, name='scipy_opti', parallel_agents=True, max_parallelism=os.cpu_count()-1, verbose_logging=True)
param: J0, value: 4.738790585595607e-06, bounds: [1e-07, 0.0001]
param: n, value: 1.0738810162185781, bounds: [1, 2]
param: R_series, value: 0.0007388379772697891, bounds: [1e-05, 0.001]
param: R_shunt, value: 94.33079418203587, bounds: [0.01, 100.0]
param: Jph, value: 239.85916420575697, bounds: [150, 250]
[19]:
scipyOpti_light.optimize() # run the optimization with scipy
Starting optimization using L-BFGS-B method
Optimization completed with status: CONVERGENCE: RELATIVE REDUCTION OF F <= FACTR*EPSMCH
Final objective value: 8.735294818137398e-07
[19]:
  message: CONVERGENCE: RELATIVE REDUCTION OF F <= FACTR*EPSMCH
  success: True
   status: 0
      fun: 8.735294818137398e-07
        x: [-6.000e+00  1.500e+00 -4.000e+00 -1.000e+00  2.000e+02]
      nit: 135
      jac: [-2.501e-02  1.570e-01  2.022e-02 -1.487e-03  3.894e-04]
     nfev: 1290
     njev: 215
 hess_inv: <5x5 LbfgsInvHessProduct with dtype=float64>
[20]:
# get the best parameters and update the params list in the optimizer and the agent
diode2_light.params = scipyOpti_light.params # update the params list in the agent with the best parameters.append
# print the best parameters
print('Best parameters:')
for p,po in zip(scipyOpti_light.params, params_orig_light):
    if p.axis_type == 'log':
        print(p.name, 'fitted value:', '{:.2e}'.format(p.value), 'original value:', '{:.2e}'.format(po.value))
    else:
        print(p.name, 'fitted value:', p.value, 'original value:', po.value)
Best parameters:
J0 fitted value: 9.99e-07 original value: 1.00e-06
n fitted value: 1.4999435034935564 original value: 1.5
R_series fitted value: 1.00e-04 original value: 1.00e-04
R_shunt fitted value: 1.00e-01 original value: 1.00e-01
Jph fitted value: 200.00085492939343 original value: 200
[21]:
# rerun the simulation with the best parameters
yfit_light = diode2_light.run(parameters={})

plt.figure(figsize=(10,10))
plt.plot(X_light,y_light,label='data')
plt.plot(X_light,yfit_light,label='fit',linestyle='--')
plt.xscale('linear')
# plt.yscale('log')
plt.xlabel('Applied voltage [V]')
plt.ylabel('Current density [A m$^{-2}$]')
plt.legend()
plt.show()
../_images/examples_diode_28_0.png