6. Machine learning (HIVE)#

6.1. Introduction#

Machine learning (ML) is the science of getting computers to learn from data and make predictions without being explicitly programmed to do so. ML algorithms enable computers to self-learn by finding patterns and extracting features from data, which can then be used to make predictions on new data. Broadly speaking ML algorithms are broken down in to three categories; supervised learning, unsupervised learning and reinforcement learning.

ML is a widely used tool which we interact with on a daily basis. Examples include suggested web searches, face detection and recognition and ChatGPT language model, to name but a few.

The use of ML in science and engineering is also becoming more prevalent. It has a wide variety of applications in the field, such as; identifying tumours from images generated by scans, genome sequencing for drought resistant plants, processing huge quantities of data generated by experimental sensors. It is also commonly used to create surrogate models (often referred to as meta-models or emulators), which are often orders of magnitude faster to evaluate compared with simulations. This enables tasks such as parameter optimisation, sensitvity analysis or what-if analysis to be performed in a fraction of the time.

Surrogate models are an example of supervised learning algorithms, where the goal is to learn the relationship between the inputs and outputs of a simulation. The outputs of these surrogates can either be single value (SV) which are key properties of the simulation results, e.g. maximum stress, or full field (FF) which is the entire results one would expect from a simulation, e.g. temperature at each node of a mesh, for example.

These tutorials show how surrogate models can be used to greatly improve the insight gained for the HIVE experimental facility. In these tutorials the use of both SV and FF surrogate models are presented.

6.2. Data collection#

To train surrogate models first simulation data from across the parameter space of interest must be collected. For the HIVE experiment there are 7 key parameters which effect the resulting temperature of the component; the displacement of the coil relative to the sample in the x,y and z direction, the rotation of the component relative to the pipe, the temperature and flow rate of the coolant, and the current in the coil. The range of values for each parameter is given in the below table, where the first 3 parameters are distances measured in metres, the rotation is measured in degrees, temperature in Celcius, coolant velocity in m/s and the current is measured in Amps.

Parameter

Range

Displacement in x

[-0.005,0.005]

Displacement in y

[-0.015,0.015]

Displacement in z

[0.003,0.006]

Rotation

[-5,5]

Coolant temperature

[30,80]

Coolant velocity

[0.65784,7.23626]

Current

[200,2000]

For this work 1000 data points are required, with 700 used for training the model and 300 used to test the performance of the model on unseen data. These are referred to as training and test datasets, with the ratio of 7:3 known as the train:test split. The RunFile used to perform these 1000 simulations and extract the necessary data can be found at RunFiles/Tutorials/ML/HIVE_Example/DataCollect.py.

Note

Performing these 1000 simualtions will be time consuming without sufficient computing resources. The data required for each task will be downloaded (if not already available), therefore this file can be used as a template to see how data can be collected.

6.3. Example 1: Power vs variation#

The positioning of the coil relative to the component has a huge impact in terms of the thermal power delivered to the component. While moving the coil closer to the component (reducing the displacement in the z direction) will increase the quantitfy of thermal power, it also leads to a less uniform, more varying, heating profile on the coil adjacent surface. In a fusion device the heat loads are locally uniform, therefore a highly non-unfirom heating profile is not representative of the real conditions a component will be subjected to. It is therefore desirable to identify a coil positioning which maximises the power delivered to the component while minimising the variation of the heating profile on the coil adjacent surface.

In this example only the first 4 parameters effect the coil positioning and therefore the results generated by the ERMES EM solver, so it is only these parameters which one must consider. Therefore the models considered in this example will have 4 inputs, and 2 outputs; the power delivered to the component and the level of variation over the surface.

The RunFile used to perform this analysis can be found at RunFiles/Tutorials/ML/HIVE_Example/PowerVariation.py. At the top of the file are flags to dictate how the analysis will be performed.

CoilType = 'Pancake'
ModelType = 'MLP'
CreateModel = True
PVAnalysis = False

The CoilType means the coil which has been used in the simulations to generate the data. Next the ModelType states the type of supervised learning algorithm which will be used. There are two options available; a multi-layered perceptrion (MLP), which is a vanilla neural network, or Gaussian process regression (GPR). CreateModel is a flag to dictate whether or not to train a new model, while the PVAnalysis flag is to deicde whether or not to perform the power-variation analysis.

