Beispiel #1
0
def OutputResults(model_part, file_name):
    output_parameters = Parameters("""
    {
        "result_file_configuration" : {
            "gidpost_flags"       : {
                "GiDPostMode"           : "GiD_PostBinary",
                "WriteDeformedMeshFlag" : "WriteDeformed",
                "WriteConditionsFlag"   : "WriteConditions",
                "MultiFileFlag"         : "SingleFile"
            },
            "file_label"          : "step",
            "output_control_type" : "step",
            "output_frequency"    : 1,
            "nodal_results"       : ["CONTROL_POINT_UPDATE","CONTROL_POINT_CHANGE","SHAPE_UPDATE","PRESSURE","AIR_PRESSURE","WATER_PRESSURE"]
        },
        "point_data_configuration"  : []
    }""")
    gid_output_original = GiDOutputProcess(model_part, file_name,
                                           output_parameters)
    gid_output_original.ExecuteInitialize()
    gid_output_original.ExecuteBeforeSolutionLoop()
    gid_output_original.ExecuteInitializeSolutionStep()
    gid_output_original.PrintOutput()
    gid_output_original.ExecuteFinalizeSolutionStep()
    gid_output_original.ExecuteFinalize()
Beispiel #2
0
    def _CreateGidControlOutput(self, output_name):
        for element in self._GetSolver().main_model_part.Elements:
            element.Set(KratosMultiphysics.INLET, False)
            if element.IsNot(KratosMultiphysics.ACTIVE):
                element.Set(KratosMultiphysics.INLET, True)
            element.Set(KratosMultiphysics.ACTIVE, True)
        from gid_output_process import GiDOutputProcess
        gid_output = GiDOutputProcess(
            self._GetSolver().main_model_part, output_name,
            KratosMultiphysics.Parameters("""
					{
						"result_file_configuration" : {
							"gidpost_flags": {
								"GiDPostMode": "GiD_PostBinary",
								"MultiFileFlag": "SingleFile"
							},
							"nodal_results"       : ["VELOCITY_POTENTIAL","AUXILIARY_VELOCITY_POTENTIAL"],
							"nodal_nonhistorical_results": ["METRIC_TENSOR_2D","TEMPERATURE","DISTANCE","TRAILING_EDGE"],
                        	"gauss_point_results" : ["PRESSURE_COEFFICIENT","VELOCITY","WAKE","KUTTA"],
							"nodal_flags_results": [],
                        	"elemental_conditional_flags_results": ["TO_SPLIT","THERMAL","STRUCTURE"]
						}
					}
					"""))
        gid_output.ExecuteInitialize()
        gid_output.ExecuteBeforeSolutionLoop()
        gid_output.ExecuteInitializeSolutionStep()
        gid_output.PrintOutput()
        gid_output.ExecuteFinalizeSolutionStep()
        gid_output.ExecuteFinalize()

        for element in self._GetSolver().main_model_part.Elements:
            if element.Is(KratosMultiphysics.INLET):
                element.Set(KratosMultiphysics.ACTIVE, False)
Beispiel #3
0
    def __WriteOutput(self, model_part, output_file):

        gid_output = GiDOutputProcess(
            model_part, output_file,
            KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration": {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostAscii",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "file_label": "time",
                                                "output_control_type": "step",
                                                "output_frequency": 1.0,
                                                "body_output": true,
                                                "node_output": false,
                                                "skin_output": false,
                                                "plane_output": [],
                                                "nodal_results": ["DISPLACEMENT","VISCOSITY"],
                                                "nodal_nonhistorical_results": [],
                                                "nodal_flags_results": [],
                                                "gauss_point_results": [],
                                                "additional_list_files": []
                                            }
                                        }
                                        """))

        gid_output.ExecuteInitialize()
        gid_output.ExecuteBeforeSolutionLoop()
        gid_output.ExecuteInitializeSolutionStep()
        gid_output.PrintOutput()
        gid_output.ExecuteFinalizeSolutionStep()
        gid_output.ExecuteFinalize()
    def _post_process(self, model_part):
        from gid_output_process import GiDOutputProcess
        gid_output = GiDOutputProcess(model_part,
                                    "gid_output",
                                    KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "nodal_flags_results" : ["INTERFACE","ACTIVE"]
                                            }
                                        }
                                        """)
                                    )

        gid_output.ExecuteInitialize()
        gid_output.ExecuteBeforeSolutionLoop()
        gid_output.ExecuteInitializeSolutionStep()
        gid_output.PrintOutput()
        gid_output.ExecuteFinalizeSolutionStep()
        gid_output.ExecuteFinalize()
    def __VisualizeWake(self):
        # To visualize the wake
        number_of_nodes = self.fluid_model_part.NumberOfNodes()
        number_of_elements = self.fluid_model_part.NumberOfElements()

        node_id = number_of_nodes + 1
        for node in self.wake_model_part.Nodes:
            node.Id = node_id
            node.SetValue(KratosMultiphysics.REACTION_WATER_PRESSURE, 1.0)
            node_id += 1

        counter = number_of_elements + 1
        for elem in self.wake_model_part.Elements:
            elem.Id = counter
            counter += 1

        from gid_output_process import GiDOutputProcess
        output_file = "representation_of_wake"
        gid_output = GiDOutputProcess(
            self.wake_model_part, output_file,
            KratosMultiphysics.Parameters("""
                                    {
                                        "result_file_configuration": {
                                            "gidpost_flags": {
                                                "GiDPostMode": "GiD_PostAscii",
                                                "WriteDeformedMeshFlag": "WriteUndeformed",
                                                "WriteConditionsFlag": "WriteConditions",
                                                "MultiFileFlag": "SingleFile"
                                            },
                                            "file_label": "time",
                                            "output_control_type": "step",
                                            "output_frequency": 1.0,
                                            "body_output": true,
                                            "node_output": false,
                                            "skin_output": false,
                                            "plane_output": [],
                                            "nodal_results": [],
                                            "nodal_nonhistorical_results": ["REACTION_WATER_PRESSURE"],
                                            "nodal_flags_results": [],
                                            "gauss_point_results": [],
                                            "additional_list_files": []
                                        }
                                    }
                                    """))

        gid_output.ExecuteInitialize()
        gid_output.ExecuteBeforeSolutionLoop()
        gid_output.ExecuteInitializeSolutionStep()
        gid_output.PrintOutput()
        gid_output.ExecuteFinalizeSolutionStep()
        gid_output.ExecuteFinalize()
def OutputModelPart(output_mdpa, output_filename, nodal_results):
    output_parameters = KM.Parameters(
        """ { "result_file_configuration" : { "nodal_results" : [] } }""")
    for entry in nodal_results:
        output_parameters["result_file_configuration"]["nodal_results"].Append(
            entry)
    gid_output_original = GiDOutputProcess(output_mdpa, output_filename,
                                           output_parameters)
    gid_output_original.ExecuteInitialize()
    gid_output_original.ExecuteBeforeSolutionLoop()
    gid_output_original.ExecuteInitializeSolutionStep()
    gid_output_original.PrintOutput()
    gid_output_original.ExecuteFinalizeSolutionStep()
    gid_output_original.ExecuteFinalize()
