Example #1
0
    def ExecuteInitialize(self):

        self.interval = KratosMultiphysics.Vector(2)
        self.interval[0] = self.params["interval"][0].GetDouble()
        self.interval[1] = self.params["interval"][1].GetDouble()
        self.print_drag_to_screen = self.params[
            "print_drag_to_screen"].GetBool()
        self.write_drag_output_file = self.params[
            "write_drag_output_file"].GetBool()

        if (self.write_drag_output_file):
            if (self.model_part.GetCommunicator().MyPID() == 0):

                output_file_name = self.params["model_part_name"].GetString(
                ) + "_drag.dat"

                file_handler_params = KratosMultiphysics.Parameters(
                    self.params["output_file_settings"])

                if file_handler_params.Has("file_name"):
                    warn_msg = 'Unexpected user-specified entry found in "output_file_settings": {"file_name": '
                    warn_msg += '"' + file_handler_params[
                        "file_name"].GetString() + '"}\n'
                    warn_msg += 'Using this specififed file name instead of the default "' + output_file_name + '"'
                    KratosMultiphysics.Logger.PrintWarning(
                        "ComputeDragProcess", warn_msg)
                else:
                    file_handler_params.AddEmptyValue("file_name")
                    file_handler_params["file_name"].SetString(
                        output_file_name)
                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file
    def __init__(self, model, params):
        '''Constructor of ComputeBoundaryForceProcess.'''

        super().__init__()

        default_settings = KM.Parameters("""
            {
                "model_part_wall_name"   : "",
                "model_part_bottom_name" : "",
                "interval"               : [0.0, 1e30],                
                "print_to_screen"        : false,
                "print_format"           : ".8f",
                "write_output_file"      : true,
                "output_file_settings"   : {}
            }
            """)

        self.interval = KM.IntervalUtility(params)

        params.ValidateAndAssignDefaults(default_settings)

        self.model_part_wall_name = params['model_part_wall_name'].GetString()
        self.model_part_wall = model[self.model_part_wall_name]
        self.model_part_bottom_name = params[
            'model_part_bottom_name'].GetString()
        self.model_part_bottom = model[self.model_part_bottom_name]

        self.print_to_screen = params['print_to_screen'].GetBool()
        self.write_output_file = params['write_output_file'].GetBool()
        self.print_format = params["print_format"].GetString()

        if (self.model_part_wall.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):

                default_file_name = params["model_part_wall_name"].GetString(
                ) + "_global_force.dat"

                file_handler_params = KM.Parameters(
                    params["output_file_settings"])

                if file_handler_params.Has("file_name"):
                    file_name = file_handler_params["file_name"].GetString()
                    msg = 'Unexpected user-specified entry found in "output_file_settings":\n'
                    msg += '\t"file_name" : "{}"\n'
                    msg += 'Using this specified file name instead of the default ("{}")'
                    KM.Logger.PrintWarning(
                        "ComputeBoundaryForceProcess",
                        msg.format(file_name, default_file_name))
                else:
                    file_handler_params.AddString("file_name",
                                                  default_file_name)

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part_wall, file_handler_params,
                    file_header).file
Example #3
0
    def __init__(self, Model, settings):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"           : "please_specify_model_part_name",
                "interval"                  : [0.0, 1e30],
                "reference_point"           : [0.0, 0.0, 0.0],
                "print_drag_to_screen"      : false,
                "print_format"              : ".8f",
                "write_drag_output_file"    : true,
                "output_file_settings": {}
            }
            """)

        self.settings = settings

        # Detect "End" as a tag and replace it by a large number
        if (self.settings.Has("interval")):
            if (self.settings["interval"][1].IsString()):
                if (self.settings["interval"][1].GetString() == "End"):
                    self.settings["interval"][1].SetDouble(1e30)
                else:
                    raise Exception(
                        "The second value of interval can be \"End\" or a number, interval currently:"
                        + self.settings["interval"].PrettyPrintJsonString())

        self.settings.ValidateAndAssignDefaults(default_settings)

        self.model_part = Model[self.settings["model_part_name"].GetString()]
        self.interval = KratosMultiphysics.Vector(2)
        self.interval[0] = self.settings["interval"][0].GetDouble()
        self.interval[1] = self.settings["interval"][1].GetDouble()
        self.print_drag_to_screen = self.settings[
            "print_drag_to_screen"].GetBool()
        self.write_drag_output_file = self.settings[
            "write_drag_output_file"].GetBool()

        self.format = self.settings["print_format"].GetString()

        # PMT: added reference point for moment calculation
        self.reference_x = self.settings["reference_point"][0].GetDouble()
        self.reference_y = self.settings["reference_point"][1].GetDouble()
        self.reference_z = self.settings["reference_point"][2].GetDouble()

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_drag_output_file):

                file_handler_params = KratosMultiphysics.Parameters(
                    settings["output_file_settings"])

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file
Example #4
0
    def __init__(self, model, params):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"      : "",
                "interval"             : [0.0, 1e30],
                "cfl_output_limit"     : 2.5,
                "print_to_screen"      : false,
                "print_format"         : ".8f",
                "write_output_file"    : true,
                "output_step"          : 8,
                "output_file_settings": {}
            }
            """)

        # Detect "End" as a tag and replace it by a large number
        if (params.Has("interval")):
            if (params["interval"][1].IsString()):
                if (params["interval"][1].GetString() == "End"):
                    params["interval"][1].SetDouble(1e30)
                else:
                    raise Exception(
                        "The second value of interval can be \"End\" or a number, interval currently:"
                        + params["interval"].PrettyPrintJsonString())

        params.ValidateAndAssignDefaults(default_settings)

        # getting the ModelPart from the Model
        self.model_part_name = params["model_part_name"].GetString()
        if self.model_part_name == "":
            raise Exception('No "model_part_name" was specified!')
        else:
            self.model_part = model[self.model_part_name]

        self.interval = params["interval"].GetVector()

        # getting output limit for summarization
        self.cfl_output_limit = params["cfl_output_limit"].GetDouble()

        self.format = params["print_format"].GetString()
        self.output_step = params["output_step"].GetInt()
        self.print_to_screen = params["print_to_screen"].GetBool()
        self.write_output_file = params["write_output_file"].GetBool()

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):
                file_handler_params = KratosMultiphysics.Parameters(
                    params["output_file_settings"])

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file
Example #5
0
 def ExecuteInitialize(self):
     self.response.Initialize()
     # Only rank 0 writes in MPI
     my_rank = 0
     comm = self.main_model_part.GetCommunicator().GetDataCommunicator()
     self.is_writing_rank = my_rank == comm.Rank()
     if self.is_writing_rank:
         file_handler_params = Kratos.Parameters(
             self.params["output_file_settings"])
         file_header = self.GetFileHeader()
         self.output_file = TimeBasedAsciiFileWriterUtility(
             self.main_model_part, file_handler_params, file_header).file
    def ExecuteInitialize(self):
        kratos_version = "not_given"
        if (self.output_settings["write_kratos_version"].GetBool()):
            kratos_version = str(Kratos.KratosGlobals.Kernel.Version())

        time_stamp = "not_specified"
        if (self.output_settings["write_time_stamp"].GetBool()):
            time_stamp = str(datetime.now())

        output_control_variable_name = self.output_settings[
            "output_control_variable"].GetString()

        self.output_files = []
        for variable_settings in self.variables_settings_list:
            container_name = variable_settings["container"].GetString()
            norm_type = variable_settings["norm_type"].GetString()
            method_name = variable_settings["method_name"].GetString()

            msg_header = ""
            msg_header += "# Spatial statistics process output\n"
            msg_header += "# Kratos version               : " + kratos_version + "\n"
            msg_header += "# Timestamp                    : " + time_stamp + "\n"
            msg_header += "# Method Name                  : " + method_name + "\n"
            msg_header += "# Norm type                    : " + norm_type + "\n"
            msg_header += "# Container type               : " + container_name + "\n"
            msg_header += "# Modelpart name               : " + self.model_part_name + "\n"
            msg_header += "# Output control variable name : " + output_control_variable_name + "\n"
            msg_header += "# ----------------------------------------------------------------------\n"
            msg_header += "# Headers:\n"

            output_file_settings = self.output_settings["output_file_settings"]
            output_file_name_syntax = output_file_settings[
                "file_name"].GetString()
            output_file_name = output_file_name_syntax.replace(
                "<model_part_name>", self.model_part_name)
            output_file_name = output_file_name.replace(
                "<container>", container_name)
            output_file_name = output_file_name.replace(
                "<norm_type>", norm_type)
            output_file_name = output_file_name.replace(
                "<method_name>", method_name)

            current_output_file_settings = Kratos.Parameters("""{}""")
            current_output_file_settings.AddEmptyValue("file_name")
            current_output_file_settings["file_name"].SetString(
                output_file_name)
            current_output_file_settings.AddEmptyValue("output_path")
            current_output_file_settings["output_path"].SetString(
                output_file_settings["output_path"].GetString())
            # restarting is not supported if STEP is used as the control variable
            if (self.__is_writing_process()):
                self.output_files.append(
                    TimeBasedAsciiFileWriterUtility(
                        self.__get_model_part(), current_output_file_settings,
                        msg_header))
            else:
                self.output_files.append("dummy")
