def test_ConstantTransformEuler(self):
        points = self.GeneratePoints()
        transform = MeshMoving.ParametricLinearTransform(
            self.GetConstantEulerAngles(), self.GetConstantReferencePoint(),
            self.GetConstantTranslationVector())

        self.CheckDefaultTransformedPoints(
            [transform.Apply(point, 0.0, 0.0, 0.0, 0.0) for point in points])
    def test_ParametricAxis(self):
        points = self.GeneratePoints()
        transform = MeshMoving.ParametricLinearTransform(
            Parameters(""" ["t", "1.0-t", 0.0] """), self.GetConstantAngle(),
            self.GetConstantReferencePoint(),
            self.GetConstantTranslationVector())

        self.CheckDefaultTransformedPoints(
            [transform.Apply(point, 0.0, 0.0, 0.0, 0.0) for point in points])

        self.assertVectorAlmostEqual(transform.Apply(points[0], 1.0, 0.0, 0.0,
                                                     0.0), [3.0, 2.0, 3.0],
                                     prec=5)
        self.assertVectorAlmostEqual(transform.Apply(points[1], 1.0, 0.0, 0.0,
                                                     0.0), [1.0, 2.0, 1.0],
                                     prec=5)
        self.assertVectorAlmostEqual(transform.Apply(points[2], 1.0, 0.0, 0.0,
                                                     0.0), [1.0, 4.0, 3.0],
                                     prec=5)
    def test_ParametricEulerAngles(self):
        points = self.GeneratePoints()
        transform = MeshMoving.ParametricLinearTransform(
            Parameters(
                f""" [{-math.pi/2.0}, {-math.pi/2.0}, "(1.0-t)*{math.pi/2.0}"] """
            ), self.GetConstantReferencePoint(),
            self.GetConstantTranslationVector())

        self.CheckDefaultTransformedPoints(
            [transform.Apply(point, 0.0, 0.0, 0.0, 0.0) for point in points])

        self.assertVectorAlmostEqual(transform.Apply(points[0], 1.0, 0.0, 0.0,
                                                     0.0), [0.0, -1.0, 3.0],
                                     prec=5)
        self.assertVectorAlmostEqual(transform.Apply(points[1], 1.0, 0.0, 0.0,
                                                     0.0), [0.0, 1.0, 5.0],
                                     prec=5)
        self.assertVectorAlmostEqual(transform.Apply(points[2], 1.0, 0.0, 0.0,
                                                     0.0), [-2.0, 1.0, 3.0],
                                     prec=5)
    def test_ParametricAngle(self):
        points = self.GeneratePoints()
        transform = MeshMoving.ParametricLinearTransform(
            self.GetConstantAxis(),
            Parameters(f""" "-(t+1.0) * {math.pi} / 2.0" """),
            self.GetConstantReferencePoint(),
            self.GetConstantTranslationVector())

        self.CheckDefaultTransformedPoints(
            [transform.Apply(point, 0.0, 0.0, 0.0, 0.0) for point in points])

        self.assertVectorAlmostEqual(transform.Apply(points[0], 1.0, 0.0, 0.0,
                                                     0.0), [-3.0, 2.0, 3.0],
                                     prec=5)
        self.assertVectorAlmostEqual(transform.Apply(points[1], 1.0, 0.0, 0.0,
                                                     0.0), [-1.0, 4.0, 3.0],
                                     prec=5)
        self.assertVectorAlmostEqual(transform.Apply(points[2], 1.0, 0.0, 0.0,
                                                     0.0), [-1.0, 2.0, 1.0],
                                     prec=5)
    def __init__(self,
                 model: KratosMultiphysics.Model,
                 parameters: KratosMultiphysics.Parameters):
        """Impose a rotation followed by translation on a ModelPart."""
        KratosMultiphysics.Process.__init__(self)

        # 'rotation_angle' can either be a float or "End", but the validator can't handle both
        # => convert 'rotation_angle' to the input type
        default_parameters = self.GetDefaultParameters()
        if parameters.Has("rotation_angle") and parameters["rotation_angle"].IsString():
            default_parameters.RemoveValue("rotation_angle")
            default_parameters.AddValue("rotation_angle", parameters["rotation_angle"])

        parameters.ValidateAndAssignDefaults(default_parameters)
        self.model_part = model[parameters["model_part_name"].GetString()]

        # Parse interval
        self.interval_utility = KratosMultiphysics.IntervalUtility(parameters)

        # Determine whether a constant transform will suffice or a parametric one is needed
        requires_parametric_transform = False

        euler_angle_parameters = parameters["euler_angles"]
        rotation_axis_parameters = parameters["rotation_axis"]
        rotation_angle_parameters = parameters["rotation_angle"]
        reference_point_parameters = parameters["reference_point"]
        translation_vector_parameters = parameters["translation_vector"]

        if rotation_angle_parameters.IsString():
            requires_parametric_transform = True
        else:
            for i in range(3):
                if euler_angle_parameters[i].IsString() or rotation_axis_parameters[i].IsString() or reference_point_parameters[i].IsString() or translation_vector_parameters[i].IsString():
                    requires_parametric_transform = True
                    break

        rotation_definition = parameters["rotation_definition"].GetString()

        if requires_parametric_transform:
            if rotation_definition == "rotation_axis":
                self.transform = MeshMovingApplication.ParametricLinearTransform(
                    rotation_axis_parameters,
                    rotation_angle_parameters,
                    reference_point_parameters,
                    translation_vector_parameters)
            elif rotation_definition == "euler_angles":
                self.transform = MeshMovingApplication.ParametricLinearTransform(
                    euler_angle_parameters,
                    reference_point_parameters,
                    translation_vector_parameters)
            else:
                raise ValueError("Invalid rotation definition '{}'".format(rotation_definition))

        else:
            reference_point = reference_point_parameters.GetVector()
            translation_vector = translation_vector_parameters.GetVector()
            if rotation_definition == "rotation_axis":
                rotation_axis = rotation_axis_parameters.GetVector()
                rotation_angle = rotation_angle_parameters.GetDouble()
                self.transform = MeshMovingApplication.LinearTransform(
                    rotation_axis,
                    rotation_angle,
                    reference_point,
                    translation_vector)
            elif rotation_definition == "euler_angles":
                euler_angles = euler_angle_parameters.GetVector()
                self.transform = MeshMovingApplication.LinearTransform(
                    euler_angles,
                    reference_point,
                    translation_vector)
            else:
                raise ValueError("Invalid rotation definition '{}'".format(rotation_definition))