class TestPatchTestSmallStrain(KratosUnittest.TestCase):
    def setUp(self):
        pass

    def _add_variables(self, mp):
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.DISPLACEMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.VOLUME_ACCELERATION)

    def _apply_BCs(self, mp, A, b):
        for node in mp.Nodes:
            node.Fix(KratosMultiphysics.DISPLACEMENT_X)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Y)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Z)

        for node in mp.Nodes:
            xvec = KratosMultiphysics.Vector(3)
            xvec[0] = node.X0
            xvec[1] = node.Y0
            xvec[2] = node.Z0

            u = A * xvec
            u += b

            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT, 0, u)

    def _apply_material_properties(self, mp, dim):
        #define properties
        mp.GetProperties()[1].SetValue(KratosMultiphysics.YOUNG_MODULUS, 210e9)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.POISSON_RATIO, 0.3)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.THICKNESS, 1.0)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.DENSITY, 1.0)
        #mp.GetProperties()[1].SetValue(StructuralMechanicsApplication.INTEGRATION_ORDER,5)

        g = [0, 0, 0]
        mp.GetProperties()[1].SetValue(KratosMultiphysics.VOLUME_ACCELERATION,
                                       g)

        if (dim == 2):
            cl = StructuralMechanicsApplication.LinearElasticPlaneStress2DLaw()
        else:
            cl = StructuralMechanicsApplication.LinearElastic3DLaw()
        mp.GetProperties()[1].SetValue(KratosMultiphysics.CONSTITUTIVE_LAW, cl)

    def _define_movement(self, dim):
        if (dim == 2):
            #define the applied motion - the idea is that the displacement is defined as u = A*xnode + b
            #so that the displcement is linear and the exact F = I + A
            A = KratosMultiphysics.Matrix(3, 3)
            A[0, 0] = 1.0e-10
            A[0, 1] = 2.0e-10
            A[0, 2] = 0.0
            A[1, 0] = 0.5e-10
            A[1, 1] = 0.7e-10
            A[1, 2] = 0.0
            A[2, 0] = 0.0
            A[2, 1] = 0.0
            A[2, 2] = 0.0

            b = KratosMultiphysics.Vector(3)
            b[0] = 0.5e-10
            b[1] = -0.2e-10
            b[2] = 0.0

        else:
            #define the applied motion - the idea is that the displacement is defined as u = A*xnode + b
            #so that the displcement is linear and the exact F = I + A
            A = KratosMultiphysics.Matrix(3, 3)
            A[0, 0] = 1.0e-10
            A[0, 1] = 2.0e-10
            A[0, 2] = 0.0
            A[1, 0] = 0.5e-10
            A[1, 1] = 0.7e-10
            A[1, 2] = 0.1e-10
            A[2, 0] = -0.2e-10
            A[2, 1] = 0.0
            A[2, 2] = -0.3e-10

            b = KratosMultiphysics.Vector(3)
            b[0] = 0.5e-10
            b[1] = -0.2e-10
            b[2] = 0.7e-10

        return A, b

    def _solve(self, mp):

        #define a minimal newton raphson solver
        linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        builder_and_solver = KratosMultiphysics.ResidualBasedBlockBuilderAndSolver(
            linear_solver)
        scheme = KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme(
        )
        convergence_criterion = KratosMultiphysics.ResidualCriteria(
            1e-14, 1e-20)

        max_iters = 20
        compute_reactions = True
        reform_step_dofs = True
        calculate_norm_dx = False
        move_mesh_flag = True
        strategy = KratosMultiphysics.ResidualBasedLinearStrategy(
            mp, scheme, linear_solver, builder_and_solver, compute_reactions,
            reform_step_dofs, calculate_norm_dx, move_mesh_flag)

        #strategy = KratosMultiphysics.ResidualBasedNewtonRaphsonStrategy(mp,
        #scheme,
        #linear_solver,
        #convergence_criterion,
        #builder_and_solver,
        #max_iters,
        #compute_reactions,
        #reform_step_dofs,
        #move_mesh_flag)
        strategy.SetEchoLevel(0)

        strategy.Check()
        strategy.Solve()

    def _check_results(self, mp, A, b):

        ##check that the results are exact on the nodes
        for node in mp.Nodes:
            xvec = KratosMultiphysics.Vector(3)
            xvec[0] = node.X0
            xvec[1] = node.Y0
            xvec[2] = node.Z0

            u = A * xvec
            u += b

            coor_list = ["X", "Y", "Z"]

            d = node.GetSolutionStepValue(KratosMultiphysics.DISPLACEMENT)
            for i in range(3):
                if abs(u[i]) > 0.0:
                    error = (d[i] - u[i]) / u[i]
                    if error > 1.0e-6:
                        print("NODE ", node.Id, ": Component ", coor_list[i],
                              ":\t", u[i], "\t", d[i], "\tError: ", error)
                    self.assertLess(error, 1.0e-6)

    def _check_outputs(self, mp, A, dim):

        E = mp.GetProperties()[1].GetValue(KratosMultiphysics.YOUNG_MODULUS)
        NU = mp.GetProperties()[1].GetValue(KratosMultiphysics.POISSON_RATIO)

        # Given the matrix A, the analytic deformation gradient is F+I
        F = A
        for i in range(3):
            F[i, i] += 1.0

        # Here compute the Cauchy green strain tensor
        Etensor = KratosMultiphysics.Matrix(3, 3)

        for i in range(3):
            for j in range(3):
                Etensor[i, j] = 0.0

        for i in range(3):
            for j in range(3):
                for k in range(3):
                    Etensor[i, j] += F[k, i] * F[k, j]

        for i in range(3):
            Etensor[i, i] -= 1.0

        for i in range(3):
            for j in range(3):
                Etensor[i, j] = 0.5 * Etensor[i, j]

        # Verify strain
        if (dim == 2):
            reference_strain = KratosMultiphysics.Vector(3)
            reference_strain[0] = Etensor[0, 0]
            reference_strain[1] = Etensor[1, 1]
            reference_strain[2] = 2.0 * Etensor[0, 1]
        else:
            reference_strain = KratosMultiphysics.Vector(6)
            reference_strain[0] = Etensor[0, 0]
            reference_strain[1] = Etensor[1, 1]
            reference_strain[2] = Etensor[2, 2]
            reference_strain[3] = 2.0 * Etensor[0, 1]
            reference_strain[4] = 2.0 * Etensor[1, 2]
            reference_strain[5] = 2.0 * Etensor[0, 2]

        for elem in mp.Elements:
            out = elem.CalculateOnIntegrationPoints(
                KratosMultiphysics.GREEN_LAGRANGE_STRAIN_VECTOR,
                mp.ProcessInfo)
            for strain in out:
                for i in range(len(reference_strain)):
                    if abs(strain[i]) > 0.0:
                        self.assertLess(
                            (reference_strain[i] - strain[i]) / strain[i],
                            1.0e-6)

        # Finally compute stress
        if (dim == 2):
            #here assume plane stress
            c1 = E / (1.00 - NU * NU)
            c2 = c1 * NU
            c3 = 0.5 * E / (1 + NU)
            reference_stress = KratosMultiphysics.Vector(3)
            reference_stress[0] = c1 * reference_strain[0] + c2 * (
                reference_strain[1])
            reference_stress[1] = c1 * reference_strain[1] + c2 * (
                reference_strain[0])
            reference_stress[2] = c3 * reference_strain[2]
        else:
            c1 = E / ((1.00 + NU) * (1 - 2 * NU))
            c2 = c1 * (1 - NU)
            c3 = c1 * NU
            c4 = c1 * 0.5 * (1 - 2 * NU)
            reference_stress = KratosMultiphysics.Vector(6)
            reference_stress[0] = c2 * reference_strain[0] + c3 * (
                reference_strain[1] + reference_strain[2])
            reference_stress[1] = c2 * reference_strain[1] + c3 * (
                reference_strain[0] + reference_strain[2])
            reference_stress[2] = c2 * reference_strain[2] + c3 * (
                reference_strain[0] + reference_strain[1])
            reference_stress[3] = c4 * reference_strain[3]
            reference_stress[4] = c4 * reference_strain[4]
            reference_stress[5] = c4 * reference_strain[5]

        for elem in mp.Elements:
            out = elem.CalculateOnIntegrationPoints(
                KratosMultiphysics.PK2_STRESS_VECTOR, mp.ProcessInfo)
            for stress in out:
                for i in range(len(reference_stress)):
                    if abs(stress[i]) > 0.0:
                        self.assertLess(
                            (reference_stress[i] - stress[i]) / stress[i],
                            1.0e-6)

    def test_SmallDisplacementElement_2D_triangle(self):
        dim = 2
        current_model = KratosMultiphysics.Model()
        mp = current_model.CreateModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.5, 0.5, 0.0)
        mp.CreateNewNode(2, 0.7, 0.2, 0.0)
        mp.CreateNewNode(3, 0.9, 0.8, 0.0)
        mp.CreateNewNode(4, 0.3, 0.7, 0.0)
        mp.CreateNewNode(5, 0.6, 0.6, 0.0)

        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,
            mp)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 2, 3, 4])

        #create Element
        mp.CreateNewElement("SmallDisplacementElement2D3N", 1, [1, 2, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement2D3N", 2, [2, 3, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement2D3N", 3, [3, 4, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement2D3N", 4, [4, 1, 5],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #checking consistent mass matrix
        M = KratosMultiphysics.Matrix(0, 0)
        mp.Elements[1].CalculateMassMatrix(M, mp.ProcessInfo)
        Area = mp.Elements[1].GetGeometry().Area()
        for i in range(3):
            for j in range(3):
                for k in range(dim):
                    if (i == j):
                        coeff = Area / 6.0
                    else:
                        coeff = Area / 12.0
                    self.assertAlmostEqual(M[i * dim + k, j * dim + k], coeff)

        #self.__post_process(mp)

    def test_SmallDisplacementElement_2D_quadrilateral(self):
        dim = 2
        current_model = KratosMultiphysics.Model()
        mp = current_model.CreateModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.00, 3.00, 0.00)
        mp.CreateNewNode(2, 1.00, 2.25, 0.00)
        mp.CreateNewNode(3, 0.75, 1.00, 0.00)
        mp.CreateNewNode(4, 2.25, 2.00, 0.00)
        mp.CreateNewNode(5, 0.00, 0.00, 0.00)
        mp.CreateNewNode(6, 3.00, 3.00, 0.00)
        mp.CreateNewNode(7, 2.00, 0.75, 0.00)
        mp.CreateNewNode(8, 3.00, 0.00, 0.00)

        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,
            mp)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 5, 6, 8])

        #create Element
        mp.CreateNewElement("SmallDisplacementElement2D4N", 1, [8, 7, 3, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement2D4N", 2, [6, 4, 7, 8],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement2D4N", 3, [1, 2, 4, 6],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement2D4N", 4, [4, 2, 3, 7],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement2D4N", 5, [2, 1, 5, 3],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def test_SmallDisplacementElement_3D_tetra(self):
        dim = 3
        current_model = KratosMultiphysics.Model()
        mp = current_model.CreateModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.0, 1.0, 0.0)
        mp.CreateNewNode(2, 0.0, 1.0, 0.1)
        mp.CreateNewNode(3, 0.28739360416666665, 0.27808503701741405,
                         0.05672979583333333)
        mp.CreateNewNode(4, 0.0, 0.1, 0.0)
        mp.CreateNewNode(5, 0.1, 0.1, 0.1)
        mp.CreateNewNode(6, 1.0, 0.0, 0.0)
        mp.CreateNewNode(7, 1.2, 0.0, 0.1)

        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,
            mp)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 2, 4, 5, 6, 7])

        #create Element
        mp.CreateNewElement("SmallDisplacementElement3D4N", 1, [5, 3, 1, 2],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D4N", 2, [3, 1, 2, 6],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D4N", 3, [6, 4, 7, 3],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D4N", 4, [5, 4, 1, 3],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D4N", 5, [4, 1, 3, 6],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D4N", 6, [5, 4, 3, 7],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D4N", 7, [3, 5, 7, 2],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D4N", 8, [6, 7, 2, 3],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def test_SmallDisplacementElement_3D_prism(self):
        dim = 3
        current_model = KratosMultiphysics.Model()
        mp = current_model.CreateModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.5, 0.5, 0.0)
        mp.CreateNewNode(2, 0.7, 0.2, 0.0)
        mp.CreateNewNode(3, 0.9, 0.8, 0.0)
        mp.CreateNewNode(4, 0.3, 0.7, 0.0)
        mp.CreateNewNode(5, 0.6, 0.6, 0.0)
        mp.CreateNewNode(6, 0.5, 0.5, 0.1)
        mp.CreateNewNode(7, 0.7, 0.2, 0.1)
        mp.CreateNewNode(8, 0.9, 0.8, 0.1)
        mp.CreateNewNode(9, 0.3, 0.7, 0.1)
        mp.CreateNewNode(10, 0.6, 0.6, 0.1)
        mp.CreateNewNode(11, 0.5, 0.5, 0.2)
        mp.CreateNewNode(12, 0.7, 0.2, 0.2)
        mp.CreateNewNode(13, 0.9, 0.8, 0.2)
        mp.CreateNewNode(14, 0.3, 0.7, 0.2)
        mp.CreateNewNode(15, 0.6, 0.6, 0.2)

        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,
            mp)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15])

        #create Element
        mp.CreateNewElement("SmallDisplacementElement3D6N", 1,
                            [1, 2, 5, 6, 7, 10],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D6N", 2,
                            [2, 3, 5, 7, 8, 10],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D6N", 3,
                            [3, 4, 5, 8, 9, 10],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D6N", 4,
                            [4, 1, 5, 9, 6, 10],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D6N", 5,
                            [6, 7, 10, 11, 12, 15],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D6N", 6,
                            [7, 8, 10, 12, 13, 15],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D6N", 7,
                            [8, 9, 10, 13, 14, 15],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D6N", 8,
                            [9, 6, 10, 14, 11, 15],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def test_SmallDisplacementElement_3D_hexa(self):
        dim = 3
        current_model = KratosMultiphysics.Model()
        mp = current_model.CreateModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.00000, 1.00000, 1.00000)
        mp.CreateNewNode(2, 0.16500, 0.74500, 0.70200)
        mp.CreateNewNode(3, 0.27300, 0.75000, 0.23000)
        mp.CreateNewNode(4, 0.78800, 0.69300, 0.64400)
        mp.CreateNewNode(5, 0.32000, 0.18600, 0.64300)
        mp.CreateNewNode(6, 0.00000, 1.00000, 0.00000)
        mp.CreateNewNode(7, 0.00000, 0.00000, 1.00000)
        mp.CreateNewNode(8, 1.00000, 1.00000, 1.00000)
        mp.CreateNewNode(9, 0.67700, 0.30500, 0.68300)
        mp.CreateNewNode(10, 0.24900, 0.34200, 0.19200)
        mp.CreateNewNode(11, 0.85000, 0.64900, 0.26300)
        mp.CreateNewNode(12, 0.82600, 0.28800, 0.28800)
        mp.CreateNewNode(13, 0.00000, 0.00000, 0.00000)
        mp.CreateNewNode(14, 1.00000, 1.00000, 0.00000)
        mp.CreateNewNode(15, 1.00000, 0.00000, 1.00000)
        mp.CreateNewNode(16, 1.00000, 0.00000, 0.00000)

        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,
            mp)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 6, 7, 8, 13, 14, 15, 16])

        #create Element
        mp.CreateNewElement("SmallDisplacementElement3D8N", 1,
                            [10, 5, 2, 3, 13, 7, 1, 6],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D8N", 2,
                            [12, 9, 5, 10, 16, 15, 7, 13],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D8N", 3,
                            [12, 11, 3, 10, 9, 4, 2, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D8N", 4,
                            [9, 4, 2, 5, 15, 8, 1, 7],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D8N", 5,
                            [4, 11, 3, 2, 8, 14, 6, 1],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D8N", 6,
                            [11, 4, 9, 12, 14, 8, 15, 16],
                            mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementElement3D8N", 7,
                            [11, 12, 10, 3, 14, 16, 13, 6],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)
        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def __post_process(self, main_model_part):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(
            main_model_part, "gid_output",
            KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "nodal_results"       : ["DISPLACEMENT"],
                                                "gauss_point_results" : ["GREEN_LAGRANGE_STRAIN_TENSOR","CAUCHY_STRESS_TENSOR"]
                                            }
                                        }
                                        """))

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()
Beispiel #8
0
class TestPatchTestShells(KratosUnittest.TestCase):
    def setUp(self):
        pass


    def _add_variables(self,mp):
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.DISPLACEMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.ROTATION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION_MOMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.VOLUME_ACCELERATION)
        mp.AddNodalSolutionStepVariable(StructuralMechanicsApplication.POINT_LOAD)


    def _add_dofs(self,mp):
        # Adding the dofs AND their corresponding reaction!
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,mp)

        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.ROTATION_X, KratosMultiphysics.REACTION_MOMENT_X,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.ROTATION_Y, KratosMultiphysics.REACTION_MOMENT_Y,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.ROTATION_Z, KratosMultiphysics.REACTION_MOMENT_Z,mp)


    def _create_nodes(self,mp,element_name):
        mp.CreateNewNode(1, -0.5, - 0.45,  0.1)
        mp.CreateNewNode(2,  0.7,  -0.5,   0.2)
        mp.CreateNewNode(3,  0.55,  0.6,   0.15)
        mp.CreateNewNode(4, -0.48,  0.65,  0.0)
        mp.CreateNewNode(5,  0.02, -0.01, -0.15)

        if element_name.endswith("4N"): # create aditional nodes needed for quad-setup
            mp.CreateNewNode(6, -0.03, -0.5,   0.0)
            mp.CreateNewNode(7,  0.51,  0.02,  0.03)
            mp.CreateNewNode(8, -0.01,  0.52, -0.05)
            mp.CreateNewNode(9, -0.49, -0.0,   0.0)


    def _create_elements(self,mp,element_name):
        if element_name.endswith("4N"): # Quadrilaterals
            mp.CreateNewElement(element_name, 1, [1,6,5,9], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 2, [6,2,7,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 3, [5,7,3,8], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 4, [9,5,8,4], mp.GetProperties()[1])
        else: # Triangles
            mp.CreateNewElement(element_name, 1, [1,2,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 2, [2,3,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 3, [3,4,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 4, [4,1,5], mp.GetProperties()[1])


    def _apply_dirichlet_BCs(self,mp):
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.DISPLACEMENT_X, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.DISPLACEMENT_Y, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.DISPLACEMENT_Z, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.ROTATION_X, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.ROTATION_Y, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.ROTATION_Z, True, mp.Nodes)


    def _apply_neumann_BCs(self,mp):
        for node in mp.Nodes:
            node.SetSolutionStepValue(StructuralMechanicsApplication.POINT_LOAD,0,[6.1,-5.5,8.9])
            mp.CreateNewCondition("PointLoadCondition3D1N",1,[node.Id],mp.GetProperties()[1])


    def _apply_material_properties(self,mp):
        #define properties
        mp.GetProperties()[1].SetValue(KratosMultiphysics.YOUNG_MODULUS,100e3)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.POISSON_RATIO,0.3)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.THICKNESS,1.0)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.DENSITY,1.0)

        g = [0,0,0]
        mp.GetProperties()[1].SetValue(KratosMultiphysics.VOLUME_ACCELERATION,g)

        cl = StructuralMechanicsApplication.LinearElasticPlaneStress2DLaw()

        mp.GetProperties()[1].SetValue(KratosMultiphysics.CONSTITUTIVE_LAW,cl)


    def _solve(self,mp):
        #define a minimal newton raphson solver
        linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        builder_and_solver = KratosMultiphysics.ResidualBasedBlockBuilderAndSolver(linear_solver)
        scheme = KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme()
        convergence_criterion = KratosMultiphysics.ResidualCriteria(1e-14,1e-20)

        max_iters = 20
        compute_reactions = True
        reform_step_dofs = True
        calculate_norm_dx = False
        move_mesh_flag = True
        strategy = KratosMultiphysics.ResidualBasedLinearStrategy(mp,
                                                                  scheme,
                                                                  linear_solver,
                                                                  builder_and_solver,
                                                                  compute_reactions,
                                                                  reform_step_dofs,
                                                                  calculate_norm_dx,
                                                                  move_mesh_flag)
        strategy.SetEchoLevel(0)

        strategy.Check()
        strategy.Solve()


    def _check_results(self,node,displacement_results, rotation_results):
        #check that the results are exact on the node
        disp = node.GetSolutionStepValue(KratosMultiphysics.DISPLACEMENT)
        self.assertAlmostEqual(disp[0], displacement_results[0], 10)
        self.assertAlmostEqual(disp[1], displacement_results[1], 10)
        self.assertAlmostEqual(disp[2], displacement_results[2], 10)

        rot = node.GetSolutionStepValue(KratosMultiphysics.ROTATION)
        self.assertAlmostEqual(rot[0], rotation_results[0], 10)
        self.assertAlmostEqual(rot[1], rotation_results[1], 10)
        self.assertAlmostEqual(rot[2], rotation_results[2], 10)


    def execute_shell_test(self, element_name, displacement_results, rotation_results, do_post_processing):
        mp = KratosMultiphysics.ModelPart("solid_part")
        mp.SetBufferSize(2)

        self._add_variables(mp)
        self._apply_material_properties(mp)
        self._create_nodes(mp,element_name)
        self._add_dofs(mp)
        self._create_elements(mp,element_name)

        #create a submodelpart for dirichlet boundary conditions
        bcs_dirichlet = mp.CreateSubModelPart("BoundaryCondtionsDirichlet")
        bcs_dirichlet.AddNodes([1,2,4])

        #create a submodelpart for neumann boundary conditions
        bcs_neumann = mp.CreateSubModelPart("BoundaryCondtionsNeumann")
        bcs_neumann.AddNodes([3])

        self._apply_dirichlet_BCs(bcs_dirichlet)
        self._apply_neumann_BCs(bcs_neumann)
        self._solve(mp)

        self._check_results(mp.Nodes[3],displacement_results, rotation_results)

        if do_post_processing:
            self.__post_process(mp)


    def test_thin_shell_triangle(self):
        element_name = "ShellThinElementCorotational3D3N"
        displacement_results = [0.0002324779832 , -0.0002233435997 , 0.0002567143455]
        rotation_results     = [0.0003627433341 , -0.0001926662603 , -0.0004682681704]

        self.execute_shell_test(element_name,
                                displacement_results,
                                rotation_results,
                                False) # Do PostProcessing for GiD?


    def test_thick_shell_triangle(self):
        element_name = "ShellThickElementCorotational3D3N"
        displacement_results = [7.18997182e-05 , -0.0001572802804 , 0.0005263940488]
        rotation_results     = [0.0003316612014 , -0.0002798472414 , 5.141506e-07]

        self.execute_shell_test(element_name,
                                displacement_results,
                                rotation_results,
                                False) # Do PostProcessing for GiD?


    def test_thin_shell_quadrilateral(self):
        element_name = "ShellThinElementCorotational3D4N"
        displacement_results = [0.0021909310921 , -0.0021683746759 , 0.0007191338749]
        rotation_results     = [0.0028191154606 , 0.0008171818407 , -0.0069146010725]

        self.execute_shell_test(element_name,
                                displacement_results,
                                rotation_results,
                                False) # Do PostProcessing for GiD?


    def test_thick_shell_quadrilateral(self):
        element_name = "ShellThickElementCorotational3D4N"
        displacement_results = [0.0003572969872 , -0.0006341259132 , 0.00127807995001]
        rotation_results     = [0.0012082600485 , -0.0004098356773 , -0.0011673798349]

        self.execute_shell_test(element_name,
                                displacement_results,
                                rotation_results,
                                False) # Do PostProcessing for GiD?


    def __post_process(self, main_model_part):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(main_model_part,
                                    "gid_output",
                                    KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "nodal_results"       : ["DISPLACEMENT", "ROTATION", "POINT_LOAD"],
                                                "gauss_point_results" : ["GREEN_LAGRANGE_STRAIN_TENSOR","CAUCHY_STRESS_TENSOR"]
                                            }
                                        }
                                        """)
                                    )

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()
Beispiel #9
0
class TestQuadraticElements(KratosUnittest.TestCase):
    def setUp(self):
        pass

    def _add_variables(self, mp):
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.DISPLACEMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.VOLUME_ACCELERATION)

    def _apply_BCs(self, mp, coeff=1.0):
        for node in mp.Nodes:
            node.Fix(KratosMultiphysics.DISPLACEMENT_X)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Y)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Z)

        for node in mp.Nodes:
            u = KratosMultiphysics.Vector(3)
            u[0] = coeff * node.X0**2
            u[1] = coeff * node.Y0**2
            u[2] = coeff * node.Z0**2

            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT, 0, u)

    def _apply_material_properties(self, mp, dim):
        #define properties
        mp.GetProperties()[0].SetValue(KratosMultiphysics.YOUNG_MODULUS, 210e9)
        mp.GetProperties()[0].SetValue(KratosMultiphysics.POISSON_RATIO, 0.3)
        mp.GetProperties()[0].SetValue(KratosMultiphysics.THICKNESS, 1.0)
        mp.GetProperties()[0].SetValue(KratosMultiphysics.DENSITY, 1.0)

        g = [0, 0, 0]
        mp.GetProperties()[0].SetValue(KratosMultiphysics.VOLUME_ACCELERATION,
                                       g)

        if (dim == 2):
            cl = StructuralMechanicsApplication.LinearElasticPlaneStress2DLaw()
        else:
            cl = StructuralMechanicsApplication.LinearElastic3DLaw()
        mp.GetProperties()[0].SetValue(KratosMultiphysics.CONSTITUTIVE_LAW, cl)

    def _solve(self, mp):

        #define a minimal newton raphson solver
        linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        builder_and_solver = KratosMultiphysics.ResidualBasedBlockBuilderAndSolver(
            linear_solver)
        scheme = KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme(
        )
        convergence_criterion = KratosMultiphysics.ResidualCriteria(
            1e-14, 1e-20)

        max_iters = 20
        compute_reactions = True
        reform_step_dofs = True
        calculate_norm_dx = False
        move_mesh_flag = True
        strategy = KratosMultiphysics.ResidualBasedLinearStrategy(
            mp, scheme, linear_solver, builder_and_solver, compute_reactions,
            reform_step_dofs, calculate_norm_dx, move_mesh_flag)

        #strategy = KratosMultiphysics.ResidualBasedNewtonRaphsonStrategy(mp,
        #scheme,
        #linear_solver,
        #convergence_criterion,
        #builder_and_solver,
        #max_iters,
        #compute_reactions,
        #reform_step_dofs,
        #move_mesh_flag)
        strategy.SetEchoLevel(0)

        strategy.Check()
        strategy.Solve()

    def _check_outputs(self, mp, dim, coeff=1.0):
        for elem in mp.Elements:
            strains = elem.CalculateOnIntegrationPoints(
                KratosMultiphysics.GREEN_LAGRANGE_STRAIN_VECTOR,
                mp.ProcessInfo)
            coords = elem.CalculateOnIntegrationPoints(
                KratosMultiphysics.INTEGRATION_COORDINATES, mp.ProcessInfo)
            for strain, coord in zip(strains, coords):
                for i in range(2):
                    self.assertLessEqual(
                        abs((coord[i] - 0.5 * strain[i] / coeff) / coord[i]),
                        5.0e-2)

    def test_Quad8(self):
        dim = 2
        current_model = KratosMultiphysics.Model()
        mp = current_model.CreateModelPart("solid_part")
        self._add_variables(mp)

        #KratosMultiphysics.ModelPartIO("quadratic_test/static_quadratic_quad_test").ReadModelPart(mp)

        self._apply_material_properties(mp, dim)

        # Create nodes
        mp.CreateNewNode(1, 0.0000000000, 2.0000000000, 0.0000000000)
        mp.CreateNewNode(2, 0.0000000000, 1.7500000000, 0.0000000000)
        mp.CreateNewNode(3, 0.2500000000, 1.9375000000, 0.0000000000)
        mp.CreateNewNode(4, 0.0000000000, 1.5000000000, 0.0000000000)
        mp.CreateNewNode(5, 0.5000000000, 1.8750000000, 0.0000000000)
        mp.CreateNewNode(6, 0.2500000000, 1.4610595703, 0.0000000000)
        mp.CreateNewNode(7, 0.5000000000, 1.6485595703, 0.0000000000)
        mp.CreateNewNode(8, 0.0000000000, 1.2500000000, 0.0000000000)
        mp.CreateNewNode(9, 0.5000000000, 1.4287109375, 0.0000000000)
        mp.CreateNewNode(10, 0.7500000000, 1.8125000000, 0.0000000000)
        mp.CreateNewNode(11, 0.5000000000, 1.2132568359, 0.0000000000)
        mp.CreateNewNode(12, 0.7500000000, 1.4007568359, 0.0000000000)
        mp.CreateNewNode(13, 0.0000000000, 1.0000000000, 0.0000000000)
        mp.CreateNewNode(14, 1.0000000000, 1.7500000000, 0.0000000000)
        mp.CreateNewNode(15, 0.2500000000, 1.0000000000, 0.0000000000)
        mp.CreateNewNode(16, 1.0000000000, 1.5625000000, 0.0000000000)
        mp.CreateNewNode(17, 0.5000000000, 1.0000000000, 0.0000000000)
        mp.CreateNewNode(18, 1.0000000000, 1.3750000000, 0.0000000000)
        mp.CreateNewNode(19, 0.0000000000, 0.7500000000, 0.0000000000)
        mp.CreateNewNode(20, 0.7500000000, 1.0000000000, 0.0000000000)
        mp.CreateNewNode(21, 1.2500000000, 1.6875000000, 0.0000000000)
        mp.CreateNewNode(22, 1.0000000000, 1.1875000000, 0.0000000000)
        mp.CreateNewNode(23, 0.5000000000, 0.7867431641, 0.0000000000)
        mp.CreateNewNode(24, 1.2500000000, 1.3492431641, 0.0000000000)
        mp.CreateNewNode(25, 1.0000000000, 1.0000000000, 0.0000000000)
        mp.CreateNewNode(26, 0.2500000000, 0.5389404297, 0.0000000000)
        mp.CreateNewNode(27, 0.0000000000, 0.5000000000, 0.0000000000)
        mp.CreateNewNode(28, 0.5000000000, 0.5712890625, 0.0000000000)
        mp.CreateNewNode(29, 1.5000000000, 1.6250000000, 0.0000000000)
        mp.CreateNewNode(30, 1.0000000000, 0.8125000000, 0.0000000000)
        mp.CreateNewNode(31, 1.5000000000, 1.4764404297, 0.0000000000)
        mp.CreateNewNode(32, 0.7500000000, 0.5992431641, 0.0000000000)
        mp.CreateNewNode(33, 1.2500000000, 1.0000000000, 0.0000000000)
        mp.CreateNewNode(34, 1.5000000000, 1.3212890625, 0.0000000000)
        mp.CreateNewNode(35, 1.0000000000, 0.6250000000, 0.0000000000)
        mp.CreateNewNode(36, 1.5000000000, 1.1617431641, 0.0000000000)
        mp.CreateNewNode(37, 0.5000000000, 0.3514404297, 0.0000000000)
        mp.CreateNewNode(38, 0.0000000000, 0.2500000000, 0.0000000000)
        mp.CreateNewNode(39, 1.5000000000, 1.0000000000, 0.0000000000)
        mp.CreateNewNode(40, 1.7500000000, 1.5625000000, 0.0000000000)
        mp.CreateNewNode(41, 1.2500000000, 0.6507568359, 0.0000000000)
        mp.CreateNewNode(42, 1.0000000000, 0.4375000000, 0.0000000000)
        mp.CreateNewNode(43, 1.7500000000, 1.2889404297, 0.0000000000)
        mp.CreateNewNode(44, 1.5000000000, 0.8382568359, 0.0000000000)
        mp.CreateNewNode(45, 0.5000000000, 0.1250000000, 0.0000000000)
        mp.CreateNewNode(46, 0.2500000000, 0.0625000000, 0.0000000000)
        mp.CreateNewNode(47, 0.7500000000, 0.1875000000, 0.0000000000)
        mp.CreateNewNode(48, 1.5000000000, 0.6787109375, 0.0000000000)
        mp.CreateNewNode(49, 0.0000000000, 0.0000000000, 0.0000000000)
        mp.CreateNewNode(50, 1.0000000000, 0.2500000000, 0.0000000000)
        mp.CreateNewNode(51, 1.7500000000, 1.0000000000, 0.0000000000)
        mp.CreateNewNode(52, 2.0000000000, 1.5000000000, 0.0000000000)
        mp.CreateNewNode(53, 2.0000000000, 1.3750000000, 0.0000000000)
        mp.CreateNewNode(54, 1.2500000000, 0.3125000000, 0.0000000000)
        mp.CreateNewNode(55, 1.5000000000, 0.5235595703, 0.0000000000)
        mp.CreateNewNode(56, 2.0000000000, 1.2500000000, 0.0000000000)
        mp.CreateNewNode(57, 1.7500000000, 0.7110595703, 0.0000000000)
        mp.CreateNewNode(58, 2.0000000000, 1.1250000000, 0.0000000000)
        mp.CreateNewNode(59, 1.5000000000, 0.3750000000, 0.0000000000)
        mp.CreateNewNode(60, 2.0000000000, 1.0000000000, 0.0000000000)
        mp.CreateNewNode(61, 2.0000000000, 0.8750000000, 0.0000000000)
        mp.CreateNewNode(62, 1.7500000000, 0.4375000000, 0.0000000000)
        mp.CreateNewNode(63, 2.0000000000, 0.7500000000, 0.0000000000)
        mp.CreateNewNode(64, 2.0000000000, 0.6250000000, 0.0000000000)
        mp.CreateNewNode(65, 2.0000000000, 0.5000000000, 0.0000000000)

        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,
            mp)

        # Create Element
        mp.CreateNewElement("SmallDisplacementElement2D8N", 1,
                            [45, 28, 27, 49, 37, 26, 38, 46],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 2,
                            [50, 35, 28, 45, 42, 32, 37, 47],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 3,
                            [59, 48, 35, 50, 55, 41, 42, 54],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 4,
                            [65, 63, 48, 59, 64, 57, 55, 62],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 5,
                            [28, 17, 13, 27, 23, 15, 19, 26],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 6,
                            [35, 25, 17, 28, 30, 20, 23, 32],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 7,
                            [48, 39, 25, 35, 44, 33, 30, 41],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 8,
                            [63, 60, 39, 48, 61, 51, 44, 57],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 9,
                            [17, 9, 4, 13, 11, 6, 8, 15],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 10,
                            [25, 18, 9, 17, 22, 12, 11, 20],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 11,
                            [39, 34, 18, 25, 36, 24, 22, 33],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 12,
                            [60, 56, 34, 39, 58, 43, 36, 51],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 13,
                            [9, 5, 1, 4, 7, 3, 2, 6],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 14,
                            [18, 14, 5, 9, 16, 10, 7, 12],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 15,
                            [34, 29, 14, 18, 31, 21, 16, 24],
                            mp.GetProperties()[0])
        mp.CreateNewElement("SmallDisplacementElement2D8N", 16,
                            [56, 52, 29, 34, 53, 40, 31, 43],
                            mp.GetProperties()[0])

        coeff = 1.0e-2
        self._apply_BCs(mp, coeff)
        self._solve(mp)
        self._check_outputs(mp, dim, coeff)

        #self.__post_process(mp)

    def __post_process(self, main_model_part):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(
            main_model_part, "gid_output",
            KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "nodal_results"       : ["DISPLACEMENT"],
                                                "gauss_point_results" : ["GREEN_LAGRANGE_STRAIN_TENSOR","CAUCHY_STRESS_TENSOR"]
                                            }
                                        }
                                        """))

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()
class TestPatchTestSmallStrainBbar(KratosUnittest.TestCase):
    def setUp(self):
        pass

    def _add_variables(self,mp):
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.DISPLACEMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.VOLUME_ACCELERATION)


    def _apply_BCs(self,mp,A,b):
        for node in mp.Nodes:
            node.Fix(KratosMultiphysics.DISPLACEMENT_X)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Y)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Z)

        for node in mp.Nodes:
            xvec = KratosMultiphysics.Vector(3)
            xvec[0] = node.X0
            xvec[1] = node.Y0
            xvec[2] = node.Z0

            u = A*xvec
            u += b

            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT,0,u)

    def _apply_material_properties(self,mp,dim):
        #define properties
        mp.GetProperties()[1].SetValue(KratosMultiphysics.YOUNG_MODULUS, 21000)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.POISSON_RATIO, 0.3)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.YIELD_STRESS, 5.5)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.ISOTROPIC_HARDENING_MODULUS, 0.12924)
        mp.GetProperties()[1].SetValue(StructuralMechanicsApplication.EXPONENTIAL_SATURATION_YIELD_STRESS, 5.5)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.HARDENING_EXPONENT, 1.0)

        g = [0,0,0]
        mp.GetProperties()[1].SetValue(KratosMultiphysics.VOLUME_ACCELERATION,g)

        if(dim == 2):
            cl = StructuralMechanicsApplication.SmallStrainJ2PlasticityPlaneStrain2DLaw()
        else:
            cl = StructuralMechanicsApplication.SmallStrainJ2Plasticity3DLaw()
        mp.GetProperties()[1].SetValue(KratosMultiphysics.CONSTITUTIVE_LAW,cl)

    def _define_movement(self,dim):
        if(dim == 2):
            #define the applied motion - the idea is that the displacement is defined as u = A*xnode + b
            #so that the displcement is linear and the exact F = I + A
            A = KratosMultiphysics.Matrix(3,3)
            A[0,0] = 1.0e-10;  A[0,1] = 2.0e-10; A[0,2] = 0.0
            A[1,0] = 0.5e-10;  A[1,1] = 0.7e-10; A[1,2] = 0.0
            A[2,0] = 0.0;      A[2,1] = 0.0;     A[2,2] = 0.0

            b = KratosMultiphysics.Vector(3)
            b[0] = 0.5e-10
            b[1] = -0.2e-10
            b[2] = 0.0

        else:
            #define the applied motion - the idea is that the displacement is defined as u = A*xnode + b
            #so that the displcement is linear and the exact F = I + A
            A = KratosMultiphysics.Matrix(3,3)
            A[0,0] = 1.0e-10;   A[0,1] = 2.0e-10; A[0,2] = 0.0
            A[1,0] = 0.5e-10;   A[1,1] = 0.7e-10; A[1,2] = 0.1e-10
            A[2,0] = -0.2e-10;  A[2,1] = 0.0;     A[2,2] = -0.3e-10

            b = KratosMultiphysics.Vector(3)
            b[0] = 0.5e-10
            b[1] = -0.2e-10
            b[2] = 0.7e-10



        return A,b

    def _solve(self,mp, linear = True):

        #define a minimal newton raphson solver
        linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        builder_and_solver = KratosMultiphysics.ResidualBasedBlockBuilderAndSolver(linear_solver)
        scheme = KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme()
        convergence_criterion = KratosMultiphysics.ResidualCriteria(1e-14,1e-20)

        max_iters = 20
        compute_reactions = True
        reform_step_dofs = True
        calculate_norm_dx = False
        move_mesh_flag = True
        if (linear):
            strategy = KratosMultiphysics.ResidualBasedLinearStrategy(mp,
                                                                            scheme,
                                                                            linear_solver,
                                                                            builder_and_solver,
                                                                            compute_reactions,
                                                                            reform_step_dofs,
                                                                            calculate_norm_dx,
                                                                            move_mesh_flag)

        else:
            strategy = KratosMultiphysics.ResidualBasedNewtonRaphsonStrategy(mp,
                                                                            scheme,
                                                                            linear_solver,
                                                                            convergence_criterion,
                                                                            builder_and_solver,
                                                                            max_iters,
                                                                            compute_reactions,
                                                                            reform_step_dofs,
                                                                            move_mesh_flag)
        strategy.SetEchoLevel(0)

        strategy.Check()
        strategy.Solve()


    def _check_results(self,mp,A,b):

        ##check that the results are exact on the nodes
        for node in mp.Nodes:
            xvec = KratosMultiphysics.Vector(3)
            xvec[0] = node.X0
            xvec[1] = node.Y0
            xvec[2] = node.Z0

            u = A*xvec
            u += b

            d = node.GetSolutionStepValue(KratosMultiphysics.DISPLACEMENT)
            self.assertAlmostEqual(d[0], u[0])
            self.assertAlmostEqual(d[1], u[1])
            self.assertAlmostEqual(d[2], u[2])

    def _check_outputs(self,mp,A,dim):

        E = mp.GetProperties()[1].GetValue(KratosMultiphysics.YOUNG_MODULUS)
        NU =mp.GetProperties()[1].GetValue(KratosMultiphysics.POISSON_RATIO)

        #given the matrix A, the analytic deformation graident is F+I
        F = A
        for i in range(3):
            F[i,i] += 1.0

        #here compute the Cauchy green strain tensor
        Etensor = KratosMultiphysics.Matrix(3,3)

        for i in range(3):
            for j in range(3):
                Etensor[i,j] = 0.0

        for i in range(3):
            for j in range(3):
                for k in range(3):
                    Etensor[i,j] += A[k,i]*A[k,j]

        for i in range(3):
            Etensor[i,i] -= 1.0

        for i in range(3):
            for j in range(3):
                Etensor[i,j] = 0.5*Etensor[i,j]

        if(dim == 2):
            #verify strain
            reference_strain = KratosMultiphysics.Vector(3)
            reference_strain[0] = Etensor[0,0]
            reference_strain[1] = Etensor[1,1]
            reference_strain[2] = 2.0*Etensor[0,1]
        else:
            reference_strain = KratosMultiphysics.Vector(6)
            reference_strain[0] = Etensor[0,0]
            reference_strain[1] = Etensor[1,1]
            reference_strain[2] = Etensor[2,2]
            reference_strain[3] = 2.0*Etensor[0,1]
            reference_strain[4] = 2.0*Etensor[1,2]
            reference_strain[5] = 2.0*Etensor[0,2]

        for elem in mp.Elements:
            out = elem.CalculateOnIntegrationPoints(KratosMultiphysics.GREEN_LAGRANGE_STRAIN_VECTOR, mp.ProcessInfo)
            for strain in out:
                for i in range(len(reference_strain)):
                    self.assertAlmostEqual(reference_strain[i], strain[i])

        #finally compute stress
        if(dim == 2):
            #here assume plane stress
            c1 = E / (1.00 - NU*NU);
            c2 = c1 * NU;
            c3 = 0.5* E / (1 + NU);
            reference_stress = KratosMultiphysics.Vector(3)
            reference_stress[0] = c1*reference_strain[0] + c2 * (reference_strain[1])	;
            reference_stress[1] = c1*reference_strain[1] + c2 * (reference_strain[0])	;
            reference_stress[2] = c3*reference_strain[2];
        else:
            c1 = E / (( 1.00 + NU ) * ( 1 - 2 * NU ) );
            c2 = c1 * ( 1 - NU );
            c3 = c1 * NU;
            c4 = c1 * 0.5 * ( 1 - 2 * NU );
            reference_stress = KratosMultiphysics.Vector(6)
            reference_stress[0] = c2*reference_strain[0] + c3 * (reference_strain[1] + reference_strain[2])
            reference_stress[1] = c2*reference_strain[1] + c3 * (reference_strain[0] + reference_strain[2])
            reference_stress[2] = c2*reference_strain[2] + c3 * (reference_strain[0] + reference_strain[1])
            reference_stress[3] = c4*reference_strain[3]
            reference_stress[4] = c4*reference_strain[4]
            reference_stress[5] = c4*reference_strain[5]

        for elem in mp.Elements:
            out = elem.CalculateOnIntegrationPoints(KratosMultiphysics.PK2_STRESS_VECTOR, mp.ProcessInfo)
            for stress in out:
                for i in range(len(reference_stress)):
                    self.assertAlmostEqual(reference_stress[i], stress[i],2)

    def test_SmallDisplacementBbarElement_2D_quadrilateral(self):
        dim = 2

        current_model = KratosMultiphysics.Model()
        mp = current_model.CreateModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp,dim)

        #create nodes
        mp.CreateNewNode(1,0.00,3.00,0.00)
        mp.CreateNewNode(2,1.00,2.25,0.00)
        mp.CreateNewNode(3,0.75,1.00,0.00)
        mp.CreateNewNode(4,2.25,2.00,0.00)
        mp.CreateNewNode(5,0.00,0.00,0.00)
        mp.CreateNewNode(6,3.00,3.00,0.00)
        mp.CreateNewNode(7,2.00,0.75,0.00)
        mp.CreateNewNode(8,3.00,0.00,0.00)

        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,mp)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1,5,6,8])

        #create Element
        mp.CreateNewElement("SmallDisplacementBbarElement2D4N", 1, [8,7,3,5], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement2D4N", 2, [6,4,7,8], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement2D4N", 3, [1,2,4,6], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement2D4N", 4, [4,2,3,7], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement2D4N", 5, [2,1,5,3], mp.GetProperties()[1])

        A,b = self._define_movement(dim)

        self._apply_BCs(bcs,A,b)
        self._solve(mp)
        self._check_results(mp,A,b)
        self._check_outputs(mp,A,dim)

        #self.__post_process(mp)

    def test_SmallDisplacementBbarElement_3D_hexa(self):
        dim = 3
        current_model = KratosMultiphysics.Model()
        mp = current_model.CreateModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp,dim)

        #create nodes
        mp.CreateNewNode(1, 0.00000,  1.00000,  1.00000)
        mp.CreateNewNode(2, 0.16500,  0.74500,  0.70200)
        mp.CreateNewNode(3, 0.27300,  0.75000,  0.23000)
        mp.CreateNewNode(4, 0.78800,  0.69300,  0.64400)
        mp.CreateNewNode(5, 0.32000,  0.18600,  0.64300)
        mp.CreateNewNode(6, 0.00000,  1.00000,  0.00000)
        mp.CreateNewNode(7, 0.00000,  0.00000,  1.00000)
        mp.CreateNewNode(8, 1.00000,  1.00000,  1.00000)
        mp.CreateNewNode(9, 0.67700,  0.30500,  0.68300)
        mp.CreateNewNode(10, 0.24900,  0.34200,  0.19200)
        mp.CreateNewNode(11, 0.85000,  0.64900,  0.26300)
        mp.CreateNewNode(12, 0.82600,  0.28800,  0.28800)
        mp.CreateNewNode(13, 0.00000,  0.00000,  0.00000)
        mp.CreateNewNode(14, 1.00000,  1.00000,  0.00000)
        mp.CreateNewNode(15, 1.00000,  0.00000,  1.00000)
        mp.CreateNewNode(16, 1.00000,  0.00000,  0.00000)

        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,mp)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1,6,7,8,13,14,15,16])

        #create Element
        mp.CreateNewElement("SmallDisplacementBbarElement3D8N", 1,[10,5,2,3,13,7,1,6], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement3D8N", 2,[12,9,5,10,16,15,7,13], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement3D8N", 3,[12,11,3,10,9,4,2,5], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement3D8N", 4,[9,4,2,5,15,8,1,7], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement3D8N", 5,[4,11,3,2,8,14,6,1], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement3D8N", 6,[11,4,9,12,14,8,15,16], mp.GetProperties()[1])
        mp.CreateNewElement("SmallDisplacementBbarElement3D8N", 7,[11,12,10,3,14,16,13,6], mp.GetProperties()[1])

        A,b = self._define_movement(dim)
        self._apply_BCs(bcs,A,b)
        self._solve(mp)
        self._check_results(mp,A,b)
        self._check_outputs(mp,A,dim)

        #self.__post_process(mp)

    def __post_process(self, main_model_part):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(main_model_part,
                                    "gid_output",
                                    KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "nodal_results"       : ["DISPLACEMENT"],
                                                "gauss_point_results" : ["GREEN_LAGRANGE_STRAIN_TENSOR","CAUCHY_STRESS_TENSOR"]
                                            }
                                        }
                                        """)
                                    )

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()
Beispiel #11
0
class TestDynamicSearch(KratosUnittest.TestCase):
    def setUp(self):
        pass

    def _dynamic_search_tests(self, input_filename, num_nodes):
        KM.Logger.GetDefaultOutput().SetSeverity(KM.Logger.Severity.WARNING)

        self.model = KM.Model()
        self.main_model_part = self.model.CreateModelPart("Structure", 2)

        ## Creation of the Kratos model (build sub_model_parts or submeshes)
        self.StructureModel = {"Structure": self.main_model_part}

        self.main_model_part.AddNodalSolutionStepVariable(KM.DISPLACEMENT)
        self.main_model_part.AddNodalSolutionStepVariable(KM.VELOCITY)
        self.main_model_part.AddNodalSolutionStepVariable(KM.ACCELERATION)
        self.main_model_part.AddNodalSolutionStepVariable(
            KM.VOLUME_ACCELERATION)
        self.main_model_part.AddNodalSolutionStepVariable(KM.REACTION)
        self.main_model_part.AddNodalSolutionStepVariable(KM.NORMAL)
        self.main_model_part.AddNodalSolutionStepVariable(
            CSMA.LAGRANGE_MULTIPLIER_CONTACT_PRESSURE)
        self.main_model_part.AddNodalSolutionStepVariable(CSMA.WEIGHTED_GAP)
        self.main_model_part.AddNodalSolutionStepVariable(KM.NODAL_H)

        self.main_model_part.CloneTimeStep(1.01)

        KM.ModelPartIO(input_filename).ReadModelPart(self.main_model_part)

        KM.VariableUtils().AddDof(KM.DISPLACEMENT_X, KM.REACTION_X,
                                  self.main_model_part)
        KM.VariableUtils().AddDof(KM.DISPLACEMENT_Y, KM.REACTION_Y,
                                  self.main_model_part)
        KM.VariableUtils().AddDof(KM.DISPLACEMENT_Z, KM.REACTION_Z,
                                  self.main_model_part)
        KM.VariableUtils().AddDof(CSMA.LAGRANGE_MULTIPLIER_CONTACT_PRESSURE,
                                  CSMA.WEIGHTED_GAP, self.main_model_part)

        if (self.main_model_part.HasSubModelPart("Contact")):
            interface_model_part = self.main_model_part.GetSubModelPart(
                "Contact")
        else:
            interface_model_part = self.main_model_part.CreateSubModelPart(
                "Contact")

        self.contact_model_part = self.main_model_part.GetSubModelPart(
            "DISPLACEMENT_Displacement_Auto2")

        model_part_slave = self.main_model_part.GetSubModelPart(
            "Parts_Parts_Auto1")
        model_part_master = self.main_model_part.GetSubModelPart(
            "Parts_Parts_Auto2")
        KM.VariableUtils().SetFlag(KM.SLAVE, False,
                                   self.contact_model_part.Nodes)
        KM.VariableUtils().SetFlag(KM.MASTER, True,
                                   self.contact_model_part.Nodes)
        KM.VariableUtils().SetFlag(KM.SLAVE, True, model_part_slave.Nodes)
        KM.VariableUtils().SetFlag(KM.MASTER, False, model_part_slave.Nodes)

        for node in model_part_slave.Nodes:
            # DEBUG
            #node.X -= 9.81 / 32.0
            #node.SetSolutionStepValue(KM.DISPLACEMENT_X, -9.81 / 32.0)
            node.SetSolutionStepValue(KM.ACCELERATION_X, 1, -9.81)
        del (node)

        self.main_model_part.ProcessInfo[KM.STEP] = 1
        self.main_model_part.ProcessInfo[KM.DELTA_TIME] = 0.5

        for prop in self.main_model_part.GetProperties():
            prop[CSMA.INTEGRATION_ORDER_CONTACT] = 3

        self.main_model_part.ProcessInfo[CSMA.ACTIVE_CHECK_FACTOR] = 3.0e-1

        KM.VariableUtils().SetFlag(KM.INTERFACE, True,
                                   self.contact_model_part.Nodes)

        pre_process = CSMA.InterfacePreprocessCondition(self.main_model_part)

        interface_parameters = KM.Parameters(
            """{"simplify_geometry": false}""")
        pre_process.GenerateInterfacePart3D(self.contact_model_part,
                                            interface_parameters)

        # We copy the conditions to the ContactSubModelPart
        for cond in self.contact_model_part.Conditions:
            interface_model_part.AddCondition(cond)
        del (cond)
        for node in self.contact_model_part.Nodes:
            interface_model_part.AddNode(node, 0)
        del (node)

        # We compute NODAL_H that can be used in the search and some values computation
        self.find_nodal_h = KM.FindNodalHProcess(self.contact_model_part)
        self.find_nodal_h.Execute()

        # We initialize the conditions
        alm_init_var = CSMA.ALMFastInit(self.contact_model_part)
        alm_init_var.Execute()

        search_parameters = KM.Parameters("""
        {
            "dynamic_search"              : true
        }
        """)
        if (num_nodes == 3):
            contact_search = CSMA.TreeContactSearch3D3N(
                self.main_model_part, search_parameters)
        else:
            contact_search = CSMA.TreeContactSearch3D4N(
                self.main_model_part, search_parameters)

        # We initialize the search utility
        contact_search.CreatePointListMortar()
        contact_search.InitializeMortarConditions()
        contact_search.UpdateMortarConditions()

        ## DEBUG
        #self.__post_process()

        import from_json_check_result_process

        check_parameters = KM.Parameters("""
        {
            "check_variables"      : ["NORMAL_GAP"],
            "input_file_name"      : "",
            "model_part_name"      : "Structure",
            "historical_value"     : false,
            "time_frequency"       : 0.0,
            "sub_model_part_name"  : "Parts_Parts_Auto1"
        }
        """)

        check_parameters["input_file_name"].SetString(input_filename +
                                                      "_dynamic_search.json")

        check = from_json_check_result_process.FromJsonCheckResultProcess(
            self.StructureModel, check_parameters)
        check.ExecuteInitialize()
        check.ExecuteBeforeSolutionLoop()
        check.ExecuteFinalizeSolutionStep()

        #import json_output_process

        #out_parameters = KM.Parameters("""
        #{
        #"output_variables"     : ["NORMAL_GAP"],
        #"output_file_name"     : "",
        #"model_part_name"      : "Structure",
        #"historical_value"     : false,
        #"time_frequency"       : 0.0,
        #"sub_model_part_name"  : "Parts_Parts_Auto1"
        #}
        #""")

        #out_parameters["output_file_name"].SetString(input_filename + "_dynamic_search.json")

        #out = json_output_process.JsonOutputProcess(self.StructureModel, out_parameters)
        #out.ExecuteInitialize()
        #out.ExecuteBeforeSolutionLoop()
        #out.ExecuteFinalizeSolutionStep()

    def test_dynamic_search_triangle(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/integration_tests/test_double_curvature_integration_triangle"

        self._dynamic_search_tests(input_filename, 3)

    def test_dynamic_search_quad(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/integration_tests/test_double_curvature_integration_quadrilateral"

        self._dynamic_search_tests(input_filename, 4)

    def __post_process(self):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(
            self.main_model_part, "gid_output",
            KM.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "nodal_results"       : ["NORMAL","DISPLACEMENT","VELOCITY","ACCELERATION"],
                                                "nodal_nonhistorical_results": ["DELTA_COORDINATES","AUXILIAR_COORDINATES","NORMAL_GAP"],
                                                "nodal_flags_results": ["ACTIVE","SLAVE","MASTER"]
                                            }
                                        }
                                        """))

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()
Beispiel #12
0
        for process in reversed(remeshing_processes):
            process.ExecuteInitialize()
            process.ExecuteBeforeSolutionLoop()
            process.ExecuteInitializeSolutionStep()

            if (output_post == True):
                output_settings = ProjectParameters["output_configuration"]
                gid_output_initial = GiDOutputProcess(
                    solver.GetComputingModelPart(),
                    problem_name + "_" + str(n + 1), output_settings)
                gid_output_initial.ExecuteInitialize()
                gid_output_initial.ExecuteBeforeSolutionLoop()
                gid_output_initial.ExecuteInitializeSolutionStep()
                gid_output_initial.ExecuteFinalizeSolutionStep()
                gid_output_initial.PrintOutput()
                gid_output_initial.ExecuteFinalize()

# Obtain the list of the processes to be applied
list_of_processes = process_factory.KratosProcessFactory(
    Model).ConstructListOfProcesses(ProjectParameters["gravity"])
list_of_processes += process_factory.KratosProcessFactory(
    Model).ConstructListOfProcesses(
        ProjectParameters["initial_conditions_process_list"])
list_of_processes += process_factory.KratosProcessFactory(
    Model).ConstructListOfProcesses(
        ProjectParameters["boundary_conditions_process_list"])
if (ProjectParameters.Has("list_other_processes") == True):
    list_of_processes += process_factory.KratosProcessFactory(
        Model).ConstructListOfProcesses(
            ProjectParameters["list_other_processes"])
if (ProjectParameters.Has("json_check_process") == True):
class KratosExecuteMapperTest:
    def __init__(self, ProjectParameters):

        # Json format solvers settings
        ProjectParametersFluid = ProjectParameters["fluid_solver_settings"]
        ProjectParametersSolid = ProjectParameters["structure_solver_settings"]

        # Defining a model part for the fluid and one for the structure
        self.structure_main_model_part = ModelPart("structure_part")
        self.fluid_main_model_part = ModelPart("fluid_part")

        # Set the domain size (2D or 3D test)
        self.structure_main_model_part.ProcessInfo.SetValue(
            DOMAIN_SIZE,
            ProjectParametersFluid["problem_data"]["domain_size"].GetInt())
        self.fluid_main_model_part.ProcessInfo.SetValue(
            DOMAIN_SIZE,
            ProjectParametersSolid["problem_data"]["domain_size"].GetInt())

        # Set the fluid and solid models
        FluidModel = {
            ProjectParametersFluid["problem_data"]["model_part_name"].GetString(
            ):
            self.structure_main_model_part
        }
        SolidModel = {
            ProjectParametersSolid["problem_data"]["model_part_name"].GetString(
            ):
            self.fluid_main_model_part
        }

        # Fluid model part variables addition
        self.fluid_main_model_part.AddNodalSolutionStepVariable(VELOCITY)
        self.fluid_main_model_part.AddNodalSolutionStepVariable(PRESSURE)
        self.fluid_main_model_part.AddNodalSolutionStepVariable(REACTION)

        # Structure model part variables addition
        self.structure_main_model_part.AddNodalSolutionStepVariable(VELOCITY)
        self.structure_main_model_part.AddNodalSolutionStepVariable(PRESSURE)
        self.structure_main_model_part.AddNodalSolutionStepVariable(POINT_LOAD)

        # Mapper variables addition
        NonConformant_OneSideMap.AddVariables(self.fluid_main_model_part,
                                              self.structure_main_model_part)

        # Fluid domain model reading
        ModelPartIO(
            ProjectParametersFluid["solver_settings"]["model_import_settings"]
            ["input_filename"].GetString()).ReadModelPart(
                self.fluid_main_model_part)
        prepare_model_part_settings_fluid = Parameters("{}")
        prepare_model_part_settings_fluid.AddValue(
            "volume_model_part_name", ProjectParametersFluid["solver_settings"]
            ["volume_model_part_name"])
        prepare_model_part_settings_fluid.AddValue(
            "skin_parts",
            ProjectParametersFluid["solver_settings"]["skin_parts"])
        import check_and_prepare_model_process_fluid
        check_and_prepare_model_process_fluid.CheckAndPrepareModelProcess(
            self.fluid_main_model_part,
            prepare_model_part_settings_fluid).Execute()

        # Solid domain model reading
        computing_model_part_name = "computing_domain"
        ModelPartIO(
            ProjectParametersSolid["solver_settings"]["model_import_settings"]
            ["input_filename"].GetString()).ReadModelPart(
                self.structure_main_model_part)
        prepare_model_part_settings_structure = Parameters("{}")
        prepare_model_part_settings_structure.AddEmptyValue(
            "computing_model_part_name").SetString(computing_model_part_name)
        prepare_model_part_settings_structure.AddValue(
            "problem_domain_sub_model_part_list",
            ProjectParametersSolid["solver_settings"]
            ["problem_domain_sub_model_part_list"])
        prepare_model_part_settings_structure.AddValue(
            "processes_sub_model_part_list",
            ProjectParametersSolid["solver_settings"]
            ["processes_sub_model_part_list"])
        import check_and_prepare_model_process_structural
        check_and_prepare_model_process_structural.CheckAndPrepareModelProcess(
            self.structure_main_model_part,
            prepare_model_part_settings_structure).Execute()

        # Get the list of the skin submodel parts where the fluid interface submodel part is stored
        for i in range(ProjectParametersFluid["solver_settings"]
                       ["skin_parts"].size()):
            skin_part_name = ProjectParametersFluid["solver_settings"][
                "skin_parts"][i].GetString()
            FluidModel.update({
                skin_part_name:
                self.fluid_main_model_part.GetSubModelPart(skin_part_name)
            })

        # Get the list of the submodel parts where the structure interface is stored
        for i in range(ProjectParametersSolid["solver_settings"]
                       ["processes_sub_model_part_list"].size()):
            part_name = ProjectParametersSolid["solver_settings"][
                "processes_sub_model_part_list"][i].GetString()
            SolidModel.update({
                part_name:
                self.structure_main_model_part.GetSubModelPart(part_name)
            })

        # Construct processes
        self.list_of_processes = process_factory.KratosProcessFactory(
            FluidModel).ConstructListOfProcesses(
                ProjectParametersFluid["boundary_conditions_process_list"])
        self.list_of_processes += process_factory.KratosProcessFactory(
            SolidModel).ConstructListOfProcesses(
                ProjectParametersSolid["constraints_process_list"])

        # Set fluid and structure interfaces
        for node in self.fluid_main_model_part.GetSubModelPart(
                "Fluid_interface").Nodes:
            node.Set(INTERFACE, True)
        for node in self.structure_main_model_part.GetSubModelPart(
                "Structure_interface").Nodes:
            node.Set(INTERFACE, True)

        for process in self.list_of_processes:
            process.ExecuteInitialize()

        # Mapper construction
        search_radius_factor = 2.0
        mapper_max_iterations = 200
        mapper_tolerance = 1e-12
        self.mapper = NonConformant_OneSideMap.NonConformant_OneSideMap(
            self.fluid_main_model_part, self.structure_main_model_part,
            search_radius_factor, mapper_max_iterations, mapper_tolerance)

        # Output settings
        self.output_post = False  # Set this variable to True if it is need to print the results for debugging purposes
        self.problem_path = os.getcwd()

        if (self.output_post == True):
            from gid_output_process import GiDOutputProcess

            self.gid_output_structure = GiDOutputProcess(
                self.structure_main_model_part,
                ProjectParametersSolid["problem_data"]
                ["problem_name"].GetString() + "_structure",
                ProjectParametersSolid["output_configuration"])

            self.gid_output_fluid = GiDOutputProcess(
                self.fluid_main_model_part,
                ProjectParametersFluid["problem_data"]
                ["problem_name"].GetString() + "_fluid",
                ProjectParametersFluid["output_configuration"])

            self.gid_output_structure.ExecuteInitialize()
            self.gid_output_fluid.ExecuteInitialize()

    def Solve(self):

        for process in self.list_of_processes:
            process.ExecuteBeforeSolutionLoop()

        if (self.output_post == True):
            self.gid_output_structure.ExecuteBeforeSolutionLoop()
            self.gid_output_fluid.ExecuteBeforeSolutionLoop()

        self.structure_main_model_part.ProcessInfo[TIME_STEPS] = 1
        self.structure_main_model_part.CloneTimeStep(1.0)
        self.fluid_main_model_part.ProcessInfo[TIME_STEPS] = 1
        self.fluid_main_model_part.CloneTimeStep(1.0)

        for process in self.list_of_processes:
            process.ExecuteInitializeSolutionStep()

        if (self.output_post == True):
            self.gid_output_structure.ExecuteInitializeSolutionStep()
            self.gid_output_fluid.ExecuteInitializeSolutionStep()

        # Solve: Information transfer
        self.mapper.FluidToStructure_ScalarMap(PRESSURE, PRESSURE, True)
        self.mapper.FluidToStructure_VectorMap(REACTION, POINT_LOAD, True,
                                               True)
        self.mapper.StructureToFluid_VectorMap(VELOCITY, VELOCITY, True, False)

        if (self.output_post == True):
            self.gid_output_structure.ExecuteFinalizeSolutionStep()
            self.gid_output_fluid.ExecuteFinalizeSolutionStep()

        for process in self.list_of_processes:
            process.ExecuteFinalizeSolutionStep()

        for process in self.list_of_processes:
            process.ExecuteBeforeOutputStep()

        for process in self.list_of_processes:
            process.ExecuteAfterOutputStep()

        if (self.output_post == True):
            self.gid_output_structure.PrintOutput()
            self.gid_output_fluid.PrintOutput()

        if (self.output_post == True):
            self.gid_output_structure.ExecuteFinalize()
            self.gid_output_fluid.ExecuteFinalize()

        for process in self.list_of_processes:
            process.ExecuteFinalize()
class Kratos_Execute_Test:
    def __init__(self, ProjectParameters):

        self.ProjectParameters = ProjectParameters

        self.main_model_part = ModelPart(self.ProjectParameters["problem_data"]
                                         ["model_part_name"].GetString())
        self.main_model_part.ProcessInfo.SetValue(
            DOMAIN_SIZE,
            self.ProjectParameters["problem_data"]["domain_size"].GetInt())

        self.Model = {
            self.ProjectParameters["problem_data"]["model_part_name"].GetString(
            ):
            self.main_model_part
        }

        # Construct the solver (main setting methods are located in the solver_module)
        solver_module = __import__(self.ProjectParameters["solver_settings"]
                                   ["solver_type"].GetString())
        self.solver = solver_module.CreateSolver(
            self.main_model_part, self.ProjectParameters["solver_settings"])

        # Add variables (always before importing the model part) (it must be integrated in the ImportModelPart)
        # If we integrate it in the model part we cannot use combined solvers
        self.solver.AddVariables()

        # Read model_part (note: the buffer_size is set here) (restart can be read here)
        self.solver.ImportModelPart()

        # Add dofs (always after importing the model part) (it must be integrated in the ImportModelPart)
        # If we integrate it in the model part we cannot use combined solvers
        self.solver.AddDofs()

        # Build sub_model_parts or submeshes (rearrange parts for the application of custom processes)
        # #Get the list of the submodel part in the object Model
        for i in range(self.ProjectParameters["solver_settings"]
                       ["processes_sub_model_part_list"].size()):
            part_name = self.ProjectParameters["solver_settings"][
                "processes_sub_model_part_list"][i].GetString()
            self.Model.update(
                {part_name: self.main_model_part.GetSubModelPart(part_name)})

        # Obtain the list of the processes to be applied
        self.list_of_processes = process_factory.KratosProcessFactory(
            self.Model).ConstructListOfProcesses(
                self.ProjectParameters["constraints_process_list"])
        self.list_of_processes += process_factory.KratosProcessFactory(
            self.Model).ConstructListOfProcesses(
                self.ProjectParameters["loads_process_list"])
        if (ProjectParameters.Has("list_other_processes") == True):
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["list_other_processes"])
        if (ProjectParameters.Has("json_check_process") == True):
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["json_check_process"])
        if (ProjectParameters.Has("check_analytic_results_process") == True):
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["check_analytic_results_process"])
        if (ProjectParameters.Has("json_output_process") == True):
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["json_output_process"])

        for process in self.list_of_processes:
            process.ExecuteInitialize()

        # ### START SOLUTION ####

        self.computing_model_part = self.solver.GetComputingModelPart()

        # ### Output settings start ####
        self.problem_path = os.getcwd()
        self.problem_name = self.ProjectParameters["problem_data"][
            "problem_name"].GetString()

        # ### Output settings start ####
        self.output_post = ProjectParameters.Has("output_configuration")
        if (self.output_post == True):
            from gid_output_process import GiDOutputProcess
            output_settings = ProjectParameters["output_configuration"]
            self.gid_output = GiDOutputProcess(self.computing_model_part,
                                               self.problem_name,
                                               output_settings)
            self.gid_output.ExecuteInitialize()

        # Sets strategies, builders, linear solvers, schemes and solving info, and fills the buffer
        self.solver.Initialize()
        self.solver.SetEchoLevel(0)  # Avoid to print anything

        if (self.output_post == True):
            self.gid_output.ExecuteBeforeSolutionLoop()

    def Solve(self):
        for process in self.list_of_processes:
            process.ExecuteBeforeSolutionLoop()

        # #Stepping and time settings (get from process info or solving info)
        # Delta time
        delta_time = self.ProjectParameters["problem_data"][
            "time_step"].GetDouble()
        # Start step
        self.main_model_part.ProcessInfo[TIME_STEPS] = 0
        # Start time
        time = self.ProjectParameters["problem_data"]["start_time"].GetDouble()
        # End time
        end_time = self.ProjectParameters["problem_data"][
            "end_time"].GetDouble()

        # Solving the problem (time integration)
        while (time <= end_time):
            time = time + delta_time
            self.main_model_part.ProcessInfo[TIME_STEPS] += 1
            self.main_model_part.CloneTimeStep(time)

            for process in self.list_of_processes:
                process.ExecuteInitializeSolutionStep()

            if (self.output_post == True):
                self.gid_output.ExecuteInitializeSolutionStep()

            self.solver.Solve()

            if (self.output_post == True):
                self.gid_output.ExecuteFinalizeSolutionStep()

            for process in self.list_of_processes:
                process.ExecuteFinalizeSolutionStep()

            for process in self.list_of_processes:
                process.ExecuteBeforeOutputStep()

            for process in self.list_of_processes:
                process.ExecuteAfterOutputStep()

            if (self.output_post == True):
                if self.gid_output.IsOutputStep():
                    self.gid_output.PrintOutput()

        if (self.output_post == True):
            self.gid_output.ExecuteFinalize()

        for process in self.list_of_processes:
            process.ExecuteFinalize()
Beispiel #15
0
class TestPatchTestShellsStressRec(KratosUnittest.TestCase):
    def setUp(self):
        pass
    

    def _add_variables(self,mp):
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.DISPLACEMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.ROTATION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.TORQUE)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.VOLUME_ACCELERATION)  
        mp.AddNodalSolutionStepVariable(StructuralMechanicsApplication.POINT_LOAD)      
        
    
    def _add_dofs(self,mp):
        # Adding the dofs AND their corresponding reaction!
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,mp)

        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.ROTATION_X, KratosMultiphysics.TORQUE_X,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.ROTATION_Y, KratosMultiphysics.TORQUE_Y,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.ROTATION_Z, KratosMultiphysics.TORQUE_Z,mp)


    def _create_nodes(self,mp,element_name):
        mp.CreateNewNode(1, -0.5, - 0.45,  0.1)
        mp.CreateNewNode(2,  0.7,  -0.5,   0.2)
        mp.CreateNewNode(3,  0.55,  0.6,   0.15)
        mp.CreateNewNode(4, -0.48,  0.65,  0.0)
        mp.CreateNewNode(5,  0.02, -0.01, -0.15)

        if element_name.endswith("4N"): # create aditional nodes needed for quad-setup
            mp.CreateNewNode(6, -0.03, -0.5,   0.0)
            mp.CreateNewNode(7,  0.51,  0.02,  0.03)
            mp.CreateNewNode(8, -0.01,  0.52, -0.05)
            mp.CreateNewNode(9, -0.49, -0.0,   0.0)


    def _create_elements(self,mp,element_name):
        if element_name.endswith("4N"): # Quadrilaterals
            mp.CreateNewElement(element_name, 1, [1,6,5,9], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 2, [6,2,7,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 3, [5,7,3,8], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 4, [9,5,8,4], mp.GetProperties()[1])
        else: # Triangles
            mp.CreateNewElement(element_name, 1, [1,2,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 2, [2,3,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 3, [3,4,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 4, [4,1,5], mp.GetProperties()[1])


    def _apply_dirichlet_BCs(self,mp):
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.DISPLACEMENT_X, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.DISPLACEMENT_Y, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.DISPLACEMENT_Z, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.ROTATION_X, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.ROTATION_Y, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.ROTATION_Z, True, mp.Nodes)


    def _apply_neumann_BCs(self,mp):
        for node in mp.Nodes:
            node.SetSolutionStepValue(StructuralMechanicsApplication.POINT_LOAD,0,[6.1,-5.5,8.9])
            mp.CreateNewCondition("PointLoadCondition3D1N",1,[node.Id],mp.GetProperties()[1])


    def _apply_material_properties(self,mp):
        #define properties
        mp.GetProperties()[1].SetValue(KratosMultiphysics.YOUNG_MODULUS,100e3)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.POISSON_RATIO,0.3)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.THICKNESS,1.0)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.DENSITY,1.0)
        
        g = [0,0,0]
        mp.GetProperties()[1].SetValue(KratosMultiphysics.VOLUME_ACCELERATION,g)
        
        cl = StructuralMechanicsApplication.LinearElasticPlaneStress2DLaw()

        mp.GetProperties()[1].SetValue(KratosMultiphysics.CONSTITUTIVE_LAW,cl) 
        

    def _solve(self,mp):
        #define a minimal newton raphson solver
        linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        builder_and_solver = KratosMultiphysics.ResidualBasedBlockBuilderAndSolver(linear_solver)
        scheme = KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme()
        convergence_criterion = KratosMultiphysics.ResidualCriteria(1e-14,1e-20)
        convergence_criterion.SetEchoLevel(0)
        
        max_iters = 20
        compute_reactions = True
        reform_step_dofs = True
        calculate_norm_dx = False
        move_mesh_flag = True
        strategy = KratosMultiphysics.ResidualBasedNewtonRaphsonStrategy(mp, 
                                                                        scheme, 
                                                                        linear_solver, 
                                                                        convergence_criterion, 
                                                                        builder_and_solver, 
                                                                        max_iters, 
                                                                        compute_reactions, 
                                                                        reform_step_dofs, 
                                                                        move_mesh_flag)
        strategy.SetEchoLevel(0)
        
        strategy.Check()
        strategy.Solve()
        
    
    def _check_results(self,node,displacement_results, rotation_results):
        ##check that the results are exact on the node
        disp = node.GetSolutionStepValue(KratosMultiphysics.DISPLACEMENT)
        self.assertAlmostEqual(disp[0], displacement_results[0], 10)
        self.assertAlmostEqual(disp[1], displacement_results[1], 10)
        self.assertAlmostEqual(disp[2], displacement_results[2], 10)

        rot = node.GetSolutionStepValue(KratosMultiphysics.ROTATION)
        self.assertAlmostEqual(rot[0], rotation_results[0], 10)
        self.assertAlmostEqual(rot[1], rotation_results[1], 10)
        self.assertAlmostEqual(rot[2], rotation_results[2], 10)
        

    def _check_results_stress(self,element,stress_variable,reference_stress_results,processInfo):
        ##check that the results are exact on the first gauss point
        ##only upper triangle of stresses are checked due to symmetry
        stress = element.CalculateOnIntegrationPoints(stress_variable, processInfo)[0]
        self.assertAlmostEqual(stress[0,0], reference_stress_results[0])
        self.assertAlmostEqual(stress[0,1], reference_stress_results[1])
        self.assertAlmostEqual(stress[0,2], reference_stress_results[2])
        self.assertAlmostEqual(stress[1,1], reference_stress_results[3])
        self.assertAlmostEqual(stress[1,2], reference_stress_results[4])
        self.assertAlmostEqual(stress[2,2], reference_stress_results[5])


    def execute_shell_test(self, element_name, displacement_results, rotation_results, shell_stress_middle_surface_results, shell_stress_top_surface_results, shell_stress_bottom_surface_results, shell_von_mises_result,do_post_processing):
        mp = KratosMultiphysics.ModelPart("solid_part")
        mp.SetBufferSize(2)

        self._add_variables(mp)
        self._apply_material_properties(mp)
        self._create_nodes(mp,element_name)
        self._add_dofs(mp)
        self._create_elements(mp,element_name)
        
        #create a submodelpart for dirichlet boundary conditions
        bcs_dirichlet = mp.CreateSubModelPart("BoundaryCondtionsDirichlet")
        bcs_dirichlet.AddNodes([1,2,4])

        #create a submodelpart for neumann boundary conditions
        bcs_neumann = mp.CreateSubModelPart("BoundaryCondtionsNeumann")
        bcs_neumann.AddNodes([3])
        
        self._apply_dirichlet_BCs(bcs_dirichlet)
        self._apply_neumann_BCs(bcs_neumann)
        self._solve(mp)
        
        # Check displacements
        self._check_results(mp.Nodes[3],displacement_results, rotation_results)
        
        # Check stresses at each surface
        self._check_results_stress(mp.Elements[1],
                                   StructuralMechanicsApplication.SHELL_STRESS_MIDDLE_SURFACE,
                                   shell_stress_middle_surface_results,mp.ProcessInfo)
        self._check_results_stress(mp.Elements[1],
                                   StructuralMechanicsApplication.SHELL_STRESS_TOP_SURFACE,
                                   shell_stress_top_surface_results,mp.ProcessInfo)
        self._check_results_stress(mp.Elements[1],
                                   StructuralMechanicsApplication.SHELL_STRESS_BOTTOM_SURFACE,
                                   shell_stress_bottom_surface_results,mp.ProcessInfo)
        
        # Check results of doubles on 2nd element @ Gauss Point [0] only
        self.assertAlmostEqual(mp.Elements[1].CalculateOnIntegrationPoints(StructuralMechanicsApplication.VON_MISES_STRESS, 
                               mp.ProcessInfo)[0], shell_von_mises_result, 9)
                    
        if do_post_processing:
            self.__post_process(mp)


    def test_thin_shell_triangle(self):
        element_name = "ShellThinElementCorotational3D3N"
        displacement_results = [0.0002324367992 , -0.0002233770349 , 0.0002567033724]
        rotation_results     = [0.0003627558482 , -0.000192601191 , -0.0004682304553]
        shell_stress_middle_surface_results = [1.3303075390101 , 0.264364591997 , 0.0 , 5.0167837539314 , 0.0 , 0.0]
        shell_stress_top_surface_results    = [-1.2283221502342 , 0.4311013553375 , 0.0 , -1.6038795679008 , 0.0 , 0.0]
        shell_stress_bottom_surface_results = [3.8889372282119 , 0.0976278286547 , 0.0 , 11.637447075717 , 0.0 , 0.0]
        shell_von_mises_result = 6.844018189553676

        self.execute_shell_test(element_name, 
                                displacement_results, 
                                rotation_results,
                                shell_stress_middle_surface_results,
                                shell_stress_top_surface_results,
                                shell_stress_bottom_surface_results,
                                shell_von_mises_result,
                                False) # Do PostProcessing for GiD?


    def test_thick_shell_triangle(self):
        element_name = "ShellThickElementCorotational3D3N"
        displacement_results = [7.18429456e-05 , -0.0001573361523 , 0.0005263535842]
        rotation_results     = [0.0003316611414 , -0.0002797797097 , 4.922597e-07]
        shell_stress_middle_surface_results = [0.3249757099621 , 2.9160990871098 , 0.2819464444644 , -3.1257443788537 , -1.8055963785359 , 0.0]
        shell_stress_top_surface_results    = [-4.1554904776369 , -3.4345555473773 , 0.0 , -9.9070455393953 , 0.0 , 0.0]
        shell_stress_bottom_surface_results = [4.8054418975623 , 9.2667537215962 , 0.0 , 3.6555567816919 , 0.0 , 0.0]
        shell_von_mises_result = 16.628498883168643

        self.execute_shell_test(element_name, 
                                displacement_results, 
                                rotation_results, 
                                shell_stress_middle_surface_results,
                                shell_stress_top_surface_results,
                                shell_stress_bottom_surface_results,
                                shell_von_mises_result,
                                False) # Do PostProcessing for GiD?


    def test_thin_shell_quadrilateral(self):
        element_name = "ShellThinElementCorotational3D4N"
        displacement_results = [0.0021867287711 , -0.002169253367 , 0.0007176841015]
        rotation_results     = [0.002816872164 , 0.0008161241026 , -0.0069076664086]
        shell_stress_middle_surface_results = [3.2764384894107 , -11.2157366764521 , 0.0 , 3.3634707516415 , 0.0 , 0.0]
        shell_stress_top_surface_results    = [20.1969362575659 , 4.5153278381999 , 0.0 , -8.6274148078231 , 0.0 , 0.0]
        shell_stress_bottom_surface_results = [-13.6440592787273 , -26.946801191103 , 0.0 , 15.3543563111075 , 0.0 , 0.0]
        shell_von_mises_result = 53.007571556565786

        self.execute_shell_test(element_name, 
                                displacement_results, 
                                rotation_results, 
                                shell_stress_middle_surface_results,
                                shell_stress_top_surface_results,
                                shell_stress_bottom_surface_results,
                                shell_von_mises_result,
                                False) # Do PostProcessing for GiD?


    def test_thick_shell_quadrilateral(self):
        element_name = "ShellThickElementCorotational3D4N"
        displacement_results = [0.0003567530995 , -0.0006345647159 , 0.0012775224387]
        rotation_results     = [0.001208364263 , -0.0004090878159 , -0.0011667612068]
        shell_stress_middle_surface_results = [2.6746781989643 , -3.4828482661147 , 0.7508096733731 , 2.7635579906239 , 6.5466218833201 , 0.0]
        shell_stress_top_surface_results    = [9.0133220797589 , 0.5580446976287 , 0.0 , -50.7214926962072 , 0.0 , 0.0]
        shell_stress_bottom_surface_results = [-3.6639656818168 , -7.5237412298536 , 0.0 , 56.2486086774573 , 0.0 , 0.0]
        shell_von_mises_result = 59.60909025300992

        self.execute_shell_test(element_name, 
                                displacement_results, 
                                rotation_results, 
                                shell_stress_middle_surface_results,
                                shell_stress_top_surface_results,
                                shell_stress_bottom_surface_results,
                                shell_von_mises_result,
                                False) # Do PostProcessing for GiD?

        
    def __post_process(self, main_model_part):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(main_model_part,
                                    "gid_output",
                                    KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },        
                                                "nodal_results"       : ["DISPLACEMENT", "ROTATION", "POINT_LOAD"],
                                                "gauss_point_results" : ["GREEN_LAGRANGE_STRAIN_TENSOR","CAUCHY_STRESS_TENSOR"]
                                            }
                                        }
                                        """)
                                    )

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()
Beispiel #16
0
class TestPatchTestShellsOrthotropic(KratosUnittest.TestCase):
    def setUp(self):
        pass


    def _add_variables(self,mp):
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.DISPLACEMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.ROTATION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION_MOMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.VOLUME_ACCELERATION)
        mp.AddNodalSolutionStepVariable(StructuralMechanicsApplication.POINT_LOAD)


    def _add_dofs(self,mp):
        # Adding the dofs AND their corresponding reaction!
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,mp)

        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.ROTATION_X, KratosMultiphysics.REACTION_MOMENT_X,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.ROTATION_Y, KratosMultiphysics.REACTION_MOMENT_Y,mp)
        KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.ROTATION_Z, KratosMultiphysics.REACTION_MOMENT_Z,mp)


    def _create_nodes(self,mp,element_name):
        mp.CreateNewNode(1, -0.5, - 0.45,  0.1)
        mp.CreateNewNode(2,  0.7,  -0.5,   0.2)
        mp.CreateNewNode(3,  0.55,  0.6,   0.15)
        mp.CreateNewNode(4, -0.48,  0.65,  0.0)
        mp.CreateNewNode(5,  0.02, -0.01, -0.15)

        if element_name.endswith("4N"): # create aditional nodes needed for quad-setup
            mp.CreateNewNode(6, -0.03, -0.5,   0.0)
            mp.CreateNewNode(7,  0.51,  0.02,  0.03)
            mp.CreateNewNode(8, -0.01,  0.52, -0.05)
            mp.CreateNewNode(9, -0.49, -0.0,   0.0)


    def _create_elements(self,mp,element_name):
        if element_name.endswith("4N"): # Quadrilaterals
            mp.CreateNewElement(element_name, 1, [1,6,5,9], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 2, [6,2,7,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 3, [5,7,3,8], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 4, [9,5,8,4], mp.GetProperties()[1])
        else: # Triangles
            mp.CreateNewElement(element_name, 1, [1,2,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 2, [2,3,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 3, [3,4,5], mp.GetProperties()[1])
            mp.CreateNewElement(element_name, 4, [4,1,5], mp.GetProperties()[1])


    def _apply_dirichlet_BCs(self,mp):
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.DISPLACEMENT_X, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.DISPLACEMENT_Y, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.DISPLACEMENT_Z, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.ROTATION_X, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.ROTATION_Y, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(KratosMultiphysics.ROTATION_Z, True, mp.Nodes)


    def _apply_neumann_BCs(self,mp):
        for node in mp.Nodes:
            node.SetSolutionStepValue(StructuralMechanicsApplication.POINT_LOAD,0,[6.1,-5.5,8.9])
            mp.CreateNewCondition("PointLoadCondition3D1N",1,[node.Id],mp.GetProperties()[1])


    def _apply_material_properties(self,mp):
        #define properties
        orthotropic_props = Matrix(4,16)

        # Orthotropic mechanical moduli
        orthotropic_props[0,0] = 0.5 #lamina thickness
        orthotropic_props[0,1] = 0.0 #lamina rotation (deg)
        orthotropic_props[0,2] = 7850 #density
        orthotropic_props[0,3] = 7500 #E1
        orthotropic_props[0,4] = 2000 #E2
        orthotropic_props[0,5] = 0.25 #nu_12
        orthotropic_props[0,6] = 1250 #G_12
        orthotropic_props[0,7] = 625 #G_13
        orthotropic_props[0,8] = 625 #G_23

        # Orthotropic mechanical strengths. (T)ensile, (C)ompression, (S)hear
        # along 1, 2, 3 lamina directions
        orthotropic_props[0,9] = 800 #T1
        orthotropic_props[0,10] = 500 #C1
        orthotropic_props[0,11] = 40 #T2
        orthotropic_props[0,12] = 300 #C2
        orthotropic_props[0,13] = 60 #S12
        orthotropic_props[0,14] = 60 #S13
        orthotropic_props[0,15] = 60 #S23

        for row in range(1,4):
            for col in range(16):
                orthotropic_props[row,col] = orthotropic_props[0,col]
        orthotropic_props[1,1] = 90
        orthotropic_props[2,1] = 90

        mp.GetProperties()[1].SetValue(
            KratosMultiphysics.StructuralMechanicsApplication.SHELL_ORTHOTROPIC_LAYERS,orthotropic_props)

        g = [0,0,0]
        mp.GetProperties()[1].SetValue(KratosMultiphysics.VOLUME_ACCELERATION,g)

        cl = StructuralMechanicsApplication.LinearElasticOrthotropic2DLaw()

        mp.GetProperties()[1].SetValue(KratosMultiphysics.CONSTITUTIVE_LAW,cl)


    def _solve(self,mp):
        #define a minimal newton raphson solver
        linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        builder_and_solver = KratosMultiphysics.ResidualBasedBlockBuilderAndSolver(linear_solver)
        scheme = KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme()
        convergence_criterion = KratosMultiphysics.ResidualCriteria(1e-14,1e-20)
        convergence_criterion.SetEchoLevel(0)

        max_iters = 20
        compute_reactions = True
        reform_step_dofs = True
        calculate_norm_dx = False
        move_mesh_flag = True
        strategy = KratosMultiphysics.ResidualBasedNewtonRaphsonStrategy(mp,
                                                                        scheme,
                                                                        convergence_criterion,
                                                                        builder_and_solver,
                                                                        max_iters,
                                                                        compute_reactions,
                                                                        reform_step_dofs,
                                                                        move_mesh_flag)
        strategy.SetEchoLevel(0)

        strategy.Check()
        strategy.Solve()


    def _check_results(self,node,displacement_results, rotation_results):
        ##check that the results are exact on the node
        disp = node.GetSolutionStepValue(KratosMultiphysics.DISPLACEMENT)
        self.assertAlmostEqual(disp[0], displacement_results[0], 10)
        self.assertAlmostEqual(disp[1], displacement_results[1], 10)
        self.assertAlmostEqual(disp[2], displacement_results[2], 10)

        rot = node.GetSolutionStepValue(KratosMultiphysics.ROTATION)
        self.assertAlmostEqual(rot[0], rotation_results[0], 10)
        self.assertAlmostEqual(rot[1], rotation_results[1], 10)
        self.assertAlmostEqual(rot[2], rotation_results[2], 10)


    def _check_results_stress(self,element,stress_variable,reference_stress_results,processInfo):
        ##check that the results are exact on the first gauss point
        ##only upper triangle of stresses are checked due to symmetry
        stress = element.CalculateOnIntegrationPoints(stress_variable, processInfo)[0]
        self.assertAlmostEqual(stress[0,0], reference_stress_results[0], 10)
        self.assertAlmostEqual(stress[0,1], reference_stress_results[1], 10)
        self.assertAlmostEqual(stress[0,2], reference_stress_results[2], 10)
        self.assertAlmostEqual(stress[1,1], reference_stress_results[3], 10)
        self.assertAlmostEqual(stress[1,2], reference_stress_results[4], 10)
        self.assertAlmostEqual(stress[2,2], reference_stress_results[5], 10)


    def execute_shell_test(self, current_model, element_name, displacement_results, rotation_results, shell_stress_top_surface_results, shell_stress_bottom_surface_results, tsai_wu_result,do_post_processing):
        mp = current_model.CreateModelPart("solid_part")
        mp.SetBufferSize(2)

        self._add_variables(mp)
        self._apply_material_properties(mp)
        self._create_nodes(mp,element_name)
        self._add_dofs(mp)
        self._create_elements(mp,element_name)

        #create a submodelpart for dirichlet boundary conditions
        bcs_dirichlet = mp.CreateSubModelPart("BoundaryCondtionsDirichlet")
        bcs_dirichlet.AddNodes([1,2,4])

        #create a submodelpart for neumann boundary conditions
        bcs_neumann = mp.CreateSubModelPart("BoundaryCondtionsNeumann")
        bcs_neumann.AddNodes([3])

        self._apply_dirichlet_BCs(bcs_dirichlet)
        self._apply_neumann_BCs(bcs_neumann)
        self._solve(mp)

        # Check displacements
        self._check_results(mp.Nodes[3],displacement_results, rotation_results)

        # Check stresses at each surface
        self._check_results_stress(mp.Elements[1],
                                   StructuralMechanicsApplication.SHELL_ORTHOTROPIC_STRESS_TOP_SURFACE,
                                   shell_stress_top_surface_results,mp.ProcessInfo)
        self._check_results_stress(mp.Elements[1],
                                   StructuralMechanicsApplication.SHELL_ORTHOTROPIC_STRESS_BOTTOM_SURFACE,
                                   shell_stress_bottom_surface_results,mp.ProcessInfo)

        # Check results of doubles on 2nd element @ Gauss Point [0] only
        self.assertAlmostEqual(mp.Elements[1].CalculateOnIntegrationPoints(StructuralMechanicsApplication.TSAI_WU_RESERVE_FACTOR,
                               mp.ProcessInfo)[0], tsai_wu_result, 9)

        if do_post_processing:
            self.__post_process(mp)


    def test_thin_shell_triangle(self):
        element_name = "ShellThinElementCorotational3D3N"
        displacement_results = [0.0028456068244 , -0.0021804536526 , 0.0014855251225]
        rotation_results     = [0.0028315743508 , -0.000450044246 , -0.0055701845132]
        shell_stress_top_surface_results    = [0.9088110489672 , -0.0570461205561 , 0.0 , 1.7678124328652 , 0.0 , 0.0]
        shell_stress_bottom_surface_results = [-0.4936295259123 , 0.2914348407351 , 0.0 , -0.5256560385672 , 0.0 , 0.0]
        tsai_wu_result = 39.6023549141987

        current_model = KratosMultiphysics.Model()
        self.execute_shell_test(current_model,
                                element_name,
                                displacement_results,
                                rotation_results,
                                shell_stress_top_surface_results,
                                shell_stress_bottom_surface_results,
                                tsai_wu_result,
                                False) # Do PostProcessing for GiD?


    def test_thick_shell_triangle(self):
        element_name = "ShellThickElementCorotational3D3N"
        displacement_results = [0.0004043490308 , -0.0016074440019 , 0.0092911008314]
        rotation_results     = [0.0021176894774 , -0.0005954288823 , -0.0015930914838]
        shell_stress_top_surface_results    = [3.4555559859345 , 3.6328430864296 , 0.2347447591457 , 0.1945591765769 , -1.5033148859134 , 0.0]
        shell_stress_bottom_surface_results = [-0.5442976284974 , -0.1011836349433 , 0.2347447591457 , -2.8139010064313 , -1.5033148859134 , 0.0]
        tsai_wu_result = 15.0065495746848

        current_model = KratosMultiphysics.Model()
        self.execute_shell_test(current_model,
                                element_name,
                                displacement_results,
                                rotation_results,
                                shell_stress_top_surface_results,
                                shell_stress_bottom_surface_results,
                                tsai_wu_result,
                                False) # Do PostProcessing for GiD?


    def test_thin_shell_quadrilateral(self):
        element_name = "ShellThinElementCorotational3D4N"
        displacement_results = [0.0225804891311 , -0.0233155244988 , 0.0048050841112]
        rotation_results     = [0.0248341724156 , 0.0105468617083 , -0.0691658930497]
        shell_stress_top_surface_results    = [0.284184788186 , -12.2844786822622 , 0.0 , 4.3796427631839 , 0.0 , 0.0]
        shell_stress_bottom_surface_results = [10.340621141106 , 5.6934270260323 , 0.0 , -2.973608875272 , 0.0 , 0.0]
        tsai_wu_result = 3.828332205752

        current_model = KratosMultiphysics.Model()
        self.execute_shell_test(current_model,
                                element_name,
                                displacement_results,
                                rotation_results,
                                shell_stress_top_surface_results,
                                shell_stress_bottom_surface_results,
                                tsai_wu_result,
                                False) # Do PostProcessing for GiD?


    def test_thick_shell_quadrilateral(self):
        element_name = "ShellThickElementCorotational3D4N"
        displacement_results = [0.0035689894826 , -0.0094851917758 , 0.0191734998621]
        rotation_results     = [0.009933211939  , 0.0006068078079  , -0.0174332051568]
        shell_stress_top_surface_results    = [-3.9178477532111 , -4.1074850572552 , -2.4426862077188 , 10.3723187292559 , 1.6354826554283 , 0.0]
        shell_stress_bottom_surface_results = [5.2113212123242 , -0.2324161069908 , -2.4426862077188 , -11.6664322521041 , 1.6354826554283 , 0.0]
        tsai_wu_result = 3.4966651118454

        current_model = KratosMultiphysics.Model()
        self.execute_shell_test(current_model,
                                element_name,
                                displacement_results,
                                rotation_results,
                                shell_stress_top_surface_results,
                                shell_stress_bottom_surface_results,
                                tsai_wu_result,
                                False) # Do PostProcessing for GiD?


    def __post_process(self, main_model_part):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(main_model_part,
                                    "gid_output",
                                    KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "nodal_results"       : ["DISPLACEMENT", "ROTATION", "POINT_LOAD"],
                                                "gauss_point_results" : ["GREEN_LAGRANGE_STRAIN_TENSOR","CAUCHY_STRESS_TENSOR"]
                                            }
                                        }
                                        """)
                                    )

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()
Beispiel #17
0
class MokBenchmarkTest(KratosUnittest.TestCase):
    def setUp(self):
        self.print_output = False
        self.work_folder = "MokBenchmarkTest"
        self.settings = "ProjectParameters.json"
        self.fluid_input_file = "mok_benchmark_Fluid"
        self.structure_input_file = "mok_benchmark_Fluid"

    def tearDown(self):
        self.deleteOutFile(self.fluid_input_file + '.time')
        self.deleteOutFile(self.structure_input_file + '.time')

    def deleteOutFile(self, filename):
        with WorkFolderScope(self.work_folder):
            try:
                remove(filename)
            except FileNotFoundError as e:
                pass

    def testMokBenchmark(self):
        with WorkFolderScope(self.work_folder):
            parameter_file = open(self.settings, 'r')
            self.ProjectParameters = Parameters(parameter_file.read())

            ## Fluid-Structure model parts definition
            self.structure_main_model_part = ModelPart(
                self.ProjectParameters["structure_solver_settings"]
                ["problem_data"]["model_part_name"].GetString())
            self.structure_main_model_part.ProcessInfo.SetValue(
                DOMAIN_SIZE,
                self.ProjectParameters["structure_solver_settings"]
                ["problem_data"]["domain_size"].GetInt())

            self.fluid_main_model_part = ModelPart(
                self.ProjectParameters["fluid_solver_settings"]["problem_data"]
                ["model_part_name"].GetString())
            self.fluid_main_model_part.ProcessInfo.SetValue(
                DOMAIN_SIZE, self.ProjectParameters["fluid_solver_settings"]
                ["problem_data"]["domain_size"].GetInt())

            FluidModel = {
                self.ProjectParameters["fluid_solver_settings"]["problem_data"]["model_part_name"].GetString(
                ):
                self.fluid_main_model_part
            }
            SolidModel = {
                self.ProjectParameters["structure_solver_settings"]["problem_data"]["model_part_name"].GetString(
                ):
                self.structure_main_model_part
            }

            ## Solver construction
            solver_module = __import__(
                self.ProjectParameters["coupling_solver_settings"]
                ["solver_settings"]["solver_type"].GetString())
            self.solver = solver_module.CreateSolver(
                self.structure_main_model_part, self.fluid_main_model_part,
                self.ProjectParameters)

            self.solver.AddVariables()

            ## Read the model - note that SetBufferSize is done here
            self.solver.ImportModelPart()

            ## Add AddDofs
            self.solver.AddDofs()

            ## Initialize GiD  I/O
            if (self.print_output == True):
                from gid_output_process import GiDOutputProcess

                self.gid_output_structure = GiDOutputProcess(
                    self.solver.structure_solver.GetComputingModelPart(),
                    self.ProjectParameters["structure_solver_settings"]
                    ["problem_data"]["problem_name"].GetString() +
                    "_structure",
                    self.ProjectParameters["structure_solver_settings"]
                    ["output_configuration"])

                self.gid_output_fluid = GiDOutputProcess(
                    self.solver.fluid_solver.GetComputingModelPart(),
                    self.ProjectParameters["fluid_solver_settings"]
                    ["problem_data"]["problem_name"].GetString() + "_fluid",
                    self.ProjectParameters["fluid_solver_settings"]
                    ["output_configuration"])

                self.gid_output_structure.ExecuteInitialize()
                self.gid_output_fluid.ExecuteInitialize()

            ## Get the list of the skin submodel parts in the object Model (FLUID)
            for i in range(self.ProjectParameters["fluid_solver_settings"]
                           ["solver_settings"]["skin_parts"].size()):
                skin_part_name = self.ProjectParameters[
                    "fluid_solver_settings"]["solver_settings"]["skin_parts"][
                        i].GetString()
                FluidModel.update({
                    skin_part_name:
                    self.fluid_main_model_part.GetSubModelPart(skin_part_name)
                })

            ## Get the list of the no-skin submodel parts in the object Model (FLUID)
            for i in range(self.ProjectParameters["fluid_solver_settings"]
                           ["solver_settings"]["no_skin_parts"].size()):
                no_skin_part_name = self.ProjectParameters[
                    "fluid_solver_settings"]["solver_settings"][
                        "no_skin_parts"][i].GetString()
                FluidModel.update({
                    no_skin_part_name:
                    self.fluid_main_model_part.GetSubModelPart(
                        no_skin_part_name)
                })

            ## Get the list of the initial conditions submodel parts in the object Model (FLUID)
            for i in range(self.ProjectParameters["fluid_solver_settings"]
                           ["initial_conditions_process_list"].size()):
                initial_cond_part_name = self.ProjectParameters[
                    "fluid_solver_settings"][
                        "initial_conditions_process_list"][i]["Parameters"][
                            "model_part_name"].GetString()
                FluidModel.update({
                    initial_cond_part_name:
                    self.fluid_main_model_part.GetSubModelPart(
                        initial_cond_part_name)
                })

            ## Get the gravity submodel part in the object Model (FLUID)
            for i in range(self.ProjectParameters["fluid_solver_settings"]
                           ["gravity"].size()):
                gravity_part_name = self.ProjectParameters[
                    "fluid_solver_settings"]["gravity"][i]["Parameters"][
                        "model_part_name"].GetString()
                FluidModel.update({
                    gravity_part_name:
                    self.fluid_main_model_part.GetSubModelPart(
                        gravity_part_name)
                })

            ## Get the list of the submodel part in the object Model (STRUCTURE)
            for i in range(
                    self.ProjectParameters["structure_solver_settings"]
                ["solver_settings"]["processes_sub_model_part_list"].size()):
                part_name = self.ProjectParameters[
                    "structure_solver_settings"]["solver_settings"][
                        "processes_sub_model_part_list"][i].GetString()
                SolidModel.update({
                    part_name:
                    self.structure_main_model_part.GetSubModelPart(part_name)
                })

            ## Processes construction
            import process_factory
            # "list_of_processes" contains all the processes already constructed (boundary conditions, initial conditions and gravity)
            # Note that the conditions are firstly constructed. Otherwise, they may overwrite the BCs information.

            # FLUID DOMAIN PROCESSES
            self.list_of_processes = process_factory.KratosProcessFactory(
                FluidModel).ConstructListOfProcesses(
                    self.ProjectParameters["fluid_solver_settings"]
                    ["initial_conditions_process_list"])
            self.list_of_processes += process_factory.KratosProcessFactory(
                FluidModel).ConstructListOfProcesses(
                    self.ProjectParameters["fluid_solver_settings"]
                    ["boundary_conditions_process_list"])
            self.list_of_processes += process_factory.KratosProcessFactory(
                FluidModel).ConstructListOfProcesses(
                    self.ProjectParameters["fluid_solver_settings"]["gravity"])

            # SOLID DOMAIN PROCESSES
            self.list_of_processes += process_factory.KratosProcessFactory(
                SolidModel).ConstructListOfProcesses(
                    self.ProjectParameters["structure_solver_settings"]
                    ["constraints_process_list"])
            self.list_of_processes += process_factory.KratosProcessFactory(
                SolidModel).ConstructListOfProcesses(
                    self.ProjectParameters["structure_solver_settings"]
                    ["loads_process_list"])

            ## Processes initialization
            for process in self.list_of_processes:
                process.ExecuteInitialize()

            # Solver initialization moved after the processes initialization, otherwise the flag INTERFACE is not set
            self.solver.Initialize()

            ## Time settings
            end_time = self.ProjectParameters["fluid_solver_settings"][
                "problem_data"]["end_time"].GetDouble()
            time = 0.0
            step = 0
            out = 0.0

            if (self.print_output == True):
                self.gid_output_structure.ExecuteBeforeSolutionLoop()
                self.gid_output_fluid.ExecuteBeforeSolutionLoop()

            for process in self.list_of_processes:
                process.ExecuteBeforeSolutionLoop()

            while (time <= end_time):

                Dt = (self.solver).ComputeDeltaTime()
                time = time + Dt
                step = step + 1

                self.solver.SetTimeStep(step)

                self.structure_main_model_part.CloneTimeStep(time)
                self.fluid_main_model_part.CloneTimeStep(time)

                for process in self.list_of_processes:
                    process.ExecuteInitializeSolutionStep()

                if (self.print_output == True):
                    self.gid_output_structure.ExecuteInitializeSolutionStep()
                    self.gid_output_fluid.ExecuteInitializeSolutionStep()

                (self.solver).Solve()

                for process in self.list_of_processes:
                    process.ExecuteFinalizeSolutionStep()

                if (self.print_output == True):
                    self.gid_output_structure.ExecuteFinalizeSolutionStep()
                    self.gid_output_fluid.ExecuteFinalizeSolutionStep()

                #TODO: decide if it shall be done only when output is processed or not
                for process in self.list_of_processes:
                    process.ExecuteBeforeOutputStep()

                if (self.print_output == True):
                    if self.gid_output_structure.IsOutputStep():
                        self.gid_output_structure.PrintOutput()
                    if self.gid_output_fluid.IsOutputStep():
                        self.gid_output_fluid.PrintOutput()

                for process in self.list_of_processes:
                    process.ExecuteAfterOutputStep()

                out = out + Dt

            for process in self.list_of_processes:
                process.ExecuteFinalize()

            if (self.print_output == True):
                self.gid_output_structure.ExecuteFinalize()
                self.gid_output_fluid.ExecuteFinalize()
class Kratos_Execute_Test:
    def __init__(self, ProjectParameters):

        self.ProjectParameters = ProjectParameters

        self.main_model_part = KratosMultiphysics.ModelPart(
            self.ProjectParameters["problem_data"]
            ["model_part_name"].GetString())
        self.main_model_part.ProcessInfo.SetValue(
            KratosMultiphysics.DOMAIN_SIZE,
            self.ProjectParameters["problem_data"]["domain_size"].GetInt())

        self.Model = {
            self.ProjectParameters["problem_data"]["model_part_name"].GetString(
            ):
            self.main_model_part
        }

        self.problem_type = self.ProjectParameters["problem_data"][
            "problem_type"].GetString()

        self.solve_problem = self.ProjectParameters["problem_data"][
            "solve_problem"].GetBool()

        if (self.problem_type == "fluid"
                and missing_external_fluid_dependencies == False):
            ## Solver construction
            import python_solvers_wrapper_fluid as fluid_wrapper
            self.solver = fluid_wrapper.CreateSolver(self.main_model_part,
                                                     self.ProjectParameters)
        elif (self.problem_type == "solid"
              and missing_external_solid_dependencies == False):
            # Construct the solver (main setting methods are located in the solver_module)
            solver_module = __import__(
                self.ProjectParameters["solver_settings"]
                ["solver_type"].GetString())
            self.solver = solver_module.CreateSolver(
                self.main_model_part,
                self.ProjectParameters["solver_settings"])
        else:
            raise NameError(
                'Problem type not defined or failing in the import')

        # Add variables (always before importing the model part) (it must be integrated in the ImportModelPart)
        # If we integrate it in the model part we cannot use combined solvers
        self.solver.AddVariables()

        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.NODAL_H)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.NODAL_AREA)

        # Read model_part (note: the buffer_size is set here) (restart can be read here)
        self.solver.ImportModelPart()

        # Add dofs (always after importing the model part) (it must be integrated in the ImportModelPart)
        # If we integrate it in the model part we cannot use combined solvers
        self.solver.AddDofs()

        # ### Output settings start ####
        self.problem_path = os.getcwd()
        self.problem_name = self.ProjectParameters["problem_data"][
            "problem_name"].GetString()

        # ### Output settings start ####
        self.output_post = ProjectParameters.Has("output_configuration")
        if (self.output_post == True):
            from gid_output_process import GiDOutputProcess
            output_settings = ProjectParameters["output_configuration"]
            self.gid_output = GiDOutputProcess(
                self.solver.GetComputingModelPart(), self.problem_name,
                output_settings)
            self.gid_output.ExecuteInitialize()

        # Sets strategies, builders, linear solvers, schemes and solving info, and fills the buffer
        self.solver.Initialize()
        self.solver.SetEchoLevel(0)  # Avoid to print anything

        if self.problem_type == "fluid":
            # Build sub_model_parts or submeshes (rearrange parts for the application of custom processes)
            # #Get the list of the submodel part in the object Model
            for i in range(self.ProjectParameters["solver_settings"]
                           ["skin_parts"].size()):
                skin_part_name = self.ProjectParameters["solver_settings"][
                    "skin_parts"][i].GetString()
                self.Model.update({
                    skin_part_name:
                    self.main_model_part.GetSubModelPart(skin_part_name)
                })

            ## Get the list of the initial conditions submodel parts in the object Model
            for i in range(
                    self.ProjectParameters["initial_conditions_process_list"].
                    size()):
                initial_cond_part_name = self.ProjectParameters[
                    "initial_conditions_process_list"][i]["Parameters"][
                        "model_part_name"].GetString()
                self.Model.update({
                    initial_cond_part_name:
                    self.main_model_part.GetSubModelPart(
                        initial_cond_part_name)
                })

            ## Get the gravity submodel part in the object Model
            for i in range(self.ProjectParameters["gravity"].size()):
                gravity_part_name = self.ProjectParameters["gravity"][i][
                    "Parameters"]["model_part_name"].GetString()
                self.Model.update({
                    gravity_part_name:
                    self.main_model_part.GetSubModelPart(gravity_part_name)
                })

        elif self.problem_type == "solid":
            # Build sub_model_parts or submeshes (rearrange parts for the application of custom processes)
            # #Get the list of the submodel part in the object Model
            for i in range(self.ProjectParameters["solver_settings"]
                           ["processes_sub_model_part_list"].size()):
                part_name = self.ProjectParameters["solver_settings"][
                    "processes_sub_model_part_list"][i].GetString()
                self.Model.update({
                    part_name:
                    self.main_model_part.GetSubModelPart(part_name)
                })

        ## Remeshing processes construction
        if (self.ProjectParameters.Has("initial_remeshing_process") == True):
            remeshing_processes = process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["initial_remeshing_process"])
            if (ProjectParameters.Has("list_other_processes") == True):
                remeshing_processes += process_factory.KratosProcessFactory(
                    self.Model).ConstructListOfProcesses(
                        self.ProjectParameters["list_other_processes"])

            ## Remeshing processes initialization
            print("STARTING ADAPTATIVE LOOP")
            if (self.ProjectParameters.Has("adaptative_loop") == True):
                adaptative_loop = ProjectParameters["adaptative_loop"].GetInt()
            else:
                adaptative_loop = 1
            for n in range(adaptative_loop):
                print("ADAPTATIVE INTERATION: ", n + 1)
                for process in reversed(remeshing_processes):
                    process.ExecuteInitialize()

        # Obtain the list of the processes to be applied
        if self.problem_type == "fluid":
            self.list_of_processes = process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["gravity"])
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["initial_conditions_process_list"])
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["boundary_conditions_process_list"])
        elif self.problem_type == "solid":
            self.list_of_processes = process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["constraints_process_list"])
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["loads_process_list"])
        if (self.ProjectParameters.Has("list_other_processes") == True):
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["list_other_processes"])
        if (self.ProjectParameters.Has("json_check_process") == True):
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["json_check_process"])
        if (self.ProjectParameters.Has("json_output_process") == True):
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["json_output_process"])
        if (self.ProjectParameters.Has("compare_two_files_check_process") ==
                True):
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["compare_two_files_check_process"])
        if (self.ProjectParameters.Has("recursive_remeshing_process") == True):
            self.list_of_processes += process_factory.KratosProcessFactory(
                self.Model).ConstructListOfProcesses(
                    self.ProjectParameters["recursive_remeshing_process"])

        for process in self.list_of_processes:
            process.ExecuteInitialize()

        # ### START SOLUTION ####

        self.computing_model_part = self.solver.GetComputingModelPart()

        if (self.output_post == True):
            self.gid_output.ExecuteBeforeSolutionLoop()

    def Solve(self):
        if self.solve_problem == True:
            for process in self.list_of_processes:
                process.ExecuteBeforeSolutionLoop()

            # #Stepping and time settings (get from process info or solving info)
            # Delta time
            delta_time = self.ProjectParameters["problem_data"][
                "time_step"].GetDouble()
            # Start step
            self.main_model_part.ProcessInfo[KratosMultiphysics.TIME_STEPS] = 0
            # Start time
            time = self.ProjectParameters["problem_data"][
                "start_time"].GetDouble()
            # End time
            end_time = self.ProjectParameters["problem_data"][
                "end_time"].GetDouble()
            step = 0

            if self.problem_type == "fluid":
                init_step = 3
            elif self.problem_type == "solid":
                init_step = 1

            # Solving the problem (time integration)
            while (time <= end_time):
                time = time + delta_time
                self.main_model_part.ProcessInfo[
                    KratosMultiphysics.TIME_STEPS] += 1
                self.main_model_part.CloneTimeStep(time)
                step = step + 1

                if (step >= init_step):
                    for process in self.list_of_processes:
                        process.ExecuteInitializeSolutionStep()

                    if (self.main_model_part.Is(
                            KratosMultiphysics.MODIFIED) == True):
                        # WE INITIALIZE THE SOLVER
                        self.solver.Initialize()
                        # WE RECOMPUTE THE PROCESSES AGAIN
                        ## Processes initialization
                        for process in self.list_of_processes:
                            process.ExecuteInitialize()
                        ## Processes before the loop
                        for process in self.list_of_processes:
                            process.ExecuteBeforeSolutionLoop()
                        ## Processes of initialize the solution step
                        for process in self.list_of_processes:
                            process.ExecuteInitializeSolutionStep()

                    if (self.output_post == True):
                        self.gid_output.ExecuteInitializeSolutionStep()

                    self.solver.Clear()
                    self.solver.Solve()

                    if (self.output_post == True):
                        self.gid_output.ExecuteFinalizeSolutionStep()

                    for process in self.list_of_processes:
                        process.ExecuteFinalizeSolutionStep()

                    for process in self.list_of_processes:
                        process.ExecuteBeforeOutputStep()

                    if (self.output_post == True):
                        if self.gid_output.IsOutputStep():
                            self.gid_output.PrintOutput()

                    for process in self.list_of_processes:
                        process.ExecuteAfterOutputStep()

            if (self.output_post == True):
                self.gid_output.ExecuteFinalize()

            for process in self.list_of_processes:
                process.ExecuteFinalize()
Beispiel #19
0
class TestPatchTestLargeStrain(KratosUnittest.TestCase):
    def setUp(self):
        pass

    def _add_variables(self, mp):
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.DISPLACEMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.VOLUME_ACCELERATION)

    def _apply_material_properties(self, mp, dim, small_strain=True):
        #define properties
        mp.GetProperties()[1].SetValue(KratosMultiphysics.YOUNG_MODULUS, 210e9)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.POISSON_RATIO, 0.3)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.THICKNESS, 1.0)

        g = [0, 0, 0]
        mp.GetProperties()[1].SetValue(KratosMultiphysics.VOLUME_ACCELERATION,
                                       g)

        if (dim == 2):
            if (small_strain == True):
                cl = StructuralMechanicsApplication.LinearElasticPlaneStress2DLaw(
                )
            else:
                cl = StructuralMechanicsApplication.HyperElasticPlaneStrain2DLaw(
                )
        else:
            if (small_strain == True):
                cl = StructuralMechanicsApplication.LinearElastic3DLaw()
            else:
                cl = StructuralMechanicsApplication.HyperElastic3DLaw()
        mp.GetProperties()[1].SetValue(KratosMultiphysics.CONSTITUTIVE_LAW, cl)

    def _set_buffer(self, mp):
        buffer_size = 3
        mp.SetBufferSize(buffer_size)
        # Cycle the buffer. This sets all historical nodal solution step data to
        # the current value and initializes the time stepping in the process info.
        mp.ProcessInfo[KratosMultiphysics.DELTA_TIME] = 1.0
        delta_time = mp.ProcessInfo[KratosMultiphysics.DELTA_TIME]
        time = mp.ProcessInfo[KratosMultiphysics.TIME]
        step = -buffer_size
        time = time - delta_time * buffer_size
        mp.ProcessInfo.SetValue(KratosMultiphysics.TIME, time)
        for i in range(0, buffer_size):
            step = step + 1
            time = time + delta_time
            mp.ProcessInfo.SetValue(KratosMultiphysics.STEP, step)
            mp.CloneTimeStep(time)

    def _apply_BCs(self, mp, A, b):
        for node in mp.Nodes:
            node.Fix(KratosMultiphysics.DISPLACEMENT_X)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Y)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Z)

        for node in mp.Nodes:
            xvec = KratosMultiphysics.Vector(3)
            u = KratosMultiphysics.Vector()

            xvec[0] = node.X0
            xvec[1] = node.Y0
            xvec[2] = node.Z0

            u = A * xvec
            u += b

            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT, 0, u)

    def _define_movement(self, dim):
        if (dim == 2):
            #define the applied motion - the idea is that the displacement is defined as u = A*xnode + b
            #so that the displcement is linear and the exact F = I + A
            A = KratosMultiphysics.Matrix(3, 3)
            A[0, 0] = 0.10
            A[0, 1] = 0.12
            A[0, 2] = 0.0
            A[1, 0] = -0.05
            A[1, 1] = 0.07
            A[1, 2] = 0.0
            A[2, 1] = 0.00
            A[2, 1] = 0.0
            A[2, 2] = 0.0

            b = KratosMultiphysics.Vector(3)
            b[0] = 0.05
            b[1] = -0.02
            b[2] = 0.00

        else:
            #define the applied motion - the idea is that the displacement is defined as u = A*xnode + b
            #so that the displcement is linear and the exact F = I + A
            A = KratosMultiphysics.Matrix(3, 3)
            A[0, 0] = 0.10
            A[0, 1] = 0.12
            A[0, 2] = 0.0
            A[1, 0] = -0.05
            A[1, 1] = 0.07
            A[1, 2] = 0.1
            A[2, 1] = -0.02
            A[2, 1] = 0.0
            A[2, 2] = -0.3

            b = KratosMultiphysics.Vector(3)
            b[0] = 0.05
            b[1] = -0.02
            b[2] = 0.07

        return A, b

    def _solve(self, mp):

        #define a minimal newton raphson solver
        linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        builder_and_solver = KratosMultiphysics.ResidualBasedEliminationBuilderAndSolver(
            linear_solver)
        scheme = KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme(
        )
        convergence_criterion = KratosMultiphysics.ResidualCriteria(
            1e-14, 1e-20)
        convergence_criterion.SetEchoLevel(0)

        max_iters = 20
        compute_reactions = True
        reform_step_dofs = True
        move_mesh_flag = True
        strategy = KratosMultiphysics.ResidualBasedNewtonRaphsonStrategy(
            mp, scheme, linear_solver, convergence_criterion,
            builder_and_solver, max_iters, compute_reactions, reform_step_dofs,
            move_mesh_flag)
        strategy.SetEchoLevel(0)

        strategy.Check()
        strategy.Solve()

    def _create_strategy(self, mp):
        #define a minimal newton raphson solver
        linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        builder_and_solver = KratosMultiphysics.ResidualBasedEliminationBuilderAndSolver(
            linear_solver)
        scheme = KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme(
        )
        convergence_criterion = KratosMultiphysics.ResidualCriteria(1e-4, 1e-9)
        convergence_criterion.SetEchoLevel(0)

        #max_iters = 1
        max_iters = 20
        compute_reactions = True
        reform_step_dofs = True
        move_mesh_flag = True
        strategy = KratosMultiphysics.ResidualBasedNewtonRaphsonStrategy(
            mp, scheme, linear_solver, convergence_criterion,
            builder_and_solver, max_iters, compute_reactions, reform_step_dofs,
            move_mesh_flag)
        strategy.SetEchoLevel(0)

        return strategy

    def _solve_with_strategy(self, strategy, lhs, step):
        strategy.Check()
        strategy.Initialize()
        strategy.InitializeSolutionStep()
        strategy.Predict()
        strategy.SolveSolutionStep()
        lhs = strategy.GetSystemMatrix()
        strategy.FinalizeSolutionStep()

    def _check_results(self, mp, A, b):

        ##check that the results are exact on the nodes
        for node in mp.Nodes:
            xvec = KratosMultiphysics.Vector(len(b))
            xvec[0] = node.X0
            xvec[1] = node.Y0
            xvec[2] = node.Z0

            u = KratosMultiphysics.Vector(2)
            u = A * xvec
            u += b

            d = node.GetSolutionStepValue(KratosMultiphysics.DISPLACEMENT)
            self.assertAlmostEqual(d[0], u[0])
            self.assertAlmostEqual(d[1], u[1])
            self.assertAlmostEqual(d[2], u[2])

    def _check_outputs(self, mp, A, dim):

        E = mp.GetProperties()[1].GetValue(KratosMultiphysics.YOUNG_MODULUS)
        NU = mp.GetProperties()[1].GetValue(KratosMultiphysics.POISSON_RATIO)

        #given the matrix A, the analytic deformation gradient is F+I
        F = A
        for i in range(3):
            F[i, i] += 1.0

        #here compute the Cauchy green strain tensor
        Etensor = KratosMultiphysics.Matrix(3, 3)

        for i in range(3):
            for j in range(3):
                Etensor[i, j] = 0.0

        for i in range(3):
            for j in range(3):
                for k in range(3):
                    Etensor[i, j] += A[k, i] * A[k, j]

        for i in range(3):
            Etensor[i, i] -= 1.0

        for i in range(3):
            for j in range(3):
                Etensor[i, j] = 0.5 * Etensor[i, j]

        if (dim == 2):
            #verify strain
            reference_strain = KratosMultiphysics.Vector(3)
            reference_strain[0] = Etensor[0, 0]
            reference_strain[1] = Etensor[1, 1]
            reference_strain[2] = 2.0 * Etensor[0, 1]
        else:
            reference_strain = KratosMultiphysics.Vector(6)
            reference_strain[0] = Etensor[0, 0]
            reference_strain[1] = Etensor[1, 1]
            reference_strain[2] = Etensor[2, 2]
            reference_strain[3] = 2.0 * Etensor[0, 1]
            reference_strain[4] = 2.0 * Etensor[1, 2]
            reference_strain[5] = 2.0 * Etensor[0, 2]

        for elem in mp.Elements:
            out = elem.CalculateOnIntegrationPoints(
                KratosMultiphysics.GREEN_LAGRANGE_STRAIN_VECTOR,
                mp.ProcessInfo)
            for strain in out:
                for i in range(len(reference_strain)):
                    self.assertTrue((abs(
                        (reference_strain[i] - strain[i]) / strain[i]) <
                                     1.0e-4))

        #finally compute stress
        if (dim == 2):
            #here assume plane stress
            c1 = E / (1.00 - NU * NU)
            c2 = c1 * NU
            c3 = 0.5 * E / (1 + NU)
            reference_stress = KratosMultiphysics.Vector(3)
            reference_stress[0] = c1 * reference_strain[0] + c2 * (
                reference_strain[1])
            reference_stress[1] = c1 * reference_strain[1] + c2 * (
                reference_strain[0])
            reference_stress[2] = c3 * reference_strain[2]
        else:
            c1 = E / ((1.00 + NU) * (1 - 2 * NU))
            c2 = c1 * (1 - NU)
            c3 = c1 * NU
            c4 = c1 * 0.5 * (1 - 2 * NU)
            reference_stress = KratosMultiphysics.Vector(6)
            reference_stress[0] = c2 * reference_strain[0] + c3 * (
                reference_strain[1] + reference_strain[2])
            reference_stress[1] = c2 * reference_strain[1] + c3 * (
                reference_strain[0] + reference_strain[2])
            reference_stress[2] = c2 * reference_strain[2] + c3 * (
                reference_strain[0] + reference_strain[1])
            reference_stress[3] = c4 * reference_strain[3]
            reference_stress[4] = c4 * reference_strain[4]
            reference_stress[5] = c4 * reference_strain[5]

        for elem in mp.Elements:
            out = elem.CalculateOnIntegrationPoints(
                KratosMultiphysics.PK2_STRESS_VECTOR, mp.ProcessInfo)
            for stress in out:
                for i in range(len(reference_stress)):
                    self.assertTrue((abs(
                        (reference_stress[i] - stress[i]) / stress[i]) <
                                     1.0e-4))

    def test_compare_TL_UL_2D_triangle(self):
        dim = 2

        bc_nodes = [1, 2]
        load_nodes = [3, 4]

        tl_mp = KratosMultiphysics.ModelPart("tl_solid_part")
        self._add_variables(tl_mp)
        self._apply_material_properties(tl_mp, dim, False)

        # Create nodes
        tl_mp.CreateNewNode(1, 0.0, 0.0, 0.0)
        tl_mp.CreateNewNode(2, 1.0, 0.0, 0.0)
        tl_mp.CreateNewNode(3, 1.0, 1.0, 0.0)
        tl_mp.CreateNewNode(4, 0.0, 1.0, 0.0)

        for node in tl_mp.Nodes:
            node.AddDof(KratosMultiphysics.DISPLACEMENT_X,
                        KratosMultiphysics.REACTION_X)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Y,
                        KratosMultiphysics.REACTION_Y)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Z,
                        KratosMultiphysics.REACTION_Z)

        # Create a submodelpart for boundary conditions
        tl_bcs = tl_mp.CreateSubModelPart("BoundaryCondtions")
        tl_bcs.AddNodes(bc_nodes)
        for node in tl_bcs.Nodes:
            node.Fix(KratosMultiphysics.DISPLACEMENT_X)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_X, 0.0)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Y)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_Y, 0.0)

        # Create Element and condition
        tl_elem = tl_mp.CreateNewElement("TotalLagrangianElement2D4N", 1,
                                         [1, 2, 3, 4],
                                         tl_mp.GetProperties()[1])
        tl_load = tl_mp.CreateSubModelPart("LoadCondtions")
        tl_load.AddNodes(load_nodes)
        tl_cond = tl_mp.CreateNewCondition("LineLoadCondition2D2N", 1,
                                           load_nodes,
                                           tl_mp.GetProperties()[1])

        self._set_buffer(tl_mp)
        tl_lhs = KratosMultiphysics.CompressedMatrix()

        ul_mp = KratosMultiphysics.ModelPart("ul_solid_part")
        self._add_variables(ul_mp)
        self._apply_material_properties(ul_mp, dim, False)

        # Create nodes
        ul_mp.CreateNewNode(1, 0.0, 0.0, 0.0)
        ul_mp.CreateNewNode(2, 1.0, 0.0, 0.0)
        ul_mp.CreateNewNode(3, 1.0, 1.0, 0.0)
        ul_mp.CreateNewNode(4, 0.0, 1.0, 0.0)

        for node in ul_mp.Nodes:
            node.AddDof(KratosMultiphysics.DISPLACEMENT_X,
                        KratosMultiphysics.REACTION_X)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Y,
                        KratosMultiphysics.REACTION_Y)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Z,
                        KratosMultiphysics.REACTION_Z)

        # Create a submodelpart for boundary conditions
        ul_bcs = ul_mp.CreateSubModelPart("BoundaryCondtions")
        ul_bcs.AddNodes(bc_nodes)
        for node in ul_bcs.Nodes:
            node.Fix(KratosMultiphysics.DISPLACEMENT_X)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_X, 0.0)
            node.Fix(KratosMultiphysics.DISPLACEMENT_Y)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_Y, 0.0)

        # Create Element
        ul_elem = ul_mp.CreateNewElement("UpdatedLagrangianElement2D4N", 1,
                                         [1, 2, 3, 4],
                                         ul_mp.GetProperties()[1])
        ul_load = ul_mp.CreateSubModelPart("LoadCondtions")
        ul_load.AddNodes(load_nodes)
        ul_cond = ul_mp.CreateNewCondition("LineLoadCondition2D2N", 1,
                                           load_nodes,
                                           tl_mp.GetProperties()[1])

        self._set_buffer(ul_mp)
        ul_lhs = KratosMultiphysics.CompressedMatrix()

        # Now we solve
        load = KratosMultiphysics.Vector(3)
        load[0] = 0.0
        load[1] = 0.0
        load[2] = 0.0

        delta_time = ul_mp.ProcessInfo[KratosMultiphysics.DELTA_TIME]
        time = ul_mp.ProcessInfo[KratosMultiphysics.TIME]

        tl_strategy = self._create_strategy(tl_mp)
        ul_strategy = self._create_strategy(ul_mp)

        for iter in range(1, 4):

            time += iter * delta_time
            tl_mp.CloneTimeStep(time)
            ul_mp.CloneTimeStep(time)

            #load[1] = iter * 1.0e10
            #tl_cond.SetValue(StructuralMechanicsApplication.LINE_LOAD, load)
            #ul_cond.SetValue(StructuralMechanicsApplication.LINE_LOAD, load)

            for node in tl_load.Nodes:
                node.Fix(KratosMultiphysics.DISPLACEMENT_X)
                node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_X,
                                          iter * 5.0e-1)
            for node in ul_load.Nodes:
                node.Fix(KratosMultiphysics.DISPLACEMENT_X)
                node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_X,
                                          iter * 5.0e-1)
            #for node in tl_load.Nodes:
            #node.Fix(KratosMultiphysics.DISPLACEMENT_Y)
            #node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_Y, iter * 5.0e-1)
            #for node in ul_load.Nodes:
            #node.Fix(KratosMultiphysics.DISPLACEMENT_Y)
            #node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_Y, iter * 5.0e-1)

            self._solve_with_strategy(tl_strategy, tl_lhs, iter)
            self._solve_with_strategy(ul_strategy, ul_lhs, iter)

            # Check displacement
            for i in range(2, 4):
                tl_dx = tl_mp.Nodes[i].GetSolutionStepValue(
                    KratosMultiphysics.DISPLACEMENT_X)
                tl_dy = tl_mp.Nodes[i].GetSolutionStepValue(
                    KratosMultiphysics.DISPLACEMENT_Y)
                ul_dx = ul_mp.Nodes[i].GetSolutionStepValue(
                    KratosMultiphysics.DISPLACEMENT_X)
                ul_dy = ul_mp.Nodes[i].GetSolutionStepValue(
                    KratosMultiphysics.DISPLACEMENT_Y)

                if (ul_dx > 0.0):
                    self.assertLess((tl_dx - ul_dx) / ul_dx, 1.0e-3)
                if (ul_dy > 0.0):
                    self.assertLess((tl_dy - ul_dy) / ul_dy, 1.0e-3)

            # Compare matrices
            for i in range(ul_lhs.Size1()):
                for j in range(ul_lhs.Size2()):
                    self.assertLess(
                        (ul_lhs[i, j] - tl_lhs[i, j]) / tl_lhs[i, j], 1.0e-3)

        #self.__post_process(tl_mp)
        #self.__post_process(ul_mp)

    def test_TL_2D_triangle(self):
        dim = 2
        mp = KratosMultiphysics.ModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.5, 0.5, 0.0)
        mp.CreateNewNode(2, 0.7, 0.2, 0.0)
        mp.CreateNewNode(3, 0.9, 0.8, 0.0)
        mp.CreateNewNode(4, 0.3, 0.7, 0.0)
        mp.CreateNewNode(5, 0.6, 0.6, 0.0)

        for node in mp.Nodes:
            node.AddDof(KratosMultiphysics.DISPLACEMENT_X,
                        KratosMultiphysics.REACTION_X)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Y,
                        KratosMultiphysics.REACTION_Y)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Z,
                        KratosMultiphysics.REACTION_Z)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 2, 3, 4])

        #create Element
        mp.CreateNewElement("TotalLagrangianElement2D3N", 1, [1, 2, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement2D3N", 2, [2, 3, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement2D3N", 3, [3, 4, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement2D3N", 4, [4, 1, 5],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def test_TL_2D_quadrilateral(self):
        dim = 2
        mp = KratosMultiphysics.ModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.00, 3.00, 0.00)
        mp.CreateNewNode(2, 1.00, 2.25, 0.00)
        mp.CreateNewNode(3, 0.75, 1.00, 0.00)
        mp.CreateNewNode(4, 2.25, 2.00, 0.00)
        mp.CreateNewNode(5, 0.00, 0.00, 0.00)
        mp.CreateNewNode(6, 3.00, 3.00, 0.00)
        mp.CreateNewNode(7, 2.00, 0.75, 0.00)
        mp.CreateNewNode(8, 3.00, 0.00, 0.00)

        for node in mp.Nodes:
            node.AddDof(KratosMultiphysics.DISPLACEMENT_X,
                        KratosMultiphysics.REACTION_X)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Y,
                        KratosMultiphysics.REACTION_Y)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Z,
                        KratosMultiphysics.REACTION_Z)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 5, 6, 8])

        #create Element
        mp.CreateNewElement("TotalLagrangianElement2D4N", 1, [8, 7, 3, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement2D4N", 2, [6, 4, 7, 8],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement2D4N", 3, [1, 2, 4, 6],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement2D4N", 4, [4, 2, 3, 7],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement2D4N", 5, [2, 1, 5, 3],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def test_TL_3D_hexa(self):
        dim = 3
        mp = KratosMultiphysics.ModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.00000, 1.00000, 1.00000)
        mp.CreateNewNode(2, 0.16500, 0.74500, 0.70200)
        mp.CreateNewNode(3, 0.27300, 0.75000, 0.23000)
        mp.CreateNewNode(4, 0.78800, 0.69300, 0.64400)
        mp.CreateNewNode(5, 0.32000, 0.18600, 0.64300)
        mp.CreateNewNode(6, 0.00000, 1.00000, 0.00000)
        mp.CreateNewNode(7, 0.00000, 0.00000, 1.00000)
        mp.CreateNewNode(8, 1.00000, 1.00000, 1.00000)
        mp.CreateNewNode(9, 0.67700, 0.30500, 0.68300)
        mp.CreateNewNode(10, 0.24900, 0.34200, 0.19200)
        mp.CreateNewNode(11, 0.85000, 0.64900, 0.26300)
        mp.CreateNewNode(12, 0.82600, 0.28800, 0.28800)
        mp.CreateNewNode(13, 0.00000, 0.00000, 0.00000)
        mp.CreateNewNode(14, 1.00000, 1.00000, 0.00000)
        mp.CreateNewNode(15, 1.00000, 0.00000, 1.00000)
        mp.CreateNewNode(16, 1.00000, 0.00000, 0.00000)

        for node in mp.Nodes:
            node.AddDof(KratosMultiphysics.DISPLACEMENT_X,
                        KratosMultiphysics.REACTION_X)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Y,
                        KratosMultiphysics.REACTION_Y)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Z,
                        KratosMultiphysics.REACTION_Z)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 6, 7, 8, 13, 14, 15, 16])

        #create Element
        mp.CreateNewElement("TotalLagrangianElement3D8N", 1,
                            [10, 5, 2, 3, 13, 7, 1, 6],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement3D8N", 2,
                            [12, 9, 5, 10, 16, 15, 7, 13],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement3D8N", 3,
                            [12, 11, 3, 10, 9, 4, 2, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement3D8N", 4,
                            [9, 4, 2, 5, 15, 8, 1, 7],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement3D8N", 5,
                            [4, 11, 3, 2, 8, 14, 6, 1],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement3D8N", 6,
                            [11, 4, 9, 12, 14, 8, 15, 16],
                            mp.GetProperties()[1])
        mp.CreateNewElement("TotalLagrangianElement3D8N", 7,
                            [11, 12, 10, 3, 14, 16, 13, 6],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def test_UL_2D_triangle(self):
        dim = 2
        mp = KratosMultiphysics.ModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.5, 0.5, 0.0)
        mp.CreateNewNode(2, 0.7, 0.2, 0.0)
        mp.CreateNewNode(3, 0.9, 0.8, 0.0)
        mp.CreateNewNode(4, 0.3, 0.7, 0.0)
        mp.CreateNewNode(5, 0.6, 0.6, 0.0)

        for node in mp.Nodes:
            node.AddDof(KratosMultiphysics.DISPLACEMENT_X,
                        KratosMultiphysics.REACTION_X)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Y,
                        KratosMultiphysics.REACTION_Y)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Z,
                        KratosMultiphysics.REACTION_Z)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 2, 3, 4])

        #create Element
        mp.CreateNewElement("UpdatedLagrangianElement2D3N", 1, [1, 2, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement2D3N", 2, [2, 3, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement2D3N", 3, [3, 4, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement2D3N", 4, [4, 1, 5],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._set_buffer(mp)
        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def test_UL_2D_quadrilateral(self):
        dim = 2
        mp = KratosMultiphysics.ModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.00, 3.00, 0.00)
        mp.CreateNewNode(2, 1.00, 2.25, 0.00)
        mp.CreateNewNode(3, 0.75, 1.00, 0.00)
        mp.CreateNewNode(4, 2.25, 2.00, 0.00)
        mp.CreateNewNode(5, 0.00, 0.00, 0.00)
        mp.CreateNewNode(6, 3.00, 3.00, 0.00)
        mp.CreateNewNode(7, 2.00, 0.75, 0.00)
        mp.CreateNewNode(8, 3.00, 0.00, 0.00)

        for node in mp.Nodes:
            node.AddDof(KratosMultiphysics.DISPLACEMENT_X,
                        KratosMultiphysics.REACTION_X)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Y,
                        KratosMultiphysics.REACTION_Y)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Z,
                        KratosMultiphysics.REACTION_Z)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 5, 6, 8])

        #create Element
        mp.CreateNewElement("UpdatedLagrangianElement2D4N", 1, [8, 7, 3, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement2D4N", 2, [6, 4, 7, 8],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement2D4N", 3, [1, 2, 4, 6],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement2D4N", 4, [4, 2, 3, 7],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement2D4N", 5, [2, 1, 5, 3],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._set_buffer(mp)
        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def test_UL_3D_hexa(self):
        dim = 3
        mp = KratosMultiphysics.ModelPart("solid_part")
        self._add_variables(mp)
        self._apply_material_properties(mp, dim)

        #create nodes
        mp.CreateNewNode(1, 0.00000, 1.00000, 1.00000)
        mp.CreateNewNode(2, 0.16500, 0.74500, 0.70200)
        mp.CreateNewNode(3, 0.27300, 0.75000, 0.23000)
        mp.CreateNewNode(4, 0.78800, 0.69300, 0.64400)
        mp.CreateNewNode(5, 0.32000, 0.18600, 0.64300)
        mp.CreateNewNode(6, 0.00000, 1.00000, 0.00000)
        mp.CreateNewNode(7, 0.00000, 0.00000, 1.00000)
        mp.CreateNewNode(8, 1.00000, 1.00000, 1.00000)
        mp.CreateNewNode(9, 0.67700, 0.30500, 0.68300)
        mp.CreateNewNode(10, 0.24900, 0.34200, 0.19200)
        mp.CreateNewNode(11, 0.85000, 0.64900, 0.26300)
        mp.CreateNewNode(12, 0.82600, 0.28800, 0.28800)
        mp.CreateNewNode(13, 0.00000, 0.00000, 0.00000)
        mp.CreateNewNode(14, 1.00000, 1.00000, 0.00000)
        mp.CreateNewNode(15, 1.00000, 0.00000, 1.00000)
        mp.CreateNewNode(16, 1.00000, 0.00000, 0.00000)

        for node in mp.Nodes:
            node.AddDof(KratosMultiphysics.DISPLACEMENT_X,
                        KratosMultiphysics.REACTION_X)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Y,
                        KratosMultiphysics.REACTION_Y)
            node.AddDof(KratosMultiphysics.DISPLACEMENT_Z,
                        KratosMultiphysics.REACTION_Z)

        #create a submodelpart for boundary conditions
        bcs = mp.CreateSubModelPart("BoundaryCondtions")
        bcs.AddNodes([1, 6, 7, 8, 13, 14, 15, 16])

        #create Element
        mp.CreateNewElement("UpdatedLagrangianElement3D8N", 1,
                            [10, 5, 2, 3, 13, 7, 1, 6],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement3D8N", 2,
                            [12, 9, 5, 10, 16, 15, 7, 13],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement3D8N", 3,
                            [12, 11, 3, 10, 9, 4, 2, 5],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement3D8N", 4,
                            [9, 4, 2, 5, 15, 8, 1, 7],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement3D8N", 5,
                            [4, 11, 3, 2, 8, 14, 6, 1],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement3D8N", 6,
                            [11, 4, 9, 12, 14, 8, 15, 16],
                            mp.GetProperties()[1])
        mp.CreateNewElement("UpdatedLagrangianElement3D8N", 7,
                            [11, 12, 10, 3, 14, 16, 13, 6],
                            mp.GetProperties()[1])

        A, b = self._define_movement(dim)

        self._set_buffer(mp)
        self._apply_BCs(bcs, A, b)
        self._solve(mp)
        self._check_results(mp, A, b)
        self._check_outputs(mp, A, dim)

        #self.__post_process(mp)

    def __post_process(self, main_model_part):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(
            main_model_part, "gid_output",
            KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },        
                                                "nodal_results"       : ["DISPLACEMENT"],
                                                "gauss_point_results" : ["GREEN_LAGRANGE_STRAIN_TENSOR","CAUCHY_STRESS_TENSOR"]
                                            }
                                        }
                                        """))

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()
Beispiel #20
0
class kratosCSMAnalyzer((__import__("analyzer_base")).analyzerBaseClass):

    # --------------------------------------------------------------------------
    def __init__(self):

        self.initializeGIDOutput()
        self.initializeProcesses()
        self.initializeSolutionLoop()

    # --------------------------------------------------------------------------
    def initializeProcesses(self):

        import process_factory
        #the process order of execution is important
        self.list_of_processes = process_factory.KratosProcessFactory(
            Model).ConstructListOfProcesses(
                ProjectParameters["constraints_process_list"])
        self.list_of_processes += process_factory.KratosProcessFactory(
            Model).ConstructListOfProcesses(
                ProjectParameters["loads_process_list"])
        if (ProjectParameters.Has("problem_process_list")):
            self.list_of_processes += process_factory.KratosProcessFactory(
                Model).ConstructListOfProcesses(
                    ProjectParameters["problem_process_list"])
        if (ProjectParameters.Has("output_process_list")):
            self.list_of_processes += process_factory.KratosProcessFactory(
                Model).ConstructListOfProcesses(
                    ProjectParameters["output_process_list"])

        #print list of constructed processes
        if (echo_level > 1):
            for process in self.list_of_processes:
                print(process)

        for process in self.list_of_processes:
            process.ExecuteInitialize()

    # --------------------------------------------------------------------------
    def initializeGIDOutput(self):

        computing_model_part = CSM_solver.GetComputingModelPart()
        problem_name = ProjectParameters["problem_data"][
            "problem_name"].GetString()

        from gid_output_process import GiDOutputProcess
        output_settings = ProjectParameters["output_configuration"]
        self.gid_output = GiDOutputProcess(computing_model_part, problem_name,
                                           output_settings)

        self.gid_output.ExecuteInitialize()

    # --------------------------------------------------------------------------
    def initializeSolutionLoop(self):

        ## Sets strategies, builders, linear solvers, schemes and solving info, and fills the buffer
        CSM_solver.Initialize()
        CSM_solver.SetEchoLevel(echo_level)

        for responseFunctionId in listOfResponseFunctions:
            listOfResponseFunctions[responseFunctionId].Initialize()

        # Start process
        for process in self.list_of_processes:
            process.ExecuteBeforeSolutionLoop()

        ## Set results when are written in a single file
        self.gid_output.ExecuteBeforeSolutionLoop()

    # --------------------------------------------------------------------------
    def analyzeDesignAndReportToCommunicator(self, currentDesign,
                                             optimizationIteration,
                                             communicator):

        # Calculation of value of objective function
        if communicator.isRequestingFunctionValueOf("strain_energy"):

            self.initializeNewSolutionStep(optimizationIteration)

            print("\n> Starting to update the mesh")
            startTime = timer.time()
            self.updateMeshForAnalysis(currentDesign)
            print("> Time needed for updating the mesh = ",
                  round(timer.time() - startTime, 2), "s")

            print(
                "\n> Starting StructuralMechanicsApplication to solve structure"
            )
            startTime = timer.time()
            self.solveStructure(optimizationIteration)
            print("> Time needed for solving the structure = ",
                  round(timer.time() - startTime, 2), "s")

            print("\n> Starting calculation of response value")
            startTime = timer.time()
            listOfResponseFunctions["strain_energy"].CalculateValue()
            print("> Time needed for calculation of response value = ",
                  round(timer.time() - startTime, 2), "s")

            communicator.reportFunctionValue(
                "strain_energy",
                listOfResponseFunctions["strain_energy"].GetValue())

        # Calculation of gradient of objective function
        if communicator.isRequestingGradientOf("strain_energy"):

            print("\n> Starting calculation of gradients")
            startTime = timer.time()
            listOfResponseFunctions["strain_energy"].CalculateGradient()
            print("> Time needed for calculating gradients = ",
                  round(timer.time() - startTime, 2), "s")

            gradientForCompleteModelPart = listOfResponseFunctions[
                "strain_energy"].GetGradient()
            gradientOnDesignSurface = {}
            for node in currentDesign.Nodes:
                gradientOnDesignSurface[
                    node.Id] = gradientForCompleteModelPart[node.Id]

            communicator.reportGradient("strain_energy",
                                        gradientOnDesignSurface)

    # --------------------------------------------------------------------------
    def initializeNewSolutionStep(self, optimizationIteration):
        main_model_part.CloneTimeStep(optimizationIteration)

    # --------------------------------------------------------------------------
    def updateMeshForAnalysis(self, currentDesign):
        for node in currentDesign.Nodes:
            node.X0 = node.X0 + node.GetSolutionStepValue(SHAPE_UPDATE_X)
            node.Y0 = node.Y0 + node.GetSolutionStepValue(SHAPE_UPDATE_Y)
            node.Z0 = node.Z0 + node.GetSolutionStepValue(SHAPE_UPDATE_Z)

    # --------------------------------------------------------------------------
    def solveStructure(self, optimizationIteration):

        # processes to be executed at the begining of the solution step
        for process in self.list_of_processes:
            process.ExecuteInitializeSolutionStep()

        self.gid_output.ExecuteInitializeSolutionStep()

        # Actual solution
        CSM_solver.Solve()

        # processes to be executed at the end of the solution step
        for process in self.list_of_processes:
            process.ExecuteFinalizeSolutionStep()

        # processes to be executed before witting the output
        for process in self.list_of_processes:
            process.ExecuteBeforeOutputStep()

        # write output results GiD: (frequency writing is controlled internally)
        if (self.gid_output.IsOutputStep()):
            self.gid_output.PrintOutput()

        self.gid_output.ExecuteFinalizeSolutionStep()

        # processes to be executed after witting the output
        for process in self.list_of_processes:
            process.ExecuteAfterOutputStep()

    # --------------------------------------------------------------------------
    def finalizeSolutionLoop(self):
        for process in self.list_of_processes:
            process.ExecuteFinalize()
        self.gid_output.ExecuteFinalize()
