def __init__(self, model, custom_settings):
        super(NavierStokesEmbeddedFMALEMonolithicSolver,self).__init__(model,custom_settings)

        self.element_name = "EmbeddedNavierStokes"
        self.condition_name = "NavierStokesWallCondition"
        self.min_buffer_size = 3

        # There is only a single rank in OpenMP, we always print
        self._is_printing_rank = True

        # Retrieve the structural model part using json input
        structure_model_part_name = self.settings["model_part_name"].GetString()
        if self.model.HasModelPart(structure_model_part_name):
            self.structure_model_part = self.model.GetModelPart(structure_model_part_name)
        else:
            raise Exception("Structural model part {0} not found in model".format(structure_model_part_name))

        ## Set the FM-ALE framework
        self.fm_ale_step_frequency = self.settings["fm_ale_settings"]["fm_ale_step_frequency"].GetInt()
        if (self.fm_ale_step_frequency != 0):
            self.fm_ale_step = 1
            self.virtual_model_part = KratosMultiphysics.ModelPart("VirtualModelPart")
            self.mesh_moving_util = KratosMeshMoving.ExplicitMeshMovingUtilities(
                self.virtual_model_part, self.structure_model_part, self.settings["fm_ale_settings"]["search_radius"].GetDouble())

        if self._IsPrintingRank():
            KratosMultiphysics.Logger.PrintInfo("NavierStokesEmbeddedFMALEMonolithicSolver", "Construction of NavierStokesEmbeddedFMALEMonolithicSolver finished.")
 def _create_mesh_moving_util(self):
     if have_mesh_moving:
         mesh_moving_util = KratosMeshMoving.ExplicitMeshMovingUtilities(
             self._get_fm_ale_virtual_model_part(),
             self._get_fm_ale_structure_model_part(),
             self.settings["fm_ale_settings"]["search_radius"].GetDouble())
         return mesh_moving_util
     else:
         raise Exception("MeshMovingApplication is required to construct the FM-ALE utility (ExplicitMeshMovingUtilities)")
    def __init__(self, main_model_part, structure_model_part, custom_settings):

        self.element_name = "EmbeddedNavierStokes"
        self.condition_name = "NavierStokesWallCondition"
        self.min_buffer_size = 3

        # There is only a single rank in OpenMP, we always print
        self._is_printing_rank = True

        #TODO: shall obtain the compute_model_part from the MODEL once the object is implemented
        self.main_model_part = main_model_part
        self.structure_model_part = structure_model_part

        ##settings string in json format
        default_settings = KratosMultiphysics.Parameters("""
        {
            "solver_type": "embedded_solver_from_defaults",
            "model_import_settings": {
                "input_type": "mdpa",
                "input_filename": "unknown_name"
            },
            "distance_reading_settings": {
                "import_mode": "from_mdpa",
                "distance_file_name": "no_distance_file"
            },
            "maximum_iterations": 7,
            "dynamic_tau": 1.0,
            "echo_level": 0,
            "time_order": 2,
            "compute_reactions": false,
            "reform_dofs_at_each_step": false,
            "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": "AMGCL_NS_Solver"
            },
            "volume_model_part_name": "volume_model_part",
            "skin_parts": [""],
            "no_skin_parts":[""],
            "time_stepping": {
                "automatic_time_step": true,
                "CFL_number": 1,
                "minimum_delta_time": 1e-2,
                "maximum_delta_time": 1.0
            },
            "move_mesh_flag": false,
            "reorder": false,
            "fm_ale_settings": {
                "fm_ale_step_frequency": 1,
                "search_radius" : 1.0
            }
        }""")

        ## Overwrite the default settings with user-provided parameters
        self.settings = custom_settings
        self.settings.ValidateAndAssignDefaults(default_settings)

        ## Construct the linear solver
        import linear_solver_factory
        self.linear_solver = linear_solver_factory.ConstructSolver(self.settings["linear_solver_settings"])

        ## Set the distance reading filename
        # TODO: remove the manual "distance_file_name" set as soon as the problem type one has been tested.
        if (self.settings["distance_reading_settings"]["import_mode"].GetString() == "from_GiD_file"):
            self.settings["distance_reading_settings"]["distance_file_name"].SetString(self.settings["model_import_settings"]["input_filename"].GetString()+".post.res")

        ## Set the FM-ALE framework
        self.fm_ale_step_frequency = self.settings["fm_ale_settings"]["fm_ale_step_frequency"].GetInt()
        if (self.fm_ale_step_frequency != 0):
            self.fm_ale_step = 1
            self.virtual_model_part = KratosMultiphysics.ModelPart("VirtualModelPart")
            self.mesh_moving_util = KratosMeshMoving.ExplicitMeshMovingUtilities(
                self.virtual_model_part, self.structure_model_part, self.settings["fm_ale_settings"]["search_radius"].GetDouble())

        if self._IsPrintingRank():
            KratosMultiphysics.Logger.PrintInfo("NavierStokesEmbeddedFMALEMonolithicSolver", "Construction of NavierStokesEmbeddedFMALEMonolithicSolver finished.")