def _CreateConvergenceAccelerator(self):
     convergence_accelerator = convergence_accelerator_factory.CreateTrilinosConvergenceAccelerator(
         self._GetFluidInterfaceSubmodelPart(),
         self._GetEpetraCommunicator(),
         self.settings["coupling_settings"]["coupling_strategy_settings"])
     self._PrintInfoOnRankZero("::[TrilinosPartitionedFSIBaseSolver]::",
                               "Coupling strategy construction finished.")
     return convergence_accelerator
    def Initialize(self):

        # Set the Trilinos space
        self.trilinos_space = KratosTrilinos.TrilinosSparseSpace()

        # Set the Epetra communicator
        self.epetra_communicator = KratosTrilinos.CreateCommunicator()

        # Construct the coupling partitioned strategy
        coupling_utility_parameters = self.settings[
            "coupling_solver_settings"]["coupling_strategy"]
        self.coupling_utility = convergence_accelerator_factory.CreateTrilinosConvergenceAccelerator(
            self._GetFluidInterfaceSubmodelPart(), self.epetra_communicator,
            coupling_utility_parameters)

        # Get the domain size
        self.domain_size = self._GetDomainSize()

        # Get the nodal update FSI utilities
        self.nodal_update_utilities = self._GetNodalUpdateUtilities()

        # Get the partitioned FSI utilities
        self.trilinos_partitioned_fsi_utilities = self._GetPartitionedFSIUtilities(
        )

        # Python structure solver initialization
        self.structure_solver.Initialize()

        # Ensure that the fluid reaction fluxes are computed if D-N scheme is considered
        if self.fluid_solver.settings["compute_reactions"].GetBool() == False:
            self.fluid_solver.settings["compute_reactions"].SetBool(True)

        # Python fluid solver initialization
        self.fluid_solver.Initialize()

        # Python mesh solver initialization
        self.mesh_solver.Initialize()

        # Initialize the Dirichlet-Neumann interface
        self._InitializeDirichletNeumannInterface()

        # Construct the interface mapper
        self._SetUpMapper()

        # Set the Neumann B.C. in the structure interface
        self._SetStructureNeumannCondition(
        )  #TODO change when the interface is able to correctly transfer distributed forces

        # Initialize the iteration value vector
        self._InitializeIterationValueVector()

        # Compute the fluid domain NODAL_AREA values (required as weight in the residual norm computation)
        KratosMultiphysics.CalculateNodalAreaProcess(
            self.fluid_solver.GetComputingModelPart(),
            self.domain_size).Execute()

        # Strategies initialization
        super(TrilinosPartitionedFSIDirichletNeumannSolver, self).Initialize()
Example #3
0
    def test_accelerator(self, accelerator_settings, force1, force2, solution):

        print("")
        print("Testing accelerator: ",
              accelerator_settings["solver_type"].GetString())

        top_part = self.model_part.GetSubModelPart("Top")

        # Construct the accelerator strategy
        coupling_utility = convergence_accelerator_factory.CreateTrilinosConvergenceAccelerator(
            top_part, self.epetra_comm, accelerator_settings)

        coupling_utility.Initialize()

        nl_it = 0
        convergence = False

        coupling_utility.InitializeSolutionStep()

        x_guess = self.space.CreateEmptyVectorPointer(self.epetra_comm)
        self.partitioned_utilities.SetUpInterfaceVector(top_part, x_guess)
        residual = self.ComputeResidual(top_part, x_guess, force1, force2)
        res_norm = self.ComputeResidualNorm(residual)

        while (nl_it <= self.accelerator_iterations):

            print(mpi.rank,
                  ": Iteration: ",
                  nl_it,
                  " residual norm: ",
                  res_norm,
                  file=sys.stderr)

            if res_norm > self.accelerator_tolerance:
                coupling_utility.InitializeNonLinearIteration()
                coupling_utility.UpdateSolution(residual.GetReference(),
                                                x_guess.GetReference())
                self.partitioned_utilities.UpdateInterfaceValues(
                    top_part, KratosMultiphysics.DISPLACEMENT,
                    x_guess.GetReference())
                coupling_utility.FinalizeNonLinearIteration()
            else:
                coupling_utility.FinalizeSolutionStep()
                convergence = True
                break

            nl_it += 1
            residual = self.ComputeResidual(top_part, x_guess, force1, force2)
            res_norm = self.ComputeResidualNorm(residual)

        # Check the obtained solution
        expected_x = solution(top_part)

        for i, node in enumerate(top_part.Nodes):
            expected = expected_x[3 * i + 2]
            obtained = node.GetSolutionStepValue(
                KratosMultiphysics.DISPLACEMENT_Z, 0)
            self.assertAlmostEqual(expected, obtained, delta=self.assert_delta)
