def IsConverged(self):
        new_data = self.interface_data.GetData()

        residual = new_data - self.prev_data
        res_norm = la.norm(residual)
        norm_new_data = la.norm(new_data)

        if norm_new_data < 1e-15:
            norm_new_data = 1.0  # to avoid division by zero

        abs_norm = res_norm / np.sqrt(residual.size)
        rel_norm = res_norm / norm_new_data

        is_converged = abs_norm < self.abs_tolerance or rel_norm < self.rel_tolerance

        if self.echo_level > 1:
            info_msg = 'Convergence for "' + colors.bold(
                self.interface_data.variable.Name()) + '": '
            if is_converged:
                info_msg += colors.green("ACHIEVED")
            else:
                info_msg += colors.red("NOT ACHIEVED")
            cs_tools.cs_print_info(self._Name(), info_msg)
        if self.echo_level > 2:
            info_msg = colors.bold("abs_norm") + " = " + str(abs_norm) + " | "
            info_msg += colors.bold("abs_tol") + " = " + str(
                self.abs_tolerance) + " || "
            info_msg += colors.bold("rel_norm") + " = " + str(rel_norm) + " | "
            info_msg += colors.bold("rel_tol") + " = " + str(
                self.rel_tolerance)
            cs_tools.cs_print_info(self._Name(), info_msg)

        return is_converged
    def IsConverged(self):
        new_data = self.interface_data.GetData()

        residual = new_data - self.prev_data

        abs_norm = la.norm(residual) / np.sqrt(residual.size)

        if self.initial_iteration:
            self.initial_iteration = False
            self.initial_norm = abs_norm

        rel_norm = abs_norm / self.initial_norm

        is_converged = abs_norm < self.abs_tolerance or rel_norm < self.rel_tolerance

        if self.echo_level > 1:
            info_msg = 'Convergence for "' + colors.bold(
                self.interface_data.variable.Name()) + '": '
            if is_converged:
                info_msg += colors.green("ACHIEVED")
            else:
                info_msg += colors.red("NOT ACHIEVED")
            cs_tools.cs_print_info(self._ClassName(), info_msg)
        if self.echo_level > 2:
            info_msg = colors.bold("abs_norm") + " = " + str(abs_norm) + " | "
            info_msg += colors.bold("abs_tol") + " = " + str(
                self.abs_tolerance) + " || "
            info_msg += colors.bold("rel_norm") + " = " + str(rel_norm) + " | "
            info_msg += colors.bold("rel_tol") + " = " + str(
                self.rel_tolerance)
            cs_tools.cs_print_info(self._ClassName(), info_msg)

        return is_converged
Example #3
0
    def _ExecuteTransferData(self, from_solver_data, to_solver_data,
                             transfer_options):
        model_part_origin = from_solver_data.GetModelPart()
        model_part_origin_name = from_solver_data.model_part_name
        variable_origin = from_solver_data.variable
        identifier_origin = from_solver_data.solver_name + "." + model_part_origin_name

        model_part_destination = to_solver_data.GetModelPart()
        model_part_destination_name = to_solver_data.model_part_name
        variable_destination = to_solver_data.variable
        identifier_destination = to_solver_data.solver_name + "." + model_part_destination_name

        mapper_flags = self.__GetMapperFlags(transfer_options)
        # TODO in the future automatically add the flags if the values are non-historical

        identifier_tuple = (identifier_origin, identifier_destination)
        inverse_identifier_tuple = (identifier_destination, identifier_origin)

        if identifier_tuple in self.__mappers:
            self.__mappers[identifier_tuple].Map(variable_origin,
                                                 variable_destination,
                                                 mapper_flags)
        elif inverse_identifier_tuple in self.__mappers:
            self.__mappers[inverse_identifier_tuple].InverseMap(
                variable_destination, variable_origin, mapper_flags)
        else:
            if model_part_origin.IsDistributed(
            ) or model_part_destination.IsDistributed():
                mapper_create_fct = python_mapper_factory.CreateMPIMapper
            else:
                mapper_create_fct = python_mapper_factory.CreateMapper

            if self.echo_level > 0:
                info_msg = "Creating Mapper:\n"
                info_msg += '    Origin: ModelPart "{}" of solver "{}"\n'.format(
                    model_part_origin_name, from_solver_data.solver_name)
                info_msg += '    Destination: ModelPart "{}" of solver "{}"'.format(
                    model_part_destination_name, to_solver_data.solver_name)

                cs_tools.cs_print_info(colors.bold(self._ClassName()),
                                       info_msg)

            mapper_creation_start_time = time()
            self.__mappers[identifier_tuple] = mapper_create_fct(
                model_part_origin, model_part_destination,
                self.settings["mapper_settings"].Clone()
            )  # Clone is necessary because the settings are validated and defaults assigned, which could influence the creation of other mappers

            if self.echo_level > 2:
                cs_tools.cs_print_info(
                    colors.bold(self._ClassName()),
                    "Creating Mapper took: {0:.{1}f} [s]".format(
                        time() - mapper_creation_start_time, 2))
            self.__mappers[identifier_tuple].Map(variable_origin,
                                                 variable_destination,
                                                 mapper_flags)
    def InitializeSolutionStep(self):
        self.step += 1
        cs_tools.cs_print_info(
            colors.bold("\ntime={0:.12g}".format(self.time) + " | step=" +
                        str(self.step)))

        self._GetSolver().InitializeSolutionStep()
