class ConvectionDiffusionTestFactory(KratosUnittest.TestCase):
    def setUp(self):
        # Within this location context:
        with controlledExecutionScope(os.path.dirname(os.path.realpath(__file__))):

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

            self.modify_parameters(ProjectParameters)

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

            # Creating the test
            model = KratosMultiphysics.Model()
            self.test = ConvectionDiffusionAnalysis(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 controlledExecutionScope(os.path.dirname(os.path.realpath(__file__))):
            self.test.RunSolutionLoop()

    def tearDown(self):
        # Within this location context:
        with controlledExecutionScope(os.path.dirname(os.path.realpath(__file__))):
            self.test.Finalize()
예제 #2
0
    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_analysis = ConvectionDiffusionAnalysis(
            model, primal_parameters)
        self.primal_model_part = model.GetModelPart(
            primal_parameters["solver_settings"]
            ["model_part_name"].GetString())

        # Create the adjoint solver
        adjoint_parameters = self._GetAdjointParameters()

        self.adjoint_analysis = ConvectionDiffusionAnalysis(
            model, adjoint_parameters)
        self.adjoint_model_part = model.GetModelPart(
            adjoint_parameters["solver_settings"]
            ["model_part_name"].GetString())

        self.primal_state_variables = [
            KM.CONDUCTIVITY, KM.TEMPERATURE, KM.HEAT_FLUX, KM.FACE_HEAT_FLUX
        ]

        self.value = None
    def _SetUpBarSimulation(self, ProjectParametersFileName):
        with open(ProjectParametersFileName, 'r') as parameter_file:
            parameters = KratosMultiphysics.Parameters(parameter_file.read())
        model = KratosMultiphysics.Model()
        bar_simulation = ConvectionDiffusionAnalysis(model, parameters)

        return bar_simulation
    def setUp(self):
        # Within this location context:
        with controlledExecutionScope(os.path.dirname(os.path.realpath(__file__))):

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

            self.modify_parameters(ProjectParameters)

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

            # Creating the test
            model = KratosMultiphysics.Model()
            self.test = ConvectionDiffusionAnalysis(model, ProjectParameters)
            self.test.Initialize()
예제 #5
0
    def testPerturbedDivergenceFreeInitialConditionProcess(self):
        if not is_fft_loaded:
            self.skipTest("Missing required Python library: scipy.fftpack")

        parameter_file_name = "test_perturbation_initial_conditions/parameters_poisson_rectangle_2d.json"
        with open(parameter_file_name, 'r') as parameter_file:
            parameters = KratosMultiphysics.Parameters(parameter_file.read())
        model = KratosMultiphysics.Model()
        simulation = ConvectionDiffusionAnalysis(model, parameters)
        simulation._GetSolver().main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.VELOCITY_X_GRADIENT)
        simulation._GetSolver().main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.VELOCITY_Y_GRADIENT)
        simulation._GetSolver().main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.VELOCITY_Z_GRADIENT)
        simulation.Initialize()
        l2norm_divergence = ComputeDivergence(simulation)
        self.assertAlmostEqual(l2norm_divergence, 0.304470818597, delta=1e-12)
    def directSensitivityCheck(self):
        model = kratos.Model()
        settings = kratos.Parameters(r'''{}''')

        with unittest.WorkFolderScope(self.work_folder, __file__):
            with open(self.primal_parameter_file_name,'r') as primal_parameter_file:
                settings.AddValue("primal_settings", kratos.Parameters(primal_parameter_file.read()))

            # enable volume source if needed
            other_processes_list = settings["primal_settings"]["processes"]["list_other_processes"]
            for i in range(other_processes_list.size()):
                if other_processes_list[i]["process_name"].GetString() == "AssignScalarVariableProcess" and other_processes_list[i]["Parameters"]["variable_name"].GetString() == "HEAT_FLUX":
                    other_processes_list[i]["Parameters"]["value"].SetDouble(self.volume_source)

            self.primalSolution(model, settings["primal_settings"])

            with open(self.adjoint_parameter_file_name,'r') as adjoint_parameter_file:
                settings.AddValue("adjoint_settings", kratos.Parameters(adjoint_parameter_file.read()))

            adjoint_analysis = ConvectionDiffusionAnalysis(model,settings["adjoint_settings"])
            adjoint_analysis.Run()

            objective_model_part_name = settings["adjoint_settings"]["solver_settings"]["response_function_settings"]["custom_settings"]["model_part_name"].GetString()
            finite_difference_results = self.perturbedSolution(model, settings["primal_settings"], objective_model_part_name, self.node_ids_to_test)

            adjoint_model_part = model.GetModelPart(settings["adjoint_settings"]["solver_settings"]["model_part_name"].GetString())
            for node_id,fd_sensitivity in zip(self.node_ids_to_test, finite_difference_results):
                node = adjoint_model_part.Nodes[node_id]
                adjoint_sensitivity = node.GetSolutionStepValue(kratos.SHAPE_SENSITIVITY,0)
                #diff = adjoint_sensitivity-fd_sensitivity
                #if (diff[0]**2 + diff[1]**2 + diff[2]**2)**0.5 < self.check_tolerance:
                #    status = "PASS"
                #else:
                #    status = "FAIL"
                #print(status, node_id, adjoint_sensitivity, fd_sensitivity, diff)
                self.assertAlmostEqual(adjoint_sensitivity[0], fd_sensitivity[0], delta=self.check_tolerance)
                self.assertAlmostEqual(adjoint_sensitivity[1], fd_sensitivity[1], delta=self.check_tolerance)