Example #7
0
    def ExecuteInitialize(self):
        # getting the ModelPart from the Model
        model_part_name_list = self.params["model_part_name_list"]
        if model_part_name_list.size() == 0:
            raise Exception('No model parts are specified!')

        self.model_part_for_time = self.model[
            model_part_name_list[0].GetString()]

        # Only rank 0 writes in MPI
        my_rank = 0
        comm = self.model_part_for_time.GetCommunicator().GetDataCommunicator()
        self.is_writing_rank = my_rank == comm.Rank()
        if self.is_writing_rank:
            file_handler_params = KratosMultiphysics.Parameters(
                self.params["output_file_settings"])
            file_header = self.GetFileHeader()
            self.output_file = TimeBasedAsciiFileWriterUtility(
                self.model_part_for_time, file_handler_params,
                file_header).file
Example #8
0
 def PrintOutput(self):
     """The output file is created, filled and closed. If several output
     timesteps are specified, there will be one file for each timestep.
     """
     time = self.model_part.ProcessInfo.GetValue(KM.TIME)
     file_name = self.settings["file_name"].GetString() + "_{:.4f}.dat".format(time)
     self.out_file_params["file_name"].SetString(file_name)
     file = TimeBasedAsciiFileWriterUtility(self.model_part, self.out_file_params, self._GetHeader()).file
     for node in self.nodes:
         file.write(self._GetData(node, self._DistanceToOrigin(node)))
     file.close()
    def __SearchPoint(self):
        # retrieving the entity type
        entity_type = self.params["entity_type"].GetString()

        if entity_type == "node":
            found_id = KratosMultiphysics.BruteForcePointLocator(self.model_part).FindNode(self.point, self.search_tolerance)
            if found_id > -1:
                self.entity.append(self.model_part.Nodes[found_id]) # note that this is a find!
                self.area_coordinates.append("dummy") # needed for looping later
        elif entity_type == "element":
            self.sf_values = KratosMultiphysics.Vector()
            found_id = KratosMultiphysics.BruteForcePointLocator(self.model_part).FindElement(self.point, self.sf_values, self.search_tolerance)
            if found_id > -1:
                self.entity.append(self.model_part.Elements[found_id]) # note that this is a find!
                self.area_coordinates.append(self.sf_values)
        elif entity_type == "condition":
            self.sf_values = KratosMultiphysics.Vector()
            found_id = KratosMultiphysics.BruteForcePointLocator(self.model_part).FindCondition(self.point, self.sf_values, self.search_tolerance)
            if found_id > -1:
                self.entity.append(self.model_part.Conditions[found_id]) # note that this is a find!
                self.area_coordinates.append(self.sf_values)
        else:
            err_msg  = 'Invalid "entity_type" specified, it can only be:\n'
            err_msg += '"node", "element", "condition"'
            raise Exception(err_msg)

        # Check if a point was found, and initalize output
        # NOTE: If the search was not successful (i.e. found_id = -1), we fail silently and
        # do nothing. This is BY DESIGN, as we are supposed to work on MPI too, and the point
        # in question might lie on a different partition.
        # Here we also check if the point has been found in more than one partition
        # In such a case only one rank (the one with the larger PID) writes the output!
        my_rank = -1 # dummy to indicate that the point is not in my partition
        comm = self.model_part.GetCommunicator().GetDataCommunicator()
        if found_id > -1: # the point lies in my partition
            my_rank = comm.Rank()
        writing_rank = comm.MaxAll(my_rank) # The partition with the larger rank writes

        if my_rank == writing_rank:

            file_handler_params = KratosMultiphysics.Parameters(self.params["output_file_settings"])
            file_header = GetFileHeader(entity_type, found_id, self.point, self.output_variables[0])

            self.output_file.append(TimeBasedAsciiFileWriterUtility(
                self.model_part, file_handler_params, file_header).file)
Example #10
0
class FlowOutputProcess(KratosMultiphysics.Process):
    """This process calculates(using c++ utilities) and writes the flow through a given list of (sub)model parts.
    In 3D use a surface eg. Inlet, Outlet
    In 2D use a line eg. Inlet, Outlet

    This process works in MPI as well as with restarts
    """
    def __init__(self, model, params):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters('''{
            "help"            : "This process calculates(using c++ utilities) and writes the flow through a given list of (sub)model parts.",
            "model_part_name_list" : [],
            "print_format"      : "",
            "output_file_settings": {}
        }''')

        self.model = model
        self.params = params
        self.params.ValidateAndAssignDefaults(default_settings)
        self.output_file = None
        self.format = self.params["print_format"].GetString()

    def ExecuteInitialize(self):
        # getting the ModelPart from the Model
        model_part_name_list = self.params["model_part_name_list"]
        if model_part_name_list.size() == 0:
            raise Exception('No model parts are specified!')

        self.model_part_for_time = self.model[
            model_part_name_list[0].GetString()]

        # Only rank 0 writes in MPI
        my_rank = 0
        comm = self.model_part_for_time.GetCommunicator().GetDataCommunicator()
        self.is_writing_rank = my_rank == comm.Rank()
        if self.is_writing_rank:
            file_handler_params = KratosMultiphysics.Parameters(
                self.params["output_file_settings"])
            file_header = self.GetFileHeader()
            self.output_file = TimeBasedAsciiFileWriterUtility(
                self.model_part_for_time, file_handler_params,
                file_header).file

    def ExecuteFinalizeSolutionStep(self):
        time = self.model_part_for_time.ProcessInfo[KratosMultiphysics.TIME]
        model_part_name_list = self.params["model_part_name_list"]

        out = str(time)
        for model_part_name_param in model_part_name_list:
            model_part_name = model_part_name_param.GetString()
            model_part = self.model[model_part_name]
            flow_value = self.CalculateFlow(model_part)

            out += " " + format(flow_value, self.format)

        out += "\n"
        if self.is_writing_rank:
            self.output_file.write(out)

    def ExecuteFinalize(self):
        if self.is_writing_rank:
            self.output_file.close()

    def GetFileHeader(self):
        model_part_name_list = self.params["model_part_name_list"]
        header = '# Flow results ' + '\n'
        header += '# time '
        for model_part_name_param in model_part_name_list:
            model_part_name = model_part_name_param.GetString()
            model_part = self.model[model_part_name]
            header += model_part.Name
            header += ' '
        header += "\n"

        return header

    def CalculateFlow(self, model_part):
        flow_value = KratosCFD.FluidAuxiliaryUtilities.CalculateFlowRate(
            model_part)
        return flow_value