After VirtualLab has been initiated using the experiment ‘HIVE’ and project name ‘ML_analysis’, the DataFile is defined, which is the file where the data required to train the model is stored

DataFile = '{}_coil/PowerVariation.hdf'.format(CoilType)

If this file doesn’t already exist it is downloaded from Zenodo (DOI: 10.5281/zenodo.8300663)

if not VirtualLab.InProject(DataFile):
    DataFileFull = "{}/{}".format(VirtualLab.GetProjectDir(),DataFile)
    print("Data doesn't exist, so downloading.")
    r = requests.get('https://zenodo.org/record/8300663/files/PowerVariation.hdf')
    os.makedirs(os.path.dirname(DataFileFull),exist_ok=True)
    with open(DataFileFull,'wb') as f:
        f.write(r.content)

To generate ML models VirtualLab’s ML method is used. All models generated using the ‘ML’ method are stored in a sub-directory ‘ML’ in the project directory.

To begin with 3 MLP models with different architectures will be created to assess their performance. The master parameters for this are

ML.File = ('NN_Models','MLP_hdf5')
ML.TrainData = [DataFile, 'Features', [['Power'],['Variation']],{'group':'Train'}]
ML.ValidationData = [DataFile, 'Features', [['Power'],['Variation']],{'group':'Test'}]
ML.TrainingParameters = {'Epochs':1000,'lr':0.05}
ML.Seed = 100

File specifies that the analysis will be performed using the ‘MLP_hdf5’ routine in the file ‘NN_Models’ found in Scripts/Common/VLRoutines. This directory contains routines which are used by a variety of different experiments. The _hdf5 in the orutine name is there to specify that the model expects the data to be in a hdf5 file. TrainData specifies where the data which is used to train model can be found. The first argument is the name of the file where data is stored, the second argument is the name of the dataset which contains the values for the inputs, while the third is the name of the datasets which contain the values for the outputs of the model. In this example the values for the 4 input parameters are stored in the dataset ‘Features’, while the outputs of the model are the two values ‘Power’ and ‘Variation’.

The fourth argument is an optional dictionary where additional information ca be provided. Here ‘group’ specifies the name of the group within the hdf5 file where these datasets can be found.

Note

Instead of using the group argument the entire path to the dataset could have been specified, e.g. ‘Train/Features’ for the second argument.

ValidationData has the same form as the TrainData but is taken from the group of data called ‘Test’. This data is not used to train the model, but is monitored during training to ensure the model isn’t overfitting the training data.

TrainingParameters is a dictionary of information which is used during the training of a model. ‘Epochs’ are the number of times the training data is iterated over, while ‘lr’ is the learning rate at which the weights of the model are updated.

The attribute Seed specifies the seed value to use to initiate any random sequences. Since the weights in an MLP are randomly generated this ensures that the model will always have the same set of initial weights to ensure reproducability.

Next are the parameters assigned to ParametersVar, which are the different architectures and names used for each model.

Architectures = [[32,32],[16,32,16],[8,16,8,4]]
for architecture in Architectures:
    ML.ModelParameters.append({'Architecture':architecture})
    arch_str = '_'.join(map(str,architecture))
    ML.Name.append("PV/{}/MLP/{}".format(CoilType,arch_str))

The first model will have two hidden layers with 32 nodes in each, the second model will have 3 hidden layers, with 16, 32 and 16 nodes respectively, and finally the third model will have 4 layers of sizes 8,16,8,4. These architectures are defined in the ModelParameters dictionary. For example the first of these three models will be saved in the directory ML/PV/Pancake/MLP/32_32 in the project directory, assuming that the CoilType is ‘Pancake’.

Once the models have been generated and saved their performance is compared against one another using the DA method.

DA.Name = "Analysis/{}/PowerVariation/MLP_Compare".format(CoilType) # results will be saved to same directory as before
DA.File = ['PowerVariation','MLP_compare']
DA.MLModels = var_parameters.ML.Name # use the models defined earlier
DA.TestData = [DataFile, 'Features', [['Power'],['Variation']],{'group':'Test'}] # unseen data to analyse performance

This uses the ‘MLP_compare’ routine found in the file Scripts/Experiments/HIVE/DA/PowerVariation.py to create a plot comparing the accuracy of the three models on the training and test data. The models to compare are defined using MLModels, which are simply the names of the models defined in ParametersVar.

Action

Ensure that ModelType is set to ‘MLP’ at the top of the RunFile and that CreateModel is True and PVAnalysis is False.

