コード例 #1
0
ファイル: solvers.py プロジェクト: maglunengineering/dssolver
    def solve(self, problem:Problem):
        problem.reassign_dofs()
        M = problem.M(True)
        K = problem.K(True)
        ndofs = 3 * len(problem.nodes)
        free_dofs = problem.free_dofs()
        full_eigenvectors = np.zeros((len(free_dofs), ndofs))

        # Unsymmetric reduction
        A = np.linalg.solve(M, K)

        # Symmetry preserving reduction
        #L = np.linalg.cholesky(M)
        #A = np.linalg.inv(L) @ K @ np.linalg.inv(L.T)

        eigenvalues, eigenvectors = np.linalg.eig(A)

        eigenvectors = eigenvectors.T # Row-major
        eigenvectors = eigenvectors[eigenvalues.argsort()]
        eigenvalues.sort()
        full_eigenvectors[:,free_dofs] = eigenvectors

        return results.ResultsModal(problem, eigenvalues, full_eigenvectors)
コード例 #2
0
ファイル: solvers.py プロジェクト: maglunengineering/dssolver
    def solve(self, problem:Problem) -> results.ResultsStaticNonlinear:
        steps = 500
        arclength = 45
        A = 0
        max_it = 35
        t0 = time.time()

        problem.reassign_dofs()
        problem.remove_dofs()
        free_dofs = problem.free_dofs()

        max_A = np.linalg.norm(problem.loads[free_dofs])
        q = problem.loads[free_dofs] / max_A
        displacements = np.zeros(len(problem.nodes) * 3)
        loads = np.zeros_like(displacements)

        #displ_storage = np.zeros((steps, 3 * len(problem.nodes)))
        displ_storage = []
        force_storage = []

        i = 0
        while i < steps and A < max_A:
            print("Predictor step {}".format(i))
            K = problem.K(True)
            wq0 = np.linalg.solve(K, q)
            f = np.sqrt(1 + wq0 @ wq0)

            sign = np.sign(wq0 @ v0 if i > 1 else 1)
            dA = arclength / f * sign
            v0 = dA*wq0
            A += dA

            displacements[free_dofs] = displacements[free_dofs] + v0
            for node in problem.nodes:
                node.displacements = displacements[node.dofs]

            # Corrector
            k = 0
            residual = self.get_internal_forces(problem)[free_dofs] - q*A
            while np.linalg.norm(residual) > 1e-3 and k < max_it:
                K = problem.K(True)
                wq = np.linalg.solve(K, q)
                wr = np.linalg.solve(K, -residual)
                dA_ = -wq @ wr / (1 + wq @ wq)
                A += dA_

                displacements[free_dofs] = displacements[free_dofs] + (wr + dA_*wq)
                for node in problem.nodes:
                    node.displacements = displacements[node.dofs]
                k += 1

                residual = self.get_internal_forces(problem)[free_dofs] - q*A

            #displ_storage[i] = displacements
            displ_storage.append(np.array(displacements))
            loads[free_dofs] = q*A
            force_storage.append(A)
            i += 1

            #print(f"Finished in {k} corrector steps (stepped {dA}, arclength {arclength})")
            if k < 4:
                arclength *= 1.05
            elif k > 8:
                arclength *= 0.6
            else:
                arclength *= 0.85

        t1 = time.time()
        dt = t1 - t0
        print(np.asarray(displ_storage))
        print(f"Ended at A = {A} in {dt} seconds")

        return results.ResultsStaticNonlinear(problem, np.asarray(displ_storage),
                                              np.asarray(force_storage))