Example #11
0
    def ExecuteInitialize(self):
        # getting the ModelPart from the Model
        model_part_name = self.params["model_part_name"].GetString()
        if model_part_name == "":
            raise Exception('No "model_part_name" was specified!')
        self.model_part = self.model[model_part_name]

        # retrieving the position of the entity
        point_position = self.params["position"].GetVector()
        if point_position.Size() != 3:
            raise Exception(
                'The position has to be provided with 3 coordinates!')
        point = KratosMultiphysics.Point(point_position[0], point_position[1],
                                         point_position[2])

        # retrieving the output variables
        output_var_names = self.params["output_variables"]
        variable_names = [
            output_var_names[i].GetString()
            for i in range(output_var_names.size())
        ]
        output_vars = [
            KratosMultiphysics.KratosGlobals.GetVariable(var)
            for var in variable_names
        ]
        if len(output_vars) == 0:
            raise Exception('No variables specified for output!')
        self.output_variables.append(output_vars)
        # validate types of variables
        for var in self.output_variables[0]:
            if self.historical_value:
                self.__CheckVariableIsSolutionStepVariable(var)
            if type(var) == KratosMultiphysics.DoubleVariable:
                continue
            elif type(var) == KratosMultiphysics.Array1DVariable3:
                continue
            else:
                err_msg = 'Type of variable "' + var.Name(
                ) + '" is not valid\n'
                err_msg += 'It can only be double, component or array3d!'
                raise Exception(err_msg)

        # retrieving the entity type
        entity_type = self.params["entity_type"].GetString()

        if entity_type == "node":
            found_id = KratosMultiphysics.BruteForcePointLocator(
                self.model_part).FindNode(point, self.search_tolerance)
            if found_id > -1:
                self.entity.append(self.model_part.Nodes[found_id]
                                   )  # note that this is a find!
                self.area_coordinates.append(
                    "dummy")  # needed for looping later
        elif entity_type == "element":
            self.sf_values = KratosMultiphysics.Vector()
            found_id = KratosMultiphysics.BruteForcePointLocator(
                self.model_part).FindElement(point, self.sf_values,
                                             self.search_tolerance)
            if found_id > -1:
                self.entity.append(self.model_part.Elements[found_id]
                                   )  # note that this is a find!
                self.area_coordinates.append(self.sf_values)
        elif entity_type == "condition":
            self.sf_values = KratosMultiphysics.Vector()
            found_id = KratosMultiphysics.BruteForcePointLocator(
                self.model_part).FindCondition(point, self.sf_values,
                                               self.search_tolerance)
            if found_id > -1:
                self.entity.append(self.model_part.Conditions[found_id]
                                   )  # note that this is a find!
                self.area_coordinates.append(self.sf_values)
        else:
            err_msg = 'Invalid "entity_type" specified, it can only be:\n'
            err_msg += '"node", "element", "condition"'
            raise Exception(err_msg)

        # Check if a point was found, and initalize output
        # NOTE: If the search was not successful (i.e. found_id = -1), we fail silently and
        # do nothing. This is BY DESIGN, as we are supposed to work on MPI too, and the point
        # in question might lie on a different partition.
        # Here we also check if the point has been found in more than one partition
        # In sich a case only one rank (the one with the larger PID) writes the output!
        my_rank = -1  # dummy to indicate that the point is not in my partition
        comm = self.model_part.GetCommunicator().GetDataCommunicator()
        if found_id > -1:  # the point lies in my partition
            my_rank = comm.Rank()
        writing_rank = comm.MaxAll(
            my_rank)  # The partition with the larger rank writes

        if my_rank == writing_rank:

            file_handler_params = KratosMultiphysics.Parameters(
                self.params["output_file_settings"])
            file_header = GetFileHeader(entity_type, found_id, point,
                                        self.output_variables[0])
            self.output_file.append(
                TimeBasedAsciiFileWriterUtility(self.model_part,
                                                file_handler_params,
                                                file_header).file)
Example #12
0
class ResponseFunctionOutputProcess(Kratos.OutputProcess):
    def __init__(self, model, params):
        Kratos.OutputProcess.__init__(self)

        default_settings = Kratos.Parameters('''{
            "response_type"       : "PLEASE_SPECIFY_RESPONSE_TYPE",
            "model_part_name"     : "PLEASE_SPECIFY_MAIN_MODEL_PART_NAME",
            "response_settings"   : {},
            "output_file_settings": {}
        }''')

        self.model = model
        self.params = params
        self.main_model_part = self.model.GetModelPart(
            self.params["model_part_name"].GetString())
        self.params.ValidateAndAssignDefaults(default_settings)
        self.output_file = None

        response_type = self.params["response_type"].GetString()
        if (response_type == "norm_square"):
            self.response = KratosCFD.VelocityPressureNormSquareResponseFunction(
                self.params["response_settings"], self.model)
        else:
            raise Exception(
                "Unknown response_type = \"" + response_type +
                "\". Supported response types are: \n\t  1. norm_square")

    def ExecuteInitialize(self):
        self.response.Initialize()
        # Only rank 0 writes in MPI
        my_rank = 0
        comm = self.main_model_part.GetCommunicator().GetDataCommunicator()
        self.is_writing_rank = my_rank == comm.Rank()
        if self.is_writing_rank:
            file_handler_params = Kratos.Parameters(
                self.params["output_file_settings"])
            file_header = self.GetFileHeader()
            self.output_file = TimeBasedAsciiFileWriterUtility(
                self.main_model_part, file_handler_params, file_header).file

    def PrintOutput(self):
        time = self.main_model_part.ProcessInfo[Kratos.TIME]

        out = str(time)
        response_value = self.response.CalculateValue(self.main_model_part)
        out += "," + str(response_value)
        out += "\n"

        if self.is_writing_rank:
            self.output_file.write(out)

    def ExecuteFinalize(self):
        if self.is_writing_rank:
            self.output_file.close()

    def GetFileHeader(self):
        header = '# Response results ' + '\n'
        header += '# time, ResponseValue'
        header += "\n"

        return header
