def Check(self):
     is_distributed = co_simulation_tools.COSIM_SPACE.IsDistributed()
     solver_parallel_type = self._GetParallelType()
     if is_distributed and not solver_parallel_type == "MPI":
         warning_msg  = 'WARNING: Global "parallel_type" (MPI) is different '
         warning_msg += 'from local one (' + solver_parallel_type + ')!'
         solverprint(self.lvl, self._Name(), ": " + red(warning_msg))
     elif not is_distributed and not solver_parallel_type == "OpenMP":
         warning_msg  = 'WARNING: Global "parallel_type" (OpenMP) is different '
         warning_msg += 'from local one (' + solver_parallel_type + ')!'
         solverprint(self.lvl, self._Name(), ": " + red(warning_msg))
    def SolveSolutionStep(self):
        for k in range(self.num_coupling_iterations):
            if self.echo_level > 0:
                couplingsolverprint(self.lvl, self._Name(),
                                    cyan("Coupling iteration:"), bold(str(k+1)+" / " + str(self.num_coupling_iterations)))

            self.convergence_accelerator.InitializeNonLinearIteration()
            self.convergence_criteria.InitializeNonLinearIteration()

            for solver_name in self.solver_names:
                solver = self.solvers[solver_name]
                self._SynchronizeInputData(solver, solver_name)
                solver.SolveSolutionStep()
                self._SynchronizeOutputData(solver, solver_name)

            self.convergence_accelerator.FinalizeNonLinearIteration()
            self.convergence_criteria.FinalizeNonLinearIteration()

            if self.convergence_criteria.IsConverged():
                if self.echo_level > 0:
                    couplingsolverprint(self.lvl, self._Name(), green("### CONVERGENCE WAS ACHIEVED ###"))
                break
            else:
                self.convergence_accelerator.ComputeUpdate()

            if k+1 >= self.num_coupling_iterations and self.echo_level > 0:
                couplingsolverprint(self.lvl, self._Name(), red("XXX CONVERGENCE WAS NOT ACHIEVED XXX"))
    def IsConverged(self):
        convergence_list = []
        for i, data_entry in enumerate(self.settings["data_list"]):
            solver = self.solvers[data_entry["solver"]]
            data_name = data_entry["data_name"]
            cs_tools.ImportArrayFromSolver(solver, data_name, self.new_data)

            residual = self.new_data - self.old_data[i]
            res_norm = la.norm(residual)
            norm_new_data = la.norm(self.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
            convergence_list.append(abs_norm < self.abs_tolerances[i] or rel_norm < self.rel_tolerances[i])
            if self.echo_level > 1:
                info_msg  = 'Convergence for "'+bold(data_entry["data_name"])+'": '
                if convergence_list[i]:
                    info_msg += green("ACHIEVED")
                else:
                    info_msg += red("NOT ACHIEVED")
                classprint(self.lvl, self._Name(), info_msg)
            if self.echo_level > 2:
                info_msg  = bold("abs_norm")+" = " + str(abs_norm) + " | "
                info_msg += bold("abs_tol")+" = " + str(self.abs_tolerances[i])
                info_msg += " || "+bold("rel_norm")+" = " + str(rel_norm) + " | "
                info_msg += bold("rel_tol") +" = " + str(self.rel_tolerances[i])
                classprint(self.lvl, self._Name(), info_msg)

        return min(convergence_list) # return false if any of them did not converge!
    def __init__(self, cosim_settings):
        if (type(cosim_settings) != dict):
            raise Exception(
                "Input is expected to be provided as a python dictionary")

        CheckCoSimulationSettingsAndAssignDefaults(cosim_settings)

        problem_data = cosim_settings["problem_data"]
        self.cosim_settings = cosim_settings

        cs_tools.PRINT_COLORS = problem_data["print_colors"]

        parallel_type = problem_data["parallel_type"]
        if parallel_type == "OpenMP":
            self.flush_stdout = True
            cs_tools.PRINTING_RANK = True
        elif parallel_type == "MPI":
            from co_simulation_mpi_space import CoSimulationMPISpace
            cs_tools.COSIM_SPACE = CoSimulationMPISpace()
            cs_tools.PRINTING_RANK = (cs_tools.COSIM_SPACE.Rank() == 0)
        else:
            raise Exception('"parallel_type" can only be "OpenMP" or "MPI"!')

        self.flush_stdout = problem_data["flush_stdout"]
        self.echo_level = problem_data["echo_level"]

        print(
            red("DEPRECATION-WARNING:"),
            "The CoSimulation-features in the EmpireApplication have been moved to the CoSimulationApplication.\nThe EmpireApplication-CoSimulation will be supported for some time, but it will be removed eventually.\nPlease update your code."
        )
Exemplo n.º 5
0
    def _ComputeUpdate(self, r, x):

        self.V.appendleft(deepcopy(r))
        self.W.appendleft(deepcopy(x))
        row = len(r)
        col = len(self.V) - 1
        k = col
        if k == 0:
            ## For the first iteration, do relaxation only
            if self.echo_level > 3:
                classprint(
                    self.lvl, self._Name(),
                    "Doing relaxation in the first iteration with factor = ",
                    "{0:.1g}".format(self.alpha))
            return self.alpha * r
        else:
            self.F = np.empty(shape=(col, row))  # will be transposed later
            self.X = np.empty(shape=(col, row))  # will be transposed later
            for i in range(0, col):
                self.F[i] = self.V[i] - self.V[i + 1]
                self.X[i] = self.W[i] - self.W[i + 1]
            self.F = self.F.T
            self.X = self.X.T

            #compute Moore-Penrose inverse of F^T F
            A = np.linalg.pinv(self.F.T @ self.F)

            switch = (self.iteration_counter + 1) / self.p

            classprint(self.lvl, magenta(self.iteration_counter))

            if switch.is_integer() == True:
                B = self.beta * np.identity(row) - (
                    self.X + self.beta * self.F) @ A @ self.F.T
                if self.echo_level > 3:
                    classprint(self.lvl, self._Name(),
                               blue("Compute B with Anderson"))
            else:
                B = self.alpha * np.identity(row)
                if self.echo_level > 3:
                    classprint(self.lvl, self._Name(),
                               red("Constant underrelaxtion"))

            delta_x = B @ r

            self.iteration_counter += 1

            return delta_x

        def FinalizeSolutionStep(self):
            self.V.clear()
            self.W.clear()

        def _Name(self):
            return self.__class__.__name__
Exemplo n.º 6
0
    def _ComputeUpdate(self, r, x):
        self.R.appendleft(deepcopy(r))
        k = len(self.R) - 1
        ## For the first iteration, do relaxation only
        if k == 0:
            alpha = min(self.alpha_old, self.init_alpha_max)
            if self.echo_level > 3:
                classprint(
                    self.lvl, self._Name(),
                    ": Doing relaxation in the first iteration with initial factor = "
                    + "{0:.1g}".format(alpha))
            return alpha * r
        else:
            r_diff = self.R[0] - self.R[1]
            numerator = np.inner(self.R[1], r_diff)
            denominator = np.inner(r_diff, r_diff)
            alpha = -self.alpha_old * numerator / denominator
            if self.echo_level > 3:
                classprint(
                    self.lvl, self._Name(),
                    ": Doing relaxation with factor = " +
                    "{0:.1g}".format(alpha))
            if alpha > 20:
                alpha = 20
                if self.echo_level > 0:
                    classprint(
                        self.lvl, self._Name(), ": " +
                        red("WARNING: dynamic relaxation factor reaches upper bound: 20"
                            ))
            elif alpha < -2:
                alpha = -2
                if self.echo_level > 0:
                    classprint(
                        self.lvl, self._Name(), ": " +
                        red("WARNING: dynamic relaxation factor reaches lower bound: -2"
                            ))
            delta_x = alpha * self.R[0]
        self.alpha_old = alpha

        return delta_x