Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RomApp] Adding training routine for neural networks to be used in ANN-PROM #11988

Merged
merged 19 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
374b00c
Adding rom_nn_trainer.py and including NN training workflow in rom_ma…
NicolasSR Jan 26, 2024
5ab20a9
Corrected calculate_rom_basis_output_process to save singular values
NicolasSR Jan 26, 2024
b9bc2f2
Applying suggested naming changes
NicolasSR Jan 29, 2024
f33bd9a
Additional name change
NicolasSR Jan 29, 2024
14aee10
Corrected default parameters check process. Minor name changes
NicolasSR Jan 29, 2024
82b881a
Added possibility of custom model name. Added check for number of mod…
NicolasSR Jan 29, 2024
a0ad4ab
Changed RomManager to accomodate the NN training within Fit()
NicolasSR Jan 29, 2024
bc19f72
Corrected problem with models root folder creation
NicolasSR Jan 30, 2024
b755258
added test for NN trainer
NicolasSR Feb 20, 2024
a020b7a
21/02/2024: corrected issue with SVD in the nn trainer test by making…
NicolasSR Feb 21, 2024
6052ab0
Minor changes from Codacy suggestions
NicolasSR Feb 21, 2024
558c6fe
Corrected bugs. Added Geometric Relative L2 Error at the evaluation o…
NicolasSR Mar 20, 2024
29e8d4d
Merged with master. Made the choice of saving the singular values an …
NicolasSR May 2, 2024
60db2ae
Added geometric error metric for POD Inf and POD Sup.
NicolasSR May 3, 2024
278a06c
Merged with current master
NicolasSR May 3, 2024
24ffeda
Made exception in ROM_manager if Tensorflow cannot be imported, only …
NicolasSR May 3, 2024
7f22db0
Solved error when merging in calculate_rom_basis
NicolasSR May 6, 2024
b4a6d94
Added comments in the default NN parameters
NicolasSR May 6, 2024
78d7d33
Added comment for type_of_decoder parameter
NicolasSR May 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def _PrintRomBasis(self, snapshots_matrix):
n_nodal_unknowns = len(self.snapshot_variables_list)

# Calculate the randomized SVD of the snapshots matrix
u,_,_,_= RandomizedSingularValueDecomposition().Calculate(snapshots_matrix, self.svd_truncation_tolerance)
u,sigma,_,_= RandomizedSingularValueDecomposition().Calculate(snapshots_matrix, self.svd_truncation_tolerance)

# Save the nodal basis
rom_basis_dict["rom_settings"]["nodal_unknowns"] = [var.Name() for var in self.snapshot_variables_list]
Expand All @@ -185,6 +185,7 @@ def _PrintRomBasis(self, snapshots_matrix):
# Storing modes in Numpy format
numpy.save(self.rom_basis_output_folder / "RightBasisMatrix.npy", u)
numpy.save(self.rom_basis_output_folder / "NodeIds.npy", numpy.arange(1,((u.shape[0]+1)/n_nodal_unknowns), 1, dtype=int))
numpy.save(self.rom_basis_output_folder / "SingularValuesVector.npy", sigma)
else:
err_msg = "Unsupported output format {}.".format(self.rom_basis_output_format)
raise Exception(err_msg)
Expand All @@ -195,7 +196,6 @@ def _PrintRomBasis(self, snapshots_matrix):
json.dump(rom_basis_dict, f, indent = 4)