Example #13
0
    def __init__(self, model, params):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"      : "",
                "interval"             : [0.0, 1e30],
                "cfl_output_limit"     : 2.5,
                "print_to_screen"      : false,
                "print_format"         : ".8f",
                "write_output_file"    : true,
                "output_step"          : 8,
                "output_file_settings": {}
            }
            """)

        # Detect "End" as a tag and replace it by a large number
        if (params.Has("interval")):
            if (params["interval"][1].IsString()):
                if (params["interval"][1].GetString() == "End"):
                    params["interval"][1].SetDouble(1e30)
                else:
                    raise Exception(
                        "The second value of interval can be \"End\" or a number, interval currently:"
                        + params["interval"].PrettyPrintJsonString())

        params.ValidateAndAssignDefaults(default_settings)

        # getting the ModelPart from the Model
        self.model_part_name = params["model_part_name"].GetString()
        if self.model_part_name == "":
            raise Exception('No "model_part_name" was specified!')
        else:
            self.model_part = model[self.model_part_name]

        self.interval = params["interval"].GetVector()

        # getting output limit for summarization
        self.cfl_output_limit = params["cfl_output_limit"].GetDouble()

        # TODO: Is it ok to do this check? If not, distribution calculation is going to be messy with if conditions for
        #       case with cfl_output_limit <= 1.0
        if (self.cfl_output_limit <= 1.0):
            raise Exception("Please provide cfl_output_limit greater than 1.0")

        self.format = params["print_format"].GetString()
        self.output_step = params["output_step"].GetInt()
        self.print_to_screen = params["print_to_screen"].GetBool()
        self.write_output_file = params["write_output_file"].GetBool()

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):
                file_handler_params = KratosMultiphysics.Parameters(
                    params["output_file_settings"])

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file

        self.distribution_params = KratosMultiphysics.Parameters('''{
            "number_of_value_groups" : 1,
            "min_value"              : "min",
            "max_value"              : "max"
        }''')
        self.distribution_params["min_value"].SetDouble(
            min(self.cfl_output_limit, 1.0))
        self.distribution_params["max_value"].SetDouble(
            max(self.cfl_output_limit, 1.0))
Example #14
0
class CFLOutputProcess(KratosMultiphysics.Process):
    """
    A class responsible for the CFL output, which is an element value in Kratos.
    """
    def __init__(self, model, params):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"      : "",
                "interval"             : [0.0, 1e30],
                "cfl_output_limit"     : 2.5,
                "print_to_screen"      : false,
                "print_format"         : ".8f",
                "write_output_file"    : true,
                "output_step"          : 8,
                "output_file_settings": {}
            }
            """)

        # Detect "End" as a tag and replace it by a large number
        if (params.Has("interval")):
            if (params["interval"][1].IsString()):
                if (params["interval"][1].GetString() == "End"):
                    params["interval"][1].SetDouble(1e30)
                else:
                    raise Exception(
                        "The second value of interval can be \"End\" or a number, interval currently:"
                        + params["interval"].PrettyPrintJsonString())

        params.ValidateAndAssignDefaults(default_settings)

        # getting the ModelPart from the Model
        self.model_part_name = params["model_part_name"].GetString()
        if self.model_part_name == "":
            raise Exception('No "model_part_name" was specified!')
        else:
            self.model_part = model[self.model_part_name]

        self.interval = params["interval"].GetVector()

        # getting output limit for summarization
        self.cfl_output_limit = params["cfl_output_limit"].GetDouble()

        # TODO: Is it ok to do this check? If not, distribution calculation is going to be messy with if conditions for
        #       case with cfl_output_limit <= 1.0
        if (self.cfl_output_limit <= 1.0):
            raise Exception("Please provide cfl_output_limit greater than 1.0")

        self.format = params["print_format"].GetString()
        self.output_step = params["output_step"].GetInt()
        self.print_to_screen = params["print_to_screen"].GetBool()
        self.write_output_file = params["write_output_file"].GetBool()

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):
                file_handler_params = KratosMultiphysics.Parameters(
                    params["output_file_settings"])

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file

        self.distribution_params = KratosMultiphysics.Parameters('''{
            "number_of_value_groups" : 1,
            "min_value"              : "min",
            "max_value"              : "max"
        }''')
        self.distribution_params["min_value"].SetDouble(
            min(self.cfl_output_limit, 1.0))
        self.distribution_params["max_value"].SetDouble(
            max(self.cfl_output_limit, 1.0))

    def ExecuteFinalizeSolutionStep(self):

        current_time = self.model_part.ProcessInfo[KratosMultiphysics.TIME]
        current_step = self.model_part.ProcessInfo[KratosMultiphysics.STEP]

        if ((current_time >= self.interval[0]) and
            (current_time < self.interval[1])) and (current_step %
                                                    self.output_step == 0):
            self._EvaluateCFL()
            output = self._CalculateWithRespectToThreshold()

            if (self.model_part.GetCommunicator().MyPID() == 0):
                output_vals = [format(val, self.format) for val in output]

                # not formatting time in order to not lead to problems with time recognition
                # in the file writer when restarting
                output_vals.insert(0, str(current_time))

                res_labels = [
                    "time: ", "mean: ", "std: ", "max: ",
                    "cfl" + "{:.1f}".format(self.cfl_output_limit) + ": ",
                    "cfl1.0: "
                ]

                if (self.print_to_screen):

                    result_msg = 'CFL evaluation for model part ' + \
                        self.model_part_name + '\n'
                    result_msg += ', '.join(
                        [a + b for a, b in zip(res_labels, output_vals)])
                    self._PrintToScreen(result_msg)

                if (self.write_output_file):
                    self.output_file.write(' '.join(output_vals) + "\n")

    def ExecuteFinalize(self):
        if (self.model_part.GetCommunicator().MyPID() == 0):
            self.output_file.close()

    def _GetFileHeader(self):
        header = '# CFL for model part ' + self.model_part_name + \
            '| CFL_threshold: ' + str(self.cfl_output_limit) + '\n'
        header += '# Time Mean Std Max HowMany>' + \
            "{:.1f}".format(self.cfl_output_limit) + ' [%] HowMany>1.0 [%]\n'
        return header

    def _PrintToScreen(self, result_msg):
        KratosMultiphysics.Logger.PrintInfo("CFLOutputProcess",
                                            "CFL VALUE RESULTS:")
        KratosMultiphysics.Logger.PrintInfo("CFLOutputProcess",
                                            "Current time: " + result_msg)

    def _CalculateWithRespectToThreshold(self):
        current_container = spatial_methods.NonHistorical.Elements.NormMethods

        _, _, _, group_histogram, group_percentage_distribution, group_means, group_variances = current_container.Distribution(
            self.model_part, KratosMultiphysics.CFL_NUMBER, "value",
            self.distribution_params)

        # % of element with cfl above threshold
        how_many = group_percentage_distribution[-1] * 100.0
        # % of element with cfl above 1
        how_many1 = (1.0 - group_percentage_distribution[0]) * 100.0

        # quantifying the mean and std for values below the threshold
        total_elements_in_threshold_range = group_histogram[
            0] + group_histogram[1]
        if (total_elements_in_threshold_range > 0):
            y_mean = (group_means[0] * group_histogram[0] + group_means[1] *
                      group_histogram[1]) / total_elements_in_threshold_range

            threshold_sum_squared = (group_variances[0] + pow(
                group_means[0], 2)) * group_histogram[0] + (
                    group_variances[1] +
                    pow(group_means[1], 2)) * group_histogram[1]
            y_std = sqrt((threshold_sum_squared -
                          total_elements_in_threshold_range * pow(y_mean, 2)) /
                         (total_elements_in_threshold_range - 1.0))
        else:
            y_mean = 0.0
            y_std = 0.0

        # qunatifying the global max
        # TODO: @Mate, where should we put the id of the element, where max is (second bland output argument is max_id)?
        x_max, _ = current_container.Max(self.model_part,
                                         KratosMultiphysics.CFL_NUMBER,
                                         "value")
        return [y_mean, y_std, x_max, how_many, how_many1]

    def _EvaluateCFL(self):
        if (self.model_part.ProcessInfo[KratosMultiphysics.DOMAIN_SIZE] == 2):
            KratosCFD.EstimateDtUtility2D.CalculateLocalCFL(self.model_part)
        else:
            KratosCFD.EstimateDtUtility3D.CalculateLocalCFL(self.model_part)
