def __init__(self, K_dict, B_dict, f_dict, **kwargs): """ Parameters ---------- K_dict : dict stiffness-matrices B_dict : dict dictionary of connectivities per interface-ids f_dict : dict external forces kwargs : dict optional arguments for solver-configuration """ super().__init__() self.set_config({ 'K_dict': K_dict, 'B_dict': B_dict, 'f_dict': f_dict, 'use_parallel': False, 'global_solver': PCPGsolver() }) self.set_config(kwargs) self._create_local_problems() self._dual_solution_length = None
def test_serial_solver(self): solver = PCPGsolver() solver.set_config({'full_reorthogonalization': True}) fetisolver = LinearDynamicFetiSolver(deepcopy(self.integrator_dict), deepcopy(self.B_dict), 0.0, 0.0003, deepcopy(self.q_0_dict), deepcopy(self.q_0_dict), deepcopy(self.q_0_dict), use_parallel=False, global_solver=solver) fetisolver.update() solution_obj = fetisolver.solve() q_dict_serial = dict() dq_dict_serial = dict() ddq_dict_serial = dict() for problem_id, problem in solution_obj.local_problems.items(): q_dict_serial[problem_id] = problem.q dq_dict_serial[problem_id] = problem.dq ddq_dict_serial[problem_id] = problem.ddq self.custom_asserter.assert_dict_almost_equal(q_dict_serial, self.q_dict_desired) self.custom_asserter.assert_dict_almost_equal(dq_dict_serial, self.dq_dict_desired) self.custom_asserter.decimals = 2 self.custom_asserter.assert_dict_almost_equal(ddq_dict_serial, self.ddq_dict_desired) info_dict_keys_desired = dict() for tstep in range(0, 3): info_dict_keys_desired[tstep] = { 'avg_iteration_time': None, 'Total_elaspsed_time': None, 'iterations': None, 'lambda_hist': None, 'residual_hist': None, 'residual': None } self.custom_asserter.assert_dict_keys_equal( solution_obj.solver_information, info_dict_keys_desired)
def __init__(self, integrator_dict, B_dict, t0, t_end, q0_dict, dq0_dict, ddq0_dict, **kwargs): """ Parameters ---------- integrator_dict : dict integrator-objects describing the dynamic behavior of the local problems. For detailed specifications on the Integrator-class see `Basics of time-integration` or `Requirements to an Integrator-Class` and for the required API the :class:`~amfeti.local_problems.integrator_base.IntegratorBase` B_dict : dict dictionary of connectivities per interface-ids t0 : double start-time t_end : double end-time q0_dict : dict start-values for local solutions (e.g. displacements) dq0_dict : dict start-values for local solutions' first time-derivative (e.g. velocities) ddq0_dict : dict start-values for local solutions' second time-derivative (e.g. accelerations) kwargs : dict optional arguments for solver-configuration """ super().__init__() self.set_config({ 'integrator_dict': integrator_dict, 'B_dict': B_dict, 't0': t0, 't_end': t_end, 'q0_dict': q0_dict, 'dq0_dict': dq0_dict, 'ddq0_dict': ddq0_dict, 'use_parallel': False, 'global_solver': PCPGsolver(), 'preconditioner': DirichletPreconditioner(), 'scaling': MultiplicityScaling() }) self.set_config(kwargs) self._create_local_problems() self._dual_solution_length = None
if key[0] == i_system: B_local[interface_dict[key]] = B_dict[key] B_dict_trans[subs_key] = B_local return K_dict_trans, B_dict_trans, f_ext_dict_trans """ We can now use this function to define the dictionaries for K, B and f_ext and call the linear static FETI solver. """ K_dict, B_dict, f_ext_dict = _create_K_B_f_dict( substructured_system.connections, substructured_system.mechanical_systems) # Defining an instance of the Preconditioned Conjugate Projected Gradient (PCPG) solver as a global system solver to be used global_solver = PCPGsolver() global_solver.set_config({'full_reorthogonalization': True}) feti_solver = LinearStaticFetiSolver(K_dict, B_dict, f_ext_dict, global_solver=global_solver) feti_solver.update() """ A solution object, containing all global solutions, solver-information and local problems, is returned by the solver. """ # Solving our system solution_obj = feti_solver.solve() """ We now have our solution, but it's a solution object so we need to
def test_parallel_solver(self): if self.run_parallel_tests: solver = PCPGsolver() solver.set_config({'full_reorthogonalization': True}) fetisolver = LinearDynamicFetiSolver(deepcopy( self.integrator_dict), deepcopy(self.B_dict), 0.0, 0.0003, deepcopy(self.q_0_dict), deepcopy(self.q_0_dict), deepcopy(self.q_0_dict), use_parallel=True, global_solver=solver) # If 6 processors are available, the following 6 lines can be omitted mpi_manager = MPIManager() mpi_manager.set_config({ 'mpi_rank2problems': { 0: np.array([1, 3]), 1: np.array([2, 4]), 2: np.array([5]), 3: np.array([6]) } }) solver_manager = ParallelSolverManager( fetisolver._local_problems, fetisolver._config_dict['global_solver']) solver_manager.set_config({'parallelization_manager': mpi_manager}) fetisolver.set_config({'solver_manager': solver_manager}) fetisolver.update() solution_obj = fetisolver.solve() q_dict_parallel = dict() dq_dict_parallel = dict() ddq_dict_parallel = dict() for problem_id, problem in solution_obj.local_problems.items(): q_dict_parallel[problem_id] = problem.q dq_dict_parallel[problem_id] = problem.dq ddq_dict_parallel[problem_id] = problem.ddq self.custom_asserter.assert_dict_almost_equal( q_dict_parallel, self.q_dict_desired) self.custom_asserter.assert_dict_almost_equal( dq_dict_parallel, self.dq_dict_desired) self.custom_asserter.decimals = 3 self.custom_asserter.assert_dict_almost_equal( ddq_dict_parallel, self.ddq_dict_desired) info_dict_keys_desired = dict() for tstep in range(0, 3): info_dict_keys_desired[tstep] = { 'avg_iteration_time': None, 'Total_elaspsed_time': None, 'iterations': None, 'lambda_hist': None, 'residual_hist': None, 'residual': None } self.custom_asserter.assert_dict_keys_equal( solution_obj.solver_information, info_dict_keys_desired) else: logger = logging.getLogger(__name__) logger.warning( 'Parallel test has not been run. If parallel tests shall be run, switch on the ' 'run_parallel_tests-flag manually.')
return integrator_dict, B_dict_trans, q_0_dict, dq_0_dict, ddq_0_dict """ We can now use this function to define the dictionaries for the integrator objects, B matrices, the local solutions and their first and second derivatives and call the nonlinear dynamic FETI solver. """ integrator_dict, B_dict, q_0_dict, dq_0_dict, ddq_0_dict = _create_integrator_B_dict( substructured_system.connections, substructured_system.mechanical_systems) logging.basicConfig(level=logging.INFO) # Defining an instance of the Preconditioned Conjugate Projected Gradient (PCPG) solver as a global system solver to be used solver = PCPGsolver() solver.set_config({'full_reorthogonalization': True, 'save_history': True}) fetisolver = NonlinearDynamicFetiSolver(integrator_dict, B_dict, 0.0, 0.003, q_0_dict, dq_0_dict, ddq_0_dict, global_solver=solver, loadpath_controller_options={ 'N_steps': 1, 'nonlinear_solver_options': { 'atol': 1.0e-06, 'rtol': 1.0e-7, 'max_iter': 10,
def setUp(self): self.solver = PCPGsolver() self.A = csr_matrix( np.array([[5, -2, 0, 0], [-2, 5, -2, 0], [0, -2, 5, -2], [0, 0, -2, 3]])) self.b = np.array([0.5, -0.3, 1.35, 0.18])
class PCPGsolverTest(TestCase): def setUp(self): self.solver = PCPGsolver() self.A = csr_matrix( np.array([[5, -2, 0, 0], [-2, 5, -2, 0], [0, -2, 5, -2], [0, 0, -2, 3]])) self.b = np.array([0.5, -0.3, 1.35, 0.18]) def tearDown(self): pass def test_solve(self): def F_callback(v): return self.A @ v def residual_callback(v): return -self.A @ v + self.b def precondition(v): return csr_matrix( np.array([[1 / 5, 0, 0, 0], [0, 1 / 5, 0, 0], [0, 0, 1 / 5, 0], [0, 0, 0, 1 / 3]])) @ v x0 = np.array([0.0, 0.0, 0.0, 0.0]) solution_actual, info_dict_pure_cg = self.solver.solve( F_callback, residual_callback, x0) solution_desired = spsolve(self.A, self.b) assert_array_almost_equal(solution_actual, solution_desired) # Full reorthogonalization self.solver.set_config({ 'save_history': True, 'full_reorthogonalization': True }) solution_actual, info_dict_fReOrth_cg = self.solver.solve( F_callback, residual_callback, x0) assert_array_almost_equal(solution_actual, solution_desired) self.assertTrue(info_dict_fReOrth_cg['iterations'] <= info_dict_pure_cg['iterations']) # Preconditioner self.solver.set_config({ 'save_history': True, 'full_reorthogonalization': False, 'precondition': precondition }) solution_actual, info_dict_precond_cg = self.solver.solve( F_callback, residual_callback, x0) assert_array_almost_equal(solution_actual, solution_desired) self.assertTrue(info_dict_precond_cg['iterations'] <= info_dict_pure_cg['iterations']) def test_project(self): def project(v): return csr_matrix( np.array([[2, 0, 0, 0], [0, 2, 0, 0], [0, 0, 2, 0], [0, 0, 0, 2]])) @ v self.solver.set_config({'projection': project}) solution_actual = self.solver._project(np.array([1, 2, 3, 4])) solution_desired = np.array([2, 4, 6, 8]) assert_array_almost_equal(solution_actual, solution_desired)
def test_serial_solver(self): solver = PCPGsolver() solver.set_config({'full_reorthogonalization': True}) fetisolver = NonlinearDynamicFetiSolver(deepcopy(self.integrator_dict), deepcopy(self.B_dict), 0.0, 0.0003, deepcopy(self.q_0_dict), deepcopy(self.q_0_dict), deepcopy(self.q_0_dict), use_parallel=False, loadpath_controller_options={ 'nonlinear_solver_options': { 'atol': 1.0e-6, 'rtol': 1.0e-9, 'max_iter': 10, 'log_iterations': True }, 'N_steps': 1 }, global_solver=solver) fetisolver.update() solution_obj = fetisolver.solve() q_dict_serial = dict() dq_dict_serial = dict() ddq_dict_serial = dict() for problem_id, problem in solution_obj.local_problems.items(): q_dict_serial[problem_id] = problem.q dq_dict_serial[problem_id] = problem.dq ddq_dict_serial[problem_id] = problem.ddq self.custom_asserter.assert_dict_almost_equal(q_dict_serial, self.q_dict_desired) self.custom_asserter.assert_dict_almost_equal(dq_dict_serial, self.dq_dict_desired) self.custom_asserter.decimals = 2 self.custom_asserter.assert_dict_almost_equal(ddq_dict_serial, self.ddq_dict_desired) info_dict_keys_desired = dict() for tstep in range(0, 3): loadstep_dict_keys_desired = dict() for lstep in range(0, 1): linear_solver_dict = dict() if lstep is 0: linear_solver_dict[0] = { 'avg_iteration_time': None, 'Total_elaspsed_time': None, 'iterations': None, 'lambda_hist': None, 'residual_hist': None, 'residual': None } elif lstep > 0: for newton_iter in range(0, 10): linear_solver_dict[newton_iter] = { 'avg_iteration_time': None, 'Total_elaspsed_time': None, 'iterations': None, 'lambda_hist': None, 'residual_hist': None, 'residual': None } loadstep_dict_keys_desired[lstep] = { 'newton': { 'residual': None, 'linear_solver': linear_solver_dict, 'iterations': None } } info_dict_keys_desired[tstep] = loadstep_dict_keys_desired self.custom_asserter.assert_dict_keys_equal( solution_obj.solver_information, info_dict_keys_desired)