Launch VirtualLab with

VirtualLab -f RunFiles/Tutorials/ML/HIVE_Example/PowerVariation.py

You should see three models being generated and saved to the directories ML/PV/Pancake/MLP/32_32, ML/PV/Pancake/MLP/16_32_16 and ML/PV/Pancake/MLP/8_16_8_4 respectively. Along with this a plot comparing the normalised root mean square error (nRMSE) for the three models on the test an train data is created and can be found at Analysis/Pancake/PowerVariation/MLP_Compare/Comparison.png, which should look like Fig. 6.1

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/MLP_compare.png

Fig. 6.1 Comparison of nRMSE of three different MLP architectures for predicting power & variation on test and train datasets.#

Next the performance of three GPR models will be assessed. The parameters for this are similar to those for the MLP case, however in the ModelParameters dictionary this time it is the kernel of the GPR model which is varied.

ML = Namespace(Name = [],ModelParameters=[])
for kernel in GPR_kernels:
    ML.ModelParameters.append({'kernel':kernel})
    ML.Name.append("PV/{}/GPR/{}".format(CoilType,kernel))

These three models will be saved under the name of their kernel in the directory ML/PV/Pancake/GPR. As GPR models must invert matricies to make predictions these models will likely take longer to train compared with the MLP models.

Action

Change ModelType to ‘GPR’ at the top of the RunFile.

Launch VirtualLab

You should see three models being generated and saved to the directories ML/PV/Pancake/GPR/RBF, ML/PV/Pancake/GPR/Matern_1.5 and ML/PV/Pancake/GPR/Matern_2.5. Along with this a plot comparing the performance of the three models will be created and can be found at Analysis/Pancake/PowerVariation/GPR_Compare/Comparison.png, which should look like Fig. 6.2.

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/GPR_compare.png

Fig. 6.2 Comparison of nRMSE of three different GPR kernels for predicting power & variation on test and train datasets.#

You should notice that the nRMSE for the three GPR models are much lower than the MLP models, indicating that GPR is able to more accurately predict the power and variation for a given coil configuration.

Next the best model is used to create an envelope of the power a component can have delivered against the level of variation in the heating profile. As the best performing model the GPR model with the Matern_2.5 kernel is chosen, which is specified by the MLModel attribute of the DA method. This analysis is performed using the ‘Insight_GPR’ function in the PowerVariation.py file.

DA.Name = "Analysis/{}/PowerVariation/GPR_Analysis".format(CoilType)
DA.File = ['PowerVariation','Insight_GPR']
DA.MLModel = "PV/{}/GPR/Matern_2.5".format(CoilType)

Action

Keep ModelType as ‘GPR’ at the top of the RunFile and change CreateModel is False and PVAnalysis to True.

Launch VirtualLab

In the directory Analysis/Pancake/PowerVariation/GPR_Analysis a plot named Envelope.png is created, which will look like Fig. 6.3. This plot demonstrates that, for a given power delivered to the component there is a big difference in the variation of the heating profile.

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/GPR_Envelope.png

Fig. 6.3 Envelope of the power delivered to the component versus the variation score of the heating profile using the Matern_2.5 GPR model.#

This method enables HIVE’s operators to identify configurations for the coil which result in the least amount of variation in the heating profile, thus better replicating the in-service conditions a component is subjected to.

6.4. Example 2: Heating profile prediction#

Often the operators of HIVE will want to be able to visualise the heating profile which a component is subjected to on the coil adjacent surface. Although the previous example showed a method for identifying desirable coil configurations, these would need to be used as inputs to a FEA simulation to first generate data for creating a visualisation of the heating profile. This example shows how it is possible to use ML models to predict and visualise the temperature on a 2D surface.

The RunFile used to perform this analysis can be found at RunFiles/Tutorials/ML/HIVE_Example/HeatingProfile.py.

At the top of the file are flags to dictate how the analysis will be performed and should look like this:

CoilType='Pancake'
PCA_Analysis = False
ModelType = 'GPR' # this can be GPR or MLP
CreateModel = True
CreateImages = True

The coil adjacent surface consists of 10,093 finite element nodes, the values for each of which we would like to predict. Creating a ML model which directly predicts that many outputs is at best impractical, and often unfeasible. This large number of outputs is compressed using the princial component analysis (PCA), which projects high dimensional data on to k-lower dimensional sub spaces.