Example #15
0
    def __init__(self, Model, params):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"       : "",
                "interval"              : [0.0, 1e30],
                "reference_point"       : [0.0,0.0,0.0],
                "z_rotation_angle"      : 0.0,
                "print_to_screen"       : false,
                "print_format"          : ".8f",
                "write_output_file"     : true,
                "output_file_settings"  : {}
            }
            """)

        # Detect 'End' as a tag and replace it by a large number
        if (params.Has('interval')):
            if (params['interval'][1].IsString()):
                if (params['interval'][1].GetString() == 'End'):
                    params['interval'][1].SetDouble(1e30)
                else:
                    raise Exception(
                        'The second value of interval can be \'End\' or a number, interval currently:'
                        + params['interval'].PrettyPrintJsonString())

        params.ValidateAndAssignDefaults(default_settings)

        self.model_part_name = params['model_part_name'].GetString()
        self.model_part = Model[self.model_part_name]
        self.interval = params["interval"].GetVector()
        self.print_to_screen = params['print_to_screen'].GetBool()
        self.write_output_file = params['write_output_file'].GetBool()
        self.format = params["print_format"].GetString()

        # added reference point for moment calculation
        self.reference = params['reference_point'].GetVector()
        if self.reference.Size() != 3:
            raise Exception(
                'The reference point position has to be provided with 3 coordinates!'
            )

        # user inpput expected in degrees, here changing to radians
        self.theta = math.radians(params['z_rotation_angle'].GetDouble())

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):

                output_file_name = params["model_part_name"].GetString(
                ) + "_global_force.dat"

                file_handler_params = KratosMultiphysics.Parameters(
                    params["output_file_settings"])

                if file_handler_params.Has("file_name"):
                    warn_msg = 'Unexpected user-specified entry found in "output_file_settings": {"file_name": '
                    warn_msg += '"' + \
                        file_handler_params["file_name"].GetString() + '"}\n'
                    warn_msg += 'Using this specififed file name instead of the default "' + \
                        output_file_name + '"'
                    KratosMultiphysics.Logger.PrintWarning(
                        "ComputeGlobalForceProcess", warn_msg)
                else:
                    file_handler_params.AddEmptyValue("file_name")
                    file_handler_params["file_name"].SetString(
                        output_file_name)

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file
Example #16
0
class CFLOutputProcess(KratosMultiphysics.Process):
    """
    A class responsible for the CFL output, which is an element value in Kratos.
    """
    def __init__(self, model, params):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"      : "",
                "interval"             : [0.0, 1e30],
                "cfl_output_limit"     : 2.5,
                "print_to_screen"      : false,
                "print_format"         : ".8f",
                "write_output_file"    : true,
                "output_step"          : 8,
                "output_file_settings": {}
            }
            """)

        # Detect "End" as a tag and replace it by a large number
        if (params.Has("interval")):
            if (params["interval"][1].IsString()):
                if (params["interval"][1].GetString() == "End"):
                    params["interval"][1].SetDouble(1e30)
                else:
                    raise Exception(
                        "The second value of interval can be \"End\" or a number, interval currently:"
                        + params["interval"].PrettyPrintJsonString())

        params.ValidateAndAssignDefaults(default_settings)

        # getting the ModelPart from the Model
        self.model_part_name = params["model_part_name"].GetString()
        if self.model_part_name == "":
            raise Exception('No "model_part_name" was specified!')
        else:
            self.model_part = model[self.model_part_name]

        self.interval = params["interval"].GetVector()

        # getting output limit for summarization
        self.cfl_output_limit = params["cfl_output_limit"].GetDouble()

        self.format = params["print_format"].GetString()
        self.output_step = params["output_step"].GetInt()
        self.print_to_screen = params["print_to_screen"].GetBool()
        self.write_output_file = params["write_output_file"].GetBool()

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):
                file_handler_params = KratosMultiphysics.Parameters(
                    params["output_file_settings"])

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file

    def ExecuteFinalizeSolutionStep(self):

        current_time = self.model_part.ProcessInfo[KratosMultiphysics.TIME]
        current_step = self.model_part.ProcessInfo[KratosMultiphysics.STEP]

        if ((current_time >= self.interval[0]) and
            (current_time < self.interval[1])) and (current_step %
                                                    self.output_step == 0):
            cfl_value = self._EvaluateCFL()

            if (self.model_part.GetCommunicator().MyPID() == 0):
                output = self._SummarizeCFL(cfl_value)
                output_vals = [format(val, self.format) for val in output]

                # not formatting time in order to not lead to problems with time recognition
                # in the file writer when restarting
                output_vals.insert(0, str(current_time))

                res_labels = [
                    "time: ", "mean: ", "std: ", "max: ",
                    "cfl" + "{:.1f}".format(self.cfl_output_limit) + ": ",
                    "cfl1.0: "
                ]

                if (self.print_to_screen):

                    result_msg = 'CFL evaluation for model part ' + \
                        self.model_part_name + '\n'
                    result_msg += ', '.join(
                        [a + b for a, b in zip(res_labels, output_vals)])
                    self._PrintToScreen(result_msg)

                if (self.write_output_file):
                    self.output_file.write(' '.join(output_vals) + "\n")

    def ExecuteFinalize(self):
        if (self.model_part.GetCommunicator().MyPID() == 0):
            self.output_file.close()

    def _GetFileHeader(self):
        header = '# CFL for model part ' + self.model_part_name + \
            '| CFL_threshold: ' + str(self.cfl_output_limit) + '\n'
        header += '# Time Mean Std Max HowMany>' + \
            "{:.1f}".format(self.cfl_output_limit) + ' [%] HowMany>1.0 [%]\n'
        return header

    def _PrintToScreen(self, result_msg):
        KratosMultiphysics.Logger.PrintInfo("CFLOutputProcess",
                                            "CFL VALUE RESULTS:")
        KratosMultiphysics.Logger.PrintInfo("CFLOutputProcess",
                                            "Current time: " + result_msg)

    def _CalculateWithRespectToThreshold(self, x):

        y = [val for val in x if val < self.cfl_output_limit]
        y1 = [val for val in x if val < 1.0]
        # % of element with cfl above threshold
        how_many = ((len(x) - len(y)) / len(x)) * 100
        # % of element with cfl above 1
        how_many1 = ((len(x) - len(y1)) / len(x)) * 100

        # quantifying the mean and std for values below the threshold
        y_mean = mean(y)
        y_std = stdev(y)

        # qunatifying the global max
        x_max = max(x)
        return [y_mean, y_std, x_max, how_many, how_many1]

    def _EvaluateCFL(self):

        if (self.model_part.ProcessInfo[KratosMultiphysics.DOMAIN_SIZE] == 2):
            KratosCFD.EstimateDtUtility2D.CalculateLocalCFL(self.model_part)
        else:
            KratosCFD.EstimateDtUtility3D.CalculateLocalCFL(self.model_part)

        local_cfl = []
        for elem in self.model_part.Elements:
            local_cfl.append(elem.GetValue(KratosMultiphysics.CFL_NUMBER))

        local_cfl = self.model_part.GetCommunicator().GetDataCommunicator(
        ).GathervDoubles(local_cfl, 0)

        return local_cfl

    def _SummarizeCFL(self, local_cfl):

        global_cfl = []
        for k in local_cfl:
            global_cfl.extend(k)

        cfl_mean, cfl_std, cfl_max, cfl_how_many, cfl_how_many1 = self._CalculateWithRespectToThreshold(
            global_cfl)

        return [cfl_mean, cfl_std, cfl_max, cfl_how_many, cfl_how_many1]
