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)
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))