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()
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)
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.")