Example #17
0
class ComputeDragProcess(KratosMultiphysics.Process):
    """
    Auxiliary base class to output total flow forces
    over obstacles in fluid dynamics problems.
    A derived class needs to be implemented to be able to use
    this functionality, as calling the base class alone is not enough.
    """
    def __init__(self, model, params):
        """
        Auxiliary class to output total flow forces over obstacles
        in fluid dynamics problems for a body fitted model part.
        """
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"           : "",
                "interval"                  : [0.0, 1e30],
                "print_drag_to_screen"      : false,
                "print_format"              : ".8f",
                "write_drag_output_file"    : true,
                "output_file_settings": {}
            }
            """)

        self.params = params
        # Detect "End" as a tag and replace it by a large number
        if (self.params.Has("interval")):
            if (self.params["interval"][1].IsString()):
                if (self.params["interval"][1].GetString() == "End"):
                    self.params["interval"][1].SetDouble(1e30)
                else:
                    raise Exception(
                        "The second value of interval can be \"End\" or a number, interval currently:"
                        + self.params["interval"].PrettyPrintJsonString())

        self.params.ValidateAndAssignDefaults(default_settings)

        self.format = self.params["print_format"].GetString()

        # getting the ModelPart from the Model
        model_part_name = self.params["model_part_name"].GetString()
        if model_part_name == "":
            raise Exception('No "model_part_name" was specified!')
        else:
            self.model_part = model[self.params["model_part_name"].GetString()]

    def ExecuteInitialize(self):

        self.interval = KratosMultiphysics.Vector(2)
        self.interval[0] = self.params["interval"][0].GetDouble()
        self.interval[1] = self.params["interval"][1].GetDouble()
        self.print_drag_to_screen = self.params[
            "print_drag_to_screen"].GetBool()
        self.write_drag_output_file = self.params[
            "write_drag_output_file"].GetBool()

        if (self.write_drag_output_file):
            if (self.model_part.GetCommunicator().MyPID() == 0):

                output_file_name = self.params["model_part_name"].GetString(
                ) + "_drag.dat"

                file_handler_params = KratosMultiphysics.Parameters(
                    self.params["output_file_settings"])

                if file_handler_params.Has("file_name"):
                    warn_msg = 'Unexpected user-specified entry found in "output_file_settings": {"file_name": '
                    warn_msg += '"' + file_handler_params[
                        "file_name"].GetString() + '"}\n'
                    warn_msg += 'Using this specififed file name instead of the default "' + output_file_name + '"'
                    KratosMultiphysics.Logger.PrintWarning(
                        "ComputeDragProcess", warn_msg)
                else:
                    file_handler_params.AddEmptyValue("file_name")
                    file_handler_params["file_name"].SetString(
                        output_file_name)
                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file

    def ExecuteFinalizeSolutionStep(self):
        current_step = self.model_part.ProcessInfo[KratosMultiphysics.STEP]
        current_time = self.model_part.ProcessInfo[KratosMultiphysics.TIME]

        if (((current_time >= self.interval[0]) and
             (current_time < self.interval[1]))
                and (current_step + 1 >= self.model_part.GetBufferSize())):
            # Compute the drag force
            drag_force = self._GetCorrespondingDragForce()

            # Write the drag force values
            if (self.model_part.GetCommunicator().MyPID() == 0):
                if (self.print_drag_to_screen):
                    result_msg = str(current_time) + " x-drag: " + format(
                        drag_force[0], self.format) + " y-drag: " + format(
                            drag_force[1], self.format) + " z-drag: " + format(
                                drag_force[2], self.format)
                    self._PrintToScreen(result_msg)

                # not formatting time in order to not lead to problems with time recognition
                # in the file writer when restarting
                if (self.write_drag_output_file):
                    self.output_file.write(
                        str(current_time) + " " +
                        format(drag_force[0], self.format) + " " +
                        format(drag_force[1], self.format) + " " +
                        format(drag_force[2], self.format) + "\n")

    def ExecuteFinalize(self):
        if (self.write_drag_output_file):
            if (self.model_part.GetCommunicator().MyPID() == 0):
                self.output_file.close()

    def _GetFileHeader(self):
        err_msg = 'ComputeDragProcess: _GetFileHeader called in base class\n'
        err_msg += 'this needs to be implemented and called from derived class'
        raise Exception(err_msg)

    def _PrintToScreen(self, result_msg):
        err_msg = 'ComputeDragProcess: _PrinToScreen called in base class\n'
        err_msg += 'this needs to be implemented and called from derived class'
        raise Exception(err_msg)

    def _GetCorrespondingDragForce(self):
        err_msg = 'ComputeDragProcess: _GetCorrespondingDragForce called in base class\n'
        err_msg += 'this needs to be implemented and called from derived class'
        raise Exception(err_msg)
Example #18
0
    def __init__(self, Model, params):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"       : "",
                "interval"              : [0.0, 1e30],
                "rampup_time"           : 0.0,
                "reference_point"       : [0.0,0.0,0.0],
                "z_rotation_angle"      : 0.0,
                "imposed_motion":{
                    "pitch": {"amplitude": [0.1], "frequency" : [1.2]},
                    "heave": {"amplitude": [0.02, 0.03], "frequency" : [0.9, 1.1]}
                },
                "print_to_screen"       : false,
                "print_format"          : ".8f",
                "write_output_file"     : true,
                "output_file_settings"  : {}
            }
            """)

        # Detect 'End' as a tag and replace it by a large number
        if (params.Has('interval')):
            if (params['interval'][1].IsString()):
                if (params['interval'][1].GetString() == 'End'):
                    params['interval'][1].SetDouble(1e30)
                else:
                    raise Exception(
                        'The second value of interval can be \'End\' or a number, interval currently:'
                        + params['interval'].PrettyPrintJsonString())

        params.ValidateAndAssignDefaults(default_settings)

        # modal part params
        self.model_part_name = params['model_part_name'].GetString()
        self.model_part = Model[self.model_part_name]
        self.interval = params["interval"].GetVector()
        self.print_to_screen = params['print_to_screen'].GetBool()
        self.write_output_file = params['write_output_file'].GetBool()
        self.format = params["print_format"].GetString()
        self.rampup_time = params['rampup_time'].GetDouble()

        # added reference point for moment calculation
        reference = params['reference_point'].GetVector()
        if reference.Size() != 3:
            raise Exception(
                'The reference point position has to be provided with 3 coordinates!'
            )
        self.reference_center = reference
        self.updated_center = reference

        # user inpput expected in degrees, here changing to radians
        self.reference_theta = math.radians(
            params['z_rotation_angle'].GetDouble())
        self.updated_theta = self.reference_theta

        self.motion_increment = {"pitch": 0.0, "heave": 0.0}
        self.prescribed_motion = {
            "pitch": {
                "amplitude":
                params['imposed_motion']['pitch']['amplitude'].GetVector(),
                "frequency":
                params['imposed_motion']['pitch']['frequency'].GetVector()
            },
            "heave": {
                "amplitude":
                params['imposed_motion']['heave']['amplitude'].GetVector(),
                "frequency":
                params['imposed_motion']['heave']['frequency'].GetVector()
            }
        }

        self.prescribed_motion['pitch']['amplitude'] = [
            math.radians(a)
            for a in self.prescribed_motion['pitch']['amplitude']
        ]

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):

                # default name as fallback
                output_file_name = params["model_part_name"].GetString()

                file_handler_params = KratosMultiphysics.Parameters(
                    params["output_file_settings"])

                self.output_file = {}
                for case in ['motion', 'force']:
                    case_file_handler_params = file_handler_params.Clone()

                    if file_handler_params.Has("file_name"):
                        output_file_name = file_handler_params[
                            "file_name"].GetString()
                        warn_msg = 'Unexpected user-specified entry found in "output_file_settings": {"file_name": '
                        warn_msg += '"' + \
                            file_handler_params["file_name"].GetString(
                            ) + '"}\n'
                        warn_msg += 'Using this specififed file name instead of the default "' + \
                            output_file_name + '"'
                        KratosMultiphysics.Logger.PrintWarning(
                            "SetMeshMotionAndGetForcesProcess", warn_msg)
                    else:
                        case_file_handler_params.AddEmptyValue("file_name")

                    case_file_handler_params["file_name"].SetString(
                        output_file_name + '_' + case + '.dat')

                    file_header = self._GetFileHeader(case)
                    self.output_file[case] = TimeBasedAsciiFileWriterUtility(
                        self.model_part, case_file_handler_params,
                        file_header).file
