class ConvectionDiffusionTestFactory(KratosUnittest.TestCase): def setUp(self): # Within this location context: with controlledExecutionScope(os.path.dirname(os.path.realpath(__file__))): # Reading the ProjectParameters with open(self.file_name + "_parameters.json",'r') as parameter_file: ProjectParameters = KratosMultiphysics.Parameters(parameter_file.read()) self.modify_parameters(ProjectParameters) # To avoid many prints if (ProjectParameters["problem_data"]["echo_level"].GetInt() == 0): KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(KratosMultiphysics.Logger.Severity.WARNING) # Creating the test model = KratosMultiphysics.Model() self.test = ConvectionDiffusionAnalysis(model, ProjectParameters) self.test.Initialize() def modify_parameters(self, project_parameters): """This function can be used in derived classes to modify existing parameters before the execution of the test (e.g. switch to MPI) """ pass def test_execution(self): # Within this location context: with controlledExecutionScope(os.path.dirname(os.path.realpath(__file__))): self.test.RunSolutionLoop() def tearDown(self): # Within this location context: with controlledExecutionScope(os.path.dirname(os.path.realpath(__file__))): self.test.Finalize()
def __init__(self, identifier, response_settings, model): self.identifier = identifier self.response_settings = response_settings # Create the primal solver with open(self.response_settings["primal_settings"].GetString(), 'r') as parameter_file: primal_parameters = Parameters(parameter_file.read()) self.primal_analysis = ConvectionDiffusionAnalysis( model, primal_parameters) self.primal_model_part = model.GetModelPart( primal_parameters["solver_settings"] ["model_part_name"].GetString()) # Create the adjoint solver adjoint_parameters = self._GetAdjointParameters() self.adjoint_analysis = ConvectionDiffusionAnalysis( model, adjoint_parameters) self.adjoint_model_part = model.GetModelPart( adjoint_parameters["solver_settings"] ["model_part_name"].GetString()) self.primal_state_variables = [ KM.CONDUCTIVITY, KM.TEMPERATURE, KM.HEAT_FLUX, KM.FACE_HEAT_FLUX ] self.value = None
def _SetUpBarSimulation(self, ProjectParametersFileName): with open(ProjectParametersFileName, 'r') as parameter_file: parameters = KratosMultiphysics.Parameters(parameter_file.read()) model = KratosMultiphysics.Model() bar_simulation = ConvectionDiffusionAnalysis(model, parameters) return bar_simulation
def setUp(self): # Within this location context: with controlledExecutionScope(os.path.dirname(os.path.realpath(__file__))): # Reading the ProjectParameters with open(self.file_name + "_parameters.json",'r') as parameter_file: ProjectParameters = KratosMultiphysics.Parameters(parameter_file.read()) self.modify_parameters(ProjectParameters) # To avoid many prints if (ProjectParameters["problem_data"]["echo_level"].GetInt() == 0): KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(KratosMultiphysics.Logger.Severity.WARNING) # Creating the test model = KratosMultiphysics.Model() self.test = ConvectionDiffusionAnalysis(model, ProjectParameters) self.test.Initialize()
def testPerturbedDivergenceFreeInitialConditionProcess(self): if not is_fft_loaded: self.skipTest("Missing required Python library: scipy.fftpack") parameter_file_name = "test_perturbation_initial_conditions/parameters_poisson_rectangle_2d.json" with open(parameter_file_name, 'r') as parameter_file: parameters = KratosMultiphysics.Parameters(parameter_file.read()) model = KratosMultiphysics.Model() simulation = ConvectionDiffusionAnalysis(model, parameters) simulation._GetSolver().main_model_part.AddNodalSolutionStepVariable( KratosMultiphysics.VELOCITY_X_GRADIENT) simulation._GetSolver().main_model_part.AddNodalSolutionStepVariable( KratosMultiphysics.VELOCITY_Y_GRADIENT) simulation._GetSolver().main_model_part.AddNodalSolutionStepVariable( KratosMultiphysics.VELOCITY_Z_GRADIENT) simulation.Initialize() l2norm_divergence = ComputeDivergence(simulation) self.assertAlmostEqual(l2norm_divergence, 0.304470818597, delta=1e-12)
def directSensitivityCheck(self): model = kratos.Model() settings = kratos.Parameters(r'''{}''') with unittest.WorkFolderScope(self.work_folder, __file__): with open(self.primal_parameter_file_name,'r') as primal_parameter_file: settings.AddValue("primal_settings", kratos.Parameters(primal_parameter_file.read())) # enable volume source if needed other_processes_list = settings["primal_settings"]["processes"]["list_other_processes"] for i in range(other_processes_list.size()): if other_processes_list[i]["process_name"].GetString() == "AssignScalarVariableProcess" and other_processes_list[i]["Parameters"]["variable_name"].GetString() == "HEAT_FLUX": other_processes_list[i]["Parameters"]["value"].SetDouble(self.volume_source) self.primalSolution(model, settings["primal_settings"]) with open(self.adjoint_parameter_file_name,'r') as adjoint_parameter_file: settings.AddValue("adjoint_settings", kratos.Parameters(adjoint_parameter_file.read())) adjoint_analysis = ConvectionDiffusionAnalysis(model,settings["adjoint_settings"]) adjoint_analysis.Run() objective_model_part_name = settings["adjoint_settings"]["solver_settings"]["response_function_settings"]["custom_settings"]["model_part_name"].GetString() finite_difference_results = self.perturbedSolution(model, settings["primal_settings"], objective_model_part_name, self.node_ids_to_test) adjoint_model_part = model.GetModelPart(settings["adjoint_settings"]["solver_settings"]["model_part_name"].GetString()) for node_id,fd_sensitivity in zip(self.node_ids_to_test, finite_difference_results): node = adjoint_model_part.Nodes[node_id] adjoint_sensitivity = node.GetSolutionStepValue(kratos.SHAPE_SENSITIVITY,0) #diff = adjoint_sensitivity-fd_sensitivity #if (diff[0]**2 + diff[1]**2 + diff[2]**2)**0.5 < self.check_tolerance: # status = "PASS" #else: # status = "FAIL" #print(status, node_id, adjoint_sensitivity, fd_sensitivity, diff) self.assertAlmostEqual(adjoint_sensitivity[0], fd_sensitivity[0], delta=self.check_tolerance) self.assertAlmostEqual(adjoint_sensitivity[1], fd_sensitivity[1], delta=self.check_tolerance)
def testConvectionDiffusionBarExplicitElementUnsteadyDOSS(self): project_parameters_file_name = "test_convection_diffusion_bar/project_parameters_bar_DOSS.json" with open(project_parameters_file_name,'r') as parameter_file: parameters = KratosMultiphysics.Parameters(parameter_file.read()) model = KratosMultiphysics.Model() bar_simulation = ConvectionDiffusionAnalysis(model, parameters) bar_simulation._GetSolver().main_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.NODAL_AREA) bar_simulation.Run() # check L2 error via midpoint rule KratosMultiphysics.CalculateNodalAreaProcess(bar_simulation._GetSolver().main_model_part,2).Execute() error = 0 model_part_name = bar_simulation.project_parameters["problem_data"]["model_part_name"].GetString() for node in bar_simulation.model.GetModelPart(model_part_name).Nodes: # L2 norm x = node.X u_analytical = x - sin(bar_simulation.time) u_numerical = node.GetSolutionStepValue(KratosMultiphysics.TEMPERATURE) error += (((u_analytical - u_numerical)**2)*node.GetSolutionStepValue(KratosMultiphysics.NODAL_AREA)) error = sqrt(error) self.assertAlmostEqual(error,0.0017678016487118946,delta=1e-12)
from __future__ import print_function, absolute_import, division #makes KratosMultiphysics backward compatible with python 2.6 and 2.7 import KratosMultiphysics from KratosMultiphysics.ConvectionDiffusionApplication.convection_diffusion_analysis import ConvectionDiffusionAnalysis """ For user-scripting it is intended that a new class is derived from ConvectionDiffusionAnalysis to do modifications """ if __name__ == "__main__": with open("ProjectParameters.json",'r') as parameter_file: parameters = KratosMultiphysics.Parameters(parameter_file.read()) model = KratosMultiphysics.Model() simulation = ConvectionDiffusionAnalysis(model,parameters) simulation.Run()
def primalSolution(self, model, settings): primal_analysis = ConvectionDiffusionAnalysis(model,settings) primal_analysis.Run()
class AdjointResponseFunction(ResponseFunctionInterface): """Linear adjoint response function. - runs the primal analysis - primal results are transferred to adjoint model part via python - uses primal results to calculate value - uses primal results to calculate gradient by running the adjoint analysis Attributes ---------- primal_analysis : Primal analysis object of the response function adjoint_analysis : Adjoint analysis object of the response function """ def __init__(self, identifier, response_settings, model): self.identifier = identifier self.response_settings = response_settings # Create the primal solver with open(self.response_settings["primal_settings"].GetString(),'r') as parameter_file: primal_parameters = Parameters( parameter_file.read() ) self.primal_analysis = ConvectionDiffusionAnalysis(model, primal_parameters) self.primal_model_part = model.GetModelPart(primal_parameters["solver_settings"]["model_part_name"].GetString()) # Create the adjoint solver adjoint_parameters = self._GetAdjointParameters() self.adjoint_analysis = ConvectionDiffusionAnalysis(model, adjoint_parameters) self.adjoint_model_part = model.GetModelPart(adjoint_parameters["solver_settings"]["model_part_name"].GetString()) self.primal_state_variables = [ KM.CONDUCTIVITY, KM.TEMPERATURE, KM.HEAT_FLUX, KM.FACE_HEAT_FLUX ] self.value = None def Initialize(self): self.primal_analysis.Initialize() self.adjoint_analysis.Initialize() def InitializeSolutionStep(self): self.value = None # Run the primal analysis. Logger.PrintInfo(self._GetLabel(), "Starting primal analysis for response:", self.identifier) startTime = timer.time() if not self.primal_analysis.time < self.primal_analysis.end_time: self.primal_analysis.end_time += 1 self.primal_analysis.RunSolutionLoop() Logger.PrintInfo(self._GetLabel(), "Time needed for solving the primal analysis = ",round(timer.time() - startTime,2),"s") def CalculateValue(self): startTime = timer.time() self.value = self._GetResponseFunctionUtility().CalculateValue(self.primal_model_part) Logger.PrintInfo(self._GetLabel(), "Time needed for calculating the response value = ",round(timer.time() - startTime,2),"s") def CalculateGradient(self): # synchronize the modelparts self._SynchronizeAdjointFromPrimal() startTime = timer.time() Logger.PrintInfo(self._GetLabel(), "Starting adjoint analysis for response:", self.identifier) if not self.adjoint_analysis.time < self.adjoint_analysis.end_time: self.adjoint_analysis.end_time += 1 self.adjoint_analysis.RunSolutionLoop() Logger.PrintInfo(self._GetLabel(), "Time needed for solving the adjoint analysis = ",round(timer.time() - startTime,2),"s") def GetValue(self): return self.value def GetNodalGradient(self, variable): if variable != KM.SHAPE_SENSITIVITY: raise RuntimeError("GetNodalGradient: No gradient for {}!".format(variable.Name)) gradient = {} for node in self.adjoint_model_part.Nodes: gradient[node.Id] = node.GetSolutionStepValue(variable) return gradient def Finalize(self): self.primal_analysis.Finalize() self.adjoint_analysis.Finalize() def _GetResponseFunctionUtility(self): return self.adjoint_analysis._GetSolver().response_function def _SynchronizeAdjointFromPrimal(self): Logger.PrintInfo(self._GetLabel(), "Synchronize primal and adjoint modelpart for response:", self.identifier) if len(self.primal_model_part.Nodes) != len(self.adjoint_model_part.Nodes): raise RuntimeError("_SynchronizeAdjointFromPrimal: Model parts have a different number of nodes!") for primal_node, adjoint_node in zip(self.primal_model_part.Nodes, self.adjoint_model_part.Nodes): adjoint_node.X0 = primal_node.X0 adjoint_node.Y0 = primal_node.Y0 adjoint_node.Z0 = primal_node.Z0 adjoint_node.X = primal_node.X adjoint_node.Y = primal_node.Y adjoint_node.Z = primal_node.Z # Put primal solution on adjoint model Logger.PrintInfo(self._GetLabel(), "Transfer primal state to adjoint model part.") variable_utils = KM.VariableUtils() for variable in self.primal_state_variables: variable_utils.CopyModelPartNodalVar(variable, self.primal_model_part, self.adjoint_model_part, 0) def _GetAdjointParameters(self): with open(self.response_settings["adjoint_settings"].GetString(),'r') as parameter_file: adjoint_parameters = Parameters( parameter_file.read() ) if self.response_settings["transfer_response_parameters"].GetBool(): # sensitivity settings if adjoint_parameters["solver_settings"].Has("sensitivity_settings"): Logger.PrintWarning(self._GetLabel(), "Adjoint settings already have 'sensitivity_settings' - Will be overwritten!") adjoint_parameters["solver_settings"].RemoveValue("sensitivity_settings") adjoint_parameters["solver_settings"].AddValue("sensitivity_settings", self.response_settings["sensitivity_settings"]) # response settings if adjoint_parameters["solver_settings"].Has("response_function_settings"): Logger.PrintWarning(self._GetLabel(), "Adjoint settings already have 'response_function_settings' - Will be overwritten!") adjoint_parameters["solver_settings"].RemoveValue("response_function_settings") adjoint_parameters["solver_settings"].AddValue("response_function_settings", self.response_settings) return adjoint_parameters def _GetLabel(self): type_labels = { "point_temperature" : "LocalTemperatureAverageResponseFunction" } response_type = self.response_settings["response_type"].GetString() return "Adjoint" + type_labels[response_type] + "Response"