-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9439 from KratosMultiphysics/rom/unify-analysis-s…
…tage [Rom] Unify analysis stage
- Loading branch information
Showing
26 changed files
with
559 additions
and
588 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
applications/RomApplication/python_scripts/rom_analysis.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import json | ||
import importlib | ||
import numpy as np | ||
|
||
import KratosMultiphysics | ||
import KratosMultiphysics.RomApplication as KratosROM | ||
from KratosMultiphysics.RomApplication import python_solvers_wrapper_rom | ||
from KratosMultiphysics.RomApplication.empirical_cubature_method import EmpiricalCubatureMethod | ||
|
||
def CreateRomAnalysisInstance(cls, global_model, parameters, hyper_reduction_element_selector = None): | ||
class RomAnalysis(cls): | ||
|
||
def __init__(self,global_model, parameters, hyper_reduction_element_selector = None): | ||
super().__init__(global_model, parameters) | ||
|
||
if hyper_reduction_element_selector != None : | ||
if hyper_reduction_element_selector == "EmpiricalCubature": | ||
self.hyper_reduction_element_selector = EmpiricalCubatureMethod() | ||
self.time_step_residual_matrix_container = [] | ||
else: | ||
err_msg = "The requested element selection method \"" + hyper_reduction_element_selector + "\" is not in the rom application\n" | ||
err_msg += "Available options are: \"EmpiricalCubature\"" | ||
raise Exception(err_msg) | ||
else: | ||
self.hyper_reduction_element_selector = None | ||
|
||
def _CreateSolver(self): | ||
""" Create the Solver (and create and import the ModelPart if it is not alread in the model) """ | ||
|
||
# Get the ROM settings from the RomParameters.json input file and set them in the "solver_settings" of the solver introducing the physics | ||
with open('RomParameters.json') as rom_parameters: | ||
rom_settings = KratosMultiphysics.Parameters(rom_parameters.read()) | ||
self.project_parameters["solver_settings"].AddValue("rom_settings", rom_settings["rom_settings"]) | ||
|
||
# Create the ROM solver | ||
return python_solvers_wrapper_rom.CreateSolverByParameters( | ||
self.model, | ||
self.project_parameters["solver_settings"], | ||
self.project_parameters["problem_data"]["parallel_type"].GetString()) | ||
|
||
def _GetSimulationName(self): | ||
return "::[ROM Simulation]:: " | ||
|
||
def ModifyAfterSolverInitialize(self): | ||
"""Here is where the ROM_BASIS is imposed to each node""" | ||
super().ModifyAfterSolverInitialize() | ||
|
||
# Get the model part where the ROM is to be applied | ||
computing_model_part = self._GetSolver().GetComputingModelPart() | ||
|
||
# Set ROM basis | ||
with open('RomParameters.json') as f: | ||
# Get the ROM data from RomParameters.json | ||
data = json.load(f) | ||
nodal_modes = data["nodal_modes"] | ||
nodal_dofs = len(data["rom_settings"]["nodal_unknowns"]) | ||
rom_dofs = self.project_parameters["solver_settings"]["rom_settings"]["number_of_rom_dofs"].GetInt() | ||
|
||
# Set the nodal ROM basis | ||
aux = KratosMultiphysics.Matrix(nodal_dofs, rom_dofs) | ||
for node in computing_model_part.Nodes: | ||
node_id = str(node.Id) | ||
for j in range(nodal_dofs): | ||
for i in range(rom_dofs): | ||
aux[j,i] = nodal_modes[node_id][j][i] | ||
node.SetValue(KratosROM.ROM_BASIS, aux) | ||
|
||
# Hyper-reduction | ||
if self.hyper_reduction_element_selector: | ||
if self.hyper_reduction_element_selector.Name == "EmpiricalCubature": | ||
self.ResidualUtilityObject = KratosROM.RomResidualsUtility( | ||
computing_model_part, | ||
self.project_parameters["solver_settings"]["rom_settings"], | ||
self._GetSolver()._GetScheme()) | ||
|
||
def FinalizeSolutionStep(self): | ||
if self.hyper_reduction_element_selector: | ||
if self.hyper_reduction_element_selector.Name == "EmpiricalCubature": | ||
KratosMultiphysics.Logger.PrintInfo("RomAnalysis","Generating matrix of residuals.") | ||
res_mat = self.ResidualUtilityObject.GetResiduals() | ||
np_res_mat = np.array(res_mat, copy=False) | ||
self.time_step_residual_matrix_container.append(np_res_mat) | ||
|
||
super().FinalizeSolutionStep() | ||
|
||
def Finalize(self): | ||
super().Finalize() | ||
|
||
if self.hyper_reduction_element_selector: | ||
if self.hyper_reduction_element_selector.Name == "EmpiricalCubature": | ||
original_number_of_elements = self._GetSolver().GetComputingModelPart().NumberOfElements() | ||
input_filename = self._GetSolver().settings["model_import_settings"]["input_filename"].GetString() | ||
self. hyper_reduction_element_selector.SetUp( | ||
self.time_step_residual_matrix_container, | ||
original_number_of_elements, | ||
input_filename) | ||
self.hyper_reduction_element_selector.Run() | ||
|
||
return RomAnalysis(global_model, parameters, hyper_reduction_element_selector) | ||
|
||
def CreateHRomAnalysisInstance(cls, global_model, parameters, hyper_reduction_element_selector = None): | ||
# Create an standard ROM analysis instance to get the type | ||
# This is required as RomAnalysis is defined inside CreateRomAnalysisInstance function | ||
rom_analysis = CreateRomAnalysisInstance(cls, global_model, parameters, hyper_reduction_element_selector) | ||
|
||
# Extend the ModifyAfterSolverInitialize method to set the element and condition hyper-reduction weights | ||
class HRomAnalysis(type(rom_analysis)): | ||
|
||
def ModifyAfterSolverInitialize(self): | ||
super().ModifyAfterSolverInitialize() | ||
computing_model_part = self._GetSolver().GetComputingModelPart() | ||
|
||
with open('ElementsAndWeights.json') as f: | ||
HR_data = json.load(f) | ||
for key in HR_data["Elements"].keys(): | ||
computing_model_part.GetElement(int(key)+1).SetValue(KratosROM.HROM_WEIGHT, HR_data["Elements"][key]) | ||
for key in HR_data["Conditions"].keys(): | ||
computing_model_part.GetCondition(int(key)+1).SetValue(KratosROM.HROM_WEIGHT, HR_data["Conditions"][key]) | ||
|
||
return HRomAnalysis(global_model, parameters, hyper_reduction_element_selector) | ||
|
||
if __name__ == "__main__": | ||
|
||
with open("ProjectParameters.json", 'r') as parameter_file: | ||
parameters = KratosMultiphysics.Parameters(parameter_file.read()) | ||
|
||
analysis_stage_module_name = parameters["analysis_stage"].GetString() | ||
analysis_stage_class_name = analysis_stage_module_name.split('.')[-1] | ||
analysis_stage_class_name = ''.join(x.title() for x in analysis_stage_class_name.split('_')) | ||
|
||
analysis_stage_module = importlib.import_module(analysis_stage_module_name) | ||
analysis_stage_class = getattr(analysis_stage_module, analysis_stage_class_name) | ||
|
||
global_model = KratosMultiphysics.Model() | ||
simulation = CreateRomAnalysisInstance(analysis_stage_class, global_model, parameters) | ||
# simulation = CreateHRomAnalysisInstance(analysis_stage_class, global_model, parameters) | ||
simulation.Run() |
68 changes: 68 additions & 0 deletions
68
applications/RomApplication/python_scripts/rom_testing_utilities.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import importlib | ||
|
||
import KratosMultiphysics | ||
import KratosMultiphysics.RomApplication.rom_analysis | ||
|
||
def SetUpSimulationInstance(model, parameters, is_hrom = False, hyper_reduction_element_selector = None): | ||
""" Creates and returns a ROM simulation instance """ | ||
|
||
# Get the parent simulation class | ||
analysis_stage_module_name = parameters["analysis_stage"].GetString() | ||
analysis_stage_class_name = analysis_stage_module_name.split('.')[-1] | ||
analysis_stage_class_name = ''.join(x.title() for x in analysis_stage_class_name.split('_')) | ||
|
||
analysis_stage_module = importlib.import_module(analysis_stage_module_name) | ||
analysis_stage_class = getattr(analysis_stage_module, analysis_stage_class_name) | ||
|
||
# Set up simulation | ||
model = KratosMultiphysics.Model() | ||
instance_factory = KratosMultiphysics.RomApplication.rom_analysis.CreateHRomAnalysisInstance if is_hrom else KratosMultiphysics.RomApplication.rom_analysis.CreateRomAnalysisInstance | ||
simulation = instance_factory( | ||
analysis_stage_class, | ||
model, | ||
parameters, | ||
hyper_reduction_element_selector) | ||
|
||
return simulation | ||
|
||
def GetNodalResults(model_part, variables_list): | ||
# Set and return an array containing the values of the variables in the variable list | ||
# Note that the array type variables need to be specified componentwise | ||
results_array = [] | ||
for node in model_part.Nodes: | ||
for variable in variables_list: | ||
results_array.append(node.GetSolutionStepValue(variable)) | ||
|
||
return results_array | ||
|
||
def GetScalarNodalResults(model_part, variable): | ||
# Set and return an array containing the scalar variable values | ||
results_array = [] | ||
for node in model_part.Nodes: | ||
results_array.append(node.GetSolutionStepValue(variable)) | ||
|
||
return results_array | ||
|
||
def GetVectorNodalResults(model_part, variable): | ||
# Set and return an array containing the vector variable values | ||
# Note that only the meaningful ones (2 in 2D and 3 in 3D) are returned | ||
results_array = [] | ||
dim = model_part.ProcessInfo[KratosMultiphysics.DOMAIN_SIZE] | ||
for node in model_part.Nodes: | ||
vector_value = node.GetSolutionStepValue(variable) | ||
for d in range(dim): | ||
results_array.append(vector_value[d]) | ||
|
||
return results_array | ||
|
||
def GetNodalAreaVector(model_part): | ||
# Calculate the NODAL_AREA and save it in the non-historical database | ||
nodal_area_calculator = KratosMultiphysics.CalculateNonHistoricalNodalAreaProcess(model_part) | ||
nodal_area_calculator.Execute() | ||
|
||
# Set and return an array containing the NODAL_AREA values | ||
nodal_area_array = [] | ||
for node in model_part.Nodes: | ||
nodal_area_array.append(node.GetValue(KratosMultiphysics.NODAL_AREA)) | ||
|
||
return nodal_area_array |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 0 additions & 35 deletions
35
applications/RomApplication/tests/fluid_dynamics_test_files/MainKratosROM.py
This file was deleted.
Oops, something went wrong.
1 change: 1 addition & 0 deletions
1
applications/RomApplication/tests/fluid_dynamics_test_files/ProjectParameters.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 0 additions & 43 deletions
43
applications/RomApplication/tests/fluid_dynamics_test_files/test_ROM.py
This file was deleted.
Oops, something went wrong.
50 changes: 0 additions & 50 deletions
50
applications/RomApplication/tests/structural_dynamic_test_files/MainKratosROM.py
This file was deleted.
Oops, something went wrong.
1 change: 1 addition & 0 deletions
1
applications/RomApplication/tests/structural_dynamic_test_files/ProjectParameters.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.