Example #4
0
    def __init__(self, structure_main_model_part, fluid_main_model_part, project_parameters):

        if (KratosMPI.mpi.rank == 0) : print("** Calling the partitioned FSI Trilinos base solver constructor...")

        # Initial tests
        start_time_structure = project_parameters["structure_solver_settings"]["problem_data"]["start_time"].GetDouble()
        start_time_fluid = project_parameters["fluid_solver_settings"]["problem_data"]["start_time"].GetDouble()
        end_time_structure = project_parameters["structure_solver_settings"]["problem_data"]["end_time"].GetDouble()
        end_time_fluid = project_parameters["fluid_solver_settings"]["problem_data"]["end_time"].GetDouble()

        if start_time_structure != start_time_fluid:
            if (KratosMPI.mpi.rank == 0) : raise("ERROR: Different initial time among subdomains!")
        if end_time_structure != end_time_fluid:
            if (KratosMPI.mpi.rank == 0) : raise("ERROR: Different final time among subdomains!")

        self.structure_main_model_part = structure_main_model_part
        self.fluid_main_model_part = fluid_main_model_part

        # Settings string in JSON format
        default_settings = KratosMultiphysics.Parameters("""
        {
        "structure_solver_settings":
            {
            "solver_type" : "trilinos_structural_mechanics_implicit_dynamic_solver",
            "model_import_settings" : {
                "input_type"     : "mdpa",
                "input_filename" : "unknown_name"
            },
            "material_import_settings" :{
                "materials_filename" : "materials.json"
            },
            "echo_level"               : 0,
            "time_integration_method"  : "Implicit",
            "analysis_type"            : "nonlinear",
            "rotation_dofs"            : false,
            "pressure_dofs"            : false,
            "reform_dofs_at_each_step" : false,
            "line_search"              : false,
            "compute_reactions"        : true,
            "compute_contact_forces"   : false,
            "block_builder"            : true,
            "move_mesh_flag"           : true,
            "solution_type"            : "Dynamic",
            "scheme_type"              : "Newmark",
            "convergence_criterion"    : "Residual_criteria",
            "displacement_relative_tolerance" : 1.0e-3,
            "displacement_absolute_tolerance" : 1.0e-5,
            "residual_relative_tolerance"     : 1.0e-3,
            "residual_absolute_tolerance"     : 1.0e-5,
            "max_iteration"          : 10,
            "linear_solver_settings" :{
                "solver_type" : "Klu",
                "scaling"     : false
            },
            "processes_sub_model_part_list"      : [""],
            "problem_domain_sub_model_part_list" : [""]
            },
        "fluid_solver_settings" : {
            "solver_type"       : "Monolithic",
            "model_import_settings" : {
                "input_type"     : "mdpa",
                "input_filename" : "unknown_name"
            },
            "maximum_iterations" : 10,
            "dynamic_tau"        : 0.01,
            "oss_switch"         : 0,
            "echo_level"         : 0,
            "consider_periodic_conditions" : false,
            "compute_reactions"            : true,
            "divergence_clearance_steps"   : 0,
            "reform_dofs_at_each_step"     : true,
            "relative_velocity_tolerance"  : 1e-3,
            "absolute_velocity_tolerance"  : 1e-5,
            "relative_pressure_tolerance"  : 1e-3,
            "absolute_pressure_tolerance"  : 1e-5,
            "linear_solver_settings"        : {
                "solver_type"                        : "MultiLevelSolver",
                "max_iteration"                      : 200,
                "tolerance"                          : 1e-8,
                "max_levels"                         : 3,
                "symmetric"                          : false,
                "reform_preconditioner_at_each_step" : true,
                "scaling"                            : true
            },
            "volume_model_part_name" : "volume_model_part",
            "skin_parts"             : [""],
            "no_skin_parts"          : [""],
            "time_stepping"          : {
                "automatic_time_step" : false,
                "time_step"           : 0.1
            },
            "alpha"              :-0.3,
            "move_mesh_strategy" : 0,
            "periodic"           : "periodic",
            "move_mesh_flag"     : false,
            "turbulence_model"   : "None"
            },
        "coupling_solver_settings": {
            "coupling_scheme"              : "DirichletNeumann",
            "solver_type"                  : "trilinos_partitioned_fsi_solver",
            "nl_tol"                       : 1e-5,
            "nl_max_it"                    : 50,
            "solve_mesh_at_each_iteration" : true,
            "coupling_strategy" : {
                "solver_type"       : "Relaxation",
                "acceleration_type" : "Aitken",
                "w_0"               : 0.825
            },
            "mesh_solver"                : "trilinos_mesh_solver_structural_similarity",
            "mesh_reform_dofs_each_step" : false,
            "structure_interfaces_list"  : [""],
            "fluid_interfaces_list"      : [""]
            },
        "mapper_settings" : [{
            "mapper_face"                                : "Unique",
            "positive_fluid_interface_submodelpart_name" : "Default_interface_submodelpart_name",
            "structure_interface_submodelpart_name"      : "Default_interface_submodelpart_name"
            }]
        }
        """)

        # Time stepping checks (no sub-stepping between subdomains has been implemented yed)
        time_step_structure = project_parameters["structure_solver_settings"]["problem_data"]["time_step"].GetDouble()
        # If automatic time stepping has been selected in the fluid domain, deactivate it and use the structure time step
        if (project_parameters["fluid_solver_settings"]["solver_settings"]["time_stepping"]["automatic_time_step"].GetBool()):
            project_parameters["fluid_solver_settings"]["solver_settings"]["time_stepping"]["automatic_time_step"].SetBool(False)
            time_step_fluid = time_step_structure
            if (KratosMPI.mpi.rank == 0) : print("WARNING: Automatic fluid time stepping cannot be used. Setting structure time step as fluid time step.")
        else:
            time_step_fluid = project_parameters["fluid_solver_settings"]["solver_settings"]["time_stepping"]["time_step"].GetDouble()
            if time_step_structure != time_step_fluid:
                if (KratosMPI.mpi.rank == 0) : raise("ERROR: Different time step among subdomains! No sub-stepping implemented yet.")

        self.time_step = time_step_fluid

        # Take the each one of the solvers settings from the ProjectParameters
        self.settings = KratosMultiphysics.Parameters("{}")
        self.settings.AddValue("structure_solver_settings",project_parameters["structure_solver_settings"]["solver_settings"])
        self.settings.AddValue("fluid_solver_settings",project_parameters["fluid_solver_settings"]["solver_settings"])
        self.settings.AddValue("coupling_solver_settings",project_parameters["coupling_solver_settings"]["solver_settings"])
        self.settings.AddValue("mapper_settings",project_parameters["coupling_solver_settings"]["mapper_settings"])

        # Overwrite the default settings with user-provided parameters
        self.settings.RecursivelyValidateAndAssignDefaults(default_settings)

        # Auxiliar variables
        self.max_nl_it = self.settings["coupling_solver_settings"]["nl_max_it"].GetInt()
        self.nl_tol = self.settings["coupling_solver_settings"]["nl_tol"].GetDouble()
        self.solve_mesh_at_each_iteration = self.settings["coupling_solver_settings"]["solve_mesh_at_each_iteration"].GetBool()
        self.coupling_algorithm = self.settings["coupling_solver_settings"]["coupling_scheme"].GetString()
        self.fluid_interface_submodelpart_name = self.settings["coupling_solver_settings"]["fluid_interfaces_list"][0].GetString()
        self.structure_interface_submodelpart_name = self.settings["coupling_solver_settings"]["structure_interfaces_list"][0].GetString()
        coupling_utility_parameters = self.settings["coupling_solver_settings"]["coupling_strategy"]

        # Construct the structure solver
        self.structure_solver = python_solvers_wrapper_structural.CreateSolver(self.structure_main_model_part,
                                                                               project_parameters["structure_solver_settings"])
        if (KratosMPI.mpi.rank == 0) : print("* Structure solver constructed.")

        # Construct the fluid solver
        self.fluid_solver = python_solvers_wrapper_fluid.CreateSolver(self.fluid_main_model_part,
                                                                      project_parameters["fluid_solver_settings"])
        if (KratosMPI.mpi.rank == 0) : print("* Fluid solver constructed.")

        # Construct the coupling partitioned strategy
        import convergence_accelerator_factory
        self.coupling_utility = convergence_accelerator_factory.CreateTrilinosConvergenceAccelerator(coupling_utility_parameters)
        if (KratosMPI.mpi.rank == 0) : print("* Coupling strategy constructed.")

        # Construct the ALE mesh solver
        mesh_solver_settings = KratosMultiphysics.Parameters("{}")
        mesh_solver_settings.AddValue("mesh_reform_dofs_each_step",self.settings["coupling_solver_settings"]["mesh_reform_dofs_each_step"])

        self.mesh_solver_module = __import__(self.settings["coupling_solver_settings"]["mesh_solver"].GetString())
        self.mesh_solver = self.mesh_solver_module.CreateSolver(self.fluid_solver.main_model_part,
                                                                mesh_solver_settings)
        if (KratosMPI.mpi.rank == 0):
            print("* ALE mesh solver constructed.")
            print("** Partitioned FSI base solver constructed.")