Exemplo n.º 1
0
class IgaTestFactory(KratosUnittest.TestCase):
    def setUp(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):

            # Reading the ProjectParameters
            with open(self.file_name + "_project_parameters.json",'r') as parameter_file:
                ProjectParameters = KratosMultiphysics.Parameters(parameter_file.read())

            # To avoid many prints
            if ProjectParameters["problem_data"]["echo_level"].GetInt() == 0:
                KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(KratosMultiphysics.Logger.Severity.WARNING)
            else:
                KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(KratosMultiphysics.Logger.Severity.INFO)

            # Creating the test
            model = KratosMultiphysics.Model()
            self.test = StructuralMechanicsAnalysis(model, ProjectParameters)
            self.test.Initialize()

    def test_execution(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):
            self.test.RunSolutionLoop()

    def tearDown(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):
            self.test.Finalize()
Exemplo n.º 2
0
class StructuralMechanicsTestFactory(KratosUnittest.TestCase):
    def setUp(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):

            # Reading the ProjectParameters
            with open(self.file_name + "_parameters.json",'r') as parameter_file:
                ProjectParameters = KratosMultiphysics.Parameters(parameter_file.read())

            # The mechanical solver selects automatically the fastest linear-solver available
            # this might not be appropriate for a test, therefore in case nothing is specified,
            # the previous default linear-solver is set
            if not ProjectParameters["solver_settings"].Has("linear_solver_settings"):
                # check if running in MPI because there we use a different default linear solver
                if IsDistributedRun():
                    default_lin_solver_settings = KratosMultiphysics.Parameters("""{
                        "solver_type" : "amesos",
                        "amesos_solver_type" : "Amesos_Klu"
                    }""")

                else:
                    default_lin_solver_settings = KratosMultiphysics.Parameters("""{
                        "solver_type": "ExternalSolversApplication.super_lu",
                        "max_iteration": 500,
                        "tolerance": 1e-9,
                        "scaling": false,
                        "symmetric_scaling": true,
                        "verbosity": 0
                    }""")
                ProjectParameters["solver_settings"].AddValue("linear_solver_settings", default_lin_solver_settings)

            self.modify_parameters(ProjectParameters)

            # To avoid many prints
            if ProjectParameters["problem_data"]["echo_level"].GetInt() == 0:
                KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(KratosMultiphysics.Logger.Severity.WARNING)
            else:
                KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(KratosMultiphysics.Logger.Severity.INFO)

            # Creating the test
            model = KratosMultiphysics.Model()
            self.test = StructuralMechanicsAnalysis(model, ProjectParameters)
            self.test.Initialize()

    def modify_parameters(self, project_parameters):
        """This function can be used in derived classes to modify existing parameters
        before the execution of the test (e.g. switch to MPI)
        """
        pass

    def test_execution(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):
            self.test.RunSolutionLoop()

    def tearDown(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):
            self.test.Finalize()
class StructuralMechanicsTestFactory(KratosUnittest.TestCase):
    def setUp(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):

            # Reading the ProjectParameters
            with open(self.file_name + "_parameters.json",
                      'r') as parameter_file:
                ProjectParameters = KratosMultiphysics.Parameters(
                    parameter_file.read())

            SelectAndVerifyLinearSolver(ProjectParameters, self.skipTest)

            self.modify_parameters(ProjectParameters)

            # To avoid many prints
            if ProjectParameters["problem_data"]["echo_level"].GetInt() == 0:
                KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(
                    KratosMultiphysics.Logger.Severity.WARNING)
            else:
                KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(
                    KratosMultiphysics.Logger.Severity.INFO)

            # Creating the test
            model = KratosMultiphysics.Model()
            self.test = StructuralMechanicsAnalysis(model, ProjectParameters)
            self.test.Initialize()

    def modify_parameters(self, project_parameters):
        """This function can be used in derived classes to modify existing parameters
        before the execution of the test (e.g. switch to MPI)
        """
        pass

    def test_execution(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):
            self.test.RunSolutionLoop()

    def tearDown(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):
            self.test.Finalize()
