DOI: 10.5281/zenodo.18470497
title: Dataset for simulations of Yttrium aluminum garnet synthesis and analysis of yield factors

description: Raw simulation data

sensitivityAnalysis.mat

This file contains 4 MATLAB structures: reactionSensitivity, diffusionSensitivity, particleSensitivity and temperatureSensitivity. Each structure has either 3 or 4 cases (".case1", ".case2", ".case3", ".case4"). Each case has ".data" and ".info" parts. The data part shows reaction yield over time and the index of each entry equals the amount of seconds that have passed since the start of reaction. The info part contains information on parameters that were tweaked in each case.

For example, after importing this file into MATLAB workspace, the command can be used x = reactionSensitivity.case1.data;in the MATLAB Command Window to assign the numerical values of yield data in time of first case of reaction sensitivity analysis.

Also, by using commands likereactionSensitivity.case1.infoin the MATLAB Command Window the associated info can retrieved for each case.

 

yieldAnalysis.mat

This file contains 10 cases ("case1", "case2", ... , "case10") of yield results in time, where the mixing was applied at different moments. Each case contains ".data" and ".info" parts as in the previous file.

After importing this file into MATLAB workspace, you can use x = case1.data;in the MATLAB Command Window to assign the numerical values of yield data in time of first case.

Partial data can be imported directly without first importing the whole file:m = matfile('yieldAnalysis.mat'); % this creates a link to the file, but does not upload it yettmp=m.case1; % this assigns the "case1" data to a variable "tmp"datum = tmp.data; % this assigns the values of "case1.data" to the variable "datum"  

 

benchmarkSimulation.mat

Note that a computer with at least 8-16 GB of RAM is recommended to load data fragments from file "benchmarkSimulation.mat". To load the full file into the workspace, at least 32 GB of RAM is recommended. Otherwise, MATLAB might crash or become unresponsive.

The file "benchmarkSimulation.mat" consists of a single variable named "DataFile", which is a 5-dimensional array of concentrations of each material in space and time. The first index (1 to 3) corresponds to the three materials of chemical reaction. The second, third and fourth indices (1 to 40 each) correspond to the computational grid elements in x, y and z directions. The fifth index (1 to 57600) corresponds to the amount of seconds since the start of reaction.

To load a part of variable "DataFile" from file "benchmarkSimulation.mat", consider the following example that can be used in MATLAB Command Window:m = matfile('benchmarkSimulation.mat');slice = m.DataFile (1, : , : , 10, 1000);

This command loads a 2D slice of points into the variable "slice". The indices are chosen such that the concentration values of first material are loaded at 10th point from the bottom (in z-coordinate) at time moment t=1000 seconds.

To visualize the results, note that additional dimensions have to be squeezed, as formally "slice" is a 1x40x40x1x1 variable. To get a 40x40 variable, use the "squeeze" command, for example:finalSlice = squeeze(slice);

In this example we loaded a 2D slice of first material concentration values at a specific time moment and a specific height of the domain. Now we can use some 2D plotting tool, for example:imagesc(finalSlice);

To find the yield at some particular moment in time, one simple way is to load a 3D array of concentration values for the first material at some time moment, for example:matrix = m.DataFile (1, : , : , : , 5000); % loads the 3D matrix of concentration values for the first material after 5000 seconds

Next, the sum of values from all cells in variable "matrix" can be computed by the following command:sum(matrix, 'all') % returns the sum of values from all cells in "matrix"

Finally, this result can be compared with the initial amount of the same material to find how much of it has reacted. Although the strict definition of yield deals with calculating the proportion of product that has formed, the applied scientiific model assumes no intermediate products and the reactants are mixed in ideal proportions. Therefore, it is sufficient to compute what part of some reactant was consumed and this number matches with the proportion of product that has already formed. However, we note that this property of applied chemical model should not be taken as a general rule in other computations.

 

Data analysis and visualization

Raw data from MATLAB .mat files was converted into .csv format and .ods spreedsheets for preliminary data analysis and visualization. High quality figures for the publication were drawn using Python matplotlib library. 

