Example #1
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()
Example #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.
        """
        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 #3
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 #4
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 #5
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)
Example #6
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 #7
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 #8
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
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)