Exemplo n.º 4
0
class AdjointResponseFunction(ResponseFunctionInterface):
    """Linear static adjoint strain energy response function.
    - runs the primal analysis (writes the primal results to an .h5 file)
    - reads the primal results from the .h5 file into the adjoint model part
    - uses primal results to calculate value
    - uses primal results to calculate gradient by running the adjoint analysis

    Attributes
    ----------
    primal_analysis : Primal analysis object of the response function
    adjoint_analysis : Adjoint analysis object of the response function
    """
    def __init__(self, identifier, response_settings, model):
        self.identifier = identifier
        self.response_settings = response_settings

        # Create the primal solver
        with open(self.response_settings["primal_settings"].GetString(),
                  'r') as parameter_file:
            primal_parameters = Parameters(parameter_file.read())

        self.primal_model_part = _GetModelPart(
            model, primal_parameters["solver_settings"])

        self.primal_analysis = StructuralMechanicsAnalysis(
            model, primal_parameters)

        self.primal_data_transfer_with_python = self.response_settings[
            "primal_data_transfer_with_python"].GetBool()

        # Create the adjoint solver
        adjoint_parameters = self._GetAdjointParameters()
        adjoint_model = KratosMultiphysics.Model()
        self.adjoint_model_part = _GetModelPart(
            adjoint_model, adjoint_parameters["solver_settings"])

        # TODO find out why it is not possible to use the same model_part
        self.adjoint_analysis = StructuralMechanicsAnalysis(
            adjoint_model, adjoint_parameters)

        self.primal_state_variables = [KratosMultiphysics.DISPLACEMENT]
        if primal_parameters["solver_settings"].Has("rotation_dofs"):
            if primal_parameters["solver_settings"]["rotation_dofs"].GetBool():
                self.primal_state_variables.append(KratosMultiphysics.ROTATION)

    def Initialize(self):
        self.primal_analysis.Initialize()
        self.adjoint_analysis.Initialize()

    def InitializeSolutionStep(self):
        # Run the primal analysis.
        # TODO if primal_analysis.status==solved: return
        Logger.PrintInfo(self._GetLabel(),
                         "Starting primal analysis for response:",
                         self.identifier)
        startTime = timer.time()
        if not self.primal_analysis.time < self.primal_analysis.end_time:
            self.primal_analysis.end_time += 1
        self.primal_analysis.RunSolutionLoop()
        Logger.PrintInfo(self._GetLabel(),
                         "Time needed for solving the primal analysis = ",
                         round(timer.time() - startTime, 2), "s")

    def CalculateValue(self):
        startTime = timer.time()
        value = self._GetResponseFunctionUtility().CalculateValue(
            self.primal_model_part)
        Logger.PrintInfo(self._GetLabel(),
                         "Time needed for calculating the response value = ",
                         round(timer.time() - startTime, 2), "s")

        self.primal_model_part.ProcessInfo[
            StructuralMechanicsApplication.RESPONSE_VALUE] = value

    def CalculateGradient(self):
        # synchronize the modelparts
        self._SynchronizeAdjointFromPrimal()
        startTime = timer.time()
        Logger.PrintInfo(self._GetLabel(),
                         "Starting adjoint analysis for response:",
                         self.identifier)
        if not self.adjoint_analysis.time < self.adjoint_analysis.end_time:
            self.adjoint_analysis.end_time += 1
        self.adjoint_analysis.RunSolutionLoop()
        Logger.PrintInfo(self._GetLabel(),
                         "Time needed for solving the adjoint analysis = ",
                         round(timer.time() - startTime, 2), "s")

    def GetValue(self):
        return self.primal_model_part.ProcessInfo[
            StructuralMechanicsApplication.RESPONSE_VALUE]

    def GetNodalGradient(self, variable):
        if variable != KratosMultiphysics.SHAPE_SENSITIVITY:
            raise RuntimeError("GetNodalGradient: No gradient for {}!".format(
                variable.Name))
        gradient = {}
        for node in self.adjoint_model_part.Nodes:
            gradient[node.Id] = node.GetSolutionStepValue(variable)
        return gradient

    def Finalize(self):
        self.primal_analysis.Finalize()
        self.adjoint_analysis.Finalize()

    def _GetResponseFunctionUtility(self):
        return self.adjoint_analysis._GetSolver().response_function

    def _SynchronizeAdjointFromPrimal(self):
        Logger.PrintInfo(
            self._GetLabel(),
            "Synchronize primal and adjoint modelpart for response:",
            self.identifier)

        if len(self.primal_model_part.Nodes) != len(
                self.adjoint_model_part.Nodes):
            raise RuntimeError(
                "_SynchronizeAdjointFromPrimal: Model parts have a different number of nodes!"
            )

        # TODO this should happen automatically
        for primal_node, adjoint_node in zip(self.primal_model_part.Nodes,
                                             self.adjoint_model_part.Nodes):
            adjoint_node.X0 = primal_node.X0
            adjoint_node.Y0 = primal_node.Y0
            adjoint_node.Z0 = primal_node.Z0
            adjoint_node.X = primal_node.X
            adjoint_node.Y = primal_node.Y
            adjoint_node.Z = primal_node.Z

        # Put primal solution on adjoint model
        if self.primal_data_transfer_with_python:
            Logger.PrintInfo(self._GetLabel(),
                             "Transfer primal state to adjoint model part.")
            variable_utils = KratosMultiphysics.VariableUtils()
            for variable in self.primal_state_variables:
                variable_utils.CopyModelPartNodalVar(variable,
                                                     self.primal_model_part,
                                                     self.adjoint_model_part,
                                                     0)

    def _GetAdjointParameters(self):

        adjoint_settings = self.response_settings[
            "adjoint_settings"].GetString()

        if adjoint_settings == "auto":
            Logger.PrintInfo(
                self._GetLabel(),
                "Automatic set up adjoint parameters for response:",
                self.identifier)

            if not self.primal_data_transfer_with_python:
                raise Exception(
                    "Auto setup of adjoint parameters does only support primal data transfer with python."
                )

            with open(self.response_settings["primal_settings"].GetString(),
                      'r') as parameter_file:
                primal_parameters = Parameters(parameter_file.read())

            # check that HDF5 process is not there
            if primal_parameters["processes"].Has("list_other_processes"):
                for i in range(
                        0, primal_parameters["processes"]
                    ["list_other_processes"].size()):
                    process = primal_parameters["processes"][
                        "list_other_processes"][i]
                    raise Exception(
                        "Auto setup of adjoint parameters does not support {} in list_other_processes"
                        .format(process["python_module"].GetString()))

            # clone primal settings as base for adjoint
            adjoint_parameters = primal_parameters.Clone()

            # analysis settings
            solver_settings = adjoint_parameters["solver_settings"]
            primal_solver_type = solver_settings["solver_type"].GetString()
            if primal_solver_type != "static":
                raise Exception(
                    "Auto setup of adjoint parameters does not support {} solver_type. Only available for 'static'"
                    .format(primal_solver_type))
            solver_settings["solver_type"].SetString("adjoint_" +
                                                     primal_solver_type)

            if not solver_settings.Has("compute_reactions"):
                solver_settings.AddEmptyValue("compute_reactions")
            solver_settings["compute_reactions"].SetBool(False)

            if not solver_settings.Has("move_mesh_flag"):
                solver_settings.AddEmptyValue("move_mesh_flag")
            solver_settings["move_mesh_flag"].SetBool(False)

            if solver_settings.Has("scheme_settings"):
                depr_msg = '\nDEPRECATION-WARNING: "scheme_settings" is deprecated, please remove it from your json parameters.\n'
                Logger.PrintWarning(__name__, depr_msg)
                solver_settings.RemoveValue("scheme_settings")

            if solver_settings["model_import_settings"][
                    "input_type"].GetString() == "use_input_model_part":
                solver_settings["model_import_settings"][
                    "input_type"].SetString("mdpa")
                if solver_settings["model_import_settings"].Has(
                        "input_filename"):
                    file_name = solver_settings["model_import_settings"][
                        "input_filename"].GetString()
                else:
                    Logger.PrintWarning(
                        self._GetLabel(),
                        "Automatic adjoint settings creator assumes the model_part_name as input_filename."
                    )
                    solver_settings["model_import_settings"].AddEmptyValue(
                        "input_filename")
                    file_name = solver_settings["model_part_name"].GetString()
                solver_settings["model_import_settings"][
                    "input_filename"].SetString(file_name)

            # Dirichlet conditions: change variables
            for i in range(
                    0, primal_parameters["processes"]
                ["constraints_process_list"].size()):
                process = adjoint_parameters["processes"][
                    "constraints_process_list"][i]
                variable_name = process["Parameters"][
                    "variable_name"].GetString()
                process["Parameters"]["variable_name"].SetString("ADJOINT_" +
                                                                 variable_name)

            # Neumann conditions - do not modify to read the same load values as in primal:

            # Output process:
            # TODO how to add the output process? How find out about the variables?
            if adjoint_parameters.Has("output_processes"):
                Logger.PrintInfo(
                    self._GetLabel(),
                    "Output process is removed for adjoint analysis. To enable it define adjoint_parameters yourself."
                )
                adjoint_parameters.RemoveValue("output_processes")

            # sensitivity settings
            adjoint_parameters["solver_settings"].AddValue(
                "sensitivity_settings",
                self.response_settings["sensitivity_settings"])

            # response settings
            adjoint_parameters["solver_settings"].AddValue(
                "response_function_settings", self.response_settings)

        else:  # adjoint parameters file is explicitely given - do not change it.
            with open(self.response_settings["adjoint_settings"].GetString(),
                      'r') as parameter_file:
                adjoint_parameters = Parameters(parameter_file.read())

        return adjoint_parameters

    def _GetLabel(self):
        type_labels = {
            "adjoint_nodal_displacement": "NodalDisplacement",
            "adjoint_linear_strain_energy": "StrainEnergy",
            "adjoint_local_stress": "LocalStress",
            "adjoint_max_stress": "MaxStress",
            "adjoint_nodal_reaction": "NodalReaction"
        }
        response_type = self.response_settings["response_type"].GetString()
        return "Adjoint" + type_labels[response_type] + "Response"
