def CreateMapper(origin_model_part, destination_model_part, mapper_settings): default_settings = KM.Parameters(""" { "filter_function_type" : "linear", "filter_radius" : 0.000000000001, "max_nodes_in_filter_radius" : 10000, "matrix_free_filtering" : false, "consistent_mapping" : false, "improved_integration" : false, "integration_method" : "gauss_integration", "number_of_gauss_points" : 5, "in_plane_morphing" : false, "in_plane_morphing_settings" : {} }""") mapper_settings.ValidateAndAssignDefaults(default_settings) if mapper_settings["in_plane_morphing"].GetBool(): return in_plane_vertex_morphing_mapper.InPlaneVertexMorphingMapper(origin_model_part, destination_model_part, mapper_settings) elif mapper_settings["matrix_free_filtering"].GetBool(): if mapper_settings["consistent_mapping"].GetBool(): raise ValueError ("Matrix free mapper has no option to map consistently yet!") if mapper_settings["improved_integration"].GetBool(): raise ValueError ("Matrix free mapper does not yet allow for an improved integration!") else: return KSO.MapperVertexMorphingMatrixFree(origin_model_part, destination_model_part, mapper_settings) else: if mapper_settings["improved_integration"].GetBool(): return KSO.MapperVertexMorphingImprovedIntegration(origin_model_part, destination_model_part, mapper_settings) else: return KSO.MapperVertexMorphing(origin_model_part, destination_model_part, mapper_settings) # ==============================================================================
def Initialize(self): self.vm_mapper.Initialize() in_plane_settings = self.settings["in_plane_morphing_settings"] background_main_mesh = self._background_model.GetModelPart("background_mesh") if in_plane_settings["model_import_settings"]["input_type"].GetString() == "mdpa": model_part_io = KM.ModelPartIO(in_plane_settings["model_import_settings"]["input_filename"].GetString()) model_part_io.ReadModelPart(background_main_mesh) elif in_plane_settings["model_import_settings"]["input_type"].GetString() in ["vrml", "wrl"]: model_part_io = WrlIO(in_plane_settings["model_import_settings"]["input_filename"].GetString()) model_part_io.ReadModelPart(background_main_mesh) background_sub_model_part_name = in_plane_settings["background_sub_model_part_name"].GetString() if background_sub_model_part_name == "": self.background_mesh = background_main_mesh else: self.background_mesh = background_main_mesh.GetSubModelPart(background_sub_model_part_name) background_geometry_utilities = KSO.GeometryUtilities(self.background_mesh) background_geometry_utilities.ComputeUnitSurfaceNormals() self.spacial_mapper = SpacialMapperFactory.CreateMapper( self.background_mesh, self.destination_model_part, in_plane_settings["spacial_mapper_settings"]) KSO.MeshControllerUtilities(self.background_mesh).WriteCoordinatesToVariable(KSO.BACKGROUND_COORDINATE)
def UpdateMeshAccordingInputVariable(self, variable): print("\n> Starting to update the mesh") startTime = timer.time() KSO.MeshControllerUtilities(self.OptimizationModelPart).UpdateMeshAccordingInputVariable(variable) KSO.MeshControllerUtilities(self.OptimizationModelPart).LogMeshChangeAccordingInputVariable(variable) print("> Time needed for updating the mesh = ",round(timer.time() - startTime,2),"s") # ==============================================================================
def UpdateMeshAccordingInputVariable(self, variable): KM.Logger.Print("") KM.Logger.PrintInfo("ShapeOpt", "Starting to update the mesh") startTime = timer.time() KSO.MeshControllerUtilities(self.OptimizationModelPart).UpdateMeshAccordingInputVariable(variable) KSO.MeshControllerUtilities(self.OptimizationModelPart).LogMeshChangeAccordingInputVariable(variable) KM.Logger.PrintInfo("ShapeOpt", "Time needed for updating the mesh = ",round(timer.time() - startTime,2),"s") # ==============================================================================
def UpdateMeshAccordingInputVariable(self, variable): KM.Logger.Print("") KM.Logger.PrintInfo("ShapeOpt", "Starting to update the mesh...") startTime = timer.time() time_before_update = self.OptimizationModelPart.ProcessInfo.GetValue( KM.TIME) step_before_update = self.OptimizationModelPart.ProcessInfo.GetValue( KM.STEP) delta_time_before_update = self.OptimizationModelPart.ProcessInfo.GetValue( KM.DELTA_TIME) # Reset step/time iterators such that they match the current iteration after calling RunSolutionLoop (which internally calls CloneTimeStep) self.OptimizationModelPart.ProcessInfo.SetValue( KM.STEP, step_before_update - 1) self.OptimizationModelPart.ProcessInfo.SetValue( KM.TIME, time_before_update - 1) self.OptimizationModelPart.ProcessInfo.SetValue(KM.DELTA_TIME, 0) KM.VariableUtils().CopyVectorVar(variable, KM.MESH_DISPLACEMENT, self.OptimizationModelPart.Nodes) if self.has_automatic_boundary_process and self.is_remeshing_used: self.OptimizationModelPart.GetSubModelPart( "auto_surface_nodes").GetNodes().clear() KSO.GeometryUtilities( self.OptimizationModelPart).ExtractBoundaryNodes( "auto_surface_nodes") if not self._mesh_moving_analysis.time < self._mesh_moving_analysis.end_time: self._mesh_moving_analysis.end_time += 1 self._mesh_moving_analysis.RunSolutionLoop() if self.is_remeshing_used: self.OptimizationModelPart.Set(KM.MODIFIED, False) self.remeshing_process.ExecuteInitializeSolutionStep() self.remeshing_process.ExecuteFinalizeSolutionStep() KSO.MeshControllerUtilities( self.OptimizationModelPart).LogMeshChangeAccordingInputVariable( KM.MESH_DISPLACEMENT) self.OptimizationModelPart.ProcessInfo.SetValue( KM.STEP, step_before_update) self.OptimizationModelPart.ProcessInfo.SetValue( KM.TIME, time_before_update) self.OptimizationModelPart.ProcessInfo.SetValue( KM.DELTA_TIME, delta_time_before_update) KM.Logger.PrintInfo("ShapeOpt", "Time needed for updating the mesh = ", round(timer.time() - startTime, 2), "s")
def Initialize(self): if self.has_automatic_boundary_process: KSO.GeometryUtilities( self.OptimizationModelPart).ExtractBoundaryNodes( "auto_surface_nodes") self._mesh_moving_analysis.Initialize()
def _CorrectOutOfPlanePart(self, destination_variable): geometry_utilities = KSO.GeometryUtilities(self.destination_model_part) mesh_utilities = KSO.MeshControllerUtilities(self.destination_model_part) mesh_utilities.UpdateMeshAccordingInputVariable(destination_variable) mesh_utilities.SetReferenceMeshToMesh() self.spacial_mapper.UpdateInterface() self.spacial_mapper.Map(KSO.BACKGROUND_COORDINATE, KSO.BACKGROUND_COORDINATE) mesh_utilities.SubtractCoordinatesFromVariable(KSO.BACKGROUND_COORDINATE, KSO.OUT_OF_PLANE_DELTA) geometry_utilities.ProjectNodalVariableOnDirection(KSO.OUT_OF_PLANE_DELTA, KSO.BACKGROUND_NORMAL) mesh_utilities.RevertMeshUpdateAccordingInputVariable(destination_variable) mesh_utilities.SetReferenceMeshToMesh() mesh_utilities.AddFirstVariableToSecondVariable(KSO.OUT_OF_PLANE_DELTA, destination_variable)
def UpdateMeshAccordingInputVariable(self, InputVariable): self.mesh_controller.UpdateMeshAccordingInputVariable(InputVariable) if self.model_settings["damping"]["recalculate_damping"].GetBool(): self.damping_utility = KSO.DampingUtilities( self.design_surface, self.damping_regions, self.model_settings["damping"])
def UpdateMeshAccordingInputVariable(self, variable): KM.Logger.Print("") KM.Logger.PrintInfo("ShapeOpt", "Starting to update the mesh...") startTime = timer.time() time_before_update = self.OptimizationModelPart.ProcessInfo.GetValue(KM.TIME) step_before_update = self.OptimizationModelPart.ProcessInfo.GetValue(KM.STEP) delta_time_before_update = self.OptimizationModelPart.ProcessInfo.GetValue(KM.DELTA_TIME) # Reset step/time iterators such that they match the current iteration after calling RunSolutionLoop (which internally calls CloneTimeStep) self.OptimizationModelPart.ProcessInfo.SetValue(KM.STEP, step_before_update-1) self.OptimizationModelPart.ProcessInfo.SetValue(KM.TIME, time_before_update-1) self.OptimizationModelPart.ProcessInfo.SetValue(KM.DELTA_TIME, 0) KM.VariableUtils().CopyVectorVar(variable, KM.MESH_DISPLACEMENT, self.OptimizationModelPart.Nodes) if not self._mesh_moving_analysis.time < self._mesh_moving_analysis.end_time: self._mesh_moving_analysis.end_time += 1 self._mesh_moving_analysis.RunSolutionLoop() KSO.MeshControllerUtilities(self.OptimizationModelPart).LogMeshChangeAccordingInputVariable(KM.MESH_DISPLACEMENT) self.OptimizationModelPart.ProcessInfo.SetValue(KM.STEP, step_before_update) self.OptimizationModelPart.ProcessInfo.SetValue(KM.TIME, time_before_update) self.OptimizationModelPart.ProcessInfo.SetValue(KM.DELTA_TIME, delta_time_before_update) KM.Logger.PrintInfo("ShapeOpt", "Time needed for updating the mesh = ",round(timer.time() - startTime,2),"s")
def Initialize(self): if self.response_settings["model_import_settings"][ "input_type"].GetString() == "mdpa": file_name = self.response_settings["model_import_settings"][ "input_filename"].GetString() model_part_io = KM.ModelPartIO(file_name) model_part_io.ReadModelPart(self.model_part) else: self.model_part = self.model.GetModelPart(self._model_part_name) only = self.response_settings["only"].GetString() if only != "": only_part = self.model.GetModelPart(only) if only_part.NumberOfConditions() == 0: _AddConditionsFromParent(self.model_part, only_part) Logger.PrintWarning( "FaceAngleResponse", "Automatically added {} conditions to model_part '{}'.". format(only_part.NumberOfConditions(), only_part.Name)) else: only_part = self.model_part if only_part.NumberOfConditions() == 0: raise RuntimeError( "The model_part '{}' does not have any surface conditions!". format(only_part.Name)) self.response_function_utility = KSO.FaceAngleResponseFunctionUtility( only_part, self.response_settings) self.response_function_utility.Initialize()
def __CreateUNVIO(self): results_directory = self.output_settings["output_directory"].GetString( ) design_history_file_path = results_directory + "/" + self.design_history_filename nodal_results = self.output_settings["nodal_results"] if self.write_design_surface: self.UNVIO = KSO.UniversalFileIO(self.design_surface, design_history_file_path, "WriteConditionsOnly", nodal_results) elif self.write_optimization_model_part: self.UNVIO = KSO.UniversalFileIO(self.optimization_model_part, design_history_file_path, "WriteElementsOnly", nodal_results)
def Map(self, origin_variable, destination_variable): self.vm_mapper.Map(origin_variable, destination_variable) geometry_utilities = KSO.GeometryUtilities(self.destination_model_part) geometry_utilities.ProjectNodalVariableOnTangentPlane( destination_variable, KSO.BACKGROUND_NORMAL) self._CorrectOutOfPlanePart(destination_variable)
def _CalculateDistances(self): geometry_tools = KSO.GeometryUtilities(self.model_part) self.signed_distances = [] self.directions = [] geometry_tools.ComputeDistancesToBoundingModelPart( self.packaging_model_part, self.signed_distances, self.directions)
def Initialize(self): self.__ImportOptimizationModelPart() self.__IdentifyDesignSurface() self.mesh_controller.Initialize() if self.model_settings["damping"]["apply_damping"].GetBool(): self.__IdentifyDampingRegions() self.damping_utility = KSO.DampingUtilities(self.design_surface, self.damping_regions, self.model_settings["damping"])
def InitializeOptimizationLoop(self): self.model_part_controller.Initialize() self.analyzer.InitializeBeforeOptimizationLoop() self.design_surface = self.model_part_controller.GetDesignSurface() self.mapper = mapper_factory.CreateMapper(self.design_surface, self.design_surface, self.mapper_settings) self.mapper.Initialize() self.data_logger = data_logger_factory.CreateDataLogger( self.model_part_controller, self.communicator, self.optimization_settings) self.data_logger.InitializeDataLogging() self.optimization_utilities = KSO.OptimizationUtilities( self.design_surface, self.optimization_settings)
def Initialize(self): if self.response_settings["model_import_settings"][ "input_type"].GetString() == "mdpa": file_name = self.response_settings["model_import_settings"][ "input_filename"].GetString() model_part_io = KM.ModelPartIO(file_name) model_part_io.ReadModelPart(self.model_part) else: self.model_part = self.model.GetModelPart(self._model_part_name) only = self.response_settings["only"].GetString() if only != "": only_part = self.model.GetModelPart(only) else: only_part = self.model_part self.response_function_utility = KSO.FaceAngleResponseFunctionUtility( only_part, self.response_settings) self.response_function_utility.Initialize()
def InverseMap(self, destination_variable, origin_variable): geometry_utilities = KSO.GeometryUtilities(self.destination_model_part) geometry_utilities.ProjectNodalVariableOnTangentPlane( destination_variable, KSO.BACKGROUND_NORMAL) self.vm_mapper.InverseMap(destination_variable, origin_variable)
def _ComputePerimeter(self, model_part): return KSO.GeometryUtilities(model_part).CalculateLength( model_part.Conditions)
def InitializeSolutionStep(self): self.previous_value = self.value self.value = None self.gradient = {} KSO.GeometryUtilities(self.model_part).ComputeUnitSurfaceNormals()
def ProjectNodalVariableOnUnitSurfaceNormals(self, variable): KSO.GeometryUtilities( self.GetDesignSurface()).ProjectNodalVariableOnUnitSurfaceNormals( variable)
def ComputeUnitSurfaceNormals(self): KSO.GeometryUtilities( self.GetDesignSurface()).ComputeUnitSurfaceNormals()
def SetDeformationVariablesToZero(self): KSO.MeshControllerUtilities( self.optimization_model_part).SetDeformationVariablesToZero()
def SetReferenceMeshToMesh(self): KSO.MeshControllerUtilities( self.optimization_model_part).SetReferenceMeshToMesh()
def test_simple_model_part(self): model = KM.Model() mp = model.CreateModelPart("surface") mp.ProcessInfo.SetValue(KM.DOMAIN_SIZE, 3) mp.AddNodalSolutionStepVariable(KSO.SHAPE_UPDATE) mp.AddNodalSolutionStepVariable(KSO.SHAPE_CHANGE) mp.AddNodalSolutionStepVariable(KM.NORMAL) mp.AddNodalSolutionStepVariable(KSO.NORMALIZED_SURFACE_NORMAL) mp.CreateNewNode(1, 0.0, 0.0, 0.0) mp.CreateNewNode(2, 1.0, 0.0, 0.0) mp.CreateNewNode(3, 1.0, 1.0, 0.0) mp.CreateNewNode(4, 0.0, 1.0, 0.0) mp.CreateNewNode(5, 1.0, 1.0, -1.0) mp.CreateNewNode(6, 1.0, 0.0, -1.0) prop = mp.GetProperties()[1] mp.CreateNewCondition("SurfaceCondition3D4N", 1, [1, 2, 3, 4], prop) mp.CreateNewCondition("SurfaceCondition3D4N", 2, [2, 6, 5, 3], prop) settings = KM.Parameters("""{ "response_type" : "surface_normal_shape_change", "model_part_name" : "surface", "model_import_settings" : { "input_type" : "use_input_model_part" } }""") response = SurfaceNormalShapeChange("surface_normal", settings, model) response.Initialize() response.InitializeSolutionStep() response.CalculateValue() response.CalculateGradient() value = response.GetValue() gradient = response.GetNodalGradient(KM.SHAPE_SENSITIVITY) ref_gradient = { 1: [0.0, 0.0, 1.0], 2: [math.sqrt(2.0) / 2.0, 0.0, math.sqrt(2.0) / 2.0], 3: [math.sqrt(2.0) / 2.0, 0.0, math.sqrt(2.0) / 2.0], 4: [0.0, 0.0, 1.0], 5: [1.0, 0.0, 0.0], 6: [1.0, 0.0, 0.0], } self.assertAlmostEqual(value, 0.0) for node in mp.Nodes: node_id = node.Id self.assertVectorAlmostEqual(KM.Vector(gradient[node_id]), KM.Vector(ref_gradient[node_id])) # update nodes and test again for node in mp.Nodes: node.SetSolutionStepValue(KSO.SHAPE_UPDATE, [1, 0, 0]) KSO.MeshControllerUtilities(mp).UpdateMeshAccordingInputVariable( KSO.SHAPE_UPDATE) response.InitializeSolutionStep() response.CalculateValue() value = response.GetValue() self.assertAlmostEqual(value, 2.0 + math.sqrt(2.0))
def InitializeOptimizationLoop(self): self.model_part_controller.Initialize() self.model_part_controller.SetMinimalBufferSize(2) self.analyzer.InitializeBeforeOptimizationLoop() self.design_surface = self.model_part_controller.GetDesignSurface() self.mapper = mapper_factory.CreateMapper(self.design_surface, self.design_surface, self.mapper_settings) self.mapper.Initialize() if self.filter_penalty_term: penalty_filter_radius = self.algorithm_settings[ "penalty_filter_radius"].GetDouble() filter_radius = self.mapper_settings["filter_radius"].GetDouble() if abs(filter_radius - penalty_filter_radius) > 1e-9: penalty_filter_settings = self.mapper_settings.Clone() penalty_filter_settings["filter_radius"].SetDouble( self.algorithm_settings["penalty_filter_radius"].GetDouble( )) self.penalty_filter = mapper_factory.CreateMapper( self.design_surface, self.design_surface, penalty_filter_settings) self.penalty_filter.Initialize() else: self.penalty_filter = self.mapper self.data_logger = data_logger_factory.CreateDataLogger( self.model_part_controller, self.communicator, self.optimization_settings) self.data_logger.InitializeDataLogging() self.optimization_utilities = KSO.OptimizationUtilities( self.design_surface, self.optimization_settings) # Identify fixed design areas KM.VariableUtils().SetFlag(KM.BOUNDARY, False, self.optimization_model_part.Nodes) radius = self.mapper_settings["filter_radius"].GetDouble() search_based_functions = KSO.SearchBasedFunctions(self.design_surface) for itr in range(self.algorithm_settings["fix_boundaries"].size()): sub_model_part_name = self.algorithm_settings["fix_boundaries"][ itr].GetString() node_set = self.optimization_model_part.GetSubModelPart( sub_model_part_name).Nodes search_based_functions.FlagNodesInRadius(node_set, KM.BOUNDARY, radius) # Specify bounds and assign starting values for ALPHA if self.bead_side == "positive": KM.VariableUtils().SetScalarVar(KSO.ALPHA, 0.5, self.design_surface.Nodes, KM.BOUNDARY, False) self.lower_bound = 0.0 self.upper_bound = 1.0 elif self.bead_side == "negative": KM.VariableUtils().SetScalarVar(KSO.ALPHA, -0.5, self.design_surface.Nodes, KM.BOUNDARY, False) self.lower_bound = -1.0 self.upper_bound = 0.0 elif self.bead_side == "both": KM.VariableUtils().SetScalarVar(KSO.ALPHA, 0.0, self.design_surface.Nodes, KM.BOUNDARY, False) self.lower_bound = -1.0 self.upper_bound = 1.0 else: raise RuntimeError("Specified bead direction mode not supported!") # Initialize ALPHA_MAPPED according to initial ALPHA values self.mapper.Map(KSO.ALPHA, KSO.ALPHA_MAPPED) # Specify bead direction bead_direction = self.algorithm_settings["bead_direction"].GetVector() if len(bead_direction) == 0: self.model_part_controller.ComputeUnitSurfaceNormals() for node in self.design_surface.Nodes: normalized_normal = node.GetSolutionStepValue( KSO.NORMALIZED_SURFACE_NORMAL) node.SetValue(KSO.BEAD_DIRECTION, normalized_normal) elif len(bead_direction) == 3: norm = math.sqrt(bead_direction[0]**2 + bead_direction[1]**2 + bead_direction[2]**2) normalized_bead_direction = [ value / norm for value in bead_direction ] KM.VariableUtils().SetNonHistoricalVectorVar( KSO.BEAD_DIRECTION, normalized_bead_direction, self.design_surface.Nodes) else: raise RuntimeError( "Wrong definition of bead direction. Options are: 1) [] -> takes surface normal, 2) [x.x,x.x,x.x] -> takes specified vector." )
kratos_response_settings["response_type"].GetString(), kratos_response_settings, model) model_part = model.GetModelPart(model_part_name) model_part.AddNodalSolutionStepVariable(KSO.DF1DX) model_part.AddNodalSolutionStepVariable(KSO.DF1DX_MAPPED) response.Initialize() response.InitializeSolutionStep() response.CalculateValue() response.CalculateGradient() response.FinalizeSolutionStep() response.Finalize() # Perform mapping WriteDictionaryDataOnNodalVariable(response.GetShapeGradient(), model_part, KSO.DF1DX) vm_mapper = KSO.MapperVertexMorphingMatrixFree(model_part, model_part, mapper_settings) vm_mapper.InverseMap(KSO.DF1DX, KSO.DF1DX_MAPPED) # Output to verify mapping OutputModelPart(model_part, "reference_part", ["DF1DX", "DF1DX_MAPPED"]) # Get results reference_value = response.GetValue() reference_gradient = model_part.Nodes[move_node_id].GetSolutionStepValue( KSO.DF1DX_MAPPED) # Initialize results file with open(results_filename, 'a') as open_file: open_file.write( "-----------------------------------------------------------------------\n" )