Persistent Parameter Scan¶
For complex setups one often wants to run different (sometimes multi-dimensional) parameter scans. In this case it is worthwhile to store the results of parameter scans such that they don’t have to be recalculated in future parameter scans. To manage computational results one can make use of the class jcmwave_resultbag
.
We revisit the example of a parallel parameter scan (Parallel Parameter Scan). As before we start by going into daemon mode:
jcmwave_daemon_shutdown();
jcmwave_daemon_add_workstation('Hostname', 'localhost', ...
'Multiplicity', 2, ...
'NThreads', 1);
The project files in the current example do not only depend on the rod radius but also on the two additional parameters finite_element_degree
(used in mie2D.jcmpt) and maximum_sidelength
(used in layout.jcmt). In general, not all parameters are varied during a parameter scan. Therefore, we define a set of default parameters:
default_keys.finite_element_degree = 3;
default_keys.maximum_sidelength = 0.1;
default_keys.radius = 0.3;
Next, we initialize a resultbag
by calling jcmwave_resultbag
with a filepath as parameter. The data of the resultbag
will be stored to this file. If it already exists all data from this file is loaded into the resultbag
.
resultbag = jcmwave_resultbag('resultbag.mat');
Warning
If you use more than one resultbag make sure that every resultbag stores its results to a different file.
With the help of Matlab’s ndgrid
-function we can define a variable keyset
that holds a two-dimensional parameter scan over the parameters maximum_sidelength
and radius
:
sidelengths = 0.5 : -0.1 : 0.1;
radii = 0.3 : 0.005 : 0.5;
[scan1,scan2] = ndgrid(sidelengths, radii);
keyset = repmat(default_keys,size(scan1)); %fill keyset with default keys
for ii = 1 : numel(keyset)
keyset(ii).maximum_sidelength = scan1(ii);
keyset(ii).radius = scan2(ii);
end
The structure can be easily extended to n-dimensional parameter scans by introducing additional scan grids scan3
, scan4
, etc.
Next, we run in parallel all the computations that are defined by the keyset
:
job_ids = [];
for ii = 1 : numel(keyset)
keys = keyset(ii);
job_ids(end+1) = jcmwave_solve('mie2D.jcmp', keys, resultbag, 'temporary', 'yes');
end
jcmwave_daemon_wait(job_ids, resultbag);
By calling the solver command with the resultbag
as the third parameter jcmwave_solve
checks if the computation for the project files (mie2D.jcmpt, layout.jcmt, materials.jcm, sources.jcm) and the current keys
is already contained in the resultbag
. If this is the case, the computation is automatically skipped. Otherwise the new result is added to the resultbag
by the function jcmwave_daemon_wait
to which the resultbag
is passed as the second parameter. Whenever a result is added it is also stored to the disk.
Note
Sometimes a computation does not depend on all parameters in the keys
-structure
(e. g. a waveguide-mode computation generally depends on fewer parameters than a subsequent scattering computation that uses a waveguide mode as light source).
We can account for this by calling jcmwave_resultbag
with a second parameter that defines the fieldname of all relevant parameters. For example by initializing the resultbag
as
resultbag = jcmwave_resultbag('resultbag.mat',{'finite_element_degree', 'radius'});
a change of the parameter maximum_sidelength
would not trigger a new computation.
For given keys the results and corresponding logs of a computation can be accessed by calling result = resultbag.get_result(keys);
and log = resultbag.get_log(keys);
respectively. A plot of the scattering cross section against the rod radius for different maximum sidelengths can be produced in the following way (see Figure “Scattering Cross Section”):
scattering_cross_section_scan = zeros(length(sidelengths),length(radii));
for ii = 1 : numel(keyset)
keys = keyset(ii);
result = resultbag.get_result(keys);
scs = real(result{2}.ElectromagneticFieldEnergyFlux{1});
scattering_cross_section_scan(ii) = scs;
end
plot(radii, scattering_cross_section_scan, '-+', 'LineWidth', 2);
xlabel('radius [\mu m]', 'FontSize', 14);
ylabel('integral scattering cross section', 'FontSize', 14);
legend(num2str(sidelengths','side length %.1f'));
set(gca, 'FontSize', 14);
![_images/scatt_scan1.png](_images/scatt_scan1.png)
Scattering Cross Section¶