def ExecuteFinalize(self):
# Prepare a NumPy array with the snapshots data
self.n_nodes = self.model_part.NumberOfNodes()
Expand Down
188 changes: 119 additions & 69 deletions applications/RomApplication/python_scripts/rom_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from KratosMultiphysics.RomApplication.rom_testing_utilities import SetUpSimulationInstance
from KratosMultiphysics.RomApplication.calculate_rom_basis_output_process import CalculateRomBasisOutputProcess
from KratosMultiphysics.RomApplication.randomized_singular_value_decomposition import RandomizedSingularValueDecomposition
from KratosMultiphysics.RomApplication.rom_nn_trainer import RomNeuralNetworkTrainer
import numpy as np
import importlib
import json
Expand All @@ -27,88 +28,119 @@ def __init__(self,project_parameters_name, general_rom_manager_parameters, Custo
self.SetUpQuantityOfInterestContainers()


def Fit(self, mu_train=[None], store_all_snapshots=False, store_fom_snapshots=False, store_rom_snapshots=False, store_hrom_snapshots=False, store_residuals_projected = False):
def Fit(self, mu_train=[None], mu_validation=[None], store_all_snapshots=False, store_fom_snapshots=False, store_rom_snapshots=False, store_hrom_snapshots=False, store_residuals_projected = False):
chosen_projection_strategy = self.general_rom_manager_parameters["projection_strategy"].GetString()
training_stages = self.general_rom_manager_parameters["rom_stages_to_train"].GetStringArray()
type_of_decoder = self.general_rom_manager_parameters["type_of_decoder"].GetString()
#######################
###### Galerkin ######
if chosen_projection_strategy == "galerkin":
if any(item == "ROM" for item in training_stages):
fom_snapshots = self.__LaunchTrainROM(mu_train)
if store_all_snapshots or store_fom_snapshots:
self._StoreSnapshotsMatrix('fom_snapshots', fom_snapshots)
self._ChangeRomFlags(simulation_to_run = "GalerkinROM")
rom_snapshots = self.__LaunchROM(mu_train)
if store_all_snapshots or store_rom_snapshots:
self._StoreSnapshotsMatrix('rom_snapshots', rom_snapshots)
self.ROMvsFOM_train = np.linalg.norm(fom_snapshots - rom_snapshots)/ np.linalg.norm(fom_snapshots)

if any(item == "HROM" for item in training_stages):
#FIXME there will be an error if we only train HROM, but not ROM
self._ChangeRomFlags(simulation_to_run = "trainHROMGalerkin")
self.__LaunchTrainHROM(mu_train, store_residuals_projected)
self._ChangeRomFlags(simulation_to_run = "runHROMGalerkin")
hrom_snapshots = self.__LaunchHROM(mu_train)
if store_all_snapshots or store_hrom_snapshots:
self._StoreSnapshotsMatrix('hrom_snapshots', hrom_snapshots)
self.ROMvsHROM_train = np.linalg.norm(rom_snapshots - hrom_snapshots) / np.linalg.norm(rom_snapshots)
#######################
if type_of_decoder =="ann_enhanced":
#TODO split all of the methods for ROM generation: Snapshots generation (train snapshots and validation snapshots), Basis Computation, NeuralNetworkTraining
# necesary steps: Modify RomBasisOuptupProcess to fetch snapshots, not only run after simulations
self.StoreFomSnapshotsAndBasis(mu_train=mu_train)
self.StoreFomValidationSnapshots(mu_validation=mu_validation)
self.TrainAnnEnhacedNeuralNetwork()
#TODO implement online stage for ann_enhanced
#self._ChangeRomFlags(simulation_to_run = "GalerkinROM_ANN?")
#rom_snapshots = self.__LaunchROM(mu_train)
elif type_of_decoder =="linear":
if any(item == "ROM" for item in training_stages):
fom_snapshots = self.__LaunchTrainROM(mu_train)
if store_all_snapshots or store_fom_snapshots:
self._StoreSnapshotsMatrix('fom_snapshots', fom_snapshots)
self._ChangeRomFlags(simulation_to_run = "GalerkinROM")
rom_snapshots = self.__LaunchROM(mu_train)
if store_all_snapshots or store_rom_snapshots:
self._StoreSnapshotsMatrix('rom_snapshots', rom_snapshots)
self.ROMvsFOM_train = np.linalg.norm(fom_snapshots - rom_snapshots)/ np.linalg.norm(fom_snapshots)

if any(item == "HROM" for item in training_stages):
#FIXME there will be an error if we only train HROM, but not ROM
self._ChangeRomFlags(simulation_to_run = "trainHROMGalerkin")
self.__LaunchTrainHROM(mu_train, store_residuals_projected)
self._ChangeRomFlags(simulation_to_run = "runHROMGalerkin")
hrom_snapshots = self.__LaunchHROM(mu_train)
if store_all_snapshots or store_hrom_snapshots:
self._StoreSnapshotsMatrix('hrom_snapshots', hrom_snapshots)
self.ROMvsHROM_train = np.linalg.norm(rom_snapshots - hrom_snapshots) / np.linalg.norm(rom_snapshots)
#######################

#######################################
## Least-Squares Petrov Galerkin ###
elif chosen_projection_strategy == "lspg":
if any(item == "ROM" for item in training_stages):
fom_snapshots = self.__LaunchTrainROM(mu_train)
if store_all_snapshots or store_fom_snapshots:
self._StoreSnapshotsMatrix('fom_snapshots', fom_snapshots)
self._ChangeRomFlags(simulation_to_run = "lspg")
rom_snapshots = self.__LaunchROM(mu_train)
if store_all_snapshots or store_rom_snapshots:
self._StoreSnapshotsMatrix('rom_snapshots', rom_snapshots)
self.ROMvsFOM_train = np.linalg.norm(fom_snapshots - rom_snapshots)/ np.linalg.norm(fom_snapshots)
if any(item == "HROM" for item in training_stages):
# Change the flags to train the HROM for LSPG
self._ChangeRomFlags(simulation_to_run = "trainHROMLSPG")
self.__LaunchTrainHROM(mu_train, store_residuals_projected)

# Change the flags to run the HROM for LSPG
self._ChangeRomFlags(simulation_to_run = "runHROMLSPG")
hrom_snapshots = self.__LaunchHROM(mu_train)

if store_all_snapshots or store_hrom_snapshots:
self._StoreSnapshotsMatrix('hrom_snapshots', hrom_snapshots)

self.ROMvsHROM_train = np.linalg.norm(rom_snapshots - hrom_snapshots) / np.linalg.norm(rom_snapshots)
#######################################
if type_of_decoder =="ann_enhanced":
err_msg = f'ann_enhanced rom only available for Galerkin Rom for the moment'
raise Exception(err_msg)
elif type_of_decoder =="linear":
if any(item == "ROM" for item in training_stages):
fom_snapshots = self.__LaunchTrainROM(mu_train)
if store_all_snapshots or store_fom_snapshots:
self._StoreSnapshotsMatrix('fom_snapshots', fom_snapshots)
self._ChangeRomFlags(simulation_to_run = "lspg")
rom_snapshots = self.__LaunchROM(mu_train)
if store_all_snapshots or store_rom_snapshots:
self._StoreSnapshotsMatrix('rom_snapshots', rom_snapshots)
self.ROMvsFOM_train = np.linalg.norm(fom_snapshots - rom_snapshots)/ np.linalg.norm(fom_snapshots)
if any(item == "HROM" for item in training_stages):
# Change the flags to train the HROM for LSPG
self._ChangeRomFlags(simulation_to_run = "trainHROMLSPG")
self.__LaunchTrainHROM(mu_train, store_residuals_projected)

# Change the flags to run the HROM for LSPG
self._ChangeRomFlags(simulation_to_run = "runHROMLSPG")
hrom_snapshots = self.__LaunchHROM(mu_train)

if store_all_snapshots or store_hrom_snapshots:
self._StoreSnapshotsMatrix('hrom_snapshots', hrom_snapshots)

self.ROMvsHROM_train = np.linalg.norm(rom_snapshots - hrom_snapshots) / np.linalg.norm(rom_snapshots)
#######################################

##########################
### Petrov Galerkin ###
elif chosen_projection_strategy == "petrov_galerkin":
if any(item == "ROM" for item in training_stages):
fom_snapshots = self.__LaunchTrainROM(mu_train)
if store_all_snapshots or store_fom_snapshots:
self._StoreSnapshotsMatrix('fom_snapshots', fom_snapshots)
self._ChangeRomFlags(simulation_to_run = "TrainPG")
self.__LaunchTrainPG(mu_train)
self._ChangeRomFlags(simulation_to_run = "PG")
rom_snapshots = self.__LaunchROM(mu_train)
if store_all_snapshots or store_rom_snapshots:
self._StoreSnapshotsMatrix('rom_snapshots', rom_snapshots)
self.ROMvsFOM_train = np.linalg.norm(fom_snapshots - rom_snapshots)/ np.linalg.norm(fom_snapshots)
if any(item == "HROM" for item in training_stages):
#FIXME there will be an error if we only train HROM, but not ROM
self._ChangeRomFlags(simulation_to_run = "trainHROMPetrovGalerkin")
self.__LaunchTrainHROM(mu_train, store_residuals_projected)
self._ChangeRomFlags(simulation_to_run = "runHROMPetrovGalerkin")
hrom_snapshots = self.__LaunchHROM(mu_train)
if store_all_snapshots or store_hrom_snapshots:
self._StoreSnapshotsMatrix('hrom_snapshots', hrom_snapshots)
self.ROMvsHROM_train = np.linalg.norm(rom_snapshots - hrom_snapshots) / np.linalg.norm(rom_snapshots)
##########################
if type_of_decoder =="ann_enhanced":
err_msg = f'ann_enhanced rom only available for Galerkin Rom for the moment'
raise Exception(err_msg)
elif type_of_decoder =="linear":
if any(item == "ROM" for item in training_stages):
fom_snapshots = self.__LaunchTrainROM(mu_train)
if store_all_snapshots or store_fom_snapshots:
self._StoreSnapshotsMatrix('fom_snapshots', fom_snapshots)
self._ChangeRomFlags(simulation_to_run = "TrainPG")
self.__LaunchTrainPG(mu_train)
self._ChangeRomFlags(simulation_to_run = "PG")
rom_snapshots = self.__LaunchROM(mu_train)
if store_all_snapshots or store_rom_snapshots:
self._StoreSnapshotsMatrix('rom_snapshots', rom_snapshots)
self.ROMvsFOM_train = np.linalg.norm(fom_snapshots - rom_snapshots)/ np.linalg.norm(fom_snapshots)
if any(item == "HROM" for item in training_stages):
#FIXME there will be an error if we only train HROM, but not ROM
self._ChangeRomFlags(simulation_to_run = "trainHROMPetrovGalerkin")
self.__LaunchTrainHROM(mu_train, store_residuals_projected)
self._ChangeRomFlags(simulation_to_run = "runHROMPetrovGalerkin")
hrom_snapshots = self.__LaunchHROM(mu_train)
if store_all_snapshots or store_hrom_snapshots:
self._StoreSnapshotsMatrix('hrom_snapshots', hrom_snapshots)
self.ROMvsHROM_train = np.linalg.norm(rom_snapshots - hrom_snapshots) / np.linalg.norm(rom_snapshots)
##########################
else:
err_msg = f'Provided projection strategy {chosen_projection_strategy} is not supported. Available options are \'galerkin\', \'lspg\' and \'petrov_galerkin\'.'
raise Exception(err_msg)

def StoreFomSnapshotsAndBasis(self, mu_train=[None]):
fom_snapshots = self.__LaunchTrainROM(mu_train)
self._StoreSnapshotsMatrix('fom_snapshots', fom_snapshots)

def StoreFomValidationSnapshots(self, mu_validation=[None]):
self.RunFOM(mu_run=mu_validation, snapshots_matrix_name='fom_snapshots_val')

def TrainAnnEnhacedNeuralNetwork(self):
NicolasSR marked this conversation as resolved.
Show resolved Hide resolved
self.__LaunchTrainNeuralNetwork()

def TestNeuralNetworkReconstruction(self):
self.__LaunchTestNeuralNetworkReconstruction()


def Test(self, mu_test=[None]):
Expand Down Expand Up @@ -166,8 +198,10 @@ def Test(self, mu_test=[None]):



def RunFOM(self, mu_run=[None]):
self.__LaunchRunFOM(mu_run)
def RunFOM(self, mu_run=[None], snapshots_matrix_name=None):
NicolasSR marked this conversation as resolved.
Show resolved Hide resolved
fom_snapshots = self.__LaunchRunFOM(mu_run)
if snapshots_matrix_name is not None:
self._StoreSnapshotsMatrix(snapshots_matrix_name, fom_snapshots)

def RunROM(self, mu_run=[None]):
chosen_projection_strategy = self.general_rom_manager_parameters["projection_strategy"].GetString()
Expand Down Expand Up @@ -455,9 +489,10 @@ def __LaunchRunFOM(self, mu_run):
"""
with open(self.project_parameters_name,'r') as parameter_file:
parameters = KratosMultiphysics.Parameters(parameter_file.read())

SnapshotsMatrix = []
for Id, mu in enumerate(mu_run):
parameters_copy = self.UpdateProjectParameters(parameters.Clone(), mu)
parameters_copy = self._AddBasisCreationToProjectParameters(parameters_copy)
parameters_copy = self._StoreResultsByName(parameters_copy,'FOM_Run',mu,Id)
materials_file_name = parameters_copy["solver_settings"]["material_import_settings"]["materials_filename"].GetString()
self.UpdateMaterialParametersFile(materials_file_name, mu)
Expand All @@ -466,8 +501,14 @@ def __LaunchRunFOM(self, mu_run):
simulation = self.CustomizeSimulation(analysis_stage_class,model,parameters_copy)
simulation.Run()
self.QoI_Run_FOM.append(simulation.GetFinalData())
for process in simulation._GetListOfOutputProcesses():
if isinstance(process, CalculateRomBasisOutputProcess):
BasisOutputProcess = process
SnapshotsMatrix.append(BasisOutputProcess._GetSnapshotsMatrix())
SnapshotsMatrix = np.block(SnapshotsMatrix)


return SnapshotsMatrix
NicolasSR marked this conversation as resolved.
Show resolved Hide resolved

def __LaunchRunROM(self, mu_run):
"""
This method should be parallel capable
Expand Down Expand Up @@ -508,6 +549,15 @@ def __LaunchRunHROM(self, mu_run, use_full_model_part):
simulation.Run()
self.QoI_Run_HROM.append(simulation.GetFinalData())

def __LaunchTrainNeuralNetwork(self):
rom_nn_trainer = RomNeuralNetworkTrainer(self.general_rom_manager_parameters)
model_name = rom_nn_trainer.TrainNetwork()
rom_nn_trainer.EvaluateNetwork(model_name)

def __LaunchTestNeuralNetworkReconstruction(self):
rom_nn_trainer = RomNeuralNetworkTrainer(self.general_rom_manager_parameters)
model_name=self.general_rom_manager_parameters["neural_network"]["online"]["model_name"].GetString()
rom_nn_trainer.EvaluateNetwork(model_name)

def _AddHromParametersToRomParameters(self,f):
f["hrom_settings"]["element_selection_type"] = self.hrom_training_parameters["element_selection_type"].GetString()
Expand Down
Loading
Loading