Exemplo n.º 5
0
class StructuralMechanicsTestFactory(KratosUnittest.TestCase):
    def setUp(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):

            # Reading the ProjectParameters
            with open(self.file_name + "_parameters.json",
                      'r') as parameter_file:
                ProjectParameters = KratosMultiphysics.Parameters(
                    parameter_file.read())

            # The mechanical solver selects automatically the fastest linear-solver available
            # this might not be appropriate for a test, therefore in case nothing is specified,
            # the previous default linear-solver is set
            if not ProjectParameters["solver_settings"].Has(
                    "linear_solver_settings"):
                # check if running in MPI because there we use a different default linear solver
                if IsDistributedRun():
                    default_lin_solver_settings = KratosMultiphysics.Parameters(
                        """{
                        "solver_type" : "amesos",
                        "amesos_solver_type" : "Amesos_Klu"
                    }""")

                else:
                    default_lin_solver_settings = KratosMultiphysics.Parameters(
                        """{
                        "solver_type": "EigenSolversApplication.sparse_lu"
                    }""")
                ProjectParameters["solver_settings"].AddValue(
                    "linear_solver_settings", default_lin_solver_settings)

            solver_type = ProjectParameters["solver_settings"][
                "linear_solver_settings"]["solver_type"].GetString()
            solver_type_splitted = solver_type.split(".")
            if len(solver_type_splitted) == 2:
                # this means that we use a solver from an application
                # hence we have to check if it exists, otherwise skip the test
                app_name = solver_type_splitted[0]
                solver_name = solver_type_splitted[1]
                if not kratos_utils.CheckIfApplicationsAvailable(app_name):
                    self.skipTest(
                        'Application "{}" is needed for the specified solver "{}" but is not available'
                        .format(app_name, solver_name))

            self.modify_parameters(ProjectParameters)

            # To avoid many prints
            if ProjectParameters["problem_data"]["echo_level"].GetInt() == 0:
                KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(
                    KratosMultiphysics.Logger.Severity.WARNING)
            else:
                KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(
                    KratosMultiphysics.Logger.Severity.INFO)

            # Creating the test
            model = KratosMultiphysics.Model()
            self.test = StructuralMechanicsAnalysis(model, ProjectParameters)
            self.test.Initialize()

    def modify_parameters(self, project_parameters):
        """This function can be used in derived classes to modify existing parameters
        before the execution of the test (e.g. switch to MPI)
        """
        pass

    def test_execution(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):
            self.test.RunSolutionLoop()

    def tearDown(self):
        # Within this location context:
        with KratosUnittest.WorkFolderScope(".", __file__):
            self.test.Finalize()