Following data files are used for visualizations and data analysis:



Benchmark_mixing.csv Data on reaction yield over time in the case of benchmark mixing (Figure 3 and Figure 5)

Benchmark_mixing_different_temperatures.ods Data on reaction yield over time at various temperatures and mixing moments

Random_Mixing.ods Data demonstrates how reaction completion time depends on mixing moment in the case of different mixings. Benchmark mixing shows the ideal scenario, while four random mixes range from moderately efficient to inefficient mixing.

Yield_factors.ods Data on yield over time depending on yield factors such as particle size, diffusion and reaction coeficient, temperature.


Code examples

Following Python code can be used for data visualization from Benchmark_mixing.csv file. This was used in our paper to draw figures 3 and 5. Similar analysis and visualization was done with data from .ods files.

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.interpolate import CubicSpline

#Parameters
reaction_completion_perc = 98.0  #what percentage of the product is obtained when we assume that the reaction is complete
stand_figsize = (6.4, 4)

#Data preparation
df = pd.read_csv('Benchmark_mixing.csv', sep=';')
df_model_data = df.iloc[list(range(1,9)) + [10,12,14],range(2,df.shape[1])]  #nustato kurias eilutes ir stulpelius imti
data_array = df_model_data.to_numpy(dtype=np.float64)
minute_vector = data_array[0,0:]
data_time_to_end_reaction = np.zeros((data_array.shape[0]-1,2))
data_time_to_end_reaction[:,0] = [0, 0.5, 1, 1.5, 2, 2.5, 4, 6, 8, 10]
for j in range(1,data_array.shape[0]):
    data = data_array[j,:]
    i = np.argmax(data >= reaction_completion_perc)
    interp_time_to_end_reaction = minute_vector[i-1] + (reaction_completion_perc - data[i-1]) * (minute_vector[i]-minute_vector[i-1]) / (data[i]-data[i-1])
    data_time_to_end_reaction[j-1,1] = interp_time_to_end_reaction / 60.

#Figure 3. Dependence between reaction time and reaction yield
fig, ax = plt.subplots(figsize=stand_figsize)
indexes = [3, 7]
colors = 'rgb'
for idx, i in enumerate(reversed(indexes)):
    ax.plot(minute_vector/60., data_array[i,:], colors[idx+1]+'-', label = 'Mixing moment at '+str(int(data_time_to_end_reaction[i-1,0] ))+' h', linewidth = 2)
ax.plot(minute_vector/60., data_array[1,:], 'r-', label = 'No mixing', linewidth = 2)
ax.axhline(reaction_completion_perc, ls ='--', color = 'k', linewidth = 2)
ax.legend(reverse=True)
ax.set_xlabel('Time, h')
ax.set_ylabel('Reaction yield, %')
plt.show()

#Figure 5. Dependence between mixing moment and reaction completion time    
fig, ax = plt.subplots(figsize=stand_figsize)
cs = CubicSpline(data_time_to_end_reaction[:,0],  data_time_to_end_reaction[:,1])
xs = np.arange(0, data_time_to_end_reaction[-1,0], 0.01)
time_opt_mixing = xs[np.argmin(cs(xs))]

xlimit_start = -0.4
ax.hlines(cs(time_opt_mixing), xlimit_start, time_opt_mixing, colors='k', linestyles='dashed', linewidth = 1)  #neveiks kol nenustatomas xlimit
ax.vlines(time_opt_mixing, 0, cs(time_opt_mixing), colors='k', linestyles='dashed', linewidth = 1)
ax.plot(xs, cs(xs), '-', color='k', linewidth = 3.0)
ax.plot(time_opt_mixing, cs(time_opt_mixing), '^', color='orange',  markersize=8)
ax.set_xlim(xlimit_start, 10.4) 
ax.set_ylim(14., 16.6)
ax.set_xticks(np.arange(0, max(data_time_to_end_reaction[:,0])+1, step=1))
ax.set_xlabel('Mixing moment, h')
ax.set_ylabel('Reaction completion time, h')
plt.show()