Exemplo n.º 1
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()
Exemplo n.º 2
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.
        """
        super(ComputeDragProcess,self).__init__()

        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.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_drag_output_file):

                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_time = self.model_part.ProcessInfo[KratosMultiphysics.TIME]

        if((current_time >= self.interval[0]) and  (current_time < self.interval[1])):
            # 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)

                if (self.write_drag_output_file):
                    self.output_file.write(format(current_time, self.format)+" "+format(drag_force[0],self.format)+" "+format(drag_force[1],self.format)+" "+format(drag_force[2],self.format)+"\n")

    def ExecuteFinalize(self):
        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)
Exemplo n.º 3
0
class ComputeIntegralValueProcess(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_to_screen"      : false,
                "variable_name"        : "",
                "print_format"              : ".8f",
                "write_output_file"    : true,
                "output_file_settings": {}
            }
            """)

        self.kratos_vars = {}  # dict storing name-KratosVars,
        # hopefully faster than accessing KratosComponents all the time

        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
        self.model_part_name = self.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.var_name = self.params["variable_name"].GetString()
        if self.var_name == "":
            raise Exception('No "var_name" was specified!')
        else:
            self.var = self.__GetKratosVariable(self.var_name)

    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_to_screen = self.params["print_to_screen"].GetBool()
        self.write_output_file = self.params["write_output_file"].GetBool()

        if (self.model_part.GetCommunicator().MyPID() == 0):
            if (self.write_output_file):
                file_handler_params = KratosMultiphysics.Parameters(
                    self.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]

        if ((current_time >= self.interval[0])
                and (current_time < self.interval[1])):
            # Compute the force
            integral_value = self._GetCorrespondingIntegralValue()

            # Write the value components
            if (self.model_part.GetCommunicator().MyPID() == 0):
                if (self.print_to_screen):
                    result_msg='Integral value for model part ' + \
                        self.model_part_name + ' and variable ' + self.var_name + '\n'
                    result_msg += str(current_time) + " x-comp: " + format(
                        integral_value[0], self.format) + " y-comp: " + format(
                            integral_value[1],
                            self.format) + " z-comp: " + format(
                                integral_value[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_output_file):
                    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 ExecuteFinalize(self):
        if (self.model_part.GetCommunicator().MyPID() == 0):
            self.output_file.close()

    def _GetFileHeader(self):
        header = '# Integral value for model part ' + self.model_part_name + ' and variable ' + self.var_name + '\n'
        header += '# Time VectorVal[0] VectorVal[1] VectorVal[2]\n'
        return header

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

    def _GetCorrespondingIntegralValue(self):
        # TODO: for now no type-check, should be checked if vector or not...
        '''
        SOMETHING LIKE THIS:


            if type(kratos_var) == KratosMultiphysics.DoubleVariable or type(kratos_var) == KratosMultiphysics.Array1DComponentVariable:
                SetData(model_part, kratos_var, data_array)
            elif type(kratos_var) == KratosMultiphysics.Array1DVariable3:
                domain_size = model_part.ProcessInfo[KratosMultiphysics.DOMAIN_SIZE]
                if not domain_size in [1,2,3]:
                    raise Exception("DOMAIN_SIZE has to be 1, 2 or 3!")
                num_nodes = NumberOfNodes(model_part)
                if data_array.size != num_nodes*domain_size:
                    raise Exception("Size of data does not match number of nodes x domain size!")
                ext = ["_X", "_Y", "_Z"]
                for i in range(domain_size):
                    component_var = self.__GetKratosVariable(kratos_var.Name()+ext[i])
                    range_begin = i*num_nodes
                    range_end = (i+1)*num_nodes
                    SetData(model_part, component_var, data_array[range_begin:range_end])
            else:
                err_msg  = 'Type of variable "' + kratos_var.Name() + '" is not valid\n'
                err_msg += 'It can only be double, component or array3d!'
                raise Exception(err_msg)

        '''
        vector_val = [0.0, 0.0, 0.0]

        for node in self.model_part.Nodes:
            nodal_result = node.GetSolutionStepValue(self.var, 0)

            vector_val[0] += nodal_result[0]
            vector_val[1] += nodal_result[1]
            vector_val[2] += nodal_result[2]

        return vector_val

    def __GetKratosVariable(self, var_name):
        if not var_name in self.kratos_vars:
            self.kratos_vars[
                var_name] = KratosMultiphysics.KratosGlobals.GetVariable(
                    var_name)

        return self.kratos_vars[var_name]