class TestPatchTestFormfinding(KratosUnittest.TestCase):
    def setUp(self):
        pass

    def _add_variables(self, mp):
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.DISPLACEMENT)
        mp.AddNodalSolutionStepVariable(KratosMultiphysics.REACTION)

    def _add_dofs(self, mp):
        # Adding the dofs AND their corresponding reaction!
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,
            mp)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,
            mp)

    def _create_nodes(self, mp, element_name):
        mp.CreateNewNode(1, 0.0, 0.0, 0.0)
        mp.CreateNewNode(2, 0.0, 10.0, 5.0)
        mp.CreateNewNode(3, 10.0, 0.0, 5.0)
        mp.CreateNewNode(4, 10.0, 10.0, 0.0)
        mp.CreateNewNode(5, 6.0, 6.0, 5.0)

    def _create_elements(self, mp, element_name):
        mp.CreateNewElement(element_name, 1, [1, 2, 5], mp.GetProperties()[1])
        mp.CreateNewElement(element_name, 2, [1, 5, 3], mp.GetProperties()[1])
        mp.CreateNewElement(element_name, 3, [3, 4, 5], mp.GetProperties()[1])
        mp.CreateNewElement(element_name, 4, [2, 4, 5], mp.GetProperties()[1])

    def _apply_dirichlet_BCs(self, mp):
        KratosMultiphysics.VariableUtils().ApplyFixity(
            KratosMultiphysics.DISPLACEMENT_X, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(
            KratosMultiphysics.DISPLACEMENT_Y, True, mp.Nodes)
        KratosMultiphysics.VariableUtils().ApplyFixity(
            KratosMultiphysics.DISPLACEMENT_Z, True, mp.Nodes)

    def _apply_material_properties(self, mp):
        #define properties
        mp.GetProperties()[1].SetValue(KratosMultiphysics.YOUNG_MODULUS, 0.0)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.POISSON_RATIO, 0.0)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.THICKNESS, 1.0)
        mp.GetProperties()[1].SetValue(KratosMultiphysics.DENSITY, 1.0)
        prestress = KratosMultiphysics.Vector(3)
        prestress[0] = 2.0
        prestress[1] = 1.0
        prestress[2] = 0.0
        mp.GetProperties()[1].SetValue(
            StructuralMechanicsApplication.PRESTRESS_VECTOR, prestress)

        cl = StructuralMechanicsApplication.LinearElasticPlaneStress2DLaw()

        mp.GetProperties()[1].SetValue(KratosMultiphysics.CONSTITUTIVE_LAW, cl)
        mp.GetProperties()[1].SetValue(
            StructuralMechanicsApplication.PROJECTION_TYPE_COMBO, "planar")

    def _solve(self, mp):
        #define a minimal newton raphson solver
        linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        builder_and_solver = KratosMultiphysics.ResidualBasedBlockBuilderAndSolver(
            linear_solver)
        scheme = KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme(
        )
        convergence_criterion = KratosMultiphysics.DisplacementCriteria(
            1e-3, 1e-3)
        convergence_criterion.SetEchoLevel(0)

        max_iters = 50
        compute_reactions = False
        reform_step_dofs = False
        calculate_norm_dx = False
        move_mesh_flag = True
        print_after_formfinding = False
        line_search = True
        strategy = KratosMultiphysics.StructuralMechanicsApplication.FormfindingUpdatedReferenceStrategy(
            mp, scheme, linear_solver, convergence_criterion, max_iters,
            compute_reactions, reform_step_dofs, move_mesh_flag,
            print_after_formfinding, line_search)
        strategy.SetEchoLevel(0)
        strategy.Check()
        strategy.Solve()

    def _check_results(self, node, displacement_results):
        #check that the results are exact on the node
        disp = node.GetSolutionStepValue(KratosMultiphysics.DISPLACEMENT)
        self.assertAlmostEqual(disp[0], displacement_results[0], 4)
        self.assertAlmostEqual(disp[1], displacement_results[1], 4)
        self.assertAlmostEqual(disp[2], displacement_results[2], 4)

    def execute_formfinding_test(self, current_model, element_name,
                                 displacement_results, do_post_processing):
        mp = current_model.CreateModelPart("solid_part")
        mp.SetBufferSize(2)

        self._add_variables(mp)
        self._apply_material_properties(mp)
        self._create_nodes(mp, element_name)
        self._add_dofs(mp)
        self._create_elements(mp, element_name)

        #create a submodelpart for dirichlet boundary conditions
        bcs_dirichlet = mp.CreateSubModelPart("BoundaryCondtionsDirichlet")
        bcs_dirichlet.AddNodes([1, 2, 3, 4])

        self._apply_dirichlet_BCs(bcs_dirichlet)
        self._solve(mp)

        self._check_results(mp.Nodes[5], displacement_results)

        if do_post_processing:
            self.__post_process(mp)

    def test_formfinding(self):
        element_name = "PreStressMembraneElement3D3N"
        displacement_results = [
            -0.3853903940829765, -0.2299393888361787, -2.213110569935068
        ]

        current_model = KratosMultiphysics.Model()

        self.execute_formfinding_test(current_model, element_name,
                                      displacement_results,
                                      False)  # Do PostProcessing for GiD?

    def __post_process(self, main_model_part):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(
            main_model_part, "gid_output",
            KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditions",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "nodal_results"       : ["DISPLACEMENT"],
                                                "gauss_point_results" : []
                                            }
                                        }
                                        """))

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()
Beispiel #22
0
# We create the remeshing process
remesh_param = KratosMultiphysics.Parameters("""{ }""")
MmgProcess = MeshingApplication.MmgProcess3D(main_model_part, remesh_param)
MmgProcess.Execute()

# Finally we export to GiD
from gid_output_process import GiDOutputProcess
gid_output = GiDOutputProcess(
    main_model_part, "gid_output",
    KratosMultiphysics.Parameters("""
                                {
                                    "result_file_configuration" : {
                                        "gidpost_flags": {
                                            "GiDPostMode": "GiD_PostBinary",
                                            "WriteDeformedMeshFlag": "WriteUndeformed",
                                            "WriteConditionsFlag": "WriteConditions",
                                            "MultiFileFlag": "SingleFile"
                                        },        
                                        "nodal_results"       : []
                                    }
                                }
                                """))

gid_output.ExecuteInitialize()
gid_output.ExecuteBeforeSolutionLoop()
gid_output.ExecuteInitializeSolutionStep()
gid_output.PrintOutput()
gid_output.ExecuteFinalizeSolutionStep()
gid_output.ExecuteFinalize()
Beispiel #23
0
    if (parallel_type == "OpenMP") or (KratosMPI.mpi.rank == 0):
        print("Time step ",step," solved.")

    for process in list_of_processes:
        process.ExecuteFinalizeSolutionStep()

    gid_output_structure.ExecuteFinalizeSolutionStep()
    gid_output_fluid.ExecuteFinalizeSolutionStep()

    #TODO: decide if it shall be done only when output is processed or not
    for process in list_of_processes:
        process.ExecuteBeforeOutputStep()

    if gid_output_structure.IsOutputStep():
        gid_output_structure.PrintOutput()

    if gid_output_fluid.IsOutputStep():
        gid_output_fluid.PrintOutput()

    for process in list_of_processes:
        process.ExecuteAfterOutputStep()

    out = out + Dt

for process in list_of_processes:
    process.ExecuteFinalize()

gid_output_structure.ExecuteFinalize()
gid_output_fluid.ExecuteFinalize()
class ManufacturedSolutionProblem:
    def __init__(self, input_file_name, settings_file_name, problem_type):

        self.problem_type = problem_type
        self.input_file_name = input_file_name
        self.settings_file_name = settings_file_name

    def SetFluidProblem(self):

        ## Parse the ProjectParameters
        parameter_file = open(self.settings_file_name, 'r')
        self.ProjectParameters = Parameters(parameter_file.read())

        ## Set the current mesh case problem info
        if (self.problem_type == "Manufactured solution"):
            self.ProjectParameters["problem_data"]["problem_name"].SetString(
                self.input_file_name + "_manufactured")
        else:
            self.ProjectParameters["problem_data"]["problem_name"].SetString(
                self.input_file_name)
        self.ProjectParameters["solver_settings"]["model_import_settings"][
            "input_filename"].SetString(self.input_file_name)

        ## Fluid model part definition
        self.main_model_part = ModelPart(self.ProjectParameters["problem_data"]
                                         ["model_part_name"].GetString())
        self.main_model_part.ProcessInfo.SetValue(
            DOMAIN_SIZE,
            self.ProjectParameters["problem_data"]["domain_size"].GetInt())

        ###TODO replace this "model" for real one once available
        Model = {
            self.ProjectParameters["problem_data"]["model_part_name"].GetString(
            ):
            self.main_model_part
        }

        ## Solver construction
        import python_solvers_wrapper_fluid
        self.solver = python_solvers_wrapper_fluid.CreateSolver(
            self.main_model_part, self.ProjectParameters)

        self.solver.AddVariables()

        ## Read the model - note that SetBufferSize is done here
        self.solver.ImportModelPart()

        ## Add AddDofs
        self.solver.AddDofs()

        ## Initialize GiD  I/O
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(
            self.solver.GetComputingModelPart(),
            self.ProjectParameters["problem_data"]["problem_name"].GetString(),
            self.ProjectParameters["output_configuration"])

        self.gid_output.ExecuteInitialize()

        ## Get the list of the skin submodel parts in the object Model
        for i in range(self.ProjectParameters["solver_settings"]
                       ["skin_parts"].size()):
            skin_part_name = self.ProjectParameters["solver_settings"][
                "skin_parts"][i].GetString()
            Model.update({
                skin_part_name:
                self.main_model_part.GetSubModelPart(skin_part_name)
            })
        for i in range(self.ProjectParameters["solver_settings"]
                       ["no_skin_parts"].size()):
            no_skin_part_name = self.ProjectParameters["solver_settings"][
                "no_skin_parts"][i].GetString()
            Model.update({
                no_skin_part_name:
                self.main_model_part.GetSubModelPart(no_skin_part_name)
            })

        ## Solver initialization
        self.solver.Initialize()

        ## Compute and set the nodal area
        self.SetNodalArea()

        ## Set the distance to 1 to have full fluid elements
        if (self.ProjectParameters["solver_settings"]
            ["solver_type"].GetString() == "Embedded"):
            for node in self.main_model_part.Nodes:
                node.SetSolutionStepValue(DISTANCE, 0, 1.0)

        ## Fix the pressure in one node (bottom left corner)
        for node in self.main_model_part.Nodes:
            if ((node.X < 0.001) and (node.Y < 0.001)):
                node.Fix(PRESSURE)
                node.SetSolutionStepValue(PRESSURE, 0, 0.0)

    def SolveFluidProblem(self):

        ## Stepping and time settings
        Dt = self.ProjectParameters["problem_data"]["time_step"].GetDouble()
        end_time = self.ProjectParameters["problem_data"][
            "end_time"].GetDouble()

        time = 0.0
        step = 0
        out = 0.0

        self.gid_output.ExecuteBeforeSolutionLoop()

        while (time <= end_time):

            time = time + Dt
            step = step + 1
            self.main_model_part.CloneTimeStep(time)

            print("STEP = ", step)
            print("TIME = ", time)

            self.gid_output.ExecuteInitializeSolutionStep()

            if (self.problem_type == "Manufactured solution"):
                # Fix the manufactured solution values (only for visualization purposes)
                self.SetManufacturedSolutionValues(fix=True,
                                                   set_on_boundary=False)
            else:
                # Set the manufactured solution source terms
                self.SetManufacturedSolutionValues(fix=True,
                                                   set_on_boundary=True)
                self.SetManufacturedSolutionSourceValues()

            if (step < 3):
                self.SetManufacturedSolutionValues(
                    False
                )  # Set the analytical solution in the two first steps
            else:
                if (self.problem_type != "Manufactured solution"):
                    self.solver.Solve()

            self.gid_output.ExecuteFinalizeSolutionStep()

            if self.gid_output.IsOutputStep():
                self.gid_output.PrintOutput()

            out = out + Dt

        self.gid_output.ExecuteFinalize()

    def SetManufacturedSolutionValues(self, fix=True, set_on_boundary=False):
        ## Set the analytical solution for the manufactured solution computation
        time = self.main_model_part.ProcessInfo[TIME]
        if (set_on_boundary == False):
            for node in self.main_model_part.Nodes:
                x_vel = self.ComputeNodalVelocityXManufacturedSolution(
                    node, time)
                y_vel = self.ComputeNodalVelocityYManufacturedSolution(
                    node, time)
                press = self.ComputeNodalPressureManufacturedSolution(node)

                if (fix == True):
                    node.Fix(VELOCITY_X)
                    node.Fix(VELOCITY_Y)
                    node.Fix(PRESSURE)

                node.SetSolutionStepValue(VELOCITY_X, 0, x_vel)
                node.SetSolutionStepValue(VELOCITY_Y, 0, y_vel)
                node.SetSolutionStepValue(PRESSURE, 0, press)
        else:
            for node in self.main_model_part.GetSubModelPart(
                    "Inlet2D_Contour").Nodes:
                x_vel = self.ComputeNodalVelocityXManufacturedSolution(
                    node, time)
                y_vel = self.ComputeNodalVelocityYManufacturedSolution(
                    node, time)

                if (fix == True):
                    node.Fix(VELOCITY_X)
                    node.Fix(VELOCITY_Y)

                node.SetSolutionStepValue(VELOCITY_X, 0, x_vel)
                node.SetSolutionStepValue(VELOCITY_Y, 0, y_vel)

    def SetNodalArea(self):
        # Compute nodal area
        for element in self.main_model_part.Elements:
            x = []
            y = []
            for node in element.GetNodes():
                x.append(node.X)
                y.append(node.Y)

            Area = 0.5 * (
                (x[1] * y[2] - x[2] * y[1]) + (x[2] * y[0] - x[0] * y[2]) +
                (x[0] * y[1] - x[1] * y[0]))  # Element area (Jacobian/2)
            # print("Element "+str(element.Id)+" area: "+str(Area))

            for node in element.GetNodes():
                aux = node.GetSolutionStepValue(
                    NODAL_AREA)  # Current nodal area (from other elements)
                aux += Area / 3.0  # Accumulate the current element nodal area
                node.SetSolutionStepValue(NODAL_AREA, 0, aux)
                node.SetValue(NODAL_AREA, aux)

        ## Check nodal area computation (squared shaped domain of 1x1 m)
        AreaTotal = 0.0
        for node in self.main_model_part.Nodes:
            # print("Node id "+str(node.Id)+" nodal area: "+str(node.GetValue(NODAL_AREA)))
            AreaTotal += node.GetValue(NODAL_AREA)

        if (abs(1.0 - AreaTotal) > 1e-5):
            print("Obtained total area: " + str(AreaTotal))
            raise Exception("Error in NODAL_AREA computation.")

    def SetManufacturedSolutionSourceValues(self):
        ## Set the body force as source term
        time = self.main_model_part.ProcessInfo[TIME]

        for node in self.main_model_part.Nodes:
            rho = node.GetSolutionStepValue(DENSITY)
            # nodal_area = node.GetValue(NODAL_AREA)
            # If VMS2D element is used, set mu as the Kinematic viscosity
            if (self.ProjectParameters["solver_settings"]
                ["solver_type"].GetString() == "Embedded"):
                mu = node.GetSolutionStepValue(DYNAMIC_VISCOSITY)
            elif (self.ProjectParameters["solver_settings"]
                  ["solver_type"].GetString() == "Monolithic"):
                mu = rho * node.GetSolutionStepValue(VISCOSITY)

            # Trigonometric transient field obtained with by hand derivation
            # rhofy = -rho*pi*cos(pi*node.X)*sin(pi*node.Y)*cos(pi*time) - 2*mu*pi*pi*cos(pi*node.X)*sin(pi*node.Y)*sin(pi*time) + rho*pi*(sin(pi*time)**2)*sin(pi*node.Y)*cos(pi*node.Y)
            # rhofx =  rho*pi*sin(pi*node.X)*cos(pi*node.Y)*cos(pi*time) + 2*mu*pi*pi*sin(pi*node.X)*cos(pi*node.Y)*sin(pi*time) + rho*pi*(sin(pi*time)**2)*sin(pi*node.X)*cos(pi*node.X)
            rhofx = -rho * pi * sin(pi * node.X) * cos(pi * node.Y) * sin(
                pi * time) + 2 * mu * pi * pi * sin(pi * node.X) * cos(
                    pi * node.Y) * cos(pi * time) + rho * pi * (cos(
                        pi * time)**2) * sin(pi * node.X) * cos(pi * node.X)
            rhofy = rho * pi * cos(pi * node.X) * sin(pi * node.Y) * sin(
                pi * time) - 2 * mu * pi * pi * cos(pi * node.X) * sin(
                    pi * node.Y) * cos(pi * time) + rho * pi * (cos(
                        pi * time)**2) * sin(pi * node.Y) * cos(pi * node.Y)

            # Trigonometric transient field obtained with symbolic generation
            # rhofx =  2*pi**2*mu*sin(pi*node.X)*sin(pi*time)*cos(pi*node.Y) + rho*(pi*sin(pi*node.X)*sin(pi*node.Y)**2*sin(pi*time)**2*cos(pi*node.X) + pi*sin(pi*node.X)*sin(pi*time)**2*cos(pi*node.X)*cos(pi*node.Y)**2) + pi*rho*sin(pi*node.X)*cos(pi*node.Y)*cos(pi*time)
            # rhofy = -2*pi**2*mu*sin(pi*node.Y)*sin(pi*time)*cos(pi*node.X) + rho*(pi*sin(pi*node.X)**2*sin(pi*node.Y)*sin(pi*time)**2*cos(pi*node.Y) + pi*sin(pi*node.Y)*sin(pi*time)**2*cos(pi*node.X)**2*cos(pi*node.Y)) - pi*rho*sin(pi*node.Y)*cos(pi*node.X)*cos(pi*time)
            # print("Node id. ",node.Id," by hand: ",rhofx_an," ",rhofy_an," sym: ",rhofx," ",rhofy)

            # Non-linear transient field
            # rhofx =   rho*pi*(node.X**2)*node.Y*cos(pi*time) - 2*mu*node.Y*sin(pi*time) + rho*(node.X**3)*(node.Y**2)*((sin(pi*time))**2)
            # rhofy =  -rho*pi*node.X*(node.Y**2)*cos(pi*time) + 2*mu*node.X*sin(pi*time) + rho*(node.X**2)*(node.Y**3)*((sin(pi*time))**2)

            # Non-linear stationary field
            # rhofx = -2*mu*node.Y + rho*node.X**3*node.Y**2
            # rhofy =  2*mu*node.X + rho*node.X**2*node.Y**3

            node.SetSolutionStepValue(
                BODY_FORCE_X, 0,
                rhofx / rho)  # Set the x-component body force field
            node.SetSolutionStepValue(
                BODY_FORCE_Y, 0,
                rhofy / rho)  # Set the y-component body force field

    def ComputeVelocityErrorNorm(self):
        err_v = 0

        for node in self.main_model_part.Nodes:
            weight = node.GetValue(NODAL_AREA)
            vel_x = node.GetSolutionStepValue(VELOCITY_X)
            vel_y = node.GetSolutionStepValue(VELOCITY_Y)
            end_time = self.main_model_part.ProcessInfo[TIME]

            analytical_vel_x = self.ComputeNodalVelocityXManufacturedSolution(
                node, end_time)
            analytical_vel_y = self.ComputeNodalVelocityYManufacturedSolution(
                node, end_time)

            err_x = analytical_vel_x - vel_x
            err_y = analytical_vel_y - vel_y
            err_node = err_x**2 + err_y**2
            err_v += weight * err_node

        return sqrt(
            err_v
        )  # Note, there is no need of dividing by the total area (sum of weights) since it is 1

    def ComputePressureErrorNorm(self):
        err_p = 0

        for node in self.main_model_part.Nodes:
            weight = node.GetValue(NODAL_AREA)
            pres = node.GetSolutionStepValue(PRESSURE)
            analytical_pres = self.ComputeNodalPressureManufacturedSolution(
                node)
            err_p += weight * (analytical_pres - pres)**2

        return sqrt(
            err_p
        )  # Note, there is no need of dividing by the total area (sum of weights) since it is 1

    def ComputeNodalDensityManufacturedSolution(self, node):
        # return 1.0 + 0.1*math.sin(0.75*math.pi*node.X) + 0.15*math.cos(1.0*math.pi*node.Y) + 0.08*math.cos(1.25*math.pi*node.X*node.Y)
        return 1.0

    # def ComputeNodalVelocityXManufacturedSolution(self, node):
    def ComputeNodalVelocityXManufacturedSolution(self, node, time):
        # return sin(pi*node.X)*cos(pi*node.Y)*sin(pi*time)   # Time dependent solution
        return sin(pi * node.X) * cos(pi * node.Y) * cos(
            pi * time)  # Time dependent solution
        # return node.X**2*node.Y*sin(pi*time)                # Non-linear transient field
        # return node.X**2*node.Y                             # Non-linear stationary field

    # def ComputeNodalVelocityYManufacturedSolution(self, node):
    def ComputeNodalVelocityYManufacturedSolution(self, node, time):
        # return -cos(pi*node.X)*sin(pi*node.Y)*sin(pi*time) # Time dependent solution
        return -cos(pi * node.X) * sin(pi * node.Y) * cos(
            pi * time)  # Time dependent solution
        # return -node.X*node.Y**2*sin(pi*time)               # Non-linear transient field
        # return -node.X*node.Y**2                            # Non-linear stationary field

    def ComputeNodalPressureManufacturedSolution(self, node):
        # return 100000.0 - 30000.0*math.cos(1.0*math.pi*node.X) + 20000.0*math.sin(1.25*math.pi*node.Y) - 25000.0*math.sin(0.75*math.pi*node.X*node.Y)
        return 0.0
Beispiel #25
0
class FEM_Solution(MainSolidFEM.Solution):
    def Info(self):
        KratosMultiphysics.Logger.PrintInfo(
            "FEM part of the FEMDEM application")

    def KratosPrintInfo(self, message):
        KratosMultiphysics.Logger.Print(message, label="")
        KratosMultiphysics.Logger.Flush()
#============================================================================================================================

    def __init__(self, Model):

        #### TIME MONITORING START ####
        # Time control starts
        self.KratosPrintInfo(timer.ctime())
        # Measure process time
        self.t0p = timer.clock()
        # Measure wall time
        self.t0w = timer.time()
        #### TIME MONITORING END ####

        #### PARSING THE PARAMETERS ####

        # Import input
        parameter_file = open("ProjectParameters.json", 'r')
        self.ProjectParameters = KratosMultiphysics.Parameters(
            parameter_file.read())

        # set echo level
        self.echo_level = self.ProjectParameters["problem_data"][
            "echo_level"].GetInt()

        self.KratosPrintInfo(" ")

        # defining the number of threads:
        num_threads = self.GetParallelSize()
        self.KratosPrintInfo("::[KSM Simulation]:: [OMP USING " +
                             str(num_threads) + " THREADS ]")
        #parallel.PrintOMPInfo()

        #### Model_part settings start ####

        # Defining the model_part
        self.model = Model
        self.model.CreateModelPart(self.ProjectParameters["problem_data"]
                                   ["model_part_name"].GetString())
        self.main_model_part = self.model.GetModelPart(
            self.ProjectParameters["problem_data"]
            ["model_part_name"].GetString())

        if (self.ProjectParameters["solver_settings"]
            ["solution_type"].GetString() == "Dynamic"):
            self.main_model_part.ProcessInfo.SetValue(KratosFemDem.IS_DYNAMIC,
                                                      1)
        else:
            self.main_model_part.ProcessInfo.SetValue(KratosFemDem.IS_DYNAMIC,
                                                      0)

        self.time_step = self.ComputeDeltaTime()
        self.start_time = self.ProjectParameters["problem_data"][
            "start_time"].GetDouble()
        self.end_time = self.ProjectParameters["problem_data"][
            "end_time"].GetDouble()

        self.main_model_part.ProcessInfo.SetValue(
            KratosMultiphysics.DOMAIN_SIZE,
            self.ProjectParameters["problem_data"]["domain_size"].GetInt())
        self.main_model_part.ProcessInfo.SetValue(
            KratosMultiphysics.DELTA_TIME, self.time_step)
        self.main_model_part.ProcessInfo.SetValue(KratosMultiphysics.TIME,
                                                  self.start_time)

        ### replace this "model" for real one once available in kratos core
        self.Model = {
            self.ProjectParameters["problem_data"]["model_part_name"].GetString(
            ):
            self.main_model_part
        }

        #construct the solver (main setting methods are located in the solver_module)
        solver_module = __import__(self.ProjectParameters["solver_settings"]
                                   ["solver_type"].GetString())
        self.solver = solver_module.CreateSolver(
            self.main_model_part, self.ProjectParameters["solver_settings"])

        #### Output settings start ####
        self.problem_path = os.getcwd()
        self.problem_name = self.ProjectParameters["problem_data"][
            "problem_name"].GetString()

#============================================================================================================================

    def AddMaterials(self):

        # Assign material to model_parts (if Materials.json exists)
        import process_factory

        if os.path.isfile("Materials.json"):
            materials_file = open("Materials.json", 'r')
            MaterialParameters = KratosMultiphysics.Parameters(
                materials_file.read())

            if (MaterialParameters.Has("material_models_list")):

                ## Get the list of the model_part's in the object Model
                for i in range(self.ProjectParameters["solver_settings"]
                               ["problem_domain_sub_model_part_list"].size()):
                    part_name = self.ProjectParameters["solver_settings"][
                        "problem_domain_sub_model_part_list"][i].GetString()
                    if (self.main_model_part.HasSubModelPart(part_name)):
                        self.Model.update({
                            part_name:
                            self.main_model_part.GetSubModelPart(part_name)
                        })

                assign_materials_processes = process_factory.KratosProcessFactory(
                    self.Model).ConstructListOfProcesses(
                        MaterialParameters["material_models_list"])
            for process in assign_materials_processes:
                process.Execute()
        else:
            self.KratosPrintInfo(" No Materials.json found ")

#============================================================================================================================

    def AddProcesses(self):

        # Build sub_model_parts or submeshes (rearrange parts for the application of custom processes)
        ## Get the list of the submodel part in the object Model
        for i in range(self.ProjectParameters["solver_settings"]
                       ["processes_sub_model_part_list"].size()):
            part_name = self.ProjectParameters["solver_settings"][
                "processes_sub_model_part_list"][i].GetString()
            if (self.main_model_part.HasSubModelPart(part_name)):
                self.Model.update({
                    part_name:
                    self.main_model_part.GetSubModelPart(part_name)
                })

        # Obtain the list of the processes to be applied
        import process_handler

        process_parameters = KratosMultiphysics.Parameters("{}")
        process_parameters.AddValue(
            "echo_level", self.ProjectParameters["problem_data"]["echo_level"])
        process_parameters.AddValue(
            "constraints_process_list",
            self.ProjectParameters["constraints_process_list"])
        process_parameters.AddValue(
            "loads_process_list", self.ProjectParameters["loads_process_list"])
        if (self.ProjectParameters.Has("problem_process_list")):
            process_parameters.AddValue(
                "problem_process_list",
                self.ProjectParameters["problem_process_list"])
        if (self.ProjectParameters.Has("output_process_list")):
            process_parameters.AddValue(
                "output_process_list",
                self.ProjectParameters["output_process_list"])

        return (process_handler.ProcessHandler(self.Model, process_parameters))

#============================================================================================================================

    def Run(self):

        self.Initialize()
        self.RunMainTemporalLoop()
        self.Finalize()
#============================================================================================================================

    def Initialize(self):

        # Add variables (always before importing the model part)
        self.solver.AddVariables()

        # Read model_part (note: the buffer_size is set here) (restart is read here)
        self.solver.ImportModelPart()

        # Add dofs (always after importing the model part)
        if ((self.main_model_part.ProcessInfo).Has(
                KratosMultiphysics.IS_RESTARTED)):
            if (self.main_model_part.ProcessInfo[
                    KratosMultiphysics.IS_RESTARTED] == False):
                self.solver.AddDofs()
        else:
            self.solver.AddDofs()

        # Add materials (assign material to model_parts if Materials.json exists)
        self.AddMaterials()

        # Add processes
        self.model_processes = self.AddProcesses()
        self.model_processes.ExecuteInitialize()

        # Print model_part and properties
        if (self.echo_level > 1):
            self.KratosPrintInfo("")
            self.KratosPrintInfo(self.main_model_part)
            for properties in self.main_model_part.Properties:
                self.KratosPrintInfo(properties)

        #### START SOLUTION ####
        self.computing_model_part = self.solver.GetComputingModelPart()

        ## Sets strategies, builders, linear solvers, schemes and solving info, and fills the buffer
        self.solver.Initialize()
        self.solver.SetEchoLevel(self.echo_level)

        # Initialize GiD  I/O (gid outputs, file_lists)
        self.SetGraphicalOutput()

        self.GraphicalOutputExecuteInitialize()

        self.model_processes.ExecuteBeforeSolutionLoop()

        self.GraphicalOutputExecuteBeforeSolutionLoop()

        # Set time settings
        self.step = self.main_model_part.ProcessInfo[KratosMultiphysics.STEP]
        self.time = self.main_model_part.ProcessInfo[KratosMultiphysics.TIME]

        self.end_time = self.ProjectParameters["problem_data"][
            "end_time"].GetDouble()
        self.delta_time = self.ProjectParameters["problem_data"][
            "time_step"].GetDouble()

#============================================================================================================================

    def RunMainTemporalLoop(self):

        # Solving the problem (time integration)
        while (self.time < self.end_time):

            self.InitializeSolutionStep()
            self.SolveSolutionStep()
            self.FinalizeSolutionStep()

#============================================================================================================================

    def InitializeSolutionStep(self):

        self.KratosPrintInfo("[STEP: " + str(self.step) + "  --  TIME: " +
                             str(self.time) + "  --  TIME_STEP: " +
                             str(self.delta_time) + "]")

        # processes to be executed at the begining of the solution step
        self.model_processes.ExecuteInitializeSolutionStep()
        self.GraphicalOutputExecuteInitializeSolutionStep()
        self.solver.InitializeSolutionStep()

#============================================================================================================================

    def SolveSolutionStep(self):
        self.clock_time = self.StartTimeMeasuring()
        self.solver.Solve()
        self.StopTimeMeasuring(self.clock_time, "Solving", False)

#============================================================================================================================

    def FinalizeSolutionStep(self):

        self.GraphicalOutputExecuteFinalizeSolutionStep()

        # processes to be executed at the end of the solution step
        self.model_processes.ExecuteFinalizeSolutionStep()

        # processes to be executed before witting the output
        self.model_processes.ExecuteBeforeOutputStep()

        # write output results GiD: (frequency writing is controlled internally)
        self.GraphicalOutputPrintOutput()

        # processes to be executed after witting the output
        self.model_processes.ExecuteAfterOutputStep()

#============================================================================================================================

    def Finalize(self):

        # Ending the problem (time integration finished)
        self.GraphicalOutputExecuteFinalize()
        self.model_processes.ExecuteFinalize()
        self.KratosPrintInfo(" ")
        self.KratosPrintInfo(
            "=================================================")
        self.KratosPrintInfo(
            " - Kratos FemDem Application Calculation End   - ")
        self.KratosPrintInfo(
            "=================================================")
        self.KratosPrintInfo(" ")
        #### END SOLUTION ####
        # Measure process time
        tfp = timer.clock()
        # Measure wall time
        tfw = timer.time()
        KratosMultiphysics.Logger.PrintInfo(
            "::[KSM Simulation]:: [Elapsed Time = %.2f" % (tfw - self.t0w),
            "seconds] (%.2f" % (tfp - self.t0p), "seconds of cpu/s time)")
        KratosMultiphysics.Logger.PrintInfo(timer.ctime())

#============================================================================================================================

    def SetGraphicalOutput(self):
        from gid_output_process import GiDOutputProcess
        self.output_settings = self.ProjectParameters["output_configuration"]
        self.graphical_output = GiDOutputProcess(self.computing_model_part,
                                                 self.problem_name,
                                                 self.output_settings)

    #============================================================================================================================
    def GraphicalOutputExecuteInitialize(self):
        self.graphical_output.ExecuteInitialize()

    #============================================================================================================================
    def GraphicalOutputExecuteBeforeSolutionLoop(self):
        # writing a initial state results file or single file (if no restart)
        if ((self.main_model_part.ProcessInfo).Has(
                KratosMultiphysics.IS_RESTARTED)):
            if (self.main_model_part.ProcessInfo[
                    KratosMultiphysics.IS_RESTARTED] == False):
                self.graphical_output.ExecuteBeforeSolutionLoop()

    #============================================================================================================================
    def GraphicalOutputExecuteInitializeSolutionStep(self):
        self.graphical_output.ExecuteInitializeSolutionStep()

    #============================================================================================================================
    def GraphicalOutputExecuteFinalizeSolutionStep(self):
        self.graphical_output.ExecuteFinalizeSolutionStep()

    #============================================================================================================================
    def GraphicalOutputPrintOutput(self):
        if (self.graphical_output.IsOutputStep()):
            self.graphical_output.PrintOutput()

    #============================================================================================================================
    def GraphicalOutputExecuteFinalize(self):
        self.graphical_output.ExecuteFinalize()

    #============================================================================================================================
    def SetParallelSize(self, num_threads):
        parallel = KratosMultiphysics.OpenMPUtils()
        parallel.SetNumThreads(int(num_threads))

    #============================================================================================================================
    def GetParallelSize(self):
        parallel = KratosMultiphysics.OpenMPUtils()
        return parallel.GetNumThreads()

    #============================================================================================================================
    def StartTimeMeasuring(self):
        # Measure process time
        time_ip = timer.clock()
        return time_ip

    #============================================================================================================================
    def StopTimeMeasuring(self, time_ip, process, report):
        # Measure process time
        time_fp = timer.clock()
        if (report):
            used_time = time_fp - time_ip
            print("::[KSM Simulation]:: [ %.2f" % round(used_time, 2), "s",
                  process, " ] ")
Beispiel #26
0
class ManufacturedSolutionProblem:
    def __init__(self, ProjectParameters, input_file_name, print_output,
                 problem_type, analytical_solution_type):

        self.problem_type = problem_type
        self.print_output = print_output
        self.input_file_name = input_file_name
        self.ProjectParameters = ProjectParameters
        self.analytical_solution_type = analytical_solution_type
        self.model = KratosMultiphysics.Model()

    def SetFluidProblem(self):

        ## Set the current mesh case problem info
        if (self.problem_type == "analytical_solution"):
            self.ProjectParameters["problem_data"]["problem_name"].SetString(
                self.input_file_name + "_manufactured")
        else:
            self.ProjectParameters["problem_data"]["problem_name"].SetString(
                self.input_file_name)
        self.ProjectParameters["solver_settings"]["model_import_settings"][
            "input_filename"].SetString(self.input_file_name)

        ## Solver construction
        self.solver = python_solvers_wrapper_fluid.CreateSolver(
            self.model, self.ProjectParameters)

        self.solver.AddVariables()

        ## Read the model - note that SetBufferSize is done here
        self.solver.ImportModelPart()
        self.solver.PrepareModelPart()

        self.main_model_part = self.model.GetModelPart(
            self.ProjectParameters["problem_data"]
            ["model_part_name"].GetString())

        ## Add AddDofs
        self.solver.AddDofs()

        ## Initialize GiD  I/O
        if (self.print_output):
            from gid_output_process import GiDOutputProcess
            self.gid_output = GiDOutputProcess(
                self.solver.GetComputingModelPart(),
                self.ProjectParameters["problem_data"]
                ["problem_name"].GetString(),
                self.ProjectParameters["output_configuration"])

            self.gid_output.ExecuteInitialize()

        ## Solver initialization
        self.solver.Initialize()

        ## Compute and set the nodal area
        self.SetNodalArea()

        ## Set the distance to 1 to have full fluid elements
        if (self.ProjectParameters["solver_settings"]
            ["solver_type"].GetString() == "Embedded"):
            for node in self.main_model_part.Nodes:
                node.SetSolutionStepValue(KratosMultiphysics.DISTANCE, 0, 1.0)

        ## Fix the pressure in one node (bottom left corner)
        for node in self.main_model_part.Nodes:
            if ((node.X < 0.001) and (node.Y < 0.001)):
                node.Fix(KratosMultiphysics.PRESSURE)
                node.SetSolutionStepValue(KratosMultiphysics.PRESSURE, 0, 0.0)

    def SolveFluidProblem(self):

        ## Stepping and time settings
        end_time = self.ProjectParameters["problem_data"][
            "end_time"].GetDouble()

        time = 0.0

        if (self.print_output):
            self.gid_output.ExecuteBeforeSolutionLoop()

        while (time <= end_time):

            time = self.solver.AdvanceInTime(time)

            if (self.print_output):
                self.gid_output.ExecuteInitializeSolutionStep()

            if (self.problem_type == "analytical_solution"):
                # Fix the manufactured solution values (only for visualization purposes)
                self.SetManufacturedSolutionValues(fix=True,
                                                   set_only_boundaries=False)
            else:
                # Set the manufactured solution source terms
                self.SetManufacturedSolutionValues(fix=True,
                                                   set_only_boundaries=True)
                self.SetManufacturedSolutionSourceValues()

            if (self.main_model_part.ProcessInfo[KratosMultiphysics.STEP] < 3):
                self.SetManufacturedSolutionValues(
                    False
                )  # Set the analytical solution in the two first steps
            else:
                if (self.problem_type != "analytical_solution"):
                    self.solver.InitializeSolutionStep()
                    self.solver.Predict()
                    self.solver.SolveSolutionStep()
                    self.solver.FinalizeSolutionStep()

            if (self.print_output):
                self.gid_output.ExecuteFinalizeSolutionStep()

                if self.gid_output.IsOutputStep():
                    self.gid_output.PrintOutput()

        if (self.print_output):
            self.gid_output.ExecuteFinalize()

    def SetManufacturedSolutionValues(self,
                                      fix=True,
                                      set_only_boundaries=False):
        ## Set the analytical solution for the manufactured solution computation
        time = self.main_model_part.ProcessInfo[KratosMultiphysics.TIME]

        if (set_only_boundaries == False):
            for node in self.main_model_part.Nodes:
                vel = self.ComputeNodalVelocityManufacturedSolution(node, time)
                pres = self.ComputeNodalPressureManufacturedSolution(node)

                if (fix == True):
                    node.Fix(KratosMultiphysics.VELOCITY_X)
                    node.Fix(KratosMultiphysics.VELOCITY_Y)
                    node.Fix(KratosMultiphysics.PRESSURE)

                node.SetSolutionStepValue(KratosMultiphysics.VELOCITY_X, 0,
                                          vel[0])
                node.SetSolutionStepValue(KratosMultiphysics.VELOCITY_Y, 0,
                                          vel[1])
                node.SetSolutionStepValue(KratosMultiphysics.PRESSURE, 0, pres)
        else:
            for node in self.main_model_part.GetSubModelPart(
                    "Inlet2D_Contour").Nodes:
                vel = self.ComputeNodalVelocityManufacturedSolution(node, time)

                if (fix == True):
                    node.Fix(KratosMultiphysics.VELOCITY_X)
                    node.Fix(KratosMultiphysics.VELOCITY_Y)

                node.SetSolutionStepValue(KratosMultiphysics.VELOCITY_X, 0,
                                          vel[0])
                node.SetSolutionStepValue(KratosMultiphysics.VELOCITY_Y, 0,
                                          vel[1])

    def SetNodalArea(self):
        # Compute nodal area
        for element in self.main_model_part.Elements:
            x = []
            y = []
            for node in element.GetNodes():
                x.append(node.X)
                y.append(node.Y)

            Area = 0.5 * (
                (x[1] * y[2] - x[2] * y[1]) + (x[2] * y[0] - x[0] * y[2]) +
                (x[0] * y[1] - x[1] * y[0]))  # Element area (Jacobian/2)
            # print("Element "+str(element.Id)+" area: "+str(Area))

            for node in element.GetNodes():
                aux = node.GetSolutionStepValue(
                    KratosMultiphysics.NODAL_AREA
                )  # Current nodal area (from other elements)
                aux += Area / 3.0  # Accumulate the current element nodal area
                node.SetSolutionStepValue(KratosMultiphysics.NODAL_AREA, 0,
                                          aux)
                node.SetValue(KratosMultiphysics.NODAL_AREA, aux)

        ## Check nodal area computation (squared shaped domain of 1x1 m)
        AreaTotal = 0.0
        for node in self.main_model_part.Nodes:
            # print("Node id "+str(node.Id)+" nodal area: "+str(node.GetValue(KratosMultiphysics.NODAL_AREA)))
            AreaTotal += node.GetValue(KratosMultiphysics.NODAL_AREA)

        if (abs(1.0 - AreaTotal) > 1e-5):
            print("Obtained total area: " + str(AreaTotal))
            raise Exception("Error in NODAL_AREA computation.")

    def SetManufacturedSolutionSourceValues(self):
        ## Set the body force as source term
        time = self.main_model_part.ProcessInfo[KratosMultiphysics.TIME]
        solver_type = self.ProjectParameters["solver_settings"][
            "solver_type"].GetString()

        for node in self.main_model_part.Nodes:
            if solver_type == "Monolithic":
                # If VMS2D element is used, set mu as the Kinematic viscosity and density in the nodes
                rho = node.GetSolutionStepValue(KratosMultiphysics.DENSITY)
                mu = rho * node.GetSolutionStepValue(
                    KratosMultiphysics.VISCOSITY)
            elif solver_type == "Embedded":
                # If the symbolic elements are used, get the density and viscosity from the first element properties
                for elem in self.main_model_part.Elements:
                    rho = elem.Properties[KratosMultiphysics.DENSITY]
                    mu = elem.Properties[KratosMultiphysics.DYNAMIC_VISCOSITY]
                    break

            rhof = self.ComputeNodalSourceTermManufacturedSolution(
                node, time, rho, mu)

            node.SetSolutionStepValue(
                KratosMultiphysics.BODY_FORCE_X, 0,
                rhof[0] / rho)  # Set the x-component body force field
            node.SetSolutionStepValue(
                KratosMultiphysics.BODY_FORCE_Y, 0,
                rhof[1] / rho)  # Set the y-component body force field

    def ComputeVelocityErrorNorm(self):
        err_v = 0

        for node in self.main_model_part.Nodes:
            weight = node.GetValue(KratosMultiphysics.NODAL_AREA)
            vel_x = node.GetSolutionStepValue(KratosMultiphysics.VELOCITY_X)
            vel_y = node.GetSolutionStepValue(KratosMultiphysics.VELOCITY_Y)
            end_time = self.main_model_part.ProcessInfo[
                KratosMultiphysics.TIME]

            analytical_vel = self.ComputeNodalVelocityManufacturedSolution(
                node, end_time)

            err_x = analytical_vel[0] - vel_x
            err_y = analytical_vel[1] - vel_y
            err_node = err_x**2 + err_y**2
            err_v += weight * err_node

        return math.sqrt(
            err_v
        )  # Note, there is no need of dividing by the total area (sum of weights) since it is 1

    def ComputePressureErrorNorm(self):
        err_p = 0

        for node in self.main_model_part.Nodes:
            weight = node.GetValue(KratosMultiphysics.NODAL_AREA)
            pres = node.GetSolutionStepValue(KratosMultiphysics.PRESSURE)
            analytical_pres = self.ComputeNodalPressureManufacturedSolution(
                node)
            err_p += weight * (analytical_pres - pres)**2

        return math.sqrt(
            err_p
        )  # Note, there is no need of dividing by the total area (sum of weights) since it is 1

    def ComputeNodalSourceTermManufacturedSolution(self, node, time, rho, mu):
        if (self.analytical_solution_type == "sinusoidal_transient_field"):
            rhofx = -rho * math.pi * math.sin(math.pi * node.X) * math.cos(
                math.pi * node.Y) * math.sin(
                    math.pi * time) + 2 * mu * math.pi * math.pi * math.sin(
                        math.pi * node.X
                    ) * math.cos(math.pi * node.Y) * math.cos(
                        math.pi * time) + rho * math.pi * (math.cos(
                            math.pi * time)**2) * math.sin(
                                math.pi * node.X) * math.cos(math.pi * node.X)
            rhofy = rho * math.pi * math.cos(math.pi * node.X) * math.sin(
                math.pi * node.Y) * math.sin(
                    math.pi * time) - 2 * mu * math.pi * math.pi * math.cos(
                        math.pi * node.X
                    ) * math.sin(math.pi * node.Y) * math.cos(
                        math.pi * time) + rho * math.pi * (math.cos(
                            math.pi * time)**2) * math.sin(
                                math.pi * node.Y) * math.cos(math.pi * node.Y)

        elif (self.analytical_solution_type == "nonlinear_transient_field"):
            rhofx = rho * math.pi * (node.X**2) * node.Y * math.cos(
                math.pi * time) - 2 * mu * node.Y * math.sin(
                    math.pi * time) + rho * (node.X**3) * (node.Y**2) * (
                        (math.sin(math.pi * time))**2)
            rhofy = -rho * math.pi * node.X * (node.Y**2) * math.cos(
                math.pi * time) + 2 * mu * node.X * math.sin(
                    math.pi * time) + rho * (node.X**2) * (node.Y**3) * (
                        (math.sin(math.pi * time))**2)

        elif (self.analytical_solution_type == "nonlinear_stationary_field"):
            rhofx = -2 * mu * node.Y + rho * node.X**3 * node.Y**2
            rhofy = 2 * mu * node.X + rho * node.X**2 * node.Y**3

        return [rhofx, rhofy]

    def ComputeNodalVelocityManufacturedSolution(self, node, time):
        if (self.analytical_solution_type == "sinusoidal_transient_field"):
            vx = math.sin(math.pi * node.X) * math.cos(
                math.pi * node.Y) * math.cos(math.pi * time)
            vy = -math.cos(math.pi * node.X) * math.sin(
                math.pi * node.Y) * math.cos(math.pi * time)

        elif (self.analytical_solution_type == "nonlinear_transient_field"):
            vx = node.X**2 * node.Y * math.sin(math.pi * time)
            vy = -node.X * node.Y**2 * math.sin(math.pi * time)

        elif (self.analytical_solution_type == "nonlinear_stationary_field"):
            vx = node.X**2 * node.Y
            vy = -node.X * node.Y**2

        return [vx, vy]

    def ComputeNodalPressureManufacturedSolution(self, node):
        # We consider solenoidal velocity fields in order to have a known zero pressure solution on the continuum
        return 0.0
class kratosCSMAnalyzer((__import__("analyzer_base")).analyzerBaseClass):

    # --------------------------------------------------------------------------
    def __init__(self):

        self.initializeGIDOutput()
        self.initializeProcesses()
        self.initializeSolutionLoop()

    # --------------------------------------------------------------------------
    def initializeProcesses(self):

        import process_factory
        #the process order of execution is important
        self.list_of_processes = process_factory.KratosProcessFactory(
            Model).ConstructListOfProcesses(
                ProjectParameters["constraints_process_list"])
        self.list_of_processes += process_factory.KratosProcessFactory(
            Model).ConstructListOfProcesses(
                ProjectParameters["loads_process_list"])
        if (ProjectParameters.Has("problem_process_list")):
            self.list_of_processes += process_factory.KratosProcessFactory(
                Model).ConstructListOfProcesses(
                    ProjectParameters["problem_process_list"])
        if (ProjectParameters.Has("output_process_list")):
            self.list_of_processes += process_factory.KratosProcessFactory(
                Model).ConstructListOfProcesses(
                    ProjectParameters["output_process_list"])

        #print list of constructed processes
        if (echo_level > 1):
            for process in self.list_of_processes:
                print(process)

        for process in self.list_of_processes:
            process.ExecuteInitialize()

    # --------------------------------------------------------------------------
    def initializeGIDOutput(self):

        computing_model_part = CSM_solver.GetComputingModelPart()
        problem_name = ProjectParameters["problem_data"][
            "problem_name"].GetString()

        from gid_output_process import GiDOutputProcess
        output_settings = ProjectParameters["output_configuration"]
        self.gid_output = GiDOutputProcess(computing_model_part, problem_name,
                                           output_settings)

        self.gid_output.ExecuteInitialize()

    # --------------------------------------------------------------------------
    def initializeSolutionLoop(self):

        ## Sets strategies, builders, linear solvers, schemes and solving info, and fills the buffer
        CSM_solver.Initialize()
        CSM_solver.SetEchoLevel(echo_level)

        mesh_solver.Initialize()
        mesh_solver.SetEchoLevel(echo_level)

        for responseFunctionId in listOfResponseFunctions:
            listOfResponseFunctions[responseFunctionId].Initialize()

        # Start process
        for process in self.list_of_processes:
            process.ExecuteBeforeSolutionLoop()

        ## Set results when are written in a single file
        self.gid_output.ExecuteBeforeSolutionLoop()

    # --------------------------------------------------------------------------
    def analyzeDesignAndReportToCommunicator(self, currentDesign,
                                             optimizationIteration,
                                             communicator):

        # Calculation of value of objective function
        if communicator.isRequestingFunctionValueOf("strain_energy"):

            self.initializeNewSolutionStep(optimizationIteration)

            print("\n> Starting ALEApplication to update the mesh")
            startTime = timer.time()
            self.updateMeshForAnalysis()
            print("> Time needed for updating the mesh = ",
                  round(timer.time() - startTime, 2), "s")

            print(
                "\n> Starting StructuralMechanicsApplication to solve structure"
            )
            startTime = timer.time()
            self.solveStructure(optimizationIteration)
            print("> Time needed for solving the structure = ",
                  round(timer.time() - startTime, 2), "s")

            print("\n> Starting calculation of strain energy")
            startTime = timer.time()
            listOfResponseFunctions["strain_energy"].CalculateValue()
            print("> Time needed for calculation of strain energy = ",
                  round(timer.time() - startTime, 2), "s")

            communicator.reportFunctionValue(
                "strain_energy",
                listOfResponseFunctions["strain_energy"].GetValue())

        # Calculation of value of constraint function
        if communicator.isRequestingFunctionValueOf("mass"):

            print("\n> Starting calculation of value of mass constraint")
            listOfResponseFunctions["mass"].CalculateValue()
            constraintFunctionValue = listOfResponseFunctions["mass"].GetValue(
            ) - listOfResponseFunctions["mass"].GetInitialValue()
            print(
                "> Time needed for calculation of value of mass constraint = ",
                round(timer.time() - startTime, 2), "s")

            communicator.reportFunctionValue("mass", constraintFunctionValue)
            communicator.setFunctionReferenceValue(
                "mass", listOfResponseFunctions["mass"].GetInitialValue())

        # Calculation of gradients of objective function
        if communicator.isRequestingGradientOf("strain_energy"):

            print("\n> Starting calculation of gradient of objective function")
            startTime = timer.time()
            listOfResponseFunctions["strain_energy"].CalculateGradient()
            print(
                "> Time needed for calculating gradient of objective function = ",
                round(timer.time() - startTime, 2), "s")

            gradientForCompleteModelPart = listOfResponseFunctions[
                "strain_energy"].GetGradient()
            gradientOnDesignSurface = {}
            for node in currentDesign.Nodes:
                gradientOnDesignSurface[
                    node.Id] = gradientForCompleteModelPart[node.Id]

            # If contribution from mesh-motion to gradient shall be considered
            # self.computeAndAddMeshDerivativesToGradient(gradientOnDesignSurface, gradientForCompleteModelPart)

            communicator.reportGradient("strain_energy",
                                        gradientOnDesignSurface)

        # Calculation of gradients of constraint function
        if communicator.isRequestingGradientOf("mass"):

            print(
                "\n> Starting calculation of gradient of constraint function")
            startTime = timer.time()
            listOfResponseFunctions["mass"].CalculateGradient()
            print(
                "> Time needed for calculating gradient of constraint function = ",
                round(timer.time() - startTime, 2), "s")

            gradientForCompleteModelPart = listOfResponseFunctions[
                "mass"].GetGradient()
            gradientOnDesignSurface = {}
            for node in currentDesign.Nodes:
                gradientOnDesignSurface[
                    node.Id] = gradientForCompleteModelPart[node.Id]

            communicator.reportGradient("mass", gradientOnDesignSurface)

    # --------------------------------------------------------------------------
    def initializeNewSolutionStep(self, optimizationIteration):
        main_model_part.CloneTimeStep(optimizationIteration)

    # --------------------------------------------------------------------------
    def updateMeshForAnalysis(self):

        # Extract surface nodes
        sub_model_part_name = "surface_nodes"
        GeometryUtilities(main_model_part).ExtractSurfaceNodes(
            sub_model_part_name)

        # Apply shape update as boundary condition for computation of mesh displacement
        for node in main_model_part.GetSubModelPart(sub_model_part_name).Nodes:
            node.Fix(MESH_DISPLACEMENT_X)
            node.Fix(MESH_DISPLACEMENT_Y)
            node.Fix(MESH_DISPLACEMENT_Z)
            disp = Vector(3)
            disp[0] = node.GetSolutionStepValue(SHAPE_UPDATE_X)
            disp[1] = node.GetSolutionStepValue(SHAPE_UPDATE_Y)
            disp[2] = node.GetSolutionStepValue(SHAPE_UPDATE_Z)
            node.SetSolutionStepValue(MESH_DISPLACEMENT, 0, disp)

        # Solve for mesh-update
        mesh_solver.Solve()

        # Update reference mesh (Since shape updates are imposed as incremental quantities)
        mesh_solver.get_mesh_motion_solver().UpdateReferenceMesh()

        # Log absolute mesh displacement
        for node in main_model_part.Nodes:
            mesh_change = Vector(3)
            mesh_change[0] = node.GetSolutionStepValue(
                MESH_CHANGE_X) + node.GetSolutionStepValue(MESH_DISPLACEMENT_X)
            mesh_change[1] = node.GetSolutionStepValue(
                MESH_CHANGE_Y) + node.GetSolutionStepValue(MESH_DISPLACEMENT_Y)
            mesh_change[2] = node.GetSolutionStepValue(
                MESH_CHANGE_Z) + node.GetSolutionStepValue(MESH_DISPLACEMENT_Z)
            node.SetSolutionStepValue(MESH_CHANGE, 0, mesh_change)

    # --------------------------------------------------------------------------
    def solveStructure(self, optimizationIteration):

        # processes to be executed at the begining of the solution step
        for process in self.list_of_processes:
            process.ExecuteInitializeSolutionStep()

        self.gid_output.ExecuteInitializeSolutionStep()

        # Actual solution
        CSM_solver.Solve()

        # processes to be executed at the end of the solution step
        for process in self.list_of_processes:
            process.ExecuteFinalizeSolutionStep()

        # processes to be executed before witting the output
        for process in self.list_of_processes:
            process.ExecuteBeforeOutputStep()

        # write output results GiD: (frequency writing is controlled internally)
        if (self.gid_output.IsOutputStep()):
            self.gid_output.PrintOutput()

        self.gid_output.ExecuteFinalizeSolutionStep()

        # processes to be executed after witting the output
        for process in self.list_of_processes:
            process.ExecuteAfterOutputStep()

    # --------------------------------------------------------------------------
    def computeAndAddMeshDerivativesToGradient(self, gradientOnDesignSurface,
                                               gradientForCompleteModelPart):

        # Here we solve the pseudo-elastic mesh-motion system again using modified BCs
        # The contributions from the mesh derivatives appear as reaction forces
        for node in main_model_part.Nodes:

            # Apply dirichlet conditions
            if node.Id in gradientOnDesignSurface.keys():
                node.Fix(MESH_DISPLACEMENT_X)
                node.Fix(MESH_DISPLACEMENT_Y)
                node.Fix(MESH_DISPLACEMENT_Z)
                xs = Vector(3)
                xs[0] = 0.0
                xs[1] = 0.0
                xs[2] = 0.0
                node.SetSolutionStepValue(MESH_DISPLACEMENT, 0, xs)
            # Apply RHS conditions
            else:
                rhs = Vector(3)
                rhs[0] = gradientForCompleteModelPart[node.Id][0]
                rhs[1] = gradientForCompleteModelPart[node.Id][1]
                rhs[2] = gradientForCompleteModelPart[node.Id][2]
                node.SetSolutionStepValue(MESH_RHS, 0, rhs)

        # Solve mesh-motion problem with previously modified BCs
        mesh_solver.Solve()

        # Compute and add gradient contribution from mesh motion
        for node_id in gradientOnDesignSurface.keys():
            node = main_model_part.Nodes[node_id]
            sens_contribution = Vector(3)
            sens_contribution = node.GetSolutionStepValue(MESH_REACTION)
            gradientOnDesignSurface[
                node.Id] = gradientOnDesignSurface[node_id] + sens_contribution

    # --------------------------------------------------------------------------
    def finalizeSolutionLoop(self):
        for process in self.list_of_processes:
            process.ExecuteFinalize()
        self.gid_output.ExecuteFinalize()
class TestMortarMapperCore(KratosUnittest.TestCase):
    def setUp(self):
        pass

    def __base_test_mapping(self, input_filename, num_nodes, master_num_nodes,
                            pure_implicit, inverted, discontinuous,
                            origin_are_conditions, destination_are_conditions):
        KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(
            KratosMultiphysics.Logger.Severity.WARNING)
        self.model = KratosMultiphysics.Model()

        self.main_model_part = self.model.CreateModelPart("Main", 2)

        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.DISPLACEMENT)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.TEMPERATURE)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.NORMAL)

        self.main_model_part.CloneTimeStep(1.01)

        KratosMultiphysics.ModelPartIO(input_filename).ReadModelPart(
            self.main_model_part)

        ## DEBUG Generate discontinous case
        #self.__generate_discontinous_case(inverted)

        if inverted:
            self.model_part_slave = self.main_model_part.GetSubModelPart(
                "Parts_Parts_Auto2")
            self.model_part_master = self.main_model_part.GetSubModelPart(
                "Parts_Parts_Auto1")
        else:
            self.model_part_slave = self.main_model_part.GetSubModelPart(
                "Parts_Parts_Auto1")
            self.model_part_master = self.main_model_part.GetSubModelPart(
                "Parts_Parts_Auto2")

        for node in self.model_part_master.Nodes:
            x = node.X
            y = node.Y
            z = node.Z
            node.SetSolutionStepValue(KratosMultiphysics.TEMPERATURE, z)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_X, x)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_Y, y)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_Z, z)
        del (node)

        map_parameters = KratosMultiphysics.Parameters("""
        {
            "echo_level"                       : 0,
            "absolute_convergence_tolerance"   : 1.0e-9,
            "relative_convergence_tolerance"   : 1.0e-4,
            "max_number_iterations"            : 10,
            "integration_order"                : 2,
            "origin_variable"                  : "TEMPERATURE",
            "discontinuous_interface"          : false,
            "origin_are_conditions"            : true,
            "destination_are_conditions"       : true
        }
        """)
        map_parameters["discontinuous_interface"].SetBool(discontinuous)
        map_parameters["origin_are_conditions"].SetBool(origin_are_conditions)
        map_parameters["destination_are_conditions"].SetBool(
            destination_are_conditions)

        if pure_implicit:
            #linear_solver = ExternalSolversApplication.SuperLUSolver()
            linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()
        else:
            linear_solver = None

        self.mortar_mapping_double = KratosMultiphysics.SimpleMortarMapperProcess(
            self.model_part_master, self.model_part_slave, map_parameters,
            linear_solver)
        map_parameters["origin_variable"].SetString("DISPLACEMENT")
        self.mortar_mapping_vector = KratosMultiphysics.SimpleMortarMapperProcess(
            self.model_part_master, self.model_part_slave, map_parameters,
            linear_solver)

    def _mapper_tests(self,
                      input_filename,
                      num_nodes,
                      master_num_nodes,
                      pure_implicit=False,
                      inverted=False,
                      discontinuous=False,
                      origin_are_conditions=True,
                      destination_are_conditions=True):

        self.__base_test_mapping(input_filename, num_nodes, master_num_nodes,
                                 pure_implicit, inverted, discontinuous,
                                 origin_are_conditions,
                                 destination_are_conditions)

        self.mortar_mapping_double.Execute()
        self.mortar_mapping_vector.Execute()

        # Debug postprocess file
        #self.__post_process()

        import from_json_check_result_process

        check_parameters = KratosMultiphysics.Parameters("""
        {
            "check_variables"      : ["TEMPERATURE","DISPLACEMENT"],
            "input_file_name"      : "",
            "model_part_name"      : "Main",
            "sub_model_part_name"  : "Parts_Parts_Auto1"
        }
        """)

        if inverted:
            check_parameters["input_file_name"].SetString(input_filename +
                                                          "_inverted.json")
        else:
            check_parameters["input_file_name"].SetString(input_filename +
                                                          ".json")

        check = from_json_check_result_process.FromJsonCheckResultProcess(
            self.model, check_parameters)
        check.ExecuteInitialize()
        check.ExecuteBeforeSolutionLoop()
        check.ExecuteFinalizeSolutionStep()

        ## The following is used to create the solution database
        #import json_output_process

        #out_parameters = KratosMultiphysics.Parameters("""
        #{
        #"output_variables"     : ["TEMPERATURE","DISPLACEMENT"],
        #"output_file_name"     : "",
        #"model_part_name"      : "Main",
        #"sub_model_part_name"  : "Parts_Parts_Auto1"
        #}
        #""")

        #if inverted:
        #out_parameters["output_file_name"].SetString(input_filename+"_inverted.json")
        #else:
        #out_parameters["output_file_name"].SetString(input_filename+".json")

        #out = json_output_process.JsonOutputProcess(self.model, out_parameters)
        #out.ExecuteInitialize()
        #out.ExecuteBeforeSolutionLoop()
        #out.ExecuteFinalizeSolutionStep()

    def test_less_basic_mortar_mapping_triangle_pure_implicit(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/auxiliar_files_for_python_unnitest/mortar_mapper_python_tests/test_integration_several_triangles"
        self._mapper_tests(input_filename, 3, 3, True)

    def test_less_basic_mortar_mapping_triangle(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/auxiliar_files_for_python_unnitest/mortar_mapper_python_tests/test_integration_several_triangles"
        self._mapper_tests(input_filename, 3, 3)

    def test_simple_curvature_mortar_mapping_triangle(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/auxiliar_files_for_python_unnitest/mortar_mapper_python_tests/test_simple_curvature"
        self._mapper_tests(input_filename, 3, 3)

    def test_mortar_mapping_triangle(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/auxiliar_files_for_python_unnitest/mortar_mapper_python_tests/test_double_curvature_integration_triangle"
        self._mapper_tests(input_filename, 3, 3)

    def test_mortar_mapping_triangle_discontinous_interface(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/auxiliar_files_for_python_unnitest/mortar_mapper_python_tests/test_double_curvature_integration_triangle_discontinous_interface"
        self._mapper_tests(input_filename, 3, 3, False, False, True)

    def test_mortar_mapping_quad(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/auxiliar_files_for_python_unnitest/mortar_mapper_python_tests/test_double_curvature_integration_quadrilateral"
        self._mapper_tests(input_filename, 4, 4)

    def test_mortar_mapping_quad_tri(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/auxiliar_files_for_python_unnitest/mortar_mapper_python_tests/test_double_curvature_integration_triangle_quadrilateral"
        self._mapper_tests(input_filename, 4, 3, False, False, False, False,
                           True)

    def test_mortar_mapping_tri_quad(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/auxiliar_files_for_python_unnitest/mortar_mapper_python_tests/test_double_curvature_integration_triangle_quadrilateral"
        self._mapper_tests(input_filename, 3, 4, False, True, False, True,
                           False)

    def __post_process(self, debug="GiD"):

        if debug == "GiD":
            from gid_output_process import GiDOutputProcess
            self.gid_output = GiDOutputProcess(
                self.main_model_part, "gid_output",
                KratosMultiphysics.Parameters("""
                                            {
                                                "result_file_configuration" : {
                                                    "gidpost_flags": {
                                                        "GiDPostMode": "GiD_PostBinary",
                                                        "WriteDeformedMeshFlag": "WriteUndeformed",
                                                        "WriteConditionsFlag": "WriteConditionsOnly",
                                                        "MultiFileFlag": "SingleFile"
                                                    },
                                                    "nodal_results"       : ["DISPLACEMENT","NORMAL","TEMPERATURE"],
                                                    "nodal_nonhistorical_results": ["NODAL_AREA","NODAL_MAUX","NODAL_VAUX"]
                                                }
                                            }
                                            """))

            self.gid_output.ExecuteInitialize()
            self.gid_output.ExecuteBeforeSolutionLoop()
            self.gid_output.ExecuteInitializeSolutionStep()
            self.gid_output.PrintOutput()
            self.gid_output.ExecuteFinalizeSolutionStep()
            self.gid_output.ExecuteFinalize()
        elif debug == "VTK":
            from vtk_output_process import VtkOutputProcess
            self.vtk_output_process = VtkOutputProcess(
                self.model,
                KratosMultiphysics.Parameters("""{
                                                "model_part_name"                    : "Main",
                                                "nodal_solution_step_data_variables" : ["DISPLACEMENT","NORMAL","TEMPERATURE"],
                                                "nodal_data_value_variables": ["NODAL_AREA","NODAL_MAUX","NODAL_VAUX"]
                                            }
                                            """))

            self.vtk_output_process.ExecuteInitialize()
            self.vtk_output_process.ExecuteBeforeSolutionLoop()
            self.vtk_output_process.ExecuteInitializeSolutionStep()
            self.vtk_output_process.PrintOutput()
            self.vtk_output_process.ExecuteFinalizeSolutionStep()
            self.vtk_output_process.ExecuteFinalize()

    def __generate_discontinous_case(self, inverted):
        counter_nodes = 0
        for node in self.main_model_part.Nodes:
            counter_nodes += 1

        counter_conditions = 0
        for cond in self.main_model_part.Conditions:
            counter_conditions += 1

        if inverted:
            self.model_part_slave = self.main_model_part.GetSubModelPart(
                "Parts_Parts_Auto2")
            self.model_part_master = self.main_model_part.GetSubModelPart(
                "Parts_Parts_Auto1")
        else:
            self.model_part_slave = self.main_model_part.GetSubModelPart(
                "Parts_Parts_Auto1")
            self.model_part_master = self.main_model_part.GetSubModelPart(
                "Parts_Parts_Auto2")

        for cond in self.model_part_slave.Conditions:

            counter_conditions += 1
            length = cond.GetGeometry().Area() * 0.01
            list_nodes = []
            for node in cond.GetNodes():
                counter_nodes += 1
                list_nodes.append(counter_nodes)
                self.model_part_slave.CreateNewNode(counter_nodes,
                                                    node.X + length,
                                                    node.Y - length, node.Z)
                node.Set(KratosMultiphysics.TO_ERASE)
            cond.Set(KratosMultiphysics.TO_ERASE)

            self.model_part_slave.CreateNewCondition(
                "SurfaceCondition3D3N", counter_conditions, list_nodes,
                self.main_model_part.GetProperties()[1])

        self.main_model_part.RemoveNodesFromAllLevels(
            KratosMultiphysics.TO_ERASE)
        self.main_model_part.RemoveConditionsFromAllLevels(
            KratosMultiphysics.TO_ERASE)

        # Debug
        #self.__post_process()

        model_part_io = KratosMultiphysics.ModelPartIO(
            GetFilePath(
                "test_double_curvature_integration_triangle_discontinous_interface"
            ), KratosMultiphysics.IO.WRITE)
        model_part_io.WriteModelPart(self.main_model_part)

    def __sci_str(self, x):
        from decimal import Decimal
        s = 10 * Decimal(str(x))
        s = ('{:.' + str(len(s.normalize().as_tuple().digits) - 1) +
             'E}').format(s)
        s = s.replace('E+', 'D0')
        s = s.replace('E-', 'D0-')
        s = s.replace('.', '')
        if s.startswith('-'):
            return '-.' + s[1:]
        else:
            return '.' + s
class TestDoubleCurvatureIntegration(KratosUnittest.TestCase):
    def setUp(self):
        pass

    def __base_test_integration(self, input_filename, num_nodes):
        KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(
            KratosMultiphysics.Logger.Severity.WARNING)

        self.main_model_part = KratosMultiphysics.ModelPart("Structure")
        self.main_model_part.SetBufferSize(2)

        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.DISPLACEMENT)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.VELOCITY)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.ACCELERATION)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.REACTION)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.NORMAL)
        self.main_model_part.AddNodalSolutionStepVariable(
            ContactStructuralMechanicsApplication.
            LAGRANGE_MULTIPLIER_CONTACT_PRESSURE)
        self.main_model_part.AddNodalSolutionStepVariable(
            ContactStructuralMechanicsApplication.WEIGHTED_GAP)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.NODAL_H)

        KratosMultiphysics.ModelPartIO(input_filename).ReadModelPart(
            self.main_model_part)

        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_X, KratosMultiphysics.REACTION_X,
            self.main_model_part)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Y, KratosMultiphysics.REACTION_Y,
            self.main_model_part)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Z, KratosMultiphysics.REACTION_Z,
            self.main_model_part)
        KratosMultiphysics.VariableUtils().AddDof(
            ContactStructuralMechanicsApplication.
            LAGRANGE_MULTIPLIER_CONTACT_PRESSURE,
            ContactStructuralMechanicsApplication.WEIGHTED_GAP,
            self.main_model_part)

        if (self.main_model_part.HasSubModelPart("Contact")):
            interface_model_part = self.main_model_part.GetSubModelPart(
                "Contact")
        else:
            interface_model_part = self.main_model_part.CreateSubModelPart(
                "Contact")

        self.contact_model_part = self.main_model_part.GetSubModelPart(
            "DISPLACEMENT_Displacement_Auto2")

        for node in self.contact_model_part.Nodes:
            node.Set(KratosMultiphysics.SLAVE, False)
        del (node)
        model_part_slave = self.main_model_part.GetSubModelPart(
            "Parts_Parts_Auto1")
        for node in model_part_slave.Nodes:
            node.Set(KratosMultiphysics.SLAVE, True)
        del (node)

        for prop in self.main_model_part.GetProperties():
            prop[ContactStructuralMechanicsApplication.
                 INTEGRATION_ORDER_CONTACT] = 3

        self.main_model_part.ProcessInfo[
            ContactStructuralMechanicsApplication.ACTIVE_CHECK_FACTOR] = 3.0e-1

        for node in self.contact_model_part.Nodes:
            node.Set(KratosMultiphysics.INTERFACE, True)

        Preprocess = ContactStructuralMechanicsApplication.InterfacePreprocessCondition(
            self.main_model_part)

        interface_parameters = KratosMultiphysics.Parameters(
            """{"simplify_geometry": false}""")
        Preprocess.GenerateInterfacePart3D(self.contact_model_part,
                                           interface_parameters)

        # We copy the conditions to the ContactSubModelPart
        for cond in self.contact_model_part.Conditions:
            interface_model_part.AddCondition(cond)
        del (cond)
        for node in self.contact_model_part.Nodes:
            interface_model_part.AddNode(node, 0)
        del (node)

        # We initialize the conditions
        alm_init_var = ContactStructuralMechanicsApplication.ALMFastInit(
            self.contact_model_part)
        alm_init_var.Execute()

        search_parameters = KratosMultiphysics.Parameters("""
        {
            "search_factor"               : 3.5,
            "allocation_size"             : 1000,
            "check_gap"                   : "NoCheck",
            "type_search"                 : "InRadius"
        }
        """)
        if (num_nodes == 3):
            contact_search = ContactStructuralMechanicsApplication.TreeContactSearch3D3N(
                self.main_model_part, search_parameters)
        else:
            contact_search = ContactStructuralMechanicsApplication.TreeContactSearch3D4N(
                self.main_model_part, search_parameters)

        # We initialize the search utility
        contact_search.CreatePointListMortar()
        contact_search.InitializeMortarConditions()
        contact_search.UpdateMortarConditions()

        if (num_nodes == 3):
            ## DEBUG
            #print(self.main_model_part)
            #self.__post_process()
            self.exact_integration = KratosMultiphysics.ExactMortarIntegrationUtility3D3N(
                3)
        else:
            ## DEBUG
            #print(self.main_model_part)
            #self.__post_process()
            self.exact_integration = KratosMultiphysics.ExactMortarIntegrationUtility3D4N(
                3)

    def _double_curvature_tests(self, input_filename, num_nodes,
                                list_of_border_cond):

        self.__base_test_integration(input_filename, num_nodes)

        #print("Solution obtained")
        tolerance = 5.0e-3
        for cond in self.contact_model_part.Conditions:
            if cond.Is(KratosMultiphysics.SLAVE):
                to_test = (cond.Id in list_of_border_cond)
                if (to_test == False):
                    area = self.exact_integration.TestGetExactAreaIntegration(
                        self.main_model_part, cond)
                    condition_area = cond.GetArea()
                    check_value = abs((area - condition_area) / condition_area)
                    if (check_value > tolerance):
                        print(cond.Id, "\t", area, "\t", condition_area, "\t",
                              self.__sci_str(check_value))
                    else:
                        self.assertLess(check_value, tolerance)

    def _moving_nodes_tests(self, input_filename, num_nodes):

        self.__base_test_integration(input_filename, num_nodes)

        for iter in range(1):
            delta_disp = 1.0e-6
            for node in self.main_model_part.GetSubModelPart(
                    "GroupPositiveX").Nodes:
                node.X += delta_disp
            del (node)
            for node in self.main_model_part.GetSubModelPart(
                    "GroupPositiveY").Nodes:
                node.Y += delta_disp
            del (node)
            for node in self.main_model_part.GetSubModelPart(
                    "GroupNegativeX").Nodes:
                node.X -= delta_disp
            del (node)
            for node in self.main_model_part.GetSubModelPart(
                    "GroupNegativeY").Nodes:
                node.Y -= delta_disp
            del (node)

            #print("Solution obtained")
            tolerance = 5.0e-5
            for cond in self.contact_model_part.Conditions:
                if cond.Is(KratosMultiphysics.SLAVE):
                    area = self.exact_integration.TestGetExactAreaIntegration(
                        self.contact_model_part, cond)
                    condition_area = cond.GetArea()
                    check_value = abs((area - condition_area) / condition_area)
                    if (check_value > tolerance):
                        print(cond.Id, "\t", area, "\t", condition_area, "\t",
                              self.__sci_str(check_value))
                    else:
                        self.assertLess(check_value, tolerance)

    def test_double_curvature_integration_triangle(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/integration_tests/test_double_curvature_integration_triangle"

        # These conditions are in the border, and can not be integrated 100% accurate
        list_of_border_cond = [
            1262, 1263, 1264, 1265, 1269, 1270, 1273, 1275, 1278, 1282, 1284,
            1285, 1286, 1288, 1290, 1291, 1292, 1294, 1295, 1297, 1298, 1302,
            1303, 1305, 1306, 1307, 1310, 1313, 1314, 1318, 1319, 1320, 1323,
            1325, 1327, 1328, 1329, 1331, 1336, 1337, 1338, 1340, 1341, 1342,
            1343, 1344, 1346, 1347, 1348, 1349, 1350, 1353, 1355, 1357, 1359,
            1360, 1366, 1367, 1368, 1369, 1370, 1377, 1378, 1379, 1381, 1382,
            1384, 1385, 1387, 1393, 1394, 1395, 1399, 1400, 1406, 1410, 1411,
            1412, 1414, 1415, 1418, 1419, 1420, 1424, 1427, 1429, 1431, 1436,
            1438, 1444, 1446, 1447, 1448, 1449, 1459, 1462, 1463, 1465, 1467,
            1468, 1474, 1477, 1479, 1485, 1491, 1493, 1507, 1515, 1517, 1531,
            1537, 1539, 1547, 1549, 1553, 1563, 1569, 1575, 1623, 1640, 1644,
            1654, 1656, 1663, 1667, 1675, 1685, 1687, 1693, 1697, 1703, 1707,
            1713, 1715, 1717, 1719, 1721, 1723, 1725
        ]

        self._double_curvature_tests(input_filename, 3, list_of_border_cond)

    def test_double_curvature_integration_quad(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/integration_tests/test_double_curvature_integration_quadrilateral"

        # These conditions are in the border, and can not be integrated 100% accurate
        list_of_border_cond = [
            916, 917, 919, 920, 923, 925, 927, 929, 933, 934, 938, 940, 941,
            944, 945, 946, 949, 951, 954, 955, 962, 963, 965, 966, 967, 968,
            969, 970, 971, 973, 974, 977, 978, 979, 980, 981, 982, 983, 984,
            985, 986, 988, 989, 990, 995, 996, 1000, 1003, 1005, 1007, 1008,
            1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021,
            1022, 1023, 1024, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048,
            1049, 1050, 1051, 1052, 1053, 1054, 1055, 1058, 1060, 1064, 1066,
            1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076
        ]

        self._double_curvature_tests(input_filename, 4, list_of_border_cond)

    def test_moving_mesh_integration_quad(self):
        input_filename = os.path.dirname(os.path.realpath(
            __file__)) + "/integration_tests/quadrilaterals_moving_nodes"

        self._moving_nodes_tests(input_filename, 4)

    def test_integration_quad_non_matching(self):
        input_filename = os.path.dirname(os.path.realpath(
            __file__)) + "/integration_tests/quadrilaterals_non_matching"

        list_of_border_cond = []
        self._double_curvature_tests(input_filename, 4, list_of_border_cond)

    def __post_process(self):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(
            self.main_model_part, "gid_output",
            KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteConditionsOnly",
                                                    "MultiFileFlag": "SingleFile"
                                                },
                                                "nodal_results"       : ["NORMAL"],
                                                "nodal_nonhistorical_results": [],
                                                "nodal_flags_results": ["ACTIVE","SLAVE"]
                                            }
                                        }
                                        """))

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()

    def __sci_str(self, x):
        from decimal import Decimal
        s = 10 * Decimal(str(x))
        s = ('{:.' + str(len(s.normalize().as_tuple().digits) - 1) +
             'E}').format(s)
        s = s.replace('E+', 'D0')
        s = s.replace('E-', 'D0-')
        s = s.replace('.', '')
        if s.startswith('-'):
            return '-.' + s[1:]
        else:
            return '.' + s
Beispiel #30
0
class TestMortarMapping(KratosUnittest.TestCase):
    def setUp(self):
        pass

    def __base_test_mapping(self, input_filename, num_nodes, pure_implicit):
        self.main_model_part = KratosMultiphysics.ModelPart("Structure")

        ## Creation of the Kratos model (build sub_model_parts or submeshes)
        self.StructureModel = {"Structure": self.main_model_part}

        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.DISPLACEMENT)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.TEMPERATURE)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.NORMAL)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.NORMAL_CONTACT_STRESS)
        self.main_model_part.AddNodalSolutionStepVariable(
            ContactStructuralMechanicsApplication.WEIGHTED_GAP)
        self.main_model_part.AddNodalSolutionStepVariable(
            KratosMultiphysics.NODAL_H)

        self.main_model_part.CloneTimeStep(1.01)

        KratosMultiphysics.ModelPartIO(input_filename).ReadModelPart(
            self.main_model_part)

        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_X, self.main_model_part)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Y, self.main_model_part)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.DISPLACEMENT_Z, self.main_model_part)
        KratosMultiphysics.VariableUtils().AddDof(
            KratosMultiphysics.TEMPERATURE, self.main_model_part)

        if (self.main_model_part.HasSubModelPart("Contact")):
            interface_model_part = self.main_model_part.GetSubModelPart(
                "Contact")
        else:
            interface_model_part = self.main_model_part.CreateSubModelPart(
                "Contact")

        self.mapping_model_part = self.main_model_part.GetSubModelPart(
            "DISPLACEMENT_Displacement_Auto2")

        self.model_part_slave = self.main_model_part.GetSubModelPart(
            "Parts_Parts_Auto1")
        for node in self.model_part_slave.Nodes:
            node.Set(KratosMultiphysics.SLAVE, True)
            node.Set(KratosMultiphysics.MASTER, False)
        del (node)
        self.model_part_master = self.main_model_part.GetSubModelPart(
            "Parts_Parts_Auto2")
        for node in self.model_part_master.Nodes:
            node.Set(KratosMultiphysics.MASTER, True)
            node.Set(KratosMultiphysics.SLAVE, False)
        del (node)

        for prop in self.main_model_part.GetProperties():
            prop[ContactStructuralMechanicsApplication.
                 INTEGRATION_ORDER_CONTACT] = 3

        self.main_model_part.ProcessInfo[
            ContactStructuralMechanicsApplication.ACTIVE_CHECK_FACTOR] = 3.0e-1

        for node in self.mapping_model_part.Nodes:
            node.Set(KratosMultiphysics.INTERFACE, True)

        Preprocess = ContactStructuralMechanicsApplication.InterfacePreprocessCondition(
            self.main_model_part)

        interface_parameters = KratosMultiphysics.Parameters(
            """{"condition_name": "", "final_string": "", "simplify_geometry": false}"""
        )
        interface_parameters["condition_name"].SetString(
            "ALMFrictionlessMortarContact")
        Preprocess.GenerateInterfacePart3D(self.main_model_part,
                                           self.mapping_model_part,
                                           interface_parameters)

        # We copy the conditions to the ContactSubModelPart
        for cond in self.mapping_model_part.Conditions:
            interface_model_part.AddCondition(cond)
        del (cond)
        for node in self.mapping_model_part.Nodes:
            interface_model_part.AddNode(node, 0)
        del (node)

        # We initialize the conditions
        alm_init_var = ContactStructuralMechanicsApplication.ALMFastInit(
            self.mapping_model_part)
        alm_init_var.Execute()

        search_parameters = KratosMultiphysics.Parameters("""
        {
            "search_factor"               : 3.5,
            "allocation_size"             : 1000,
            "type_search"                 : "InRadius",
            "use_exact_integration"       : true
        }
        """)
        contact_search = ContactStructuralMechanicsApplication.TreeContactSearch(
            self.main_model_part, search_parameters)

        # We initialize the search utility
        contact_search.CreatePointListMortar()
        contact_search.InitializeMortarConditions()
        contact_search.UpdateMortarConditions()

        for node in self.model_part_master.Nodes:
            x = node.X
            y = node.Y
            z = node.Z
            node.SetSolutionStepValue(KratosMultiphysics.TEMPERATURE, z)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_X, x)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_Y, y)
            node.SetSolutionStepValue(KratosMultiphysics.DISPLACEMENT_Z, z)
        del (node)

        map_parameters = KratosMultiphysics.Parameters("""
        {
            "echo_level"                       : 0,
            "absolute_convergence_tolerance"   : 1.0e-9,
            "relative_convergence_tolerance"   : 1.0e-4,
            "max_number_iterations"            : 10,
            "integration_order"                : 2
        }
        """)

        if (pure_implicit == True):
            #linear_solver = ExternalSolversApplication.SuperLUSolver()
            linear_solver = KratosMultiphysics.SkylineLUFactorizationSolver()

            if (num_nodes == 3):
                self.mortar_mapping_double = KratosMultiphysics.SimpleMortarMapperProcess3D3NDoubleHistorical(
                    self.main_model_part, KratosMultiphysics.TEMPERATURE,
                    map_parameters, linear_solver)
                self.mortar_mapping_vector = KratosMultiphysics.SimpleMortarMapperProcess3D3NVectorHistorical(
                    self.main_model_part, KratosMultiphysics.DISPLACEMENT,
                    map_parameters, linear_solver)
            else:
                self.mortar_mapping_double = KratosMultiphysics.SimpleMortarMapperProcess3D4NDoubleHistorical(
                    self.main_model_part, KratosMultiphysics.TEMPERATURE,
                    map_parameters, linear_solver)
                self.mortar_mapping_vector = KratosMultiphysics.SimpleMortarMapperProcess3D4NVectorHistorical(
                    self.main_model_part, KratosMultiphysics.DISPLACEMENT,
                    map_parameters, linear_solver)
        else:
            if (num_nodes == 3):
                self.mortar_mapping_double = KratosMultiphysics.SimpleMortarMapperProcess3D3NDoubleHistorical(
                    self.main_model_part, KratosMultiphysics.TEMPERATURE,
                    map_parameters)
                self.mortar_mapping_vector = KratosMultiphysics.SimpleMortarMapperProcess3D3NVectorHistorical(
                    self.main_model_part, KratosMultiphysics.DISPLACEMENT,
                    map_parameters)
            else:
                self.mortar_mapping_double = KratosMultiphysics.SimpleMortarMapperProcess3D4NDoubleHistorical(
                    self.main_model_part, KratosMultiphysics.TEMPERATURE,
                    map_parameters)
                self.mortar_mapping_vector = KratosMultiphysics.SimpleMortarMapperProcess3D4NVectorHistorical(
                    self.main_model_part, KratosMultiphysics.DISPLACEMENT,
                    map_parameters)

    def _mapper_tests(self, input_filename, num_nodes, pure_implicit=False):

        self.__base_test_mapping(input_filename, num_nodes, pure_implicit)

        self.mortar_mapping_double.Execute()
        self.mortar_mapping_vector.Execute()

        ## DEBUG
        #self.__post_process()

        import from_json_check_result_process

        check_parameters = KratosMultiphysics.Parameters("""
        {
            "check_variables"      : ["TEMPERATURE","DISPLACEMENT"],
            "input_file_name"      : "",
            "model_part_name"      : "Structure",
            "sub_model_part_name"  : "Parts_Parts_Auto1"
        }
        """)

        check_parameters["input_file_name"].SetString(input_filename + ".json")

        check = from_json_check_result_process.FromJsonCheckResultProcess(
            self.StructureModel, check_parameters)
        check.ExecuteInitialize()
        check.ExecuteBeforeSolutionLoop()
        check.ExecuteFinalizeSolutionStep()

        #import json_output_process

        #out_parameters = KratosMultiphysics.Parameters("""
        #{
        #"output_variables"     : ["TEMPERATURE","DISPLACEMENT"],
        #"output_file_name"     : "",
        #"model_part_name"      : "Structure",
        #"sub_model_part_name"  : "Parts_Parts_Auto1"
        #}
        #""")

        #out_parameters["output_file_name"].SetString(input_filename+".json")

        #out = json_output_process.JsonOutputProcess(self.StructureModel, out_parameters)
        #out.ExecuteInitialize()
        #out.ExecuteBeforeSolutionLoop()
        #out.ExecuteFinalizeSolutionStep()

    def test_basic_mortar_mapping_triangle(self):
        input_filename = os.path.dirname(os.path.realpath(
            __file__)) + "/integration_tests/test_integration_triangle"
        self._mapper_tests(input_filename, 3, False)

    def test_basic_mortar_mapping_quad(self):
        input_filename = os.path.dirname(os.path.realpath(
            __file__)) + "/integration_tests/test_integration_quad"
        self._mapper_tests(input_filename, 4, False)

    def test_less_basic_mortar_mapping_triangle(self):
        input_filename = os.path.dirname(os.path.realpath(
            __file__)) + "/integration_tests/test_integration_triangles"
        self._mapper_tests(input_filename, 3, False)

    def test_less_basic_2_mortar_mapping_triangle(self):
        input_filename = os.path.dirname(os.path.realpath(
            __file__)) + "/integration_tests/test_integration_triangles_2"
        self._mapper_tests(input_filename, 3, False)

    def test_simple_curvature_mortar_mapping_triangle(self):
        input_filename = os.path.dirname(os.path.realpath(
            __file__)) + "/integration_tests/test_simple_curvature"
        self._mapper_tests(input_filename, 3, False)

    def test_mortar_mapping_triangle(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/integration_tests/test_double_curvature_integration_triangle"
        self._mapper_tests(input_filename, 3, False)

    def test_mortar_mapping_quad(self):
        input_filename = os.path.dirname(
            os.path.realpath(__file__)
        ) + "/integration_tests/test_double_curvature_integration_quadrilateral"
        self._mapper_tests(input_filename, 4, False)

    def __post_process(self):
        from gid_output_process import GiDOutputProcess
        self.gid_output = GiDOutputProcess(
            self.main_model_part, "gid_output",
            KratosMultiphysics.Parameters("""
                                        {
                                            "result_file_configuration" : {
                                                "gidpost_flags": {
                                                    "GiDPostMode": "GiD_PostBinary",
                                                    "WriteDeformedMeshFlag": "WriteUndeformed",
                                                    "WriteConditionsFlag": "WriteElementsOnly",
                                                    "MultiFileFlag": "SingleFile"
                                                },        
                                                "nodal_results"       : ["DISPLACEMENT","TEMPERATURE"],
                                                "nodal_nonhistorical_results": ["NORMAL","NODAL_AREA"],
                                                "nodal_flags_results": ["MASTER","SLAVE"]
                                            }
                                        }
                                        """))

        self.gid_output.ExecuteInitialize()
        self.gid_output.ExecuteBeforeSolutionLoop()
        self.gid_output.ExecuteInitializeSolutionStep()
        self.gid_output.PrintOutput()
        self.gid_output.ExecuteFinalizeSolutionStep()
        self.gid_output.ExecuteFinalize()

    def __sci_str(self, x):
        from decimal import Decimal
        s = 10 * Decimal(str(x))
        s = ('{:.' + str(len(s.normalize().as_tuple().digits) - 1) +
             'E}').format(s)
        s = s.replace('E+', 'D0')
        s = s.replace('E-', 'D0-')
        s = s.replace('.', '')
        if s.startswith('-'):
            return '-.' + s[1:]
        else:
            return '.' + s