PCA is a lossy compression algorithm, meaning that compressing the data and then reconstructing it will not return the original data. Fig. 6.4 shows the error between the original data and the reconstructed data against the number of principal components used to compress the data for the train and test data.

Note

PCA is able to perfectly reconstruct the train data as the principal components are optimal with respect to this data.

This plot also highlights the number of princial components needed to ensure that 99% (10) and 99.9% (41) of the variance in the data is retained. Generally, ensuring that a certain amount of variance in the data is retained is the most popular method by which to choose the number of principal components to use.

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/PCA_Sensitivity_heating.png

Fig. 6.4 Plot of reconstruction error using principal component analysis for Joule heating field on coil adjacent surface.#

For this example, 11 principal components will be used because there is only a very small improvement in the reconstruction loss for a x4 increase in the number of principal components.

Note

If you’d like to generate this plot for yourself, make sure the PCA_Analysis at the top of the RunFile is set to True

Below are the parameters which are used to generate the GPR ML model:

ML.Name = 'HeatProfile/{}/GPR'.format(CoilType)
ML.File = ('GPR_Models','GPR_PCA_hdf5')
ML.TrainingParameters = {'Epochs':1000,'lr':0.05}
ML.TrainData = [DataFile, 'Features', 'SurfaceJH',{'group':'Train'}]
ML.ModelParameters = {'kernel':'Matern_2.5','min_noise':1e-8,'noise_init':1e-6}
ML.Metric = {'threshold':0.99}

The File attribute is similar to that from example 1, however this time we use a routine which will specifically compresses down the output using PCA. The TrainData attribute is also similar, with a dataset known as ‘SurfaceJH’ used for the output. The number of principal components to use is specified using Metric, where threshold will ensure at least 0.99 of the variance is retained. ModelParameters is again used to define the kernel used, which in this case is ‘Matern_2.5’. Along with this additional parameters relating to the noise of the model are set. This reduces the minimum bound of the noise parameter from 1E-3 set by GPyTorch to 1E-8, along with initialising its value at a smaller value. Again, TrainingParameters specifies the parameters used to train the model.

Next, the model will be used to generate images of heating profiles and compare them with simulations (on the test dataset). The simulations to compare are references using DA.Index in the ‘CreateImage’ section of the script. This is currently set to [1], meaning that a comparison for simulation number 1 will be performed.

Note

These images are generated using ParaViS. If you are using a virtual machine the GUI will need to be opened for the creation of images. This can be achieved by ensuring that GUI is set to True at the top of the file.

Action

Ensure that ModelType is ‘GPR’ at the top of the RunFile and that CreateModel and CreateImages are set to True.

Launch VirtualLab with

VirtualLab -f RunFiles/Tutorials/ML/HIVE_Example/HeatingProfile.py

Note

Generating the model may take 10 minutes or so, so feel free to grab yourself a coffee.

You should first notice that a model named ‘HeatProfile/Pancake/GPR’ is being generated. Following this the analysis is performed, with the resulting images saved to Analysis/Pancake/HeatingProfile/GPR. Here you will find the ‘ground truth’ Joule heating profile generated by ERMES (Ex1_Simulation.png) as shown in Fig. 6.5 along with that predicted by the GPR model (Ex1_ML.png) as shown in Fig. 6.6. You also have the absolute error between the two (Ex1_Error.png).

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/heating_Ex1_Simulation.png

Fig. 6.5 Joule heating profile on coil adjacent surface from simulation (example 1)#

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/heating_Ex1_ML.png

Fig. 6.6 Joule heating profile on coil adjacent surface from GPR model (example 1)#

These plots show that there is sufficiently accurate agreement between the simulation and GPR model for predicting the Joule heating profile on the coil adjacent surface.

Action

Create images for other examples by changing DA.Index to any number(s) between 0 and 299 (since there are 300 simulations in the test dataset). For example

DA.Index = [4,11,32]

will generate comparison images for simulation 4,11 and 32.

You dont need to generate a new model, so ensure that CreateModel* is set to False.

This example shows how it would be possible for the operators of HIVE to visualise the heating profile generated by the positioning of the coil in a fraction of the time compared with a simulation. This enables more rapid decision making with regards to setting up the experiment.

Note

The above analysis has been performed using GPR models, however MLP models are also available. Feel free to change ModelType to ‘MLP’ and follow the same steps as the above.