예제 #7
0
 def testConvectionDiffusionBarExplicitElementUnsteadyDOSS(self):
     project_parameters_file_name = "test_convection_diffusion_bar/project_parameters_bar_DOSS.json"
     with open(project_parameters_file_name,'r') as parameter_file:
         parameters = KratosMultiphysics.Parameters(parameter_file.read())
     model = KratosMultiphysics.Model()
     bar_simulation = ConvectionDiffusionAnalysis(model, parameters)
     bar_simulation._GetSolver().main_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.NODAL_AREA)
     bar_simulation.Run()
     # check L2 error via midpoint rule
     KratosMultiphysics.CalculateNodalAreaProcess(bar_simulation._GetSolver().main_model_part,2).Execute()
     error = 0
     model_part_name = bar_simulation.project_parameters["problem_data"]["model_part_name"].GetString()
     for node in bar_simulation.model.GetModelPart(model_part_name).Nodes:
         # L2 norm
         x = node.X
         u_analytical = x - sin(bar_simulation.time)
         u_numerical = node.GetSolutionStepValue(KratosMultiphysics.TEMPERATURE)
         error += (((u_analytical - u_numerical)**2)*node.GetSolutionStepValue(KratosMultiphysics.NODAL_AREA))
     error = sqrt(error)
     self.assertAlmostEqual(error,0.0017678016487118946,delta=1e-12)
예제 #8
0
from __future__ import print_function, absolute_import, division #makes KratosMultiphysics backward compatible with python 2.6 and 2.7

import KratosMultiphysics
from KratosMultiphysics.ConvectionDiffusionApplication.convection_diffusion_analysis import ConvectionDiffusionAnalysis

"""
For user-scripting it is intended that a new class is derived
from ConvectionDiffusionAnalysis to do modifications
"""

if __name__ == "__main__":

    with open("ProjectParameters.json",'r') as parameter_file:
        parameters = KratosMultiphysics.Parameters(parameter_file.read())

    model = KratosMultiphysics.Model()
    simulation = ConvectionDiffusionAnalysis(model,parameters)
    simulation.Run()
    def primalSolution(self, model, settings):

        primal_analysis = ConvectionDiffusionAnalysis(model,settings)
        primal_analysis.Run()
예제 #10
0
class AdjointResponseFunction(ResponseFunctionInterface):
    """Linear adjoint response function.
    - runs the primal analysis
    - primal results are transferred to adjoint model part via python
    - 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_analysis = ConvectionDiffusionAnalysis(model, primal_parameters)
        self.primal_model_part = model.GetModelPart(primal_parameters["solver_settings"]["model_part_name"].GetString())

        # Create the adjoint solver
        adjoint_parameters = self._GetAdjointParameters()

        self.adjoint_analysis = ConvectionDiffusionAnalysis(model, adjoint_parameters)
        self.adjoint_model_part = model.GetModelPart(adjoint_parameters["solver_settings"]["model_part_name"].GetString())

        self.primal_state_variables = [
            KM.CONDUCTIVITY,
            KM.TEMPERATURE,
            KM.HEAT_FLUX,
            KM.FACE_HEAT_FLUX
        ]

        self.value = None

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

    def InitializeSolutionStep(self):
        self.value = None

        # Run the primal analysis.
        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()
        self.value = self._GetResponseFunctionUtility().CalculateValue(self.primal_model_part)
        Logger.PrintInfo(self._GetLabel(), "Time needed for calculating the response value = ",round(timer.time() - startTime,2),"s")

    def CalculateGradient(self):
        # 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.value

    def GetNodalGradient(self, variable):
        if variable != KM.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!")

        for primal_node, adjoint_node in zip(self.primal_model_part.Nodes, self.adjoint_model_part.Nodes):
            adjoint_node.X0 = primal_node.X0
            adjoint_node.Y0 = primal_node.Y0
            adjoint_node.Z0 = primal_node.Z0
            adjoint_node.X = primal_node.X
            adjoint_node.Y = primal_node.Y
            adjoint_node.Z = primal_node.Z

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

    def _GetAdjointParameters(self):

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

        if self.response_settings["transfer_response_parameters"].GetBool():

            # sensitivity settings
            if adjoint_parameters["solver_settings"].Has("sensitivity_settings"):
                Logger.PrintWarning(self._GetLabel(), "Adjoint settings already have 'sensitivity_settings' - Will be overwritten!")
                adjoint_parameters["solver_settings"].RemoveValue("sensitivity_settings")
            adjoint_parameters["solver_settings"].AddValue("sensitivity_settings", self.response_settings["sensitivity_settings"])

            # response settings
            if adjoint_parameters["solver_settings"].Has("response_function_settings"):
                Logger.PrintWarning(self._GetLabel(), "Adjoint settings already have 'response_function_settings' - Will be overwritten!")
                adjoint_parameters["solver_settings"].RemoveValue("response_function_settings")
            adjoint_parameters["solver_settings"].AddValue("response_function_settings", self.response_settings)
        
        return adjoint_parameters

    def _GetLabel(self):
        type_labels = {
            "point_temperature" : "LocalTemperatureAverageResponseFunction"
        }
        response_type = self.response_settings["response_type"].GetString()
        return "Adjoint" + type_labels[response_type] + "Response"