Example #5
0
    def SolveSolutionStep(self):
        for k in range(self.num_coupling_iterations):
            if self.echo_level > 0:
                cs_tools.cs_print_info(
                    self._ClassName(), colors.cyan("Coupling iteration:"),
                    colors.bold(
                        str(k + 1) + " / " +
                        str(self.num_coupling_iterations)))

            for coupling_op in self.coupling_operations_dict.values():
                coupling_op.InitializeCouplingIteration()

            for conv_acc in self.convergence_accelerators_list:
                conv_acc.InitializeNonLinearIteration()

            for conv_crit in self.convergence_criteria_list:
                conv_crit.InitializeNonLinearIteration()

            for solver_name, solver in self.solver_wrappers.items():
                self._SynchronizeInputData(solver_name)
                solver.SolveSolutionStep()
                self._SynchronizeOutputData(solver_name)

            for coupling_op in self.coupling_operations_dict.values():
                coupling_op.FinalizeCouplingIteration()

            for conv_acc in self.convergence_accelerators_list:
                conv_acc.FinalizeNonLinearIteration()

            for conv_crit in self.convergence_criteria_list:
                conv_crit.FinalizeNonLinearIteration()

            is_converged = all([
                conv_crit.IsConverged()
                for conv_crit in self.convergence_criteria_list
            ])

            if is_converged:
                if self.echo_level > 0:
                    cs_tools.cs_print_info(
                        self._ClassName(),
                        colors.green("### CONVERGENCE WAS ACHIEVED ###"))
                self.__CommunicateStateOfConvergence(True)
                return True

            if k + 1 >= self.num_coupling_iterations and self.echo_level > 0:
                cs_tools.cs_print_info(
                    self._ClassName(),
                    colors.red("XXX CONVERGENCE WAS NOT ACHIEVED XXX"))
                self.__CommunicateStateOfConvergence(
                    True
                )  # True because max number of iterations is achieved. Otherwise external solver is stuck in time
                return False

            # if it reaches here it means that the coupling has not converged and this was not the last coupling iteration
            self.__CommunicateStateOfConvergence(False)

            # do relaxation only if this iteration is not the last iteration of this timestep
            for conv_acc in self.convergence_accelerators_list:
                conv_acc.ComputeAndApplyUpdate()
    def Run(self):
        num_coupling_interfaces = self.settings["coupling_interfaces"].size()
        self.__CustomPrint(
            1,
            colors.cyan("Starting export") + " of CouplingInterfaces ...")

        for i in range(num_coupling_interfaces):
            coupling_interface_settings = self.settings["coupling_interfaces"][
                i]
            sub_model_part_name = coupling_interface_settings[
                "sub_model_part_name"].GetString()
            comm_name = coupling_interface_settings["comm_name"].GetString()

            receive_interface = False
            operation = "Exporting"
            if coupling_interface_settings.Has("receive_interface"):
                receive_interface = coupling_interface_settings[
                    "receive_interface"].GetBool()
                operation = "Importing"

            self.__CustomPrint(
                2,
                colors.cyan(operation) +
                ' coupling-interface "{}" on ModelPart "{}"'.format(
                    comm_name, sub_model_part_name))

            if not self.dry_run:
                if receive_interface:
                    # use an aux-modelpart, which will not be used again
                    KratosCoSim.EMPIRE_API.EMPIRE_API_recvMesh(
                        self.model.CreateModelPart(sub_model_part_name),
                        comm_name)
                    # TODO maybe restructure and do all receives after all sends
                else:
                    KratosCoSim.EMPIRE_API.EMPIRE_API_sendMesh(
                        self.model["ExtSolver." + sub_model_part_name],
                        comm_name)
            else:
                self.__CustomPrint(2, colors.magenta('... skipped'))

            self.__CustomPrint(
                1,
                colors.cyan("Finished " + operation) +
                " of CouplingInterfaces")

        # time loop
        self.__CustomPrint(1, "Starting Solution Loop")
        for i in range(self.settings["num_steps"].GetInt()):
            if self.echo_level > 0: print()  # newline
            self.__CustomPrint(
                1,
                colors.bold('Step: {}/{}'.format(
                    i + 1, self.settings["num_steps"].GetInt())))
            self.SolveSolutionStep()
        self.__CustomPrint(1, "Finished")
    def SolveSolutionStep(self):
        for k in range(self.num_coupling_iterations):
            if self.echo_level > 0:
                cs_tools.cs_print_info(
                    self._ClassName(), colors.cyan("Coupling iteration:"),
                    colors.bold(
                        str(k + 1) + " / " +
                        str(self.num_coupling_iterations)))

            for coupling_op in self.coupling_operations_dict.values():
                coupling_op.InitializeCouplingIteration()

            for conv_acc in self.convergence_accelerators_list:
                conv_acc.InitializeNonLinearIteration()

            for conv_crit in self.convergence_criteria_list:
                conv_crit.InitializeNonLinearIteration()

            for solver_name, solver in self.solver_wrappers.items():
                self._SynchronizeInputData(solver_name)
                solver.SolveSolutionStep()
                self._SynchronizeOutputData(solver_name)

            for coupling_op in self.coupling_operations_dict.values():
                coupling_op.FinalizeCouplingIteration()

            for conv_acc in self.convergence_accelerators_list:
                conv_acc.FinalizeNonLinearIteration()

            for conv_crit in self.convergence_criteria_list:
                conv_crit.FinalizeNonLinearIteration()

            is_converged = all([
                conv_crit.IsConverged()
                for conv_crit in self.convergence_criteria_list
            ])

            self.__CommunicateStateOfConvergence(is_converged)

            if is_converged:
                if self.echo_level > 0:
                    cs_tools.cs_print_info(
                        self._ClassName(),
                        colors.green("### CONVERGENCE WAS ACHIEVED ###"))
                return True
            else:
                # TODO I think this should not be done in the last iterations if the solution does not converge in this timestep
                for conv_acc in self.convergence_accelerators_list:
                    conv_acc.ComputeAndApplyUpdate()

            if k + 1 >= self.num_coupling_iterations and self.echo_level > 0:
                cs_tools.cs_print_info(
                    self._ClassName(),
                    colors.red("XXX CONVERGENCE WAS NOT ACHIEVED XXX"))
                return False
    def __init__(self, settings, solver_wrapper):
        self.interface_data = solver_wrapper.GetInterfaceData(
            settings["data_name"].GetString())
        settings.RemoveValue("data_name")
        settings.RemoveValue("solver")

        if not settings.Has("label"):
            settings.AddEmptyValue("label").SetString(
                colors.bold('{}.{}'.format(self.interface_data.solver_name,
                                           self.interface_data.name)))

        self.conv_crit = CreateConvergenceCriterion(settings)