6.5. Example 3: Inverse solutions (temperature)#

This example demonstrates how 3D surrogate models can be used to solve a variety of different inverse problem posed by HIVE. The work here builds on the previous example, showing how a 3D surrogate model of the temperature field can be generated. This will then be used to identify the experimental parameters which will deliver the maximum temperature to the component, along with those that deliver a certain desired temperature.

The RunFile used to perform this analysis can be found at RunFiles/Tutorials/ML/HIVE_Example/InverseSolution_T.py. At the top of the file are flags to dictate how the analysis will be performed and should look like this:

CoilType='Pancake'
PCA_Analysis = False
ModelType = 'GPR' # this can be GPR or MLP
CreateModel = True
InverseAnalysis = True

Fig. 6.7 shows the reconstruction error versus the number of principal components used to compress the data. The first thing to note is that much smaller errors are possible with this dataset compared with that in example 2. If 20 princial components are used then the reconstruction error is less than 1E-3 for both the test and train data, which shows that the compression is appropriate for this application.

Clearly more principal components could be used, however increasing to 200 would reduce the reconsturction error to around 1E-4, which is a large computational increase for only a small improvement in the ovrall accuracy. As a result, 20 principal components will be used for this analysis.

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/PCA_Sensitivity_T.png

Fig. 6.7 Plot of reconstruction error using principal component analysis for temperature field#

Note

If you’d like to generate this plot for yourself, make sure the PCA_Analysis at the top of the RunFile is set to True. This, however, may take a little while.

The parameters for generating the GPR model are similar to those in example 2. However, notice that this time ML.Metric specifies the number of principal components to use, instead of the variance threshold:

ML = Namespace()
ML.Name = 'Temperature/{}/GPR'.format(CoilType)
ML.File = ('GPR_Models','GPR_PCA_hdf5')
ML.TrainingParameters = {'Epochs':1000,'lr':0.05}
ML.TrainData = [DataFile, 'Features', 'Temperature',{'group':'Train'}]
ML.ModelParameters = {'kernel':'Matern_2.5','min_noise':1e-8,'noise_init':1e-6}
ML.Metric = {'nb_components':20}

Following this you have the parameters to perform analyses with the model. The key parameters here are Index, which indicates the index for which to generate comparison images like in the previous example, and DesiredTemp, which is the maximum temperature we would like the component to reach for us to identify the experimental parameters. These are currently:

DA.Index = [2]
DA.DesiredTemp = 600

Action

Ensure that ModelType is ‘GPR’ at the top of the RunFile and that CreateModel and InverseAnalysis are set to True.

Launch VirtualLab with

VirtualLab -f RunFiles/Tutorials/ML/HIVE_Example/InverseSolution_T.py

Note

This example uses ParaViS to generate images. If you are using a virtual machine the GUI will need to be opened for the creation of images. This can be achieved by ensuring that GUI is set to True at the top of the RunFile.

Note

Generating the model may take a little while, so feel free to grab yourself a coffee.

Fistly you will see the loss of the model reduce as the model parameters are updated using the training data, like in the previous examples. This model is saved to Temperature/Pancake/GPR in the ML directory in the project directory.

Following this the analysis with the model will take place. Printed to the terminal you should see the parameter combination which will deliver the maximum temperature to the component within the defined parameter space. This should look like the following:

Parameter combination which will deliver a maximum temperature of 1333.90 C:

-5.00e-03, -1.50e-02, 3.00e-03, -5.00e+00, 7.99e+01, 4.17e+00, 2.00e+03

Many of these values are intuitive. The third value, displacement in the z direction, is the minmum value possible (coil is as close to the component as possible), with the fourth value - the rotation - pushing the coil even closer to the component. The fifth value is the coolant temperature, which is at the maximum value of 80 °C, while the seventh value is the current, which is also at its maximum value of 2000 A. An image of the temperature field at the maximum temperature can be found at MaxTemperature.png in the results directory Analysis/Pancake/InverseSolution_T/GPR, and should look like Fig. 6.8.

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/MaxTemperature.png

Fig. 6.8 Temperature profile which delivers the maximum temperature within a defined parameter space.#

While the above problem is somewhat trivial, often the goal of a HIVE experiment is to reach a certain maximum temperature within a component, or deliver a certain temperature to a specific part of the component. This type of problem is much less intuitive due to the combination of a high number of experimental parameters. There are also, usually, a number of combination of parameters which will deliver the desired result. The next part of the output provides 5 combinations of experimental parameters which will deliver a maximum temperature to the component specified by DesiredTemp, which in this case is 600 °C. These should look like:

