def test_wrong_input_set_data(self): settings = KM.Parameters("""{ "model_part_name" : "mp_4_test", "variable_name" : "PRESSURE" }""") settings_model_part = KM.Parameters("""{ "model_part_name" : "mp_4_test", "variable_name" : "PRESSURE", "location" : "model_part" }""") coupling_data = CouplingInterfaceData(settings, self.model) coupling_data.Initialize() coupling_data_mp = CouplingInterfaceData(settings_model_part, self.model) coupling_data_mp.Initialize() wrong_data = [1,2,3] correct_data = [1,2,3,4,5] with self.assertRaisesRegex(Exception, "The sizes of the data are not matching, got: 3, expected: 5"): coupling_data.SetData(wrong_data) with self.assertRaisesRegex(Exception, "The buffer-size is not large enough: current buffer size: 2 | requested solution_step_index: 3"): coupling_data.SetData(correct_data, 2) with self.assertRaisesRegex(Exception, "accessing data from previous steps is only possible with historical nodal data!"): coupling_data_mp.SetData(correct_data, 2)
def test_without_initialization(self): settings = KM.Parameters("""{ "model_part_name" : "mp_4_test", "variable_name" : "DISPLACEMENT", "dimension" : 2 }""") coupling_data = CouplingInterfaceData(settings, self.model) # coupling_data.Initialize() # intentially commented to raise error with self.assertRaisesRegex(Exception, ' can onyl be called after initializing the CouplingInterfaceData!'): self.assertMultiLineEqual(str(coupling_data), coupling_interface_data_str) with self.assertRaisesRegex(Exception, ' can onyl be called after initializing the CouplingInterfaceData!'): coupling_data.PrintInfo() with self.assertRaisesRegex(Exception, ' can onyl be called after initializing the CouplingInterfaceData!'): coupling_data.GetModelPart() with self.assertRaisesRegex(Exception, ' can onyl be called after initializing the CouplingInterfaceData!'): coupling_data.IsDistributed() with self.assertRaisesRegex(Exception, ' can onyl be called after initializing the CouplingInterfaceData!'): coupling_data.Size() with self.assertRaisesRegex(Exception, ' can onyl be called after initializing the CouplingInterfaceData!'): coupling_data.GetBufferSize() with self.assertRaisesRegex(Exception, ' can onyl be called after initializing the CouplingInterfaceData!'): coupling_data.GetData() with self.assertRaisesRegex(Exception, ' can onyl be called after initializing the CouplingInterfaceData!'): coupling_data.SetData([])
class TestConvergenceCriteriaWrapper(KratosUnittest.TestCase): def setUp(self): self.model = KM.Model() self.model_part = self.model.CreateModelPart("default") self.model_part.AddNodalSolutionStepVariable(KM.PRESSURE) self.model_part.AddNodalSolutionStepVariable(KM.PARTITION_INDEX) self.dimension = 3 self.model_part.ProcessInfo[KM.DOMAIN_SIZE] = self.dimension self.my_pid = KM.DataCommunicator.GetDefault().Rank() self.num_nodes = self.my_pid % 5 + 3 # num_nodes in range (3 ... 7) if self.my_pid == 4: self.num_nodes = 0 # in order to emulate one partition not having local nodes for i in range(self.num_nodes): node = self.model_part.CreateNewNode( i, 0.1 * i, 0.0, 0.0 ) # this creates the same coords in different ranks, which does not matter for this test node.SetSolutionStepValue(KM.PARTITION_INDEX, self.my_pid) node.SetSolutionStepValue(KM.PRESSURE, uniform(-10, 50)) if KM.IsDistributedRun(): KratosMPI.ParallelFillCommunicator(self.model_part).Execute() data_settings = KM.Parameters("""{ "model_part_name" : "default", "variable_name" : "PRESSURE" }""") self.interface_data = CouplingInterfaceData(data_settings, self.model) self.interface_data.Initialize() self.dummy_solver_wrapper = DummySolverWrapper( {"data_4_testing": self.interface_data}) def test_wrapper(self): conv_acc_settings = KM.Parameters("""{ "type" : "relative_norm_previous_residual", "data_name" : "data_4_testing" }""") conv_crit_wrapper = ConvergenceCriteriaWrapper( conv_acc_settings, self.dummy_solver_wrapper) data_init = self.interface_data.GetData() conv_crit_mock = Mock() is_converged = True attrs = {'IsConverged.return_value': is_converged} conv_crit_mock.configure_mock(**attrs) conv_crit_wrapper.conv_crit = conv_crit_mock conv_crit_wrapper.InitializeSolutionStep() conv_crit_wrapper.InitializeNonLinearIteration() # setting new solution for computing the residual rand_data = [uniform(-10, 50) for _ in range(self.num_nodes)] self.interface_data.SetData(rand_data) exp_res = rand_data - data_init self.assertEqual(conv_crit_wrapper.IsConverged(), is_converged) self.assertEqual( conv_crit_mock.IsConverged.call_count, int(self.my_pid == 0)) # only one rank calls "IsConverged" global_exp_res = np.array( np.concatenate(KM.DataCommunicator.GetDefault().GathervDoubles( exp_res, 0))) global_rand_data_inp = np.array( np.concatenate(KM.DataCommunicator.GetDefault().GathervDoubles( rand_data, 0))) if self.my_pid == 0: # numpy arrays cannot be compared using the mock-functions, hence using the numpy functions np.testing.assert_array_equal( global_exp_res, conv_crit_mock.IsConverged.call_args[0][0]) np.testing.assert_array_equal( global_rand_data_inp, conv_crit_mock.IsConverged.call_args[0][1])
class TestConvergenceAcceleratorWrapper(KratosUnittest.TestCase): def setUp(self): self.model = KM.Model() self.model_part = self.model.CreateModelPart("default") self.model_part.AddNodalSolutionStepVariable(KM.PRESSURE) self.model_part.AddNodalSolutionStepVariable(KM.PARTITION_INDEX) self.dimension = 3 self.model_part.ProcessInfo[KM.DOMAIN_SIZE] = self.dimension self.my_pid = KM.DataCommunicator.GetDefault().Rank() self.num_nodes = self.my_pid % 5 + 3 # num_nodes in range (3 ... 7) if self.my_pid == 4: self.num_nodes = 0 # in order to emulate one partition not having local nodes for i in range(self.num_nodes): node = self.model_part.CreateNewNode( i, 0.1 * i, 0.0, 0.0 ) # this creates the same coords in different ranks, which does not matter for this test node.SetSolutionStepValue(KM.PARTITION_INDEX, self.my_pid) node.SetSolutionStepValue(KM.PRESSURE, uniform(-10, 50)) if KM.IsDistributedRun(): KratosMPI.ParallelFillCommunicator(self.model_part).Execute() data_settings = KM.Parameters("""{ "model_part_name" : "default", "variable_name" : "PRESSURE" }""") self.interface_data = CouplingInterfaceData(data_settings, self.model) self.interface_data.Initialize() self.dummy_solver_wrapper = DummySolverWrapper( {"data_4_testing": self.interface_data}) def test_accelerator_without_support_for_distributed_data(self): conv_acc_settings = KM.Parameters("""{ "type" : "constant_relaxation", "data_name" : "data_4_testing" }""") conv_acc_wrapper = ConvergenceAcceleratorWrapper( conv_acc_settings, self.dummy_solver_wrapper) exp_inp = self.interface_data.GetData() update_solution_return_value = [ uniform(-10, 50) for _ in range(self.num_nodes) ] global_update_solution_return_value = np.array( np.concatenate(KM.DataCommunicator.GetDefault().GathervDoubles( update_solution_return_value, 0))) conv_acc_mock = Mock() attrs = { 'SupportsDistributedData.return_value': False, 'UpdateSolution.return_value': global_update_solution_return_value } conv_acc_mock.configure_mock(**attrs) conv_acc_wrapper.conv_acc = conv_acc_mock conv_acc_wrapper.InitializeSolutionStep() self.assertEqual(conv_acc_mock.SupportsDistributedData.call_count, 1) self.assertEqual( conv_acc_wrapper.gather_scatter_required, self.interface_data.IsDistributed( )) # gather-scatter is only required in case of distributed data self.assertEqual(conv_acc_wrapper.executing_rank, self.my_pid == 0) conv_acc_wrapper.InitializeNonLinearIteration() # setting new solution for computing the residual rand_data = [uniform(-10, 50) for _ in range(self.num_nodes)] self.interface_data.SetData(rand_data) exp_res = rand_data - exp_inp conv_acc_wrapper.ComputeAndApplyUpdate() self.assertEqual( conv_acc_mock.UpdateSolution.call_count, int(self.my_pid == 0)) # only one rank calls "UpdateSolution" global_exp_res = np.array( np.concatenate(KM.DataCommunicator.GetDefault().GathervDoubles( exp_res, 0))) global_exp_inp = np.array( np.concatenate(KM.DataCommunicator.GetDefault().GathervDoubles( exp_inp, 0))) if self.my_pid == 0: # numpy arrays cannot be compared using the mock-functions, hence using the numpy functions np.testing.assert_array_equal( global_exp_res, conv_acc_mock.UpdateSolution.call_args[0][0]) np.testing.assert_array_equal( global_exp_inp, conv_acc_mock.UpdateSolution.call_args[0][1]) np.testing.assert_array_equal(exp_inp + update_solution_return_value, self.interface_data.GetData()) def test_accelerator_with_support_for_distributed_data(self): conv_acc_settings = KM.Parameters("""{ "type" : "constant_relaxation", "data_name" : "data_4_testing" }""") conv_acc_wrapper = ConvergenceAcceleratorWrapper( conv_acc_settings, self.dummy_solver_wrapper) exp_inp = self.interface_data.GetData() update_solution_return_value = [ uniform(-10, 50) for _ in range(self.num_nodes) ] conv_acc_mock = Mock() attrs = { 'SupportsDistributedData.return_value': True, 'UpdateSolution.return_value': update_solution_return_value } conv_acc_mock.configure_mock(**attrs) conv_acc_wrapper.conv_acc = conv_acc_mock conv_acc_wrapper.InitializeSolutionStep() self.assertEqual(conv_acc_mock.SupportsDistributedData.call_count, 1) self.assertFalse(conv_acc_wrapper.gather_scatter_required) self.assertTrue(conv_acc_wrapper.executing_rank) conv_acc_wrapper.InitializeNonLinearIteration() # setting new solution for computing the residual rand_data = [uniform(-10, 50) for _ in range(self.num_nodes)] self.interface_data.SetData(rand_data) exp_res = rand_data - exp_inp conv_acc_wrapper.ComputeAndApplyUpdate() self.assertEqual(conv_acc_mock.UpdateSolution.call_count, 1) # numpy arrays cannot be compared using the mock-functions, hence using the numpy functions np.testing.assert_array_equal( exp_res, conv_acc_mock.UpdateSolution.call_args[0][0]) np.testing.assert_array_equal( exp_inp, conv_acc_mock.UpdateSolution.call_args[0][1]) np.testing.assert_array_equal(exp_inp + update_solution_return_value, self.interface_data.GetData())