Example #9
0
    def TransferData(self, from_solver_data, to_solver_data, transfer_options):
        # TODO check location of data => should coincide with the one for the mapper
        # or throw if it is not in a suitable location (e.g. on the ProcessInfo)

        self._CheckAvailabilityTransferOptions(transfer_options)

        model_part_origin = from_solver_data.GetModelPart()
        model_part_origin_name = from_solver_data.model_part_name
        variable_origin = from_solver_data.variable
        identifier_origin = from_solver_data.solver_name + "." + model_part_origin_name

        model_part_destination = to_solver_data.GetModelPart()
        model_part_destination_name = to_solver_data.model_part_name
        variable_destination = to_solver_data.variable
        identifier_destination = to_solver_data.solver_name + "." + model_part_destination_name

        mapper_flags = self.__GetMapperFlags(transfer_options)

        identifier_tuple = (identifier_origin, identifier_destination)
        inverse_identifier_tuple = (identifier_destination, identifier_origin)

        if identifier_tuple in self.__mappers:
            self.__mappers[identifier_tuple].Map(variable_origin,
                                                 variable_destination,
                                                 mapper_flags)
        elif inverse_identifier_tuple in self.__mappers:
            self.__mappers[inverse_identifier_tuple].InverseMap(
                variable_destination, variable_origin, mapper_flags)
        else:
            # CheckIfInterfaceDataIsSuitable() # TODO
            if model_part_origin.IsDistributed(
            ) or model_part_destination.IsDistributed():
                mapper_create_fct = KratosMapping.MapperFactory.CreateMPIMapper
            else:
                mapper_create_fct = KratosMapping.MapperFactory.CreateMapper

            if self.echo_level > 0:
                info_msg = "Creating Mapper:\n"
                info_msg += '    Origin: ModePart "{}" of solver "{}"\n'.format(
                    model_part_origin_name, from_solver_data.solver_name)
                info_msg += '    Destination: ModePart "{}" of solver "{}"'.format(
                    model_part_destination_name, to_solver_data.solver_name)

                cs_tools.cs_print_info(colors.bold(self._ClassName()),
                                       info_msg)

            self.__mappers[identifier_tuple] = mapper_create_fct(
                model_part_origin, model_part_destination,
                self.settings["mapper_settings"].Clone()
            )  # Clone is necessary here bcs settings are influenced among mappers otherwise. TODO check in the MapperFactory how to solve this better
            self.__mappers[identifier_tuple].Map(variable_origin,
                                                 variable_destination,
                                                 mapper_flags)
 def PrintInfo(self):
     cs_tools.cs_print_info("Convergence Criteria",
                            colors.bold(self._ClassName()))
