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, residual, current_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

        info_msg = ""

        if self.echo_level > 1:
            info_msg = 'Convergence '

            if self.label != "":
                info_msg += 'for "{}": '.format(self.label)

            if is_converged:
                info_msg += colors.green("ACHIEVED")
            else:
                info_msg += colors.red("NOT ACHIEVED")

        if self.echo_level > 2:
            info_msg += '\n\t abs-norm = {:.2e} | abs-tol = {} || rel-norm = {:.2e} | rel-tol = {}'.format(
                abs_norm, self.abs_tolerance, rel_norm, self.rel_tolerance)

        if info_msg != "":
            cs_tools.cs_print_info(self._ClassName(), 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
    def IsConverged(self, residual, current_data):
        res_norm = la.norm(residual)
        norm_new_data = la.norm(current_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

        info_msg = ""

        if self.echo_level > 1:
            info_msg = 'Convergence '

            if self.label != "":
                info_msg += 'for "{}": '.format(self.label)

            if is_converged:
                info_msg += colors.green("ACHIEVED")
            else:
                info_msg += colors.red("NOT ACHIEVED")

        if self.echo_level > 2:
            info_msg += '\n\t abs-norm = {:.2e} | abs-tol = {} || rel-norm = {:.2e} | rel-tol = {}'.format(
                abs_norm, self.abs_tolerance, rel_norm, self.rel_tolerance)

        if info_msg != "":
            cs_tools.cs_print_info(self._ClassName(), info_msg)

        return is_converged
Exemple #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 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 IsConverged(self):
        # Compute energy scalar on interface
        current_data = 0.0

        for solver_index in range(0, len(self.interface_data)):
            #check length of data vectors are the same
            interface_energy = 0.0
            data_1 = self.interface_data[solver_index][0].GetData()
            data_2 = self.interface_data[solver_index][1].GetData()
            if len(data_1) != len(data_2):
                self.__RaiseException(
                    'Data vector lengths for conjugate criteria composition must be identical, but they are different!'
                )
            else:
                for i in range(0, len(data_1)):
                    interface_energy += data_1[i] * data_2[i]
            if solver_index == 0:
                current_data = interface_energy
            else:
                current_data -= self.second_domain_data_sign * interface_energy  #assumes domain_difference

        abs_norm = la.norm(current_data)

        if self.ignore_first_convergence and self.iteration == 1:
            is_converged = False
        else:
            is_converged = abs_norm < self.abs_tolerance

        self.iteration += 1

        info_msg = ""

        if self.echo_level > 1:
            info_msg = 'Convergence '

            if self.label != "":
                info_msg += 'for "{}": '.format(self.label)

            if is_converged:
                info_msg += colors.green("ACHIEVED")
            else:
                info_msg += colors.red("NOT ACHIEVED")

        if self.echo_level > 2:
            info_msg += '\n\t abs-norm = {:.2e} | abs-tol = {}'.format(
                abs_norm, self.abs_tolerance)

        if info_msg != "":
            cs_tools.cs_print_info(self._ClassName(), info_msg)

        return is_converged
def cs_print_warning(label, *args):
    KM.Logger.PrintWarning(
        colors.red("Warning: ") + colors.bold(label), " ".join(map(str, args)))
Exemple #9
0
    def UpdateSolution(self, r, x):
        self.R.appendleft(deepcopy(r))
        self.X.appendleft(x + r)  # r = x~ - x
        row = len(r)
        col = len(self.R) - 1
        k = col
        num_old_matrices = len(self.v_old_matrices)

        if self.V_old == [] and self.W_old == []:  # No previous vectors to reuse
            if k == 0:
                ## For the first iteration in the first time step, do relaxation only
                if self.echo_level > 3:
                    cs_print_info(
                        self._ClassName(),
                        "Doing relaxation in the first iteration with factor = ",
                        "{0:.1g}".format(self.alpha))
                return self.alpha * r
            else:
                if self.echo_level > 3:
                    cs_print_info(self._ClassName(),
                                  "Doing multi-vector extrapolation")
                    cs_print_info(self._ClassName(), "Number of new modes: ",
                                  col)
                self.V_new = np.empty(shape=(col,
                                             row))  # will be transposed later
                for i in range(0, col):
                    self.V_new[i] = self.R[i] - self.R[i + 1]
                self.V_new = self.V_new.T
                V = self.V_new

                ## Check the dimension of the newly constructed matrix
                if (V.shape[0] < V.shape[1]) and self.echo_level > 0:
                    cs_print_warning(
                        self._ClassName(), ": " + colors.red(
                            "WARNING: column number larger than row number!"))

                ## Construct matrix W(differences of predictions)
                self.W_new = np.empty(shape=(col,
                                             row))  # will be transposed later
                for i in range(0, col):
                    self.W_new[i] = self.X[i] - self.X[i + 1]
                self.W_new = self.W_new.T
                W = self.W_new

                ## Solve least-squares problem
                delta_r = -self.R[0]
                c = np.linalg.lstsq(V, delta_r)[0]

                ## Compute the update
                delta_x = np.dot(W, c) - delta_r

                return delta_x
        else:  # previous vectors can be reused
            if k == 0:  # first iteration
                if self.echo_level > 3:
                    cs_print_info(self._ClassName(),
                                  "Using matrices from previous time steps")
                    cs_print_info(self._ClassName(),
                                  "Number of previous matrices: ",
                                  num_old_matrices)
                V = self.V_old
                W = self.W_old
                ## Solve least-squares problem
                delta_r = -self.R[0]
                c = np.linalg.lstsq(V, delta_r)[0]

                ## Compute the update
                delta_x = np.dot(W, c) - delta_r
                return delta_x
            else:
                ## For other iterations, construct new V and W matrices and combine them with old ones
                if self.echo_level > 3:
                    cs_print_info(self._ClassName(),
                                  "Doing multi-vector extrapolation")
                    cs_print_info(self._ClassName(), "Number of new modes: ",
                                  col)
                    cs_print_info(self._ClassName(),
                                  "Number of previous matrices: ",
                                  num_old_matrices)
                ## Construct matrix V (differences of residuals)
                self.V_new = np.empty(shape=(col,
                                             row))  # will be transposed later
                for i in range(0, col):
                    self.V_new[i] = self.R[i] - self.R[i + 1]
                self.V_new = self.V_new.T
                V = np.hstack((self.V_new, self.V_old))
                ## Check the dimension of the newly constructed matrix
                if (V.shape[0] < V.shape[1]) and self.echo_level > 0:
                    cs_print_warning(
                        self._ClassName(), ": " + colors.red(
                            "WARNING: column number larger than row number!"))

                ## Construct matrix W(differences of predictions)
                self.W_new = np.empty(shape=(col,
                                             row))  # will be transposed later
                for i in range(0, col):
                    self.W_new[i] = self.X[i] - self.X[i + 1]
                self.W_new = self.W_new.T
                W = np.hstack((self.W_new, self.W_old))

                ## Solve least-squares problem
                delta_r = -self.R[0]
                c = np.linalg.lstsq(V, delta_r)[0]

                ## Compute the update
                delta_x = np.dot(W, c) - delta_r

                return delta_x