def CalculateValue(self): Logger.PrintInfo("MassResponse", "Starting primal analysis for response", self.identifier) startTime = timer.time() value = self.response_function_utility.CalculateValue() self.model_part.ProcessInfo[StructuralMechanicsApplication.RESPONSE_VALUE] = value Logger.PrintInfo("MassResponse", "Time needed for calculating the response value = ",round(timer.time() - startTime,2),"s")
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 _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!" ) # TODO this should happen automatically 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 - for "auto" setting, else it has to be done by the user e.g. using hdf5 process if self.response_settings["adjoint_settings"].GetString() == "auto": Logger.PrintInfo(self._GetLabel(), "Transfer primal state to adjoint model part.") variable_utils = KratosMultiphysics.VariableUtils() for variable in self.primal_state_variables: variable_utils.CopyModelPartNodalVar(variable, self.primal_model_part, self.adjoint_model_part, 0)
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!" ) # TODO this should happen automatically 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 if self.primal_data_transfer_with_python: Logger.PrintInfo(self._GetLabel(), "Transfer primal state to adjoint model part.") variable_utils = KratosMultiphysics.VariableUtils() for variable in self.primal_state_variables: variable_utils.CopyModelPartNodalVar(variable, self.primal_model_part, self.adjoint_model_part, 0)
def CalculateGradient(self): Logger.PrintInfo("\n> Starting gradient calculation for response", self.identifier) startTime = timer.time() self.response_function_utility.CalculateGradient() Logger.PrintInfo("> Time needed for calculating gradients", round(timer.time() - startTime, 2), "s")
def CalculateGradient(self): Logger.PrintInfo("\n> Starting adjoint analysis for response:", self.identifier) startTime = timer.time() self.adjoint_analysis._GetSolver().Predict() self.adjoint_analysis._GetSolver().SolveSolutionStep() Logger.PrintInfo("> Time needed for solving the adjoint analysis = ", 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 InitializeSolutionStep(self): # Run the primal analysis. # TODO if primal_analysis.status==solved: return 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 CalculateGradient(self): Logger.PrintInfo("\n> Starting gradient calculation for response", self.identifier) startTime = timer.time() for node in self.model_part.Nodes: normalized_normal = node.GetSolutionStepValue(KSO.NORMALIZED_SURFACE_NORMAL) self.gradient[node.Id] = normalized_normal Logger.PrintInfo("> Time needed for calculating gradients = ", round(timer.time() - startTime,2), "s")
def CalculateValue(self): Logger.PrintInfo("FaceAngleResponse", "Starting calculation of response value:", self.identifier) startTime = timer.time() self.value = self.response_function_utility.CalculateValue() Logger.PrintInfo("FaceAngleResponse", "Time needed for calculating the response value = ", round(timer.time() - startTime, 2), "s")
def Writeresults(self, time): # We reorder the Id of the model parts femdem_util = FEMDEM.FEMDEMCouplingUtilities() reorder_util_elem = FEMDEM.RenumberingNodesUtility( self.solid_model_part, self.fluid_model_part) reorder_util_elem.RenumberElements() Logger.PrintInfo("", "") Logger.PrintInfo( "", "***************** PRINTING RESULTS FOR GID *************************" ) Logger.PrintInfo("", "") Logger.Flush() number_pfem_nodes = femdem_util.GetNumberOfNodes(self.fluid_model_part) for node in self.balls_model_part.Nodes: node.Id = node.Id + number_pfem_nodes if self.GiDMultiFileFlag == "Multiples": self.mixed_solid_fluid_model_part.Elements.clear() self.mixed_solid_fluid_model_part.Nodes.clear() self.mixed_solid_balls_model_part.Elements.clear() self.mixed_solid_balls_model_part.Nodes.clear() self.mixed_solid_balls_fluid_model_part.Elements.clear() self.mixed_solid_balls_fluid_model_part.Nodes.clear() # Now we fill the mixed MDPA in order to print post_utils = DEMApplication.PostUtilities() post_utils.AddModelPartToModelPart( self.mixed_solid_fluid_model_part, self.fluid_model_part) post_utils.AddModelPartToModelPart( self.mixed_solid_balls_model_part, self.balls_model_part) post_utils.AddModelPartToModelPart( self.mixed_solid_balls_model_part, self.rigid_faces_model_part) post_utils.AddModelPartToModelPart( self.mixed_solid_balls_fluid_model_part, self.balls_model_part) post_utils.AddModelPartToModelPart( self.mixed_solid_balls_fluid_model_part, self.rigid_faces_model_part) post_utils.AddModelPartToModelPart( self.mixed_solid_balls_fluid_model_part, self.solid_model_part) post_utils.AddModelPartToModelPart( self.mixed_solid_balls_fluid_model_part, self.fluid_model_part) FEMDEM.FEMDEMCouplingUtilities().RemoveDuplicates( self.mixed_solid_fluid_model_part) self.write_dem_fem_results(time) reorder_util_elem.UndoRenumberElements()
def CalculateValue(self): Logger.PrintInfo("StrainEnergyResponse", "Starting primal analysis for response", self.identifier) startTime = timer.time() self.primal_analysis._GetSolver().Predict() self.primal_analysis._GetSolver().SolveSolutionStep() Logger.PrintInfo("StrainEnergyResponse", "Time needed for solving the primal analysis",round(timer.time() - startTime,2),"s") startTime = timer.time() value = self.response_function_utility.CalculateValue() self.primal_model_part.ProcessInfo[StructuralMechanicsApplication.RESPONSE_VALUE] = value Logger.PrintInfo("StrainEnergyResponse", "Time needed for calculating the response value",round(timer.time() - startTime,2),"s")
def Assess( self, model_part ): # in the first time step the 'old' pressure vector is created and filled stationarity = self.tool.AssessStationarity(model_part, self.tol) if stationarity: Logger.PrintInfo("SwimmingDEM", "\nThe fluid has reached a stationary state.") Logger.PrintInfo("Its calculation will be omitted from here on.\n") Logger.Flush() return stationarity
def CalculateGradient(self): Logger.PrintInfo("FaceAngleResponse", "Starting gradient calculation for response", self.identifier) for node in self.model_part.Nodes: node.SetSolutionStepValue(KM.SHAPE_SENSITIVITY, [0.0, 0.0, 0.0]) startTime = timer.time() self.response_function_utility.CalculateGradient() Logger.PrintInfo("FaceAngleResponse", "Time needed for calculating gradients", round(timer.time() - startTime, 2), "s")
def ImportApplication(application, application_name, application_folder, caller): Globals = KratosMultiphysics.KratosGlobals Kernel = Globals.Kernel main_caller = Globals.AuthorizedCaller applications_root = Globals.ApplicationsRoot # caller and main_caller are generated from the output of inspect.stack(). # In particular position [1] is the name of the file containing the call. # Note that position [0] (a frame instance) could also be used for the check, # but can return false if both calls are made from the python interpreter if main_caller[1] != caller[1]: msg = "\n***\n* Python file " + str(caller[1]) + "\n* requires " + str(application_name) + "\n* Please import it from your main Python script, " +str(main_caller[1]+'\n***') # print caller # print main_caller raise RuntimeError(msg) elif application_name not in Globals.RequestedApplications: # This check is possibly redundant, as Python won't import the same module twice Logger.PrintInfo("", "Importing " + application_name) # Add application to dictionary of registered applications Globals.RequestedApplications[application_name] = application # Add python scrips folder to path application_path = os.path.join(applications_root, application_folder) python_path = os.path.join(application_path, 'python_scripts') sys.path.append(python_path) # Add constitutive laws python scrips folder to path constitutive_laws_path = os.path.join(python_path, 'constitutive_laws') sys.path.append(constitutive_laws_path) # Add application to kernel Kernel.ImportApplication(application) # Dynamic renumbering of variables to ensure consistency Kernel.Initialize() for iterName, iterApplication in list(Globals.RequestedApplications.items()): # print("Initializing",iterName) Kernel.InitializeApplication(iterApplication)
def ExecuteInitialize(self): self.empirical_spring_element_process.ExecuteInitialize() ## add new element in the computing MP for element_i in self.custom_model_part.Elements: self.computing_model_part.AddElement(element_i, 0) Logger.PrintInfo("Initialized", "EmpiricalSpringElementProcess")
def CalculateValue(self): Logger.PrintInfo("\n> Starting primal analysis for response", self.identifier) startTime = timer.time() value = 0.0 for node in self.model_part.Nodes: shape_update = node.GetSolutionStepValue(KSO.SHAPE_UPDATE) normalized_normal = node.GetSolutionStepValue(KSO.NORMALIZED_SURFACE_NORMAL) value += shape_update[0] * normalized_normal[0] value += shape_update[1] * normalized_normal[1] value += shape_update[2] * normalized_normal[2] self.value = value + self.previous_value Logger.PrintInfo("> Time needed for calculating the response value = ", 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): Logger.PrintInfo("\n> Starting gradient calculation for response", self.identifier) startTime = timer.time() if not self.directions or not self.signed_distances: self._CalculateDistances() for i, node in enumerate(self.model_part.Nodes): gradient = self._CalculateNodalGradient( self.signed_distances[i], self.directions[i * 3:i * 3 + 3]) self.gradient[node.Id] = gradient Logger.PrintInfo("> Time needed for calculating gradients = ", round(timer.time() - startTime, 2), "s")
def ImportApplication(application, application_name, application_folder, caller, mod_path=None): KratosGlobals = KratosMultiphysics.KratosGlobals Kernel = KratosGlobals.Kernel applications_root = KratosGlobals.ApplicationsRoot Logger.PrintInfo("", "Importing " + application_name) # Add python scrips folder to path application_path = os.path.join(applications_root, application_folder) python_path = os.path.join(application_path, 'python_scripts') sys.path.append(python_path) # Add constitutive laws python scrips folder to path constitutive_laws_path = os.path.join(python_path, 'constitutive_laws') sys.path.append(constitutive_laws_path) warn_msg = '\nThe python-import-mechanism used for application "' + application_name warn_msg += '" is DEPRECATED!\n' warn_msg += 'Please check the following website for instuctions on how to update it:\n' warn_msg += 'https://github.com/KratosMultiphysics/Kratos/wiki/Applications-as-python-modules\n' warn_msg += 'The old mechanism will be removed on 01.10.2019!\n' Logger.PrintWarning('\n\x1b[1;31mDEPRECATION-WARNING\x1b[0m', warn_msg) # adding the scripts in "APP_NAME/python_scripts" such that they are treated as a regular python-module if mod_path is not None: # optional for backwards compatibility mod_path.append(python_path) # Add application to kernel Kernel.ImportApplication(application)
def ExecuteInitialize(self): self.edge_cable_element_process.ExecuteInitialize() ## add new element in the computing MP for element_i in self.edge_model_part.Elements: self.computing_model_part.AddElement(element_i, 0) Logger.PrintInfo("Initialized","EdgeCableElementProcess")
def ExecuteInitializeSolutionStep(self): self.UpdateInletPosition() Logger.PrintInfo('ImposeWindInletProcess', 'inlet position = %e' % self.inlet_position) if len(self.inlet_nodes) > 0: self.AssignVelocity() self.ApplyRamp()
def FinalizeSolutionStep(self): super().FinalizeSolutionStep() tolerance = 1.001 for node in self.spheres_model_part.Nodes: node_vel = node.GetSolutionStepValue(KratosMultiphysics.VELOCITY_Y) node_force = node.GetSolutionStepValue( KratosMultiphysics.TOTAL_FORCES_Y) if node.Id == 6: if self.time >= 1.15: Logger.PrintInfo(node_vel) Logger.PrintInfo(node_force) self.assertAlmostEqual(node_vel, 0.380489240, delta=tolerance) self.assertAlmostEqual(node_force, -120983.1002, delta=tolerance)
def CalculateValue(self): Logger.PrintInfo("\n> Starting primal analysis for response", self.identifier) startTime = timer.time() if not self.directions or not self.signed_distances: self._CalculateDistances() value = 0.0 for i in range(len(self.signed_distances)): value += self._CalculateNodalValue(self.signed_distances[i]) self.value = value Logger.PrintInfo("> Time needed for calculating the response value = ", round(timer.time() - startTime, 2), "s")
def CalculateValue(self): startTime = timer.time() value = self._GetResponseFunctionUtility().CalculateValue( self.primal_model_part) Logger.PrintInfo("> Time needed for calculating the response value = ", round(timer.time() - startTime, 2), "s") self.primal_model_part.ProcessInfo[ StructuralMechanicsApplication.RESPONSE_VALUE] = value
def Usage(): ''' Prints the usage of the script ''' lines = [ 'Usage:', '\t python kratos_run_tests [-l level] [-v verbosity]', 'Options', '\t -h, --help: Shows this command', '\t -l, --level: Minimum level of detail of the tests: \'all\'(Default) \'(nightly)\' \'(small)\' \'(validation)\'', # noqa '\t -v, --verbose: Verbosity level: 0, 1 (Default), 2', '\t --using-mpi: If running in MPI and executing the MPI-tests' ] for l in lines: Logger.PrintInfo(l) # using the logger to only print once in MPI
def ExecuteFinalizeSolutionStep(self): Logger.PrintInfo('COMPUTE MOMENT') m = KratosMultiphysics.Vector(3) for cond in self.body_model_part.Conditions: n = KratosMultiphysics.Vector( cond.GetValue(KratosMultiphysics.NORMAL) ) #normal direction assumed outward of domain cp = cond.GetValue(KratosMultiphysics.PRESSURE) mid_point = cond.GetGeometry().Center() lever = mid_point - self.reference_point m += crossProduct(lever, n * (-cp)) Cm = m[2] / self.reference_area Logger.PrintInfo('moment', m[2]) Logger.PrintInfo('Cm', Cm) Logger.PrintInfo('Mach', self.velocity_infinity[0] / 340) if self.create_output_file: with open("moment.dat", 'w') as mom_file: mom_file.write('{0:15.12f}'.format(Cm))
def Writeresults(self, time): Logger.PrintInfo("DEM-Struct", "") Logger.PrintInfo( "DEM-Struct", "******************* PRINTING RESULTS FOR GID ***************************" ) Logger.Flush() if self.GiDMultiFileFlag == "Multiples": self.mixed_model_part.Elements.clear() self.mixed_model_part.Nodes.clear() # here order is important! DEMApplication.PostUtilities().AddModelPartToModelPart( self.mixed_model_part, self.balls_model_part) DEMApplication.PostUtilities().AddModelPartToModelPart( self.mixed_model_part, self.rigid_faces_model_part) DEMApplication.PostUtilities().AddModelPartToModelPart( self.mixed_model_part, self.contact_model_part) DEMApplication.PostUtilities().AddModelPartToModelPart( self.mixed_model_part, self.structures_model_part) self.write_dem_fem_results(time)
def AddFluidFractionField(self): Logger.PrintInfo( "SwimmingDEM", '******************************************************************' ) Logger.PrintInfo() Logger.PrintInfo("SwimmingDEM", 'Adding Imposed Fluid Fraction Fields...') Logger.PrintInfo() Logger.Flush() count = 0 for field in self.field_list: count += 1 Logger.PrintInfo("SwimmingDEM", 'field number', count, ':') Logger.PrintInfo() Logger.PrintInfo("SwimmingDEM", vars(field)) Logger.PrintInfo() Logger.PrintInfo( "SwimmingDEM", '******************************************************************' ) Logger.Flush() for field in self.field_list: for node in self.fluid_model_part.Nodes: fluid_fraction = node.GetSolutionStepValue( Kratos.FLUID_FRACTION, 0) if self.CheckIsInside([node.X, node.Y, node.Z], field.low, field.high): value = fluid_fraction + field.frac_0 + field.frac_grad[ 0] * node.X + field.frac_grad[ 1] * node.Y + field.frac_grad[2] * node.Z value = min(max(value, 0.0), self.min_fluid_fraction) node.SetSolutionStepValue(Kratos.FLUID_FRACTION, 0, value)
def InitializeSolutionStep(self): # synchronize the modelparts # TODO this should happen automatically Logger.PrintInfo( "\n> Synchronize primal and adjoint modelpart for response:", self.identifier) self._SynchronizeAdjointFromPrimal() # Run the primal analysis. # TODO if primal_analysis.status==solved: return Logger.PrintInfo("\n> 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("> Time needed for solving the primal analysis = ", round(timer.time() - startTime, 2), "s") # TODO the response value calculation for stresses currently only works on the adjoint modelpart # this needs to be improved, also the response value should be calculated on the PRIMAL modelpart!! self.adjoint_analysis.time = self.adjoint_analysis._GetSolver( ).AdvanceInTime(self.adjoint_analysis.time) self.adjoint_analysis.InitializeSolutionStep()