Skip to content

Commit

Permalink
Merge pull request #9439 from KratosMultiphysics/rom/unify-analysis-s…
Browse files Browse the repository at this point in the history
…tage

[Rom] Unify analysis stage
  • Loading branch information
rubenzorrilla authored Dec 15, 2021
2 parents 9cec75a + 82c4611 commit 4062546
Show file tree
Hide file tree
Showing 26 changed files with 559 additions and 588 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
class ConvectionDiffusionAnalysisROM(ConvectionDiffusionAnalysis):

def __init__(self,model,project_parameters):
KratosMultiphysics.Logger.PrintWarning('\x1b[1;31m[DEPRECATED CLASS] \x1b[0m',"\'ConvectionDiffusionAnalysisROM\'", "class is deprecated. Use the \'RomAnalysis\' one instead.")
super().__init__(model,project_parameters)

#### Internal functions ####
Expand Down Expand Up @@ -42,6 +43,3 @@ def ModifyAfterSolverInitialize(self):
aux[j,i] = nodal_modes[Counter][j][i]
node.SetValue(romapp.ROM_BASIS, aux ) # ROM basis
counter+=1



Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class FluidDynamicsAnalysisROM(FluidDynamicsAnalysis):

def __init__(self,model,project_parameters):
KratosMultiphysics.Logger.PrintWarning('\x1b[1;31m[DEPRECATED CLASS] \x1b[0m',"\'FluidDynamicsAnalysisROM\'", "class is deprecated. Use the \'RomAnalysis\' one instead.")
super().__init__(model,project_parameters)

#### Internal functions ####
Expand Down
137 changes: 137 additions & 0 deletions applications/RomApplication/python_scripts/rom_analysis.py
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()
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
class StructuralMechanicsAnalysisROM(StructuralMechanicsAnalysis):

def __init__(self,model,project_parameters, hyper_reduction_element_selector = None):
KratosMultiphysics.Logger.PrintWarning('\x1b[1;31m[DEPRECATED CLASS] \x1b[0m',"\'StructuralMechanicsAnalysisROM\'", "class is deprecated. Use the \'RomAnalysis\' one instead.")
super().__init__(model,project_parameters)
if hyper_reduction_element_selector != None :
if hyper_reduction_element_selector == "EmpiricalCubature":
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"analysis_stage": "KratosMultiphysics.FluidDynamicsApplication.fluid_dynamics_analysis",
"problem_data" : {
"problem_name" : "couette_flow_test",
"parallel_type" : "OpenMP",
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"analysis_stage" : "KratosMultiphysics.StructuralMechanicsApplication.structural_mechanics_analysis",
"problem_data" : {
"problem_name" : "Structure_Dynamic_2D",
"parallel_type" : "OpenMP",
Expand Down
Loading

0 comments on commit 4062546

Please sign in to comment.