2.02e-04, -7.33e-03, 4.36e-03, -3.30e+00, 4.46e+01, 5.58e+00, 1.63e+03
-4.43e-03, -1.81e-04, 5.04e-03, 2.36e+00, 7.19e+01, 4.84e+00, 1.76e+03
-3.32e-03, -9.34e-03, 3.82e-03, -3.30e+00, 4.35e+01, 3.78e+00, 1.45e+03
2.82e-03, 7.08e-03, 5.33e-03, 8.09e-01, 6.76e+01, 3.17e+00, 1.78e+03
-2.57e-03, 6.57e-03, 3.56e-03, -1.67e+00, 5.28e+01, 3.43e+00, 1.48e+03

Images for each of the 4 temperature field are saved to the result directory, highlighting the multiple different temperature profiles which will deliver a maximum temperature of 600 °C.

Alongside these images you will find a comparison for the example specified by Da.Index between the temperature profile generated by the GPR model and by the simulation. In this case, this was example number 2. The temperature profile from the simulation and GPR model are shown in Fig. 6.9. and Fig. 6.10. respectively.

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/T_Ex2_Simulation.png

Fig. 6.9 Temperature profile from simulation (example 2)#

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/T_Ex2_ML.png

Fig. 6.10 Temperature profile using ML model (example 2)#

This example shows how a 3D GPR surrogate model can solve one of the most prevalent inverse problems posed by HIVE, providing not only the experimental parameters but also images of their resulting temperature field.

Action

Change ModelType to ‘MLP’ at the top of the file and re run the analysis.

You should notice that while an MLP trains faster than a GPR model it is less accurate.

6.6. Example 4: Inverse solutions (Von Mises)#

In this example a surrogate model of the Von Mises stress field is used in conjunction with the temperature field surrogate generated in the previous example to identify more complex inverse solutions.

The RunFile used to perform this analysis can be found at RunFiles/Tutorials/ML/HIVE_Example/InverseSolution_VM.py. At the top of the file are flags to dictate how the analysis will be performed and should look like this:

CoilType='Pancake'
PCA_Analysis = False
ModelType = 'GPR' # this can be GPR or MLP
CreateModel = True
InverseAnalysis = True

Fig. 6.11 shows the reconstruction error versus the number of principal components used to compress the Von Mises stress nodal data. Notice that the reconstruction error is higher for the Von Mises stress compared with the temperature data from the previous example. To achieve a reconstruction error of 1E-3 with this data around 100 principal component would be required, which is relatively large. Instead 20 principal components will be used, which will still ensure that more than 99.9% of the variance is retained.

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/PCA_Sensitivity_VM.png

Fig. 6.11 Plot of reconstruction error using principal component analysis for temperature field#

Note

If you’d like to generate this plot for yourself, make sure the PCA_Analysis at the top of the RunFile is set to True. This, however, may take a little while.

The parameters for generating the GPR model are identical to those in the previous example, with the only difference being that the name of the dataset used for the model output is now ‘VonMises’:

ML.Name = 'VonMises/GPR'
ML.File = ('GPR_Models','GPR_PCA_hdf5')
ML.TrainingParameters = {'Epochs':1000,'lr':0.05}
ML.TrainData = [DataFile, 'Features', 'VonMises',{'group':'Train'}]
ML.ModelParameters = {'kernel':'Matern_2.5','min_noise':1e-8,'noise_init':1e-6}
ML.Metric = {'nb_components':20}

Following this you have the parameters to perform analysis with the model. Notice that in this example both the temperature and Von Mises ML models are used:

DA.Name = 'Analysis/{}/InverseSolution_VM/GPR'.format(CoilType)
DA.File = ('InverseSolution','AnalysisVM_GPR')
DA.MLModel_T = 'Temperature/{}/GPR'.format(CoilType)
DA.MLModel_VM = 'VonMises/{}/GPR'.format(CoilType)

The other parameters used in this analysis are the same as the previous example:

DA.Index = [2]
DA.DesiredTemp = 600

Index is the index of the test data which will be used to compare the output of the model with the ‘ground truth’ simulation, as we did in the previous example.

Action