Example #11
0
def cs_print_warning(label, *args):
    KM.Logger.PrintWarning(
        colors.red("Warning: ") + colors.bold(label), " ".join(map(str, args)))
Example #12
0
def cs_print_info(label, *args):
    KM.Logger.PrintInfo(colors.bold(label), " ".join(map(str, args)))
 def PrintInfo(self):
     '''Function to print Info abt the Object
     Can be overridden in derived classes to print more information
     '''
     cs_tools.cs_print_info("Convergence Accelerator",
                            colors.bold(self._Name()))
    def __init__(self, settings, solvers):
        super().__init__(settings)

        if self.settings["criteria_composition"].GetString(
        ) != "energy_conjugate":
            self.__RaiseException(
                'Energy conjugate criteria composition requires energy conjugate variables to be specified in "data_name" and "conjugate_data_name".'
            )

        self.iteration = 1
        self.abs_tolerance = self.settings["abs_tolerance"].GetDouble()
        self.ignore_first_convergence = self.settings[
            "ignore_first_convergence"].GetBool()

        # Determine if we are looking at the energy difference between two domains (solvers), or just one
        self.solver_vec = [solvers[settings["solver"].GetString()]]
        is_dual_domain = False
        for criteria_option in settings["criteria_options"]:
            if criteria_option.GetString() == "domain_difference":
                is_dual_domain = True
                break
        if is_dual_domain:
            is_error = False
            if settings.Has("solver_domain_two"):
                solver_domain_two = settings["solver_domain_two"].GetString()
                if solver_domain_two == "UNSPECIFIED":
                    is_error = True
                else:
                    self.solver_vec.append(solvers[solver_domain_two])
            else:
                is_error = True
            if is_error:
                self.__RaiseException(
                    'Domain difference requires "solver_domain_two" to be set to the second domain.'
                )

        # Setup interface data matrix (general form)
        self.interface_data = [None] * len(solvers)
        for solver_index in range(0, len(self.interface_data)):
            self.interface_data[solver_index] = [
                self.solver_vec[solver_index].GetInterfaceData(
                    settings["data_name"].GetString())
            ]
            self.interface_data[solver_index].append(
                self.solver_vec[solver_index].GetInterfaceData(
                    settings["conjugate_data_name"].GetString()))

        self.second_domain_data_sign = 1.0
        if "swap_second_domain_data_sign" in settings[
                "criteria_options"].GetStringArray():
            self.second_domain_data_sign = -1.0

        settings.RemoveValue("data_name")
        settings.RemoveValue("solver")

        if not settings.Has("label"):
            settings.AddEmptyValue("label").SetString(
                colors.bold('{}.{}'.format(
                    self.interface_data[0][0].solver_name,
                    self.interface_data[0][0].name)))
        self.label = self.settings["label"].GetString()
 def Check(self):
     cs_tools.cs_print_warning("Convergence Criteria",
                               colors.bold(self._ClassName()),
                               'does not implement "Check"')
 def PrintInfo(self):
     '''Function to print Info abt the Object
     Can be overridden in derived classes to print more information
     '''
     cs_tools.cs_print_info("Predictor", colors.bold(self._ClassName()))