Example #19
0
class ComputeCustomBaseReactionProcess(KratosMultiphysics.Process):
    def __init__(self, Model, settings):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"           : "please_specify_model_part_name",
                "interval"                  : [0.0, 1e30],
                "reference_point"           : [0.0, 0.0, 0.0],
                "print_drag_to_screen"      : false,
                "print_format"              : ".8f",
                "write_drag_output_file"    : true,
                "output_file_settings": {}
            }
            """)

        self.settings = settings

        # Detect "End" as a tag and replace it by a large number
        if (self.settings.Has("interval")):
            if (self.settings["interval"][1].IsString()):
                if (self.settings["interval"][1].GetString() == "End"):
                    self.settings["interval"][1].SetDouble(1e30)
                else:
                    raise Exception(
                        "The second value of interval can be \"End\" or a number, interval currently:"
                        + self.settings["interval"].PrettyPrintJsonString())

        self.settings.ValidateAndAssignDefaults(default_settings)

        self.model_part = Model[self.settings["model_part_name"].GetString()]
        self.interval = KratosMultiphysics.Vector(2)
        self.interval[0] = self.settings["interval"][0].GetDouble()
        self.interval[1] = self.settings["interval"][1].GetDouble()
        self.print_drag_to_screen = self.settings[
            "print_drag_to_screen"].GetBool()
        self.write_drag_output_file = self.settings[
            "write_drag_output_file"].GetBool()

        self.format = self.settings["print_format"].GetString()

        # PMT: added reference point for moment calculation
        self.reference_x = self.settings["reference_point"][0].GetDouble()
        self.reference_y = self.settings["reference_point"][1].GetDouble()
        self.reference_z = self.settings["reference_point"][2].GetDouble()

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_drag_output_file):

                file_handler_params = KratosMultiphysics.Parameters(
                    settings["output_file_settings"])

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file

    def ExecuteFinalizeSolutionStep(self):

        current_time = self.model_part.ProcessInfo[KratosMultiphysics.TIME]

        if ((current_time >= self.interval[0])
                and (current_time < self.interval[1])):

            # Note that MPI communication is done within VariableUtils().SumHistoricalNodeVectorVariable()
            #reaction_vector = KratosMultiphysics.VariableUtils().SumHistoricalNodeVectorVariable(KratosMultiphysics.REACTION, self.model_part, 0)

            # PMT: TODO: only checked for OpenMP, update for MPI
            fx = 0.0
            fy = 0.0
            fz = 0.0

            mx = 0.0
            my = 0.0
            mz = 0.0

            for node in self.model_part.Nodes:
                reaction = node.GetSolutionStepValue(
                    KratosMultiphysics.REACTION, 0)
                moment_reaction = node.GetSolutionStepValue(
                    KratosMultiphysics.REACTION_MOMENT, 0)

                # PMT: NOTE: sign is flipped to go from reaction to action
                fx += (1) * reaction[0]
                fy += (1) * reaction[1]
                fz += (1) * reaction[2]

                x = node.X - self.reference_x
                y = node.Y - self.reference_y
                z = node.Z - self.reference_z
                mx += y * (1) * reaction[2] - z * (1) * reaction[1] + (
                    1) * moment_reaction[0]
                my += z * (1) * reaction[0] - x * (1) * reaction[2] + (
                    1) * moment_reaction[1]
                mz += x * (1) * reaction[1] - y * (1) * reaction[0] + (
                    1) * moment_reaction[2]

            if (self.model_part.GetCommunicator().MyPID() == 0):

                if (self.print_drag_to_screen):
                    print("CUSTOM BASE REACTION RESULTS:")
                    print("Current time: " + str(current_time))
                    print("Forces:" + " Fx: " + str(fx) + " Fy: " + str(fy) +
                          " Fz: " + str(fz))
                    print("Moments:" + " Mx: " + str(mx) + " My: " + str(my) +
                          " Mz: " + str(mz))

                if (self.write_drag_output_file):
                    #     with open(self.drag_filename, 'a') as file:
                    #         output_str = str(current_time)
                    #         output_str += "   " + str(fx) + "   " + str(fy) + "   " + str(fz)
                    #         output_str += "   " + str(mx) + "   " + str(my) + "   " + str(mz) + "\n"
                    #         file.write(output_str)
                    #         file.close()

                    # if (self.write_output_file):
                    # output_str = str(current_time)
                    # output_str += "   " + format(fx, self.format) + "   " + format(fy, self.format) + "   " + format(fz, self.format)
                    # output_str += "   " + format(mx, self.format) + "   " + format(my, self.format) + "   " + format(mz, self.format) + "\n"

                    output_str = str(current_time)
                    output_str += "   " + str(fx) + "   " + str(
                        fy) + "   " + str(fz)
                    output_str += "   " + str(mx) + "   " + str(
                        my) + "   " + str(mz) + "\n"

                    self.output_file.write(output_str)

                    # self.output_file.write(str(current_time)+" "+format(integral_value[0], self.format)+" "+format(
                    #     integral_value[1], self.format)+" "+format(integral_value[2], self.format)+"\n")

    def _GetFileHeader(self):
        header = '# Integral value for model part ' + self.settings[
            "model_part_name"].GetString(
            ) + ' ' + 'at reference point X = ' + str(
                self.reference_x) + ', Y = ' + str(
                    self.reference_y) + ', Z = ' + str(self.reference_z) + '\n'
        header += '# Time Fx: Fy: Fz: Mx: My: Mz:\n'
        return header

    def ExecuteFinalize(self):
        if (self.model_part.GetCommunicator().MyPID() == 0):
            self.output_file.close()
Example #20
0
class ComputeGlobalForceProcess(KratosMultiphysics.Process):
    '''
    Computes the flow- and body-attached forces 
    for a the whole model part with body-fitted mesh
    thus the naming GlobalForces

    Takes as input a CCW positive (in degrees) rotation around
    axis z for the body-attached forces
    '''
    def __init__(self, Model, params):
        KratosMultiphysics.Process.__init__(self)

        default_settings = KratosMultiphysics.Parameters("""
            {
                "model_part_name"       : "",
                "interval"              : [0.0, 1e30],
                "reference_point"       : [0.0,0.0,0.0],
                "z_rotation_angle"      : 0.0,
                "print_to_screen"       : false,
                "print_format"          : ".8f",
                "write_output_file"     : true,
                "output_file_settings"  : {}
            }
            """)

        # Detect 'End' as a tag and replace it by a large number
        if (params.Has('interval')):
            if (params['interval'][1].IsString()):
                if (params['interval'][1].GetString() == 'End'):
                    params['interval'][1].SetDouble(1e30)
                else:
                    raise Exception(
                        'The second value of interval can be \'End\' or a number, interval currently:'
                        + params['interval'].PrettyPrintJsonString())

        params.ValidateAndAssignDefaults(default_settings)

        self.model_part_name = params['model_part_name'].GetString()
        self.model_part = Model[self.model_part_name]
        self.interval = params["interval"].GetVector()
        self.print_to_screen = params['print_to_screen'].GetBool()
        self.write_output_file = params['write_output_file'].GetBool()
        self.format = params["print_format"].GetString()

        # added reference point for moment calculation
        self.reference = params['reference_point'].GetVector()
        if self.reference.Size() != 3:
            raise Exception(
                'The reference point position has to be provided with 3 coordinates!'
            )

        # user inpput expected in degrees, here changing to radians
        self.theta = math.radians(params['z_rotation_angle'].GetDouble())

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):

                output_file_name = params["model_part_name"].GetString(
                ) + "_global_force.dat"

                file_handler_params = KratosMultiphysics.Parameters(
                    params["output_file_settings"])

                if file_handler_params.Has("file_name"):
                    warn_msg = 'Unexpected user-specified entry found in "output_file_settings": {"file_name": '
                    warn_msg += '"' + \
                        file_handler_params["file_name"].GetString() + '"}\n'
                    warn_msg += 'Using this specififed file name instead of the default "' + \
                        output_file_name + '"'
                    KratosMultiphysics.Logger.PrintWarning(
                        "ComputeGlobalForceProcess", warn_msg)
                else:
                    file_handler_params.AddEmptyValue("file_name")
                    file_handler_params["file_name"].SetString(
                        output_file_name)

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part, file_handler_params, file_header).file

    def ExecuteFinalizeSolutionStep(self):

        current_time = self.model_part.ProcessInfo[KratosMultiphysics.TIME]

        if ((current_time >= self.interval[0])
                and (current_time < self.interval[1])):
            ff, mf, fb, mb = self._EvaluateGlobalForces()

            if (self.model_part.GetCommunicator().MyPID() == 0):
                output = []
                output.extend(ff)
                output.extend(mf)
                output.extend(fb)
                output.extend(mb)

                output_vals = [format(val, self.format) for val in output]
                # not formatting time in order to not lead to problems with time recognition
                # in the file writer when restarting
                output_vals.insert(0, str(current_time))

                res_labels = [
                    'time: ', 'fx: ', 'fy: ', 'fz: ', 'mx: ', 'my: ', 'mz: ',
                    'fx\': ', 'fy\': ', 'fz\': ', 'mx\': ', 'my\': ', 'mz\': '
                ]

                if (self.print_to_screen):
                    result_msg = 'Global force evaluation for model part ' + \
                        self.model_part_name + '\n'
                    result_msg += ', '.join(
                        [a + b for a, b in zip(res_labels, output_vals)])
                    self._PrintToScreen(result_msg)
                    sys.stdout.flush()

                if (self.write_output_file):
                    self.output_file.write(' '.join(output_vals) + '\n')

    def _EvaluateGlobalForces(self):
        # flow-attached forces: in x-y-z coordinate system
        ff = [0.0, 0.0, 0.0]
        mf = [0.0, 0.0, 0.0]

        for node in self.model_part.GetCommunicator().LocalMesh().Nodes:
            # sign is flipped to go from reaction to action -> force
            nodal_force = (-1) * node.GetSolutionStepValue(
                KratosMultiphysics.REACTION, 0)

            # summing up nodal contributions to get resultant for model_part
            ff[0] += nodal_force[0]
            ff[1] += nodal_force[1]
            ff[2] += nodal_force[2]

            x = node.X - self.reference[0]
            y = node.Y - self.reference[1]
            z = node.Z - self.reference[2]
            mf[0] += y * nodal_force[2] - z * nodal_force[1]
            mf[1] += z * nodal_force[0] - x * nodal_force[2]
            mf[2] += x * nodal_force[1] - y * nodal_force[0]

        # body-attached forces -> here only a rotation around z-axis
        # in x'-y'-z' coordinate system
        # of the summed-up forces and moment

        fb = ccw_rotate_comp_around_z(ff, self.theta)
        mb = ccw_rotate_comp_around_z(mf, self.theta)

        ff = self.model_part.GetCommunicator().GetDataCommunicator(
        ).SumDoubles(ff, 0)
        mf = self.model_part.GetCommunicator().GetDataCommunicator(
        ).SumDoubles(mf, 0)

        fb = self.model_part.GetCommunicator().GetDataCommunicator(
        ).SumDoubles(fb, 0)
        mb = self.model_part.GetCommunicator().GetDataCommunicator(
        ).SumDoubles(mb, 0)

        return ff, mf, fb, mb

    def _GetFileHeader(self):
        header = '# Global force for model part ' + self.model_part_name + '\n'
        header += '# Time Fx Fy Fz Mx My Mz Fx\' Fy\' Fz\' Mx\' My\' Mz\'\n'
        return header

    def _PrintToScreen(self, result_msg):
        KratosMultiphysics.Logger.PrintInfo(
            'ComputeGlobalForceProcess',
            'Global force results - flow- and body-attached:')
        KratosMultiphysics.Logger.PrintInfo('ComputeGlobalForceProcess',
                                            'Current time: ' + result_msg)
class ComputeBoundaryForceProcess(KM.Process):
    '''
    Get the external accelerations and computes the hydrostatic forces.
    The results are written in a file or printed into screen.
    '''
    def __init__(self, model, params):
        '''Constructor of ComputeBoundaryForceProcess.'''

        super().__init__()

        default_settings = KM.Parameters("""
            {
                "model_part_wall_name"   : "",
                "model_part_bottom_name" : "",
                "interval"               : [0.0, 1e30],                
                "print_to_screen"        : false,
                "print_format"           : ".8f",
                "write_output_file"      : true,
                "output_file_settings"   : {}
            }
            """)

        self.interval = KM.IntervalUtility(params)

        params.ValidateAndAssignDefaults(default_settings)

        self.model_part_wall_name = params['model_part_wall_name'].GetString()
        self.model_part_wall = model[self.model_part_wall_name]
        self.model_part_bottom_name = params[
            'model_part_bottom_name'].GetString()
        self.model_part_bottom = model[self.model_part_bottom_name]

        self.print_to_screen = params['print_to_screen'].GetBool()
        self.write_output_file = params['write_output_file'].GetBool()
        self.print_format = params["print_format"].GetString()

        if (self.model_part_wall.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):

                default_file_name = params["model_part_wall_name"].GetString(
                ) + "_global_force.dat"

                file_handler_params = KM.Parameters(
                    params["output_file_settings"])

                if file_handler_params.Has("file_name"):
                    file_name = file_handler_params["file_name"].GetString()
                    msg = 'Unexpected user-specified entry found in "output_file_settings":\n'
                    msg += '\t"file_name" : "{}"\n'
                    msg += 'Using this specified file name instead of the default ("{}")'
                    KM.Logger.PrintWarning(
                        "ComputeBoundaryForceProcess",
                        msg.format(file_name, default_file_name))
                else:
                    file_handler_params.AddString("file_name",
                                                  default_file_name)

                file_header = self._GetFileHeader()
                self.output_file = TimeBasedAsciiFileWriterUtility(
                    self.model_part_wall, file_handler_params,
                    file_header).file

    def ExecuteFinalizeSolutionStep(self):
        '''Print the boundary forces to a file or into screen.'''

        current_time = self.model_part_wall.ProcessInfo[KM.TIME]

        if self.interval.IsInInterval(current_time):
            accelerations, forces = self._EvaluateGlobalForces()

            if self.model_part_wall.GetCommunicator().MyPID() == 0:

                output_values = []
                # not formatting time in order to not lead to problems with time recognition
                # in the file writer when restarting
                output_values.append(str(current_time))
                for val in accelerations:
                    output_values.append(format(val, self.print_format))
                for val in forces:
                    output_values.append(format(val, self.print_format))

                if self.print_to_screen:
                    result_msg = 'Global force evaluation for model part ' + \
                        self.model_part_wall_name + '\n'
                    res_labels = [
                        'time: ', 'acc_x: ', 'acc_y: ', 'acc_z: ', 'f_x: ',
                        'f_y: ', 'f_z: '
                    ]
                    result_msg += ', '.join(
                        [a + b for a, b in zip(res_labels, output_values)])
                    self._PrintToScreen(result_msg)

                if self.write_output_file:
                    self.output_file.write(' '.join(output_values) + '\n')

    def _EvaluateGlobalForces(self):
        for node in self.model_part_wall.Nodes:
            acceleration = node.GetSolutionStepValue(KM.MESH_ACCELERATION)
            break

        process_info = self.model_part_wall.ProcessInfo
        sum_forces = SW.ShallowWaterUtilities().ComputeHydrostaticForces(
            self.model_part_wall.Conditions, process_info)
        sum_forces += SW.ShallowWaterUtilities().ComputeHydrostaticForces(
            self.model_part_bottom.Elements, process_info)

        return acceleration, sum_forces

    def _GetFileHeader(self):
        header = '# Global force for model part ' + self.model_part_wall_name + '\n'
        header += '# Time acc_x acc_y acc_z f_x f_y f_z\n'
        return header

    @staticmethod
    def _PrintToScreen(result_msg):
        KM.Logger.PrintInfo('ComputeBoundaryForceProcess',
                            'Global force results - flow- and body-attached:')
        KM.Logger.PrintInfo('ComputeBoundaryForceProcess',
                            'Current time: ' + result_msg)