Ensure that ModelType is ‘GPR’ at the top of the RunFile and that CreateModel and InverseAnalysis are set to True.

Launch VirtualLab with

VirtualLab -f RunFiles/Tutorials/ML/HIVE_Example/InverseSolution_VM.py

Note

This example uses ParaViS to generate images. If you are using a virtual machine the GUI will need to be opened for the creation of images. This can be achieved by ensuring that GUI is set to True at the top of the RunFile.

Note

Generating the model may take a little while, so feel free to grab yourself a coffee.

The inverse analysis performed first is to identify the experimental parameters which will provide the maximum amount of Von Mises stress in the component. You should notice an output like this:

Parameter combination which will deliver a maximum Von Mises stress of 965.04 MPa:

4.12e-03, -1.09e-02, 3.00e-03, -5.00e+00, 7.99e+01, 6.58e-01, 2.00e+03

Many of these are as we’d expect, with the coil displacement in the z direction at 3.00e-03, it’s minimum value, along with the coolant temperature at its maximum value (80 °C) and the current also at the maximum (2000 A). This combination of parameters will result in a Von Mises stress of 965 MPa. An image of the Von Mises stress field using these parameters can be found at Analysis/Pancake/InverseSolution_VM/GPR/MaxVonMises.png.

DesiredTemp is again the maximum temperature we want the component to reach, however as we have the von Mises model we would like to go a step further. The previous example showed a variety of different temperature profiles where the maximum temperature of 600 °C is delivered, each of which will result in a different stress fields in the component. Therefore, it is desirable to identify the experimental parameters which will maximise the Von Mises stress while ensuring that 600 °C is delivered to the component. The output for this should look like this:

Parameter combination which delivers 600.00 C and maximises the Von Mises stress, delivering 586.28 MPa:

4.56e-03, 7.27e-03, 5.51e-03, -5.00e+00, 3.00e+01, 7.22e+00, 1.92e+03

Note

Using two models for the optimisation may be slightly time-consuming.

An image of the temperature field and Von Mises stress field using these parameters can be found at T600_T.png. and T600_VM.png in Analysis/Pancake/InverseSolution_VM/GPR.

Alongside these you will find Ex2_Simulation.png Ex2_ML.png and Ex2_Error.png which show a comparison of the model output with the simulation for example 2 (that which was specified using DA.Index).

Note

You can perform the same analysis again using an MLP model if you’d like.

6.7. Example 5: Thermocouple optimisation#

One of the instruments used to collects data from an experiment on HIVE is by using thermocouples. Thermocouples are probes which are joined to the surface of a component prior to an experiment and provide pointwise temperature data. Unfortunately this data does not provide a huge amount of understanding about the component’s behaviour, especially at locations the thermocouples can’t measure, e.g. the inside of the component. Knowledge of the full temperature field throughout the component would greatly improve the understanding of the component and its suitability for a fusion device.

In this example, the temperature surrogate models generated in example 3 are used to predict what the temperature field is throughout the component by using simulated thermocouple data. Using examples from the test dataset, temperature at thermocouple locations are extracted and it is assumed that this is the only information we have.

Following this, the sensitivity of the placement of the thermocouples is presented, along with a method of optimising their location.

The RunFile used to perform this analysis can be found at RunFiles/Tutorials/ML/HIVE_Example/Thermocouple.py. At the top of the file are flags to dictate how the analysis will be performed and should look like this:

CoilType='Pancake'
ModelType = 'MLP' # this can be GPR or MLP
EstimateField = True
Sensitivity = False
Optimise = False

Notice that ModelType in this example is ‘MLP’, which is chosen because it’s evaluation is substantially faster compared with GPR, which is useful for the optimisation of the thermocouple locations.

Note

The MLP model for the temperature field should have been created in example 3. This will need to be completed before the analysis of this example can take place.

To estimate the field from the thermocouple, firstly the placement of the thermocouples is required. This is specified using the ThermocoupleConfig attribute

DA.ThermocoupleConfig = [['TileSideA',0.5,0.5],
                        ['TileFront',0.5,0.5],
                        ['TileSideB',0.5,0.5],
                        ['TileBack',0.5,0.5],
                        ['BlockFront',0.5,0.5],
                        ['BlockBack',0.5,0.5],
                        ['BlockBottom',0.5,0.5]]

Here each list represents a thermocouple, with the first value being the surface which the thermocouple is attached to, with the next 2 the positioning on the surface (scaled to [0,1] range). This configuration is for 7 thermocouples, with each placed at the centre of the respective surface, see Fig. 6.12 - 6.14.

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/TC_1.png

Fig. 6.12 Thermocouples at centre of surfaces (viewpoint 1)#

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/TC_2.png

Fig. 6.13 Thermocouples at centre of surfaces (viewpoint 2)#

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/TC_3.png

Fig. 6.14 Thermocouples at centre of surfaces (viewpoint 3)#

These are the 7 thermocouples which will be used, with the temperature data extracted from example 7 of the test dataset (again specified using Index).

Action

Ensure that ModelType is ‘MLP’ at the top of the RunFile and that EstimateField is set to True, while Sensitivity and Optimise are both False.

Launch VirtualLab with

VirtualLab -f RunFiles/Tutorials/ML/HIVE_Example/Thermocouple.py

In the directory Analysis/Pancake/Thermocouple/MLP/EstimateField you will find Ex7_Simulation.png which shows the temperature field predicted by the simulation, while Ex7_ML.png shows the temperature field estimated by the surrogate model using the temperature at the 7 thermocouple locations. An error plot is also provided in Ex7_Error.png, highlighting good agreement between the two. This shows that it is possible to estimate a full temperature field using only 7 surface temperature points.

Adding thermocouples to components is a time-consuming task, therefore it is desirable to use as few of them as possible. Where the thermocouples are placed has a big impact on whether or not the original temperature field can be reconstructed.

The next task will look at 5 random configuraitions of 4 thermocouples to see how many temperature fields fit to them. These are decided using the NbConfig and NbThermocouple attributes

DA.CandidateSurfaces = ['TileSideA','TileSideB','TileFront','TileBack','BlockFront','BlockBack','BlockBottom']
DA.NbThermocouples = 4
DA.NbConfig = 5

The CandidateSurfaces attribute is simply the different surfaces where thermocouples can be placed.

Action

Change EstimateField is set to False and Sensitivity to True.

Launch VirtualLab

In Analysis/Pancake/Thermocouple/MLP/Sensitivity you will find PlacementSensitivity.png, which is also shown in Fig. 6.15.

https://gitlab.com/ibsim/media/-/raw/master/images/VirtualLab/ML_HIVE/PlacementSensitivity.png

Fig. 6.15 Thermocouples at centre of surfaces (viewpoint 3)#

This plot provides a score for each configuration. This score is the number of temperature fields which fit the temperature data provided, averaged over 5 test cases. A score of 1 represents a perfect score, since this means that in all 5 cases only a single temperature field fit to the data.

Configuration 3 provides a very low score, showing that this would be a good choice compared with the others. A visualisation of the thermocouple placements which gave this score can be found in TC_configs/Config_3. Visualisation of the other, less impressive, configurations can also be found in the TC_configs directory.

The above raises the question regarding an optimal number and configuration of thermocouples. The next task will look at identifying the optimal configuration of thermocouples. Here, we use the gradient-free genetic algorithm to find an optima, see here for more details.

Similar to above, here we define the CandidateSurfaces and NbThermocouples, but we also define GeneticAlgorithm

DA.GeneticAlgorithm = {'NbGen':5,'NbPop':20,'NbExample':5,'seed':100}

GeneticAlgorithm is a dictionary containing information for running the genetic algorithm optimisation. ‘NbGen’ is the maximum number of generations which the optimisation will run for, while ‘NbPop’ is the population size. ‘NbExample’ is the number of testcases to average the score over, while ‘seed’ seeds the initial population for reproducability. Additional parameters can also be passed to the algorithm, see routine ‘Optimise_MLP’ in Scripts/Experiments/HIVE/DA/Thermocouple.py.

Action

Change Sensitivity is set to False and Optimise to True.

Launch VirtualLab

In the terminal information relating to the genetic algorithm will be printed, mainly the current best score and configuration found.

You should find that with 4 thermocouples it is possible to identify a configuration which will deliver a perfect score of 1. The placement of these thermocouples can be seen in Analysis/Pancake/Thermocouple/MLP/Optimise_4/OptimalConfig.

Action

Perform the same analysis again but with NbThermocouple = 3.

Launch VirtualLab

You should notice that when only 3 thermocouples are used the lowest score is well above the optimal score of 1, meaning that 4 thermocouples are required to accurately predict the temperature field throughput the component.