Пример #1
0
    def initialize(self, model_part_from, model_part_to):
        super().initialize()

        self.model = data_structure.Model()
        n = len(self.mappers)

        # initialize upstream transformers
        mp = model_part_from
        mp_names_from = [mp.name]
        self.model.create_model_part(mp.name, mp.x0, mp.y0, mp.z0, mp.id)
        for i in range(self.index):
            mp_names_from.append(f'mp_from_{i + 1}')
            self.mappers[i].initialize(self.model,
                                       mp_names_from[i],
                                       mp_names_from[i + 1],
                                       forward=True)

        # initialize downstream transformers
        mp = model_part_to
        mp_names_to = [mp.name]
        self.model.create_model_part(mp.name, mp.x0, mp.y0, mp.z0, mp.id)
        for i in range(n - 1 - self.index):
            mp_names_to.append(f'mp_to_{i + 1}')
            self.mappers[n - 1 - i].initialize(self.model,
                                               mp_names_to[i],
                                               mp_names_to[i + 1],
                                               forward=False)

        # initialize interpolator
        mp_from = self.model.get_model_part(mp_names_from[-1])
        mp_to = self.model.get_model_part(mp_names_to[-1])
        self.mappers[self.index].initialize(mp_from, mp_to)

        self.mp_names = mp_names_from + mp_names_to[::-1]
Пример #2
0
    def __init__(self, n_from, n_to):
        self.n_from = n_from
        self.n_to = n_to
        self.var = 'pressure'
        self.mp_name_from = 'wall_from'
        self.mp_name_to = 'wall_to'

        self.model = data_structure.Model()

        # Interface from
        dtheta = 2 * np.pi / self.n_from
        self.theta_from = np.linspace(0, 2 * np.pi - dtheta, self.n_from)
        self.x_from, self.y_from = self.get_cartesian(self.theta_from)
        self.v_from = self.fun(self.x_from, self.y_from)
        self.model.create_model_part(self.mp_name_from, self.x_from, self.y_from,
                                     np.zeros(self.n_from), np.arange(self.n_from))
        parameters = [{'model_part': self.mp_name_from, 'variables': [self.var]}]
        self.interface_from = data_structure.Interface(parameters, self.model)
        self.interface_from.set_interface_data(self.v_from)

        # Interface to
        dtheta = 2 * np.pi / self.n_to
        self.theta_to = np.linspace(0, 2 * np.pi - dtheta, self.n_to)
        self.x_to, self.y_to = self.get_cartesian(self.theta_to)
        self.model.create_model_part(self.mp_name_to, self.x_to, self.y_to,
                                     np.zeros(self.n_to), np.arange(self.n_to))
        parameters = [{'model_part': self.mp_name_to, 'variables': [self.var]}]
        self.interface_to = data_structure.Interface(parameters, self.model)
Пример #3
0
    def test_call_3d_var(self):
        var = 'displacement'
        mp_name_in = 'wall_in'
        mp_name_out = 'wall_out'

        n = 10
        x, y, z = np.random.rand(n), np.random.rand(n), np.random.rand(n)
        v_in = np.random.rand(n, 3)

        model = data_structure.Model()
        model.create_model_part(mp_name_in, x, y, z, np.arange(n))
        parameters_in = [{'model_part': mp_name_in, 'variables': [var]}]
        interface_in = data_structure.Interface(parameters_in, model)
        interface_in.set_variable_data(mp_name_in, var, v_in)

        mapper = create_instance(self.parameters)
        mapper.initialize(model, mp_name_in, mp_name_out, forward=True)

        parameters_out = [{'model_part': mp_name_out, 'variables': [var]}]
        interface_out = data_structure.Interface(parameters_out, model)
        mapper((interface_in, mp_name_in, var),
               (interface_out, mp_name_out, var))

        v_out = interface_out.get_variable_data(mp_name_out, var)
        np.testing.assert_array_equal(v_in[:, 0], v_out[:, 1])
        np.testing.assert_array_equal(v_in[:, 1], v_out[:, 2])
        np.testing.assert_array_equal(v_in[:, 2], v_out[:, 0])
Пример #4
0
    def test_convergence_criterion_relative_norm(self):
        m = 10
        dz = 2
        a0 = 10
        a1 = 1e-4
        a2 = 1e-6
        variable = 'area'
        model_part_name = 'wall'
        interface_settings = [{'model_part': model_part_name, 'variables': [variable]}]

        # create model and model_part
        model = data_structure.Model()
        ids = np.arange(0, m)
        x0 = np.zeros(m)
        y0 = np.zeros(m)
        z0 = np.arange(0, m * dz, dz)
        model.create_model_part(model_part_name, x0, y0, z0, ids)

        a0_array = np.full((m, 1), a0)
        a1_array = np.full((m, 1), a1)
        a2_array = np.full((m, 1), a2)

        # create interface
        interface = Interface(interface_settings, model)

        # create convergence criterion
        parameters = {'type': 'convergence_criteria.relative_norm',
                      'settings': {'tolerance': 1e-6, 'order': 2}}
        convergence_criterion_relative_norm = create_instance(parameters)
        convergence_criterion_relative_norm.initialize()

        # test convergence criterion
        for i in range(3):
            convergence_criterion_relative_norm.initialize_solution_step()
            is_satisfied = convergence_criterion_relative_norm.is_satisfied()
            self.assertFalse(is_satisfied)
            interface.set_variable_data(model_part_name, variable, a0_array)
            convergence_criterion_relative_norm.update(interface)
            is_satisfied = convergence_criterion_relative_norm.is_satisfied()
            self.assertFalse(is_satisfied)
            interface.set_variable_data(model_part_name, variable, a1_array)
            convergence_criterion_relative_norm.update(interface)
            is_satisfied = convergence_criterion_relative_norm.is_satisfied()
            self.assertFalse(is_satisfied)
            interface.set_variable_data(model_part_name, variable, a2_array)
            convergence_criterion_relative_norm.update(interface)
            is_satisfied = convergence_criterion_relative_norm.is_satisfied()
            self.assertTrue(is_satisfied)
            interface.set_variable_data(model_part_name, variable, a1_array)
            convergence_criterion_relative_norm.update(interface)
            is_satisfied = convergence_criterion_relative_norm.is_satisfied()
            self.assertFalse(is_satisfied)
            convergence_criterion_relative_norm.finalize_solution_step()
Пример #5
0
    def __init__(self, n_x_from, n_theta_from, n_x_to, n_theta_to, length):
        self.n_x_from = n_x_from
        self.n_theta_from = n_theta_from
        self.n_from = n_x_from * n_theta_from
        self.n_x_to = n_x_to
        self.n_theta_to = n_theta_to
        self.n_to = n_x_to * n_theta_to
        self.length = length
        self.var = 'pressure'
        self.mp_name_from = 'wall_from'
        self.mp_name_to = 'wall_to'
        self.model = data_structure.Model()

        self.model = data_structure.Model()

        # Interface from
        shape = (self.n_x_from, self.n_theta_from)
        dtheta = 2 * np.pi / self.n_theta_from
        theta_from = np.ones(shape) * np.linspace(0, 2 * np.pi - dtheta, self.n_theta_from).reshape(1, -1)

        self.x_from = np.ones(shape) * np.linspace(0, self.length, self.n_x_from).reshape(-1, 1)
        self.y_from, self.z_from = self.get_cartesian(theta_from)
        self.v_from = self.fun(self.x_from, self.y_from, self.z_from)
        self.model.create_model_part(self.mp_name_from, self.x_from.flatten(), self.y_from.flatten(),
                                     self.z_from.flatten(), np.arange(self.n_from))
        parameters = [{'model_part': self.mp_name_from, 'variables': [self.var]}]
        self.interface_from = data_structure.Interface(parameters, self.model)
        self.interface_from.set_interface_data(self.v_from.flatten())

        # Interface to
        shape = (self.n_x_to, self.n_theta_to)
        dtheta = 2 * np.pi / self.n_theta_to
        theta_to = np.ones(shape) * np.linspace(0, 2 * np.pi - dtheta, self.n_theta_to).reshape(1, -1)

        self.x_to = np.ones(shape) * np.linspace(0, self.length, self.n_x_to).reshape(-1, 1)
        self.y_to, self.z_to = self.get_cartesian(theta_to)
        self.model.create_model_part(self.mp_name_to, self.x_to.flatten(), self.y_to.flatten(),
                                     self.z_to.flatten(), np.arange(self.n_to))
        parameters = [{'model_part': self.mp_name_to, 'variables': [self.var]}]
        self.interface_to = data_structure.Interface(parameters, self.model)
Пример #6
0
    def test_predictor_linear(self):
        m = 10
        dz = 3
        a0 = 1
        p1 = 1
        a1 = 2
        p2 = 3
        variable = 'area'
        model_part_name = 'wall'
        interface_settings = [{
            'model_part': model_part_name,
            'variables': [variable]
        }]

        # create model and model_part
        model = data_structure.Model()
        ids = np.arange(0, m)
        x0 = np.zeros(m)
        y0 = np.zeros(m)
        z0 = np.arange(0, m * dz, dz)
        model.create_model_part(model_part_name, x0, y0, z0, ids)

        a0_array = np.full((m, 1), a0)

        # create interface
        interface = Interface(interface_settings, model)
        interface.set_variable_data(model_part_name, variable, a0_array)

        # create predictor
        parameters = {'type': 'predictors.linear'}
        predictor_linear = create_instance(parameters)
        predictor_linear.initialize(interface)

        # first prediction needs to be equal to initialized value
        predictor_linear.initialize_solution_step()
        prediction = predictor_linear.predict(interface)
        self.assertIsInstance(prediction, Interface)
        prediction_as_array = prediction.get_interface_data()
        for i in range(m):
            self.assertAlmostEqual(p1, prediction_as_array[i])
        interface_as_array = a1 * prediction_as_array
        interface.set_interface_data(interface_as_array)
        predictor_linear.update(interface)
        predictor_linear.finalize_solution_step()

        # second prediction needs to be linear
        predictor_linear.initialize_solution_step()
        prediction = predictor_linear.predict(interface)
        self.assertIsInstance(prediction, Interface)
        prediction_as_array = prediction.get_interface_data()
        for i in range(m):
            self.assertAlmostEqual(p2, prediction_as_array[i])
Пример #7
0
    def __init__(self, n_x_from, n_y_from, n_x_to, n_y_to):
        self.n_x_from = n_x_from
        self.n_y_from = n_y_from
        self.n_from = n_x_from * n_y_from
        self.n_x_to = n_x_to
        self.n_y_to = n_y_to
        self.n_to = n_x_to * n_y_to
        self.var = 'displacement'
        self.mp_name_from = 'wall_from'
        self.mp_name_to = 'wall_to'
        self.model = data_structure.Model()

        model = data_structure.Model()

        # ModelPart from
        shape = (self.n_x_from, self.n_y_from)
        self.x_from = np.ones(shape) * np.linspace(-1, 1, self.n_x_from).reshape(-1, 1)
        self.y_from = np.ones(shape) * np.linspace(-1, 1, self.n_y_from).reshape(1, -1)
        self.z_from = np.sinc(np.sqrt((10 * self.x_from) ** 2 + (self.y_from * 10) ** 2) / np.pi)
        self.v_from = self.fun(self.x_from, self.y_from, self.z_from)
        self.model.create_model_part(self.mp_name_from, self.x_from.flatten(), self.y_from.flatten(),
                                     self.z_from.flatten(), np.arange(self.n_from))
        parameters = [{'model_part': self.mp_name_from, 'variables': [self.var]}]
        self.interface_from = data_structure.Interface(parameters, self.model)
        tmp = np.hstack((self.v_from[0].reshape(-1, 1),
                         self.v_from[1].reshape(-1, 1),
                         self.v_from[2].reshape(-1, 1)))
        self.interface_from.set_variable_data(self.mp_name_from, self.var, tmp)

        # ModelPart to
        shape = (self.n_x_to, self.n_y_to)
        self.x_to = np.ones(shape) * np.linspace(-1, 1, self.n_x_to).reshape(-1, 1)
        self.y_to = np.ones(shape) * np.linspace(-1, 1, self.n_y_to).reshape(1, -1)
        self.z_to = np.sinc(np.sqrt((10 * self.x_to) ** 2 + (self.y_to * 10) ** 2) / np.pi)
        self.v_to = self.fun(self.x_to, self.y_to, self.z_to)
        self.model.create_model_part(self.mp_name_to, self.x_to.flatten(), self.y_to.flatten(),
                                     self.z_to.flatten(), np.arange(self.n_to))
        parameters = [{'model_part': self.mp_name_to, 'variables': [self.var]}]
        self.interface_to = data_structure.Interface(parameters, self.model)
Пример #8
0
    def test_convergence_criterion_and(self):
        m = 10
        dz = 2
        a0 = 1
        variable = 'area'
        model_part_name = 'wall'
        interface_settings = [{'model_part': model_part_name, 'variables': [variable]}]

        # create model and model_part
        model = data_structure.Model()
        ids = np.arange(0, m)
        x0 = np.zeros(m)
        y0 = np.zeros(m)
        z0 = np.arange(0, m * dz, dz)
        model.create_model_part(model_part_name, x0, y0, z0, ids)

        a0_array = np.full((m, 1), a0)

        # create interface
        interface = Interface(interface_settings, model)
        interface.set_variable_data(model_part_name, variable, a0_array)

        # read settings
        parameter_file_name = os.path.join(os.path.dirname(__file__), 'test_and.json')
        with open(parameter_file_name, 'r') as parameter_file:
            parameters = json.load(parameter_file)

        convergence_criterion_and = create_instance(parameters)
        convergence_criterion_and.initialize()
        for i in range(3):
            convergence_criterion_and.initialize_solution_step()
            is_satisfied = convergence_criterion_and.is_satisfied()
            self.assertFalse(is_satisfied)
            convergence_criterion_and.update(interface)
            is_satisfied = convergence_criterion_and.is_satisfied()
            self.assertFalse(is_satisfied)
            convergence_criterion_and.update(interface)
            is_satisfied = convergence_criterion_and.is_satisfied()
            self.assertFalse(is_satisfied)
            convergence_criterion_and.update(interface)
            is_satisfied = convergence_criterion_and.is_satisfied()
            self.assertFalse(is_satisfied)
            convergence_criterion_and.update(interface)
            is_satisfied = convergence_criterion_and.is_satisfied()
            self.assertTrue(is_satisfied)
            convergence_criterion_and.update(interface)
            is_satisfied = convergence_criterion_and.is_satisfied()
            self.assertTrue(is_satisfied)
            convergence_criterion_and.finalize_solution_step()
Пример #9
0
    def test_check_duplicate_points(self):
        self.parameters['settings']['directions'] = ['x', 'y', 'z']
        mapper = create_instance(self.parameters)

        model = data_structure.Model()
        coords = np.array([[0, 0, 0], [1, 0, 0]])
        mp_to = model.create_model_part('mp_to_1', *split(coords), np.arange(2))

        coords = np.vstack((coords, np.array([[1e-10, 0., 0.]])))
        mp_from = model.create_model_part('mp_from_1', *split(coords), np.arange(3))
        self.assertRaises(Warning, mapper.initialize, *(mp_from, mp_to))
        mapper.finalize()

        coords = np.vstack((coords, np.array([[1e-14, 0., 0.]])))
        mp_from = model.create_model_part('mp_from_2', *split(coords), np.arange(4))
        self.assertRaises(ValueError, mapper.initialize, *(mp_from, mp_to))
        mapper.finalize()
Пример #10
0
    def test_mapper_combined(self):
        parameter_file_name = os.path.join(os.path.dirname(__file__),
                                           'test_combined.json')
        with open(parameter_file_name, 'r') as parameter_file:
            parameters = json.load(parameter_file)

        # compare 3 mappers: nearest, combined_a, combined_b
        for var in ['pressure', 'displacement']:
            mp_name_from = 'wall_from'
            mp_name_to = 'wall_to'
            model = data_structure.Model()

            n = 100
            tmp = np.linspace(0, 1, n)
            x, y, z = tmp, tmp**1.1, tmp**1.2
            v_from = np.random.rand(n,
                                    data_structure.variables_dimensions[var])
            mp_from = model.create_model_part(mp_name_from, x, y, z,
                                              np.arange(n))
            mp_to = model.create_model_part(mp_name_to, np.flip(x), np.flip(y),
                                            np.flip(z), np.arange(n))

            parameters_from = [{
                'model_part': mp_name_from,
                'variables': [var]
            }]
            int_from = data_structure.Interface(parameters_from, model)
            int_from.set_variable_data(mp_name_from, var, v_from)
            parameters_to = [{'model_part': mp_name_to, 'variables': [var]}]
            int_to = data_structure.Interface(parameters_to, model)

            # create mappers, get output data
            data = []
            for mapper_name in [
                    'mapper_nearest', 'mapper_combined_a', 'mapper_combined_b'
            ]:
                mapper = create_instance(parameters[mapper_name])
                mapper.initialize(mp_from, mp_to)
                mapper((int_from, mp_name_from, var),
                       (int_to, mp_name_to, var))
                data.append(int_to.get_variable_data(mp_name_to, var))

            # check output data
            np.testing.assert_array_equal(data[0], data[1])
            np.testing.assert_array_equal(data[0], data[2])
Пример #11
0
    def test_initialize(self):
        mp_name_in = 'wall_in'
        mp_name_out = 'wall_out'

        # create model_part_in
        n_in = 10
        x_in = np.linspace(0, 2 * np.pi, n_in)
        y_in = 1. + 0.2 * np.sin(x_in)
        z_in = np.zeros(10)
        model = data_structure.Model()
        model.create_model_part(mp_name_in, x_in, y_in, z_in, np.arange(n_in))

        # create reference geometry for 3D model_part_out
        n_t = self.parameters['settings']['n_tangential']
        n_out_ref = n_in * n_t
        x_out_ref = np.zeros(n_out_ref)
        y_out_ref = np.zeros(n_out_ref)
        z_out_ref = np.zeros(n_out_ref)

        for i_t in range(n_t):
            for i_from in range(n_in):
                start = i_t * n_in
                end = (i_t + 1) * n_in
                theta = i_t * 2 * np.pi / n_t
                x_out_ref[start:end] = x_in
                y_out_ref[start:end] = np.cos(theta) * y_in
                z_out_ref[start:end] = np.sin(theta) * y_in

        # initialize mapper to get model_part_out
        mapper = create_instance(self.parameters)
        mapper.initialize(model, mp_name_in, mp_name_out, forward=False)

        # get mapped geometry from 3D model_part_out
        mp_out = model.get_model_part(mp_name_out)
        n_out = mp_out.size
        x_out = mp_out.x0
        y_out = mp_out.y0
        z_out = mp_out.z0

        # compare mapped and reference geometries
        self.assertEqual(n_out, n_out_ref)
        np.testing.assert_array_equal(x_out, x_out_ref)
        np.testing.assert_array_equal(y_out, y_out_ref)
        np.testing.assert_array_equal(z_out, z_out_ref)
Пример #12
0
    def __init__(self, parameters):
        super().__init__()
        self.settings = parameters['settings']
        self.model = data_structure.Model()
        dx = lx / (nx - 1)
        dy = ly / (ny - 1)
        perturb_factor = 0.0
        x = np.linspace(0, lx, nx) + np.random.rand(nx) * dx * perturb_factor
        y = np.linspace(0, ly, ny) + np.random.rand(ny) * dy * perturb_factor

        xx, yy = np.meshgrid(x, y)
        x0_in = xx.ravel()
        y0_in = yy.ravel()

        x0_out = xx.ravel()
        y0_out = yy.ravel()

        z0_in = np.zeros_like(x0_in)
        z0_out = np.zeros_like(x0_out)

        node_ids_in = np.arange(0, nx * ny)
        node_ids_out = np.arange(0, nx * ny)

        self.mp_name_in_list = []
        for interface_settings in self.settings['interface_input']:
            self.model.create_model_part(interface_settings['model_part'],
                                         x0_in, y0_in, z0_in, node_ids_in)
            self.mp_name_in_list.append(interface_settings['model_part'])
        self.mp_name_out_list = []
        for interface_settings in self.settings['interface_output']:
            self.model.create_model_part(interface_settings['model_part'],
                                         x0_out, y0_out, z0_out, node_ids_out)
            self.mp_name_out_list.append(interface_settings['model_part'])

        # # Interfaces
        self.interface_input = Interface(self.settings["interface_input"],
                                         self.model)
        self.interface_output = Interface(self.settings["interface_output"],
                                          self.model)

        # run time
        self.run_time = 0.0
Пример #13
0
    def __init__(self, n_theta_from, n_phi_from, n_theta_to, n_phi_to):
        self.n_theta_from = n_theta_from
        self.n_phi_from = n_phi_from
        self.n_from = n_theta_from * n_phi_from
        self.n_theta_to = n_theta_to
        self.n_phi_to = n_phi_to  # for bounding box: not too far from n_phi_from!
        self.n_to = n_theta_to * n_phi_to
        self.var = 'pressure'
        self.mp_name_from = 'wall_from'
        self.mp_name_to = 'wall_to'
        self.model = data_structure.Model()

        # Interface from
        shape = (self.n_theta_from, self.n_phi_from)
        dtheta = 2 * np.pi / self.n_theta_from
        dphi = np.pi / (self.n_phi_from - 1)
        theta = np.ones(shape) * np.linspace(0, 2 * np.pi - dtheta, self.n_theta_from).reshape(-1, 1)
        phi = np.ones(shape) * np.linspace(dphi, np.pi - dphi, self.n_phi_from).reshape(1, -1)

        self.x_from, self.y_from, self.z_from = self.get_cartesian(theta, phi)
        self.v_from = self.fun(self.x_from, self.y_from, self.z_from)
        self.model.create_model_part(self.mp_name_from, self.x_from.flatten(), self.y_from.flatten(),
                                     self.z_from.flatten(), np.arange(self.n_from))
        parameters = [{'model_part': self.mp_name_from, 'variables': [self.var]}]
        self.interface_from = data_structure.Interface(parameters, self.model)
        self.interface_from.set_interface_data(self.v_from.flatten())

        # Interface to
        shape = (self.n_theta_to, self.n_phi_to)
        dtheta = 2 * np.pi / self.n_theta_to
        dphi = np.pi / (self.n_phi_to - 1)
        theta = np.ones(shape) * np.linspace(0, 2 * np.pi - dtheta, self.n_theta_to).reshape(-1, 1)
        phi = np.ones(shape) * np.linspace(dphi, np.pi - dphi, self.n_phi_to).reshape(1, -1)

        self.x_to, self.y_to, self.z_to = self.get_cartesian(theta, phi)
        self.model.create_model_part(self.mp_name_to, self.x_to.flatten(), self.y_to.flatten(),
                                     self.z_to.flatten(), np.arange(self.n_to))
        parameters = [{'model_part': self.mp_name_to, 'variables': [self.var]}]
        self.interface_to = data_structure.Interface(parameters, self.model)
Пример #14
0
    def __init__(self, n_from, n_to):
        self.n_from = n_from
        self.n_to = n_to
        self.var = 'pressure'
        self.mp_name_from = 'wall_from'
        self.mp_name_to = 'wall_to'

        self.model = data_structure.Model()

        # Interface from
        self.z_from = np.linspace(0, 10, self.n_from) ** .5
        self.v_from = self.fun(self.z_from)
        self.model.create_model_part(self.mp_name_from, np.zeros(self.n_from),
                                     np.zeros(self.n_from), self.z_from, np.arange(self.n_from))
        parameters = [{'model_part': self.mp_name_from, 'variables': [self.var]}]
        self.interface_from = data_structure.Interface(parameters, self.model)
        self.interface_from.set_interface_data(self.v_from)

        # Interface to
        self.z_to = np.linspace(0, 10, self.n_to) ** .5
        self.model.create_model_part(self.mp_name_to, np.zeros(self.n_to),
                                     np.zeros(self.n_to), self.z_to, np.arange(self.n_to))
        parameters = [{'model_part': self.mp_name_to, 'variables': [self.var]}]
        self.interface_to = data_structure.Interface(parameters, self.model)
Пример #15
0
    def test_initialize(self):
        mp_name_in = 'wall_in'
        mp_name_out_f = 'wall_out_f'
        mp_name_out_b = 'wall_out_b'

        n = 10
        x, y, z = np.random.rand(n), np.random.rand(n), np.random.rand(n)

        model = data_structure.Model()
        model.create_model_part(mp_name_in, x, y, z, np.arange(n))

        # model_part_from given
        mapper = create_instance(self.parameters)
        mapper.initialize(model, mp_name_in, mp_name_out_f, forward=True)
        mp_out = model.get_model_part(mp_name_out_f)
        coords_out = np.column_stack((mp_out.x0, mp_out.y0, mp_out.z0))
        np.testing.assert_array_equal(coords_out, np.column_stack((z, x, y)))

        # model_part_to given
        mapper = create_instance(self.parameters)
        mapper.initialize(model, mp_name_in, mp_name_out_b, forward=False)
        mp_out = model.get_model_part(mp_name_out_b)
        coords_out = np.column_stack((mp_out.x0, mp_out.y0, mp_out.z0))
        np.testing.assert_array_equal(coords_out, np.column_stack((y, z, x)))
Пример #16
0
    def test_predictor(self):
        m = 10
        dz = 3
        a0 = 1
        a1 = 2
        a2 = 3
        a3 = 4
        a4 = 5
        variable = 'area'
        model_part_name = 'wall'
        interface_settings = [{
            'model_part': model_part_name,
            'variables': [variable]
        }]

        # create model and model_part
        model = data_structure.Model()
        ids = np.arange(0, m)
        x0 = np.zeros(m)
        y0 = np.zeros(m)
        z0 = np.arange(0, m * dz, dz)
        model.create_model_part(model_part_name, x0, y0, z0, ids)

        a0_array = np.full((m, 1), a0)

        # create interface
        interface = Interface(interface_settings, model)
        interface.set_variable_data(model_part_name, variable, a0_array)
        interface_as_array = interface.get_interface_data()

        # create predictor
        parameters = {'type': 'predictors.cubic'}
        predictor_cubic = create_instance(parameters)
        predictor_cubic.initialize(interface)

        # a linear relation should be predicted in the same way by linear, quadratic and cubic predictors
        predictor_cubic.initialize_solution_step()
        interface.set_interface_data(a1 * interface_as_array)
        predictor_cubic.update(interface)
        predictor_cubic.finalize_solution_step()
        predictor_cubic.initialize_solution_step()
        interface.set_interface_data(a2 * interface_as_array)
        predictor_cubic.update(interface)
        predictor_cubic.finalize_solution_step()
        predictor_cubic.initialize_solution_step()
        interface.set_interface_data(a3 * interface_as_array)
        predictor_cubic.update(interface)
        predictor_cubic.finalize_solution_step()

        predictor_cubic.initialize_solution_step()
        prediction_linear = predictor_cubic.linear(
            interface).get_interface_data()
        prediction_quadratic = predictor_cubic.quadratic(
            interface).get_interface_data()
        prediction_cubic = predictor_cubic.cubic(
            interface).get_interface_data()
        for i in range(m):
            self.assertAlmostEqual(a4, prediction_linear[i])
            self.assertAlmostEqual(a4, prediction_quadratic[i])
            self.assertAlmostEqual(a4, prediction_cubic[i])

        # rror if no update
        with self.assertRaises(Exception):
            predictor_cubic.initialize_solution_step()
            predictor_cubic.finalize_solution_step()

        # error if updated twice
        with self.assertRaises(Exception):
            predictor_cubic.initialize_solution_step()
            _ = predictor_cubic.predict(interface)
            _ = predictor_cubic.predict(interface)
            predictor_cubic.finalize_solution_step()

        # error if prediction after update
        with self.assertRaises(Exception):
            predictor_cubic.initialize_solution_step()
            _ = predictor_cubic.update(interface)
            _ = predictor_cubic.predict(interface)
            predictor_cubic.finalize_solution_step()
Пример #17
0
    def __init__(self, parameters):
        super().__init__()

        # settings
        self.settings = parameters['settings']
        self.working_directory = self.settings['working_directory']
        self.env = get_solver_env(__name__, self.working_directory)
        # adapted application from openfoam ('coconut_<application name>')
        self.application = self.settings['application']
        self.delta_t = self.settings['delta_t']
        self.time_precision = self.settings['time_precision']
        self.start_time = self.settings['timestep_start'] * self.delta_t
        self.timestep = self.physical_time = self.iteration = self.prev_timestamp = self.cur_timestamp = None
        self.openfoam_process = None
        self.write_interval = self.write_precision = None
        # boundary_names is the set of boundaries in OpenFoam used for coupling
        self.boundary_names = self.settings['boundary_names']
        self.version = '4.1'

        # set on True to save copy of input and output files in every iteration
        self.debug = False

        # check interface names in 'interface_input' and 'interface_output' with boundary names provided in
        # boundary_names
        self.check_interfaces()

        # check that the correct modules have been loaded
        self.check_software()

        # remove possible CoCoNuT-message from previous interrupt
        self.remove_all_messages()

        # obtain number of cores from self.working_directory/system/decomposeParDict
        self.cores = 1
        if self.settings['parallel']:
            file_name = os.path.join(self.working_directory,
                                     'system/decomposeParDict')
            if not os.path.isfile(file_name):
                raise RuntimeError(
                    f'In the parameters:\n{self.settings}\n key "parallel" is set to {True} but {file_name} '
                    f'does not exist')
            else:
                with open(file_name, 'r') as file:
                    decomposedict_string = file.read()
                self.cores = of_io.get_int(input_string=decomposedict_string,
                                           keyword='numberOfSubdomains')

        # modify controlDict file to add pressure and wall shear stress functionObjects for all the boundaries in
        # self.settings["boundary_names"]
        self.read_modify_controldict()

        # creating Model
        self.model = data_structure.Model()

        # writeCellcentres writes cellcentres in internal field and face centres in boundaryField
        check_call(f'writeCellCentres -time 0 &> log.writeCellCentres;',
                   cwd=self.working_directory,
                   shell=True,
                   env=self.env)
        boundary_filename = os.path.join(self.working_directory,
                                         'constant/polyMesh/boundary')

        for boundary in self.boundary_names:
            with open(boundary_filename, 'r') as boundary_file:
                boundary_file_string = boundary_file.read()
            boundary_dict = of_io.get_dict(input_string=boundary_file_string,
                                           keyword=boundary)
            # get point ids and coordinates for all the faces in the boundary
            node_ids, node_coords = of_io.get_boundary_points(
                case_directory=self.working_directory,
                time_folder='0',
                boundary_name=boundary)
            nfaces = of_io.get_int(input_string=boundary_dict,
                                   keyword='nFaces')
            start_face = of_io.get_int(input_string=boundary_dict,
                                       keyword='startFace')

            # create input model part
            self.model.create_model_part(f'{boundary}_input',
                                         node_coords[:, 0], node_coords[:, 1],
                                         node_coords[:, 2], node_ids)

            filename_x = os.path.join(self.working_directory, '0/ccx')
            filename_y = os.path.join(self.working_directory, '0/ccy')
            filename_z = os.path.join(self.working_directory, '0/ccz')

            x0 = of_io.get_boundary_field(file_name=filename_x,
                                          boundary_name=boundary,
                                          size=nfaces,
                                          is_scalar=True)
            y0 = of_io.get_boundary_field(file_name=filename_y,
                                          boundary_name=boundary,
                                          size=nfaces,
                                          is_scalar=True)
            z0 = of_io.get_boundary_field(file_name=filename_z,
                                          boundary_name=boundary,
                                          size=nfaces,
                                          is_scalar=True)
            ids = np.arange(0, nfaces)

            # create output model part
            mp_output = self.model.create_model_part(f'{boundary}_output', x0,
                                                     y0, z0, ids)
            mp_output.start_face = start_face
            mp_output.nfaces = nfaces

        # create interfaces
        self.interface_input = Interface(self.settings['interface_input'],
                                         self.model)
        self.interface_output = Interface(self.settings['interface_output'],
                                          self.model)

        # time
        self.init_time = self.init_time
        self.run_time = 0.0

        # compile openfoam adapted solver
        solver_dir = os.path.join(os.path.dirname(__file__), self.application)
        try:
            check_call(f'wmake {solver_dir} &> log.wmake',
                       cwd=self.working_directory,
                       shell=True,
                       env=self.env)
        except subprocess.CalledProcessError:
            raise RuntimeError(
                f'Compilation of {self.application} failed. Check {os.path.join(self.working_directory, "log.wmake")}'
            )

        self.residual_variables = self.settings.get('residual_variables', None)
        self.res_filepath = os.path.join(self.working_directory,
                                         'residuals.csv')

        if self.residual_variables is not None:
            self.write_residuals_fileheader()
Пример #18
0
    def test_coupled_solver_aitken(self):
        m = 10
        dz = 2
        r = 0.1
        x = 10
        xt0 = 10.5
        xt1 = 10.2
        xt2 = 10.1
        xt3 = 10.7
        xt4 = 9.9
        variable = 'area'  # TODO: does not match JSON setings
        model_part_name = 'wall'
        interface_settings = [{
            'model_part': model_part_name,
            'variables': [variable]
        }]

        # create model and model_part
        model = data_structure.Model()
        ids = np.arange(0, m)
        x0 = np.zeros(m)
        y0 = np.zeros(m)
        z0 = np.arange(0, m * dz, dz)
        model.create_model_part(model_part_name, x0, y0, z0, ids)

        # create interface
        interface = Interface(interface_settings, model)

        omega_max = self.parameters['settings']['omega_max']

        with cd(self.working_dir):
            coupled_solver = create_instance(self.parameters)
            coupled_solver.initialize()
        coupled_solver.initialize_solution_step()

        interface_r = interface.copy()
        interface_r.set_interface_data(np.full(m, r))
        interface_x = interface.copy()
        interface_x.set_interface_data(x * np.ones(m))
        interface_xt0 = interface.copy()
        interface_xt0.set_interface_data(xt0 * np.ones(m))
        interface_xt1 = interface.copy()
        interface_xt1.set_interface_data(xt1 * np.ones(m))
        interface_xt2 = interface.copy()
        interface_xt2.set_interface_data(xt2 * np.ones(m))
        interface_xt3 = interface.copy()
        interface_xt3.set_interface_data(xt3 * np.ones(m))
        interface_xt4 = interface.copy()
        interface_xt4.set_interface_data(xt4 * np.ones(m))

        # test value of self.added
        is_ready = coupled_solver.is_ready()
        self.assertFalse(is_ready)

        # test update()
        coupled_solver.update(interface_x, interface_xt0)
        is_ready = coupled_solver.is_ready()
        self.assertTrue(is_ready)
        omega = coupled_solver.omega
        self.assertEqual(omega, omega_max)
        coupled_solver.update(interface_x, interface_xt1)
        is_ready = coupled_solver.is_ready()
        self.assertTrue(is_ready)
        omega = coupled_solver.omega
        self.assertAlmostEqual(omega, 5 / 3 * omega_max, 10)
        coupled_solver.update(interface_x, interface_xt2)
        omega = coupled_solver.omega
        self.assertAlmostEqual(omega, 10 / 3 * omega_max, 10)

        # test predict()
        interface_dx = coupled_solver.predict(interface_r)
        omega = interface_dx.get_interface_data()[0] / r
        self.assertEqual(omega, coupled_solver.omega)
        coupled_solver.predict(interface_r)
        omega = coupled_solver.omega
        self.assertAlmostEqual(omega, 10 / 3 * omega_max, 10)

        # new solution step
        coupled_solver.finalize_solution_step()
        coupled_solver.initialize_solution_step()

        # test value of self.added
        is_ready = coupled_solver.is_ready()
        self.assertFalse(is_ready)

        # test update()
        coupled_solver.update(interface_x, interface_xt0)
        is_ready = coupled_solver.is_ready()
        self.assertTrue(is_ready)
        omega = coupled_solver.omega
        self.assertEqual(omega, omega_max)
        coupled_solver.update(interface_x, interface_xt3)
        omega = coupled_solver.omega
        self.assertAlmostEqual(omega, -5 / 2 * omega_max, 10)

        # new solution step
        coupled_solver.finalize_solution_step()
        coupled_solver.initialize_solution_step()

        # test update()
        coupled_solver.update(interface_x, interface_xt0)
        omega = coupled_solver.omega
        self.assertEqual(omega, -omega_max)
        coupled_solver.update(interface_x, interface_xt4)
        omega = coupled_solver.omega
        self.assertAlmostEqual(omega, -5 / 6 * omega_max, 10)

        # new solution step
        coupled_solver.finalize_solution_step()
        coupled_solver.initialize_solution_step()

        # test update()
        coupled_solver.update(interface_x, interface_xt0)
        omega = coupled_solver.omega
        self.assertAlmostEqual(omega, -5 / 6 * omega_max, 10)
Пример #19
0
    def __init__(self, parameters):
        super().__init__()

        self.settings = parameters["settings"]
        self.working_directory = join(os.getcwd(),
                                      self.settings["working_directory"])
        self.env = tools.get_solver_env(__name__, self.working_directory)
        delta_t = self.settings["delta_t"]
        timestep_start = self.settings["timestep_start"]
        dimensions = self.settings["dimensions"]
        self.timestep = None

        input_file_name = join(self.working_directory,
                               self.settings["input_file"])

        with open(input_file_name, "r") as parameter_file:
            kratos_parameters = json.load(parameter_file)

        kratos_parameters["problem_data"]["start_time"] = timestep_start
        kratos_parameters["problem_data"]["time_step"] = delta_t
        kratos_parameters["problem_data"]["domain_size"] = dimensions
        kratos_parameters["problem_data"]["end_time"] = 1e15

        interface_sub_model_parts_list = self.settings[
            "kratos_interface_sub_model_parts_list"]

        kratos_parameters[
            "interface_sub_model_parts_list"] = interface_sub_model_parts_list

        with open(os.path.join(self.working_directory, input_file_name),
                  'w') as f:
            json.dump(kratos_parameters, f, indent=4)

        self.check_interface()

        self.model = data_structure.Model()

        dir_path = os.path.dirname(os.path.realpath(__file__))
        run_script_file = os.path.join(dir_path, 'run_kratos_structural_60.py')

        self.kratos_process = Popen(
            f'python3 {run_script_file} {input_file_name} &> log',
            shell=True,
            cwd=self.working_directory,
            env=self.env)

        self.wait_message('start_ready')

        for mp_name in interface_sub_model_parts_list:
            file_path = os.path.join(self.working_directory,
                                     f'{mp_name}_nodes.csv')
            node_data = pd.read_csv(file_path, skipinitialspace=True)
            node_ids = np.array(node_data.node_id)
            x0 = np.array(node_data.x0)
            y0 = np.array(node_data.y0)
            z0 = np.array(node_data.z0)
            self.model.create_model_part(f'{mp_name}_input', x0, y0, z0,
                                         node_ids)
            self.model.create_model_part(f'{mp_name}_output', x0, y0, z0,
                                         node_ids)

        # # Interfaces
        self.interface_input = Interface(self.settings["interface_input"],
                                         self.model)
        self.interface_output = Interface(self.settings["interface_output"],
                                          self.model)

        # time
        self.init_time = self.init_time
        self.run_time = 0.0

        self.residual_variables = self.settings.get('residual_variables', None)
        self.res_filepath = os.path.join(self.working_directory,
                                         'residuals.csv')

        if self.residual_variables is not None:
            self.write_residuals_fileheader()
Пример #20
0
    def test_call(self):
        def fun_s(x):
            return 1. + 2.5 * x

        def fun_v(x, y, z):
            theta = np.arctan2(z, y)
            v_x = 1. + 2.5 * x
            v_y = v_x * 0.5 * np.cos(theta)
            v_z = v_x * 0.5 * np.sin(theta)
            return np.column_stack((v_x, v_y, v_z))

        mp_name_from = 'wall_from'
        mp_name_to = 'wall_to'
        var_s = 'pressure'
        var_v = 'displacement'

        n_in = 10
        n_to = n_in * 2
        tmp = np.linspace(0, 5, n_in)
        r_tmp = (1. + 0.2 * np.sin(2 * np.pi / 5 * tmp))

        # create model_part_to (3D)
        x_to = np.zeros(n_to)
        y_to = np.zeros(n_to)
        z_to = np.zeros(n_to)

        i = 0
        for k in range(n_in):
            for p in range(2):
                x_to[i] = tmp[k]
                y_to[i] = r_tmp[k] * np.cos(np.radians(2.5))
                z_to[i] = r_tmp[k] * ((-1)**p) * np.sin(np.radians(2.5))
                i += 1
            k += 1

        model = data_structure.Model()
        model.create_model_part(mp_name_to, x_to, y_to, z_to, np.arange(n_to))

        # initialize mapper to get model_part_from (2D)
        mapper = create_instance(self.parameters)
        mapper.initialize(model, mp_name_to, mp_name_from, forward=False)
        parameters_from = [{
            'model_part': mp_name_from,
            'variables': [var_s, var_v]
        }]
        interface_from = data_structure.Interface(parameters_from, model)
        mp_from = interface_from.get_model_part(mp_name_from)
        x_from, y_from, z_from = mp_from.x0, mp_from.y0, mp_from.z0

        v_s_from = fun_s(x_from).reshape(-1, 1)
        v_v_from = fun_v(x_from, y_from, z_from)
        interface_from.set_variable_data(mp_name_from, var_s, v_s_from)
        interface_from.set_variable_data(mp_name_from, var_v, v_v_from)

        parameters_to = [{
            'model_part': mp_name_to,
            'variables': [var_s, var_v]
        }]
        interface_to = data_structure.Interface(parameters_to, model)

        # check mapped values for 1D variable
        mapper((interface_from, mp_name_from, var_s),
               (interface_to, mp_name_to, var_s))
        v_s_to_ref = fun_s(x_to).reshape(-1, 1)
        v_s_to = interface_to.get_variable_data(mp_name_to, var_s)
        np.testing.assert_allclose(v_s_to, v_s_to_ref, rtol=1e-14)

        # check mapped values for 3D variable
        mapper((interface_from, mp_name_from, var_v),
               (interface_to, mp_name_to, var_v))
        v_v_to_ref = fun_v(x_to, y_to, z_to)
        v_v_to = interface_to.get_variable_data(mp_name_to, var_v)
        np.testing.assert_allclose(v_v_to, v_v_to_ref, rtol=1e-14)

        # extra: visualization
        if self.gui:
            v_s_from, v_s_to = v_s_from.flatten(), v_s_to.flatten()
            c_from = cm.jet((v_s_from - v_s_from.min()) /
                            (v_s_from.max() - v_s_from.min()))
            c_to = cm.jet(
                (v_s_to - v_s_from.min()) / (v_s_from.max() - v_s_from.min()))

            fig = plt.figure()

            ax_s = fig.add_subplot(121, projection='3d')
            ax_s.set_title('check geometry and scalar mapping')
            ax_s.scatter(x_from,
                         y_from,
                         z_from,
                         s=50,
                         c=c_from,
                         depthshade=True,
                         marker='s')
            ax_s.scatter(x_to, y_to, z_to, s=20, c=c_to, depthshade=True)

            ax_v = fig.add_subplot(122, projection='3d')
            ax_v.set_title('check vector mapping')
            ax_v.quiver(x_from,
                        y_from,
                        z_from,
                        v_v_from[:, 0],
                        v_v_from[:, 1],
                        v_v_from[:, 2],
                        pivot='tail',
                        arrow_length_ratio=0.05,
                        normalize=False,
                        length=0.05,
                        colors='r',
                        linewidth=3)
            ax_v.quiver(x_to,
                        y_to,
                        z_to,
                        v_v_to[:, 0],
                        v_v_to[:, 1],
                        v_v_to[:, 2],
                        pivot='tail',
                        arrow_length_ratio=0.05,
                        normalize=False,
                        length=0.05)

            for ax in [ax_s, ax_v]:
                ax.set_xlabel('x')
                ax.set_ylabel('y')
                ax.set_zlabel('z')

            plt.get_current_fig_manager().window.showMaximized()
            plt.xlim(0, 6)
            plt.ylim(0.7, 1.5)
            plt.show()
            plt.close()
Пример #21
0
    def test_initialize(self):
        mp_name_in = 'wall_in'
        mp_name_out = 'wall_out'

        # create geometry for 3D model_part_in
        n_in = 10
        n_from = n_in * 2
        x = np.linspace(0, 0.1, n_in)
        r = 1 + 0.07 * np.sin(x * 600)

        x_in = np.zeros(n_from)
        y_in = np.zeros(n_from)
        z_in = np.zeros(n_from)

        i = 0
        for k in range(n_in):
            for p in range(2):
                x_in[i] = x[k]
                y_in[i] = r[k] * np.cos(np.radians(2.5))
                z_in[i] = r[k] * ((-1)**p) * np.sin(np.radians(2.5))
                i += 1
            k += 1

        model = data_structure.Model()
        model.create_model_part(mp_name_in, x_in, y_in, z_in,
                                np.arange(n_from))

        # create reference geometry for 2D model_part_out
        n_out_ref = n_in
        x_out_ref = np.zeros(n_out_ref)
        y_out_ref = np.zeros(n_out_ref)
        z_out_ref = np.zeros(n_out_ref)

        i_to = 0

        for i_from in range(n_from):
            r = y_in[i_from]
            z = z_in[i_from]
            if z_in[i_from] > 0:
                x_out_ref[i_to] = x_in[i_from]
                y_out_ref[i_to] = np.cos(np.radians(2.5)) * r + np.sin(
                    np.radians(2.5)) * z
                z_out_ref[i_to] = 0
                i_to += 1
            i_from += 1

        # initialize mapper to get model_part_out
        mapper = create_instance(self.parameters)
        mapper.initialize(model, mp_name_in, mp_name_out, forward=False)

        # get mapped geometry from 2D model_part_out
        mp_out = model.get_model_part(mp_name_out)
        n_out = mp_out.size
        x_out = mp_out.x0
        y_out = mp_out.y0
        z_out = mp_out.z0

        # print("z_out")
        # print(z_out)
        # print("z_out_ref")
        # print(z_out_ref)

        # compare mapped and reference geometries
        self.assertEqual(n_out, n_out_ref)
        np.testing.assert_array_equal(x_out, x_out_ref)
        np.testing.assert_array_equal(y_out, y_out_ref)
        np.testing.assert_array_equal(z_out, z_out_ref)
Пример #22
0
    def test_model_ls(self):
        m = 5
        dz = 2
        x = 10
        variable = 'area'
        model_part_name = 'wall'
        interface_settings = [{
            'model_part': model_part_name,
            'variables': [variable]
        }]

        # create model and model_part
        model = data_structure.Model()
        ids = np.arange(0, m)
        x0 = np.zeros(m)
        y0 = np.zeros(m)
        z0 = np.arange(0, m * dz, dz)
        model.create_model_part(model_part_name, x0, y0, z0, ids)

        x_array = np.full((m, 1), x)

        # create interface
        interface = Interface(interface_settings, model)
        interface.set_variable_data(model_part_name, variable, x_array)

        # read settings
        parameter_file_name = os.path.join(os.path.dirname(__file__),
                                           'test_ls.json')
        with open(parameter_file_name, 'r') as parameter_file:
            settings = json.load(parameter_file)

        # with reuse

        min_significant = settings["setting1"]["settings"]["min_significant"]
        q = settings["setting1"]["settings"]["q"]

        ls = create_instance(settings["setting1"])
        ls.size_in = ls.size_out = m
        ls.out = interface.copy()
        ls.initialize()
        ls.initialize_solution_step()

        r = interface.copy()
        xt = interface.copy()
        r1 = np.array([1, 2, 3, 4, 5])
        xt1 = np.array([5, 4, 3, 2, 1])
        r2 = np.array([8, 5, 5, 5, 8])
        xt2 = np.array([1, 4, 8, 5, 5])
        r3 = np.array([7, 5, 6, 4, 3])
        r4 = np.array([1, 1, 7, 4, 0])
        xt4 = np.array([9, 7, 5, 8, 4])
        r5 = np.array([9, 5, 10, 6, 4])
        xt5 = np.array([5, 1, 2, 3, 9])
        r6 = np.array([7, 8, 1, 2, 3])
        xt6 = np.array([7, 5, 5, 1, 2])
        r7 = np.array([1, 2, 5, 1, 2])
        xt7 = np.array([4, 2, 1, 1, 2])
        r8 = np.array([6, 3, 9, 0, 3])
        xt8 = np.array([3, 1, 2, 3, 9])
        r9 = np.array([1, 3, 5, 0, 8])
        xt9 = np.array([8, 1, 5, 3, 9])
        r10 = np.array([1, 3, -5, 8, 8])
        xt10 = np.array([8, -9, 5, 3, -9])
        r11 = r1
        xt11 = xt1
        r12 = r2
        xt12 = xt2
        r13 = r10 * 0.95
        xt13 = xt10

        is_ready = ls.is_ready()
        self.assertFalse(is_ready)

        r.set_interface_data(r1)
        xt.set_interface_data(xt1)
        ls.add(r, xt)

        self.assertTrue(ls.added)
        np.testing.assert_array_equal(r1[:, np.newaxis], ls.rref)
        np.testing.assert_array_equal(xt1[:, np.newaxis], ls.xtref)
        is_ready = ls.is_ready()
        self.assertFalse(is_ready)

        r.set_interface_data(r2)
        xt.set_interface_data(xt2)
        ls.add(r, xt)

        self.assertTrue(ls.added)
        np.testing.assert_array_equal(r2[:, np.newaxis], ls.rref)
        np.testing.assert_array_equal(xt2[:, np.newaxis], ls.xtref)
        v = np.hstack((ls.vcurr, np.hstack(ls.vprev)))
        w = np.hstack((ls.wcurr, np.hstack(ls.wprev)))
        self.assertEqual(v.shape, (m, 1))
        np.testing.assert_array_equal(v[:, 0], r2 - r1)
        self.assertEqual(w.shape, (m, 1))
        np.testing.assert_array_equal(w[:, 0], xt2 - xt1)
        is_ready = ls.is_ready()
        self.assertTrue(is_ready)
        r.set_interface_data(r3)
        dxt = ls.predict(-1 * r)
        dxt_sol = [
            4.94444444444445, 0, -6.18055555555556, -3.70833333333333,
            -4.944444444444452
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)

        r.set_interface_data(r4)
        xt.set_interface_data(xt4)
        ls.add(r, xt)

        v = np.hstack((ls.vcurr, np.hstack(ls.vprev)))
        w = np.hstack((ls.wcurr, np.hstack(ls.wprev)))
        self.assertEqual(v.shape, (m, 2))
        np.testing.assert_array_equal(v[:, 0], r4 - r2)
        self.assertEqual(w.shape, (m, 2))
        np.testing.assert_array_equal(w[:, 0], xt4 - xt2)
        r.set_interface_data(r3)
        dxt = ls.predict(-1 * r)
        dxt_sol = [
            3.55677154582763, -1.20861833105335, -7.26607387140903,
            -6.29343365253078, -6.37688098495212
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)

        r.set_interface_data(r5)
        xt.set_interface_data(xt5)
        ls.add(r, xt)

        v = np.hstack((ls.vcurr, np.hstack(ls.vprev)))
        w = np.hstack((ls.wcurr, np.hstack(ls.wprev)))
        self.assertEqual(v.shape, (m, 2))
        np.testing.assert_array_equal(v[:, 0], r5 - r4)
        self.assertEqual(w.shape, (m, 2))
        np.testing.assert_array_equal(w[:, 0], xt5 - xt4)
        r.set_interface_data(r3)
        dxt = ls.predict(-1 * r)
        dxt_sol = [
            2.17629179331307, 7.43617021276596, 5.80395136778116,
            5.96504559270517, -6.89209726443769
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        v = np.hstack((ls.vcurr, np.hstack(ls.vprev)))
        w = np.hstack((ls.wcurr, np.hstack(ls.wprev)))
        self.assertEqual(v.shape, (m, 2))
        np.testing.assert_array_equal(v.T.flatten(),
                                      np.hstack((r5 - r4, r4 - r2)))
        self.assertEqual(w.shape, (m, 2))
        np.testing.assert_array_equal(w.T.flatten(),
                                      np.hstack((xt5 - xt4, xt4 - xt2)))

        r.set_interface_data(r6)
        xt.set_interface_data(xt6)
        ls.add(r, xt)
        r.set_interface_data(r7)
        xt.set_interface_data(xt7)
        ls.add(r, xt)
        r.set_interface_data(r8)
        xt.set_interface_data(xt8)
        ls.add(r, xt)

        r.set_interface_data(r3)
        dxt = ls.predict(-1 * r)
        dxt_sol = [
            7.67847593582868, 21.1203208556145, 21.6136363636358,
            23.3649732620315, -1.94652406417126
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        v = np.hstack((ls.vcurr, np.hstack(ls.vprev)))
        w = np.hstack((ls.wcurr, np.hstack(ls.wprev)))
        self.assertEqual(v.shape, (m, 5))
        np.testing.assert_array_equal(
            v.T.flatten(),
            np.hstack((r8 - r7, r7 - r6, r6 - r5, r5 - r4, r4 - r2)))
        self.assertEqual(w.shape, (m, 5))
        np.testing.assert_array_equal(
            w.T.flatten(),
            np.hstack((xt8 - xt7, xt7 - xt6, xt6 - xt5, xt5 - xt4, xt4 - xt2)))

        r.set_interface_data(r9)
        xt.set_interface_data(xt9)
        ls.add(r, xt)
        r.set_interface_data(r10)
        xt.set_interface_data(xt10)
        ls.add(r, xt)

        r.set_interface_data(r3)
        dxt = ls.predict(-1 * r)
        dxt_sol = [
            -4.19875900720576, -5.62710168134507, -2.21637309847878,
            -0.788630904723781, -11.8953162530024
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        v = np.hstack((ls.vcurr, np.hstack(ls.vprev)))
        w = np.hstack((ls.wcurr, np.hstack(ls.wprev)))
        self.assertEqual(v.shape, (m, 5))
        np.testing.assert_array_equal(
            v.T.flatten(),
            np.hstack((r10 - r9, r9 - r8, r8 - r7, r7 - r6, r6 - r5)))
        self.assertEqual(w.shape, (m, 5))
        np.testing.assert_array_equal(
            w.T.flatten(),
            np.hstack(
                (xt10 - xt9, xt9 - xt8, xt8 - xt7, xt7 - xt6, xt6 - xt5)))

        r.set_interface_data(r13)
        xt.set_interface_data(xt13)
        ls.add(r, xt)
        r.set_interface_data(r3)

        dxt = ls.predict(-1 * r)
        dxt_sol = [
            -4.19875900720576, -5.62710168134507, -2.21637309847878,
            -0.788630904723781, -11.8953162530024
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        v = np.hstack((ls.vcurr, np.hstack(ls.vprev)))
        w = np.hstack((ls.wcurr, np.hstack(ls.wprev)))
        self.assertEqual(v.shape, (m, 5))
        np.testing.assert_array_equal(
            v.T.flatten(),
            np.hstack((r10 - r9, r9 - r8, r8 - r7, r7 - r6, r6 - r5)))
        self.assertEqual(w.shape, (m, 5))
        np.testing.assert_array_equal(
            w.T.flatten(),
            np.hstack(
                (xt10 - xt9, xt9 - xt8, xt8 - xt7, xt7 - xt6, xt6 - xt5)))

        v1 = ls.vcurr
        w1 = ls.wcurr

        # new solution step
        ls.finalize_solution_step()
        np.testing.assert_array_equal(ls.vprev[0].flatten(), v1.flatten())
        np.testing.assert_array_equal(ls.wprev[0].flatten(), w1.flatten())
        ls.initialize_solution_step()
        self.assertIsNone(ls.rref)
        self.assertFalse(ls.added)
        self.assertEqual(ls.vcurr.shape, (m, 0))
        self.assertEqual(ls.wcurr.shape, (m, 0))
        is_ready = ls.is_ready()
        self.assertTrue(is_ready)

        r.set_interface_data(r11)
        xt.set_interface_data(xt11)
        ls.add(r, xt)

        r.set_interface_data(r3)
        dxt = ls.predict(-1 * r)
        dxt_sol = [
            -4.19875900720576, -5.62710168134507, -2.21637309847878,
            -0.788630904723781, -11.8953162530024
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        self.assertTrue(ls.added)
        self.assertEqual(ls.vcurr.shape, (m, 0))
        self.assertEqual(ls.wcurr.shape, (m, 0))

        r.set_interface_data(r12)
        xt.set_interface_data(xt12)
        ls.add(r, xt)

        r.set_interface_data(r3)
        dxt = ls.predict(-1 * r)
        dxt_sol = [
            -8.52029914529913, -3.96866096866096, -0.505163817663819,
            -0.426103988603991, -14.1239316239316
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        v = np.hstack((ls.vcurr, np.hstack(ls.vprev)))
        w = np.hstack((ls.wcurr, np.hstack(ls.wprev)))
        self.assertEqual(v.shape, (m, 5))
        np.testing.assert_array_equal(
            v.T.flatten(),
            np.hstack((r12 - r11, r10 - r9, r9 - r8, r7 - r6, r6 - r5)))
        self.assertEqual(w.shape, (m, 5))
        np.testing.assert_array_equal(
            w.T.flatten(),
            np.hstack(
                (xt12 - xt11, xt10 - xt9, xt9 - xt8, xt7 - xt6, xt6 - xt5)))

        v2 = ls.vcurr
        w2 = ls.wcurr

        # new solution step
        ls.finalize_solution_step()
        np.testing.assert_array_equal(
            np.hstack(ls.vprev).flatten(),
            np.hstack([v2, v1[:, :2], v1[:, 3:]]).flatten())
        np.testing.assert_array_equal(
            np.hstack(ls.wprev).flatten(),
            np.hstack([w2, w1[:, :2], w1[:, 3:]]).flatten())
        ls.initialize_solution_step()

        # new solution step
        ls.finalize_solution_step()
        np.testing.assert_array_equal(
            np.hstack(ls.vprev).flatten(),
            np.hstack([np.empty((m, 0)), v2]).flatten())
        np.testing.assert_array_equal(
            np.hstack(ls.wprev).flatten(),
            np.hstack([np.empty((m, 0)), w2]).flatten())
        self.assertEqual(len(ls.vprev), q)
        self.assertEqual(len(ls.wprev), q)
        ls.initialize_solution_step()

        # without reuse

        min_significant = settings["setting2"]["settings"]["min_significant"]
        q = settings["setting2"]["settings"]["q"]

        ls = create_instance(settings["setting2"])
        ls.size_in = ls.size_out = m
        ls.out = interface.copy()
        ls.initialize()
        ls.initialize_solution_step()

        r.set_interface_data(r1)
        xt.set_interface_data(xt1)
        ls.add(r, xt)
        r.set_interface_data(r2)
        xt.set_interface_data(xt2)
        ls.add(r, xt)
        r.set_interface_data(r4)
        xt.set_interface_data(xt4)
        ls.add(r, xt)
        r.set_interface_data(r5)
        xt.set_interface_data(xt5)
        ls.add(r, xt)
        r.set_interface_data(r6)
        xt.set_interface_data(xt6)
        ls.add(r, xt)
        r.set_interface_data(r7)
        xt.set_interface_data(xt7)
        ls.add(r, xt)
        r.set_interface_data(r8)
        xt.set_interface_data(xt8)
        ls.add(r, xt)
        r.set_interface_data(r9)
        xt.set_interface_data(xt9)
        ls.add(r, xt)
        r.set_interface_data(r10)
        xt.set_interface_data(xt10)
        ls.add(r, xt)

        r.set_interface_data(r3)
        dxt = ls.predict(-1 * r)
        dxt_sol = [
            -4.19875900720576, -5.62710168134507, -2.21637309847878,
            -0.788630904723781, -11.8953162530024
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        v = np.hstack((ls.vcurr, np.hstack(ls.vprev)))
        w = np.hstack((ls.wcurr, np.hstack(ls.wprev)))
        self.assertEqual(v.shape, (m, 5))
        np.testing.assert_array_equal(
            v.T.flatten(),
            np.hstack((r10 - r9, r9 - r8, r8 - r7, r7 - r6, r6 - r5)))
        self.assertEqual(w.shape, (m, 5))
        np.testing.assert_array_equal(
            w.T.flatten(),
            np.hstack(
                (xt10 - xt9, xt9 - xt8, xt8 - xt7, xt7 - xt6, xt6 - xt5)))

        # new solution step
        ls.finalize_solution_step()
        np.testing.assert_array_equal(
            np.hstack(ls.vprev).flatten(),
            np.hstack((np.empty((m, 0)))).flatten())
        np.testing.assert_array_equal(
            np.hstack(ls.wprev).flatten(),
            np.hstack((np.empty((m, 0)))).flatten())
        ls.initialize_solution_step()
        self.assertIsNone(ls.rref)
        self.assertFalse(ls.added)
        self.assertEqual(ls.vcurr.shape, (m, 0))
        self.assertEqual(ls.wcurr.shape, (m, 0))
        is_ready = ls.is_ready()
        self.assertFalse(is_ready)

        r.set_interface_data(r11)
        xt.set_interface_data(xt11)
        ls.add(r, xt)

        is_ready = ls.is_ready()
        self.assertFalse(is_ready)

        r.set_interface_data(r12)
        xt.set_interface_data(xt12)
        ls.add(r, xt)

        is_ready = ls.is_ready()
        self.assertTrue(is_ready)
Пример #23
0
    def __init__(self, parameters):
        super().__init__()

        # set parameters
        self.settings = parameters['settings']
        self.dir_csm = join(
            os.getcwd(),
            self.settings['working_directory'])  # *** alternative for getcwd?
        self.env = tools.get_solver_env(__name__, self.dir_csm)
        self.check_software()
        path_src = os.path.realpath(os.path.dirname(__file__))
        self.logfile = 'abaqus.log'

        self.cores = self.settings['cores']  # number of CPUs Abaqus has to use
        self.dimensions = self.settings['dimensions']
        self.array_size = self.settings['arraysize']
        self.delta_t = self.settings['delta_t']
        self.timestep_start = self.settings['timestep_start']
        self.surfaceIDs = self.settings['surfaceIDs']
        self.n_surfaces = len(self.surfaceIDs)
        self.mp_mode = self.settings['mp_mode']
        self.input_file = self.settings['input_file']
        self.save_interval = self.settings.get('save_interval', 1)
        self.timestep = self.timestep_start
        self.iteration = None
        self.model_part_surface_ids = {
        }  # surface IDs corresponding to ModelParts

        self.subcycling = self.settings.get(
            'subcycling',
            False)  # value from parameters or False if not present
        if self.subcycling:
            self.min_inc = self.settings['min_inc']
            self.initial_inc = self.settings['initial_inc']
            self.max_num_inc = self.settings['max_num_inc']
            self.max_inc = self.settings['max_inc']
            self.ramp = int(
                self.settings['ramp']
            )  # 0 or 1 required to substitute in user-subroutines (FORTRAN)
        else:
            self.ramp = 0
            self.max_num_inc = 1

        # prepare abaqus_v6.env
        hostname_replace = ''
        if self.mp_mode == 'MPI' and 'AbaqusHosts.txt' in os.listdir(
                self.dir_csm):
            with open(join(self.dir_csm, 'AbaqusHosts.txt'), 'r') as host_file:
                host_names = host_file.read().split()
            hostname_replace = str([[hostname,
                                     host_names.count(hostname)]
                                    for hostname in set(host_names)])
        with open(join(path_src, 'abaqus_v6.env'), 'r') as infile:
            with open(join(self.dir_csm, 'abaqus_v6.env'), 'w') as outfile:
                for line in infile:
                    line = line.replace('|HOSTNAME|', hostname_replace) if self.mp_mode == 'MPI' \
                        else (line, '')['|HOSTNAME|' in line]  # replace |HOSTNAME| if MPI else remove line
                    line = line.replace('|MP_MODE|', self.mp_mode)
                    line = line.replace('|PID|', str(os.getpid()))
                    if '|' in line:
                        raise ValueError(
                            f'The following line in abaqus_v6.env still contains a \'|\' after '
                            f'substitution: \n \t{line} \n Probably a parameter was not substituted'
                        )
                    outfile.write(line)

        # create start and restart file (each time step > 1 is a restart of the previous converged time step)
        self.write_start_and_restart_inp(join(self.dir_csm, self.input_file),
                                         self.dir_csm + '/CSM_Time0.inp',
                                         self.dir_csm + '/CSM_Restart.inp')

        # prepare Abaqus USRInit.f
        usr = '******'
        with open(join(path_src, usr), 'r') as infile:
            with open(join(self.dir_csm, 'usrInit.f'), 'w') as outfile:
                for line in infile:
                    line = line.replace('|dimension|', str(self.dimensions))
                    line = line.replace('|surfaces|', str(self.n_surfaces))
                    line = line.replace('|cpus|', str(self.cores))

                    # if PWD is too long then FORTRAN code can not compile so this needs special treatment
                    line = self.replace_fortran(line, '|PWD|',
                                                os.path.abspath(os.getcwd()))
                    line = self.replace_fortran(
                        line, '|CSM_dir|', self.settings['working_directory'])
                    if '|' in line:
                        raise ValueError(
                            f'The following line in USRInit.f still contains a \'|\' after substitution: '
                            f'\n \t{line} \nProbably a parameter was not substituted'
                        )
                    outfile.write(line)

        # compile Abaqus USRInit.f in library libusr
        path_libusr = join(self.dir_csm, 'libusr/')
        shutil.rmtree(path_libusr, ignore_errors=True)  # needed if restart
        os.mkdir(path_libusr)
        cmd = f'abaqus make library=usrInit.f directory={path_libusr} >> {self.logfile} 2>&1'
        self.print_log(f'### Compilation of usrInit.f ###')
        subprocess.run(cmd,
                       shell=True,
                       cwd=self.dir_csm,
                       executable='/bin/bash',
                       env=self.env)

        # get load points from usrInit.f at timestep_start
        self.print_log(
            f'\n### Get load integration points using usrInit.f ###')
        if self.timestep_start == 0:
            cmd1 = f'rm -f CSM_Time{self.timestep_start}Surface*Faces.dat ' \
                f'CSM_Time{self.timestep_start}Surface*FacesBis.dat'
            # the output files will have a name with a higher time step  ('job=') than the input file ('input=')
            cmd2 = f'abaqus job=CSM_Time{self.timestep_start + 1} input=CSM_Time{self.timestep_start} ' \
                f'cpus=1 output_precision=full interactive >> {self.logfile} 2>&1'
            commands = cmd1 + '; ' + cmd2
            subprocess.run(commands,
                           shell=True,
                           cwd=self.dir_csm,
                           executable='/bin/bash',
                           env=self.env)
        else:  # restart: this only used for checks
            cmd1 = f'rm -f CSM_Time{self.timestep_start}Surface*Faces.dat ' \
                f'CSM_Time{self.timestep_start}Surface*FacesBis.dat'
            cmd2 = f'abaqus job=CSM_Time{self.timestep_start + 1} oldjob=CSM_Time{self.timestep_start} ' \
                f'input=CSM_Restart cpus=1 output_precision=full interactive >> {self.logfile} 2>&1'
            commands = cmd1 + '; ' + cmd2
            subprocess.run(commands,
                           shell=True,
                           cwd=self.dir_csm,
                           executable='/bin/bash',
                           env=self.env)

        # prepare GetOutput.cpp
        get_output = 'GetOutput.cpp'
        temp_str = ''
        for j in range(0, self.n_surfaces - 1):
            temp_str += f'\"{self.surfaceIDs[j]}\", '
        temp_str += f'\"{self.surfaceIDs[self.n_surfaces-1]}\"'

        with open(join(path_src, get_output), 'r') as infile:
            with open(join(self.dir_csm, get_output), 'w') as outfile:
                for line in infile:
                    line = line.replace('|surfaces|', str(self.n_surfaces))
                    line = line.replace('|surfaceIDs|', temp_str)
                    line = line.replace('|dimension|', str(self.dimensions))
                    if '|' in line:
                        raise ValueError(
                            f'The following line in GetOutput.cpp still contains a \'|\' after '
                            f'substitution: \n \t{line} \n Probably a parameter was not substituted'
                        )
                    outfile.write(line)

        # compile GetOutput.cpp
        self.print_log(f'\n### Compilation of GetOutput.cpp ###')
        cmd = f'abaqus make job=GetOutput user=GetOutput.cpp >> {self.logfile} 2>&1'
        subprocess.run(cmd,
                       shell=True,
                       cwd=self.dir_csm,
                       executable='/bin/bash',
                       env=self.env)

        # get node positions (not load points) at timestep_start (0 is an argument to GetOutput.exe)
        self.print_log(
            f'\n### Get geometrical node positions using GetOutput ###')
        cmd = f'abaqus ./GetOutput.exe CSM_Time{self.timestep_start + 1} 0 >> {self.logfile} 2>&1'
        subprocess.run(cmd,
                       shell=True,
                       cwd=self.dir_csm,
                       executable='/bin/bash',
                       env=self.env)

        for i in range(0, self.n_surfaces):
            path_output = join(
                self.dir_csm,
                f'CSM_Time{self.timestep_start + 1}Surface{i}Output.dat')
            path_nodes = join(
                self.dir_csm,
                f'CSM_Time{self.timestep_start}Surface{i}Nodes.dat')
            shutil.move(path_output, path_nodes)

            # create elements file per surface
            face_file = os.path.join(
                self.dir_csm,
                f'CSM_Time{self.timestep_start}Surface{i}Cpu0Faces.dat')
            output_file = os.path.join(
                self.dir_csm,
                f'CSM_Time{self.timestep_start}Surface{i}Elements.dat')
            self.make_elements(face_file, output_file)

        # prepare Abaqus USR.f
        usr = '******'
        with open(join(path_src, usr), 'r') as infile:
            with open(join(self.dir_csm, 'usr.f'), 'w') as outfile:
                for line in infile:
                    line = line.replace('|dimension|', str(self.dimensions))
                    line = line.replace('|arraySize|', str(self.array_size))
                    line = line.replace('|surfaces|', str(self.n_surfaces))
                    line = line.replace('|cpus|', str(self.cores))
                    line = line.replace('|ramp|', str(self.ramp))
                    line = line.replace('|deltaT|', str(self.delta_t))

                    # if PWD is too long then FORTRAN code cannot compile so this needs special treatment
                    line = self.replace_fortran(line, '|PWD|',
                                                os.path.abspath(os.getcwd()))
                    line = self.replace_fortran(
                        line, '|CSM_dir|', self.settings['working_directory'])
                    if '|' in line:
                        raise ValueError(
                            f'The following line in USR.f still contains a \'|\' after substitution: '
                            f'\n \t{line} \n Probably a parameter was not substituted'
                        )
                    outfile.write(line)

        # compile Abaqus USR.f
        self.print_log(f'\n### Compilation of usr.f ###')
        shutil.rmtree(
            path_libusr)  # remove libusr containing compiled USRInit.f
        os.mkdir(path_libusr)
        cmd = f'abaqus make library=usr.f directory={path_libusr} >> {self.logfile} 2>&1'
        subprocess.run(cmd,
                       shell=True,
                       cwd=self.dir_csm,
                       executable='/bin/bash',
                       env=self.env)

        # create Model
        self.model = data_structure.Model()

        # create input ModelParts (load points)
        for item in (self.settings['interface_input']):
            mp_name = item['model_part']

            for i, surfaceID in enumerate(
                    self.surfaceIDs
            ):  # identify surfaceID corresponding to ModelPart
                if surfaceID in mp_name:
                    self.model_part_surface_ids[mp_name] = i
                    break
            if mp_name not in self.model_part_surface_ids:
                raise AttributeError(
                    f'Could not identify surfaceID corresponding to ModelPart {mp_name}'
                )
            mp_id = self.model_part_surface_ids[mp_name]

            # read in elements file
            elem0_file = join(self.dir_csm,
                              f'CSM_Time0Surface{mp_id}Elements.dat')
            elements0 = np.loadtxt(elem0_file)
            n_elem = int(
                elements0[0, 0]
            )  # elements first item on line 1 contains number of elements
            n_lp = int(
                elements0[0, 1]
            )  # elements second item on line 1 contains number of total load points
            if elements0.shape[0] - 1 != int(
                    n_elem
            ):  # elements remainder contains element numbers in interface
                raise ValueError(
                    f'Number of lines ({elements0.shape[0]}) in {elem0_file} does not correspond with '
                    f'the number of elements ({n_elem})')
            if self.timestep_start != 0:  # check if elements0 corresponds to timestep_start
                elem_file = join(
                    self.dir_csm,
                    f'CSM_Time{self.timestep_start}Surface{mp_id}Elements.dat')
                elements = np.loadtxt(elem_file)
                if int(elements[0, 0]) != n_elem or int(elements[0,
                                                                 1]) != n_lp:
                    raise ValueError(
                        f'Number of load points has changed for {mp_name}')

            # read in faces file for load points
            faces0_file = join(self.dir_csm,
                               f'CSM_Time0Surface{mp_id}Cpu0Faces.dat')
            faces0 = np.loadtxt(faces0_file)
            if faces0.shape[1] != self.dimensions + 2:
                raise ValueError(f'Given dimension does not match coordinates')

            # get load point coordinates and ids of load points
            prev_elem = 0
            prev_lp = 0
            ids = np.arange(n_lp)
            coords_tmp = np.zeros(
                (n_lp, 3))  # z-coordinate mandatory: 0.0 for 2D
            for i in range(0, n_lp):
                elem = int(faces0[i, 0])
                lp = int(faces0[i, 1])
                if elem < prev_elem:
                    raise ValueError(
                        f'Element sequence is wrong ({elem}<{prev_elem})')
                elif elem == prev_elem and lp != prev_lp + 1:
                    raise ValueError(
                        f'Next line for same element ({elem}) does not contain next load point'
                    )
                elif elem > prev_elem and lp != 1:
                    raise ValueError(
                        f'First line for element ({elem}) does not contain its first load point'
                    )

                coords_tmp[i, :self.dimensions] = faces0[
                    i, -self.dimensions:]  # extract last 'dimensions' columns

                prev_elem = elem
                prev_lp = lp

            x0 = coords_tmp[:, 0]
            y0 = coords_tmp[:, 1]
            z0 = coords_tmp[:, 2]

            # create ModelPart
            self.model.create_model_part(mp_name, x0, y0, z0, ids)

        # create output ModelParts (geometrical nodes)
        for item in (self.settings['interface_output']):
            mp_name = item['model_part']

            for i, surfaceID in enumerate(
                    self.surfaceIDs
            ):  # identify surfaceID corresponding to ModelPart
                if surfaceID in mp_name:
                    self.model_part_surface_ids[mp_name] = i
                    break
            if mp_name not in self.model_part_surface_ids:
                raise AttributeError(
                    f'Could not identify surfaceID corresponding to ModelPart {mp_name}'
                )
            mp_id = self.model_part_surface_ids[mp_name]

            # read in nodes file
            nodes0_file = join(self.dir_csm,
                               f'CSM_Time0Surface{mp_id}Nodes.dat')
            nodes0 = np.loadtxt(nodes0_file,
                                skiprows=1)  # first line is a header
            n_nodes0 = nodes0.shape[0]
            if nodes0.shape[1] != self.dimensions:
                raise ValueError(f'Given dimension does not match coordinates')
            if self.timestep_start != 0:  # check if nodes0 corresponds to timestep_start
                nodes_file = join(
                    self.dir_csm,
                    f'CSM_Time{self.timestep_start}Surface{mp_id}Nodes.dat')
                nodes = np.loadtxt(nodes_file,
                                   skiprows=1)  # first line is a header
                n_nodes = nodes.shape[0]
                if n_nodes != n_nodes0:
                    raise ValueError(
                        f'Number of interface nodes has changed for {mp_name}')

            # get geometrical node coordinates
            ids = np.arange(
                n_nodes0
            )  # Abaqus does not use node ids but maintains the output order
            coords_tmp = np.zeros(
                (n_nodes0, 3))  # z-coordinate mandatory: 0.0 for 2D
            coords_tmp[:, :self.dimensions] = nodes0

            x0 = coords_tmp[:, 0]
            y0 = coords_tmp[:, 1]
            z0 = coords_tmp[:, 2]

            # create ModelPart
            self.model.create_model_part(mp_name, x0, y0, z0, ids)

        # check whether the input ModelParts and output ModelParts have proper overlap
        for surfaceID in self.surfaceIDs:
            for item in self.settings['interface_input']:
                mp_name = item['model_part']
                if surfaceID in mp_name:
                    mp_in = self.model.get_model_part(mp_name)
                    break
            for item in self.settings['interface_output']:
                mp_name = item['model_part']
                if surfaceID in mp_name:
                    mp_out = self.model.get_model_part(mp_name)
                    break
            tools.check_bounding_box(mp_in, mp_out)

        # create Interfaces
        self.interface_input = data_structure.Interface(
            self.settings['interface_input'], self.model)
        self.interface_output = data_structure.Interface(
            self.settings['interface_output'], self.model)

        # time
        self.init_time = self.init_time
        self.run_time = 0.0

        # debug
        self.debug = False  # set on True to save copy of input and output files in every iteration
Пример #24
0
    def test_model_mv(self):
        m = 5
        dz = 2
        x = 10
        variable = 'area'
        model_part_name = 'wall'
        interface_settings = [{
            'model_part': model_part_name,
            'variables': [variable]
        }]

        # create model and model_part
        model = data_structure.Model()
        ids = np.arange(0, m)
        x0 = np.zeros(m)
        y0 = np.zeros(m)
        z0 = np.arange(0, m * dz, dz)
        model.create_model_part(model_part_name, x0, y0, z0, ids)

        x_array = np.full((m, 1), x)

        # create interface
        interface = Interface(interface_settings, model)
        interface.set_variable_data(model_part_name, variable, x_array)

        # read settings
        parameter_file_name = os.path.join(os.path.dirname(__file__),
                                           'test_mv.json')
        with open(parameter_file_name, 'r') as parameter_file:
            settings = json.load(parameter_file)

        min_significant = settings["settings"]["min_significant"]

        mv = create_instance(settings)
        mv.size_in = mv.size_out = m
        mv.out = interface.copy()
        mv.initialize()
        mv.initialize_solution_step()

        r = interface.copy()
        xt = interface.copy()
        r1 = np.array([1, 2, 3, 4, 5])
        xt1 = np.array([5, 4, 3, 2, 1])
        r2 = np.array([8, 5, 5, 5, 8])
        xt2 = np.array([1, 4, 8, 5, 5])
        r3 = np.array([7, 5, 6, 4, 3])
        r4 = np.array([1, 1, 7, 4, 0])
        xt4 = np.array([9, 7, 5, 8, 4])
        r5 = np.array([9, 5, 10, 6, 4])
        xt5 = np.array([5, 1, 2, 3, 9])
        r6 = np.array([7, 8, 1, 2, 3])
        xt6 = np.array([7, 5, 5, 1, 2])
        r7 = np.array([1, 2, 5, 1, 2])
        xt7 = np.array([4, 2, 1, 1, 2])
        r8 = np.array([6, 3, 9, 0, 3])
        xt8 = np.array([3, 1, 2, 3, 9])
        r9 = np.array([1, 3, 5, 0, 8])
        xt9 = np.array([8, 1, 5, 3, 9])
        r10 = np.array([1, 3, -5, 8, 8])
        xt10 = np.array([8, -9, 5, 3, -9])
        r11 = r1
        xt11 = xt1
        r12 = r2
        xt12 = xt2
        r13 = r10 * 0.95
        xt13 = xt10

        is_ready = mv.is_ready()
        self.assertFalse(is_ready)

        r.set_interface_data(r1)
        xt.set_interface_data(xt1)
        mv.add(r, xt)

        self.assertTrue(mv.added)
        np.testing.assert_array_equal(r1[:, np.newaxis], mv.rref)
        np.testing.assert_array_equal(xt1[:, np.newaxis], mv.xtref)
        self.assertIsNone(mv.ncurr)
        is_ready = mv.is_ready()
        self.assertFalse(is_ready)

        r.set_interface_data(r2)
        xt.set_interface_data(xt2)
        mv.add(r, xt)

        self.assertTrue(mv.added)
        np.testing.assert_array_equal(r2[:, np.newaxis], mv.rref)
        np.testing.assert_array_equal(xt2[:, np.newaxis], mv.xtref)
        self.assertEqual(mv.v.shape, (m, 1))
        np.testing.assert_array_equal(mv.v[:, 0], r2 - r1)
        self.assertEqual(mv.w.shape, (m, 1))
        np.testing.assert_array_equal(mv.w[:, 0], xt2 - xt1)
        n_sol = [
            -0.388888888888889, -0.166666666666667, -0.111111111111111,
            -0.0555555555555556, -0.166666666666667, 0, 0, 0, 0, 0,
            0.486111111111111, 0.208333333333333, 0.138888888888889,
            0.0694444444444445, 0.208333333333333, 0.291666666666667,
            0.125000000000000, 0.0833333333333333, 0.0416666666666667,
            0.125000000000000, 0.388888888888889, 0.166666666666667,
            0.111111111111111, 0.0555555555555556, 0.166666666666667
        ]
        np.testing.assert_allclose(mv.ncurr.flatten(), n_sol)
        np.testing.assert_array_equal(mv.nprev.flatten(),
                                      np.zeros((m, m)).flatten())
        is_ready = mv.is_ready()
        self.assertTrue(is_ready)
        r.set_interface_data(r3)
        dxt = mv.predict(-1 * r)
        dxt_sol = [
            4.94444444444445, 0, -6.18055555555556, -3.70833333333333,
            -4.944444444444452
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)

        r.set_interface_data(r4)
        xt.set_interface_data(xt4)
        mv.add(r, xt)

        self.assertEqual(mv.v.shape, (m, 2))
        np.testing.assert_array_equal(mv.v[:, 0], r4 - r2)
        self.assertEqual(mv.w.shape, (m, 2))
        np.testing.assert_array_equal(mv.w[:, 0], xt4 - xt2)
        n_sol = [
            -0.306429548563612, -0.216142270861833, 0.251709986320109,
            -0.0437756497948016, -0.555403556771546, 0.0718194254445965,
            -0.0430916552667578, 0.316005471956224, 0.0102599179206566,
            -0.338577291381669, 0.550615595075240, 0.169630642954856,
            0.422708618331053, 0.0786593707250342, -0.0957592339261285,
            0.445280437756498, 0.0328317373461012, 0.759233926128591,
            0.0636114911080711, -0.599179206566348, 0.474008207934337,
            0.115595075239398, 0.485636114911081, 0.0677154582763338,
            -0.234610123119015
        ]
        np.testing.assert_allclose(mv.ncurr.flatten(), n_sol)
        r.set_interface_data(r3)
        dxt = mv.predict(-1 * r)
        dxt_sol = [
            3.55677154582763, -1.20861833105335, -7.26607387140903,
            -6.29343365253078, -6.37688098495212
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)

        r.set_interface_data(r5)
        xt.set_interface_data(xt5)
        mv.add(r, xt)

        self.assertEqual(mv.v.shape, (m, 2))
        np.testing.assert_array_equal(mv.v[:, 0], r5 - r4)
        self.assertEqual(mv.w.shape, (m, 2))
        np.testing.assert_array_equal(mv.w[:, 0], xt5 - xt4)
        n_sol = [
            -0.258792878853669, -0.180633955709944, 0.376899696048632,
            0.0121580547112462, -0.590534085974816, -0.460486322188450,
            -0.200607902735562, -0.446808510638298, -0.159574468085106,
            0.0364741641337384, -0.266391663048198, -0.0651324359531047,
            -0.729483282674772, -0.168693009118541, 0.479374728614850,
            -0.379722101606600, -0.171081198436822, -0.316109422492401,
            -0.123100303951368, -0.0208423795049935, 0.395788102475033,
            0.155449413808076, 0.541033434650456, 0.162613981762918,
            -0.184107685627443
        ]
        np.testing.assert_allclose(mv.ncurr.flatten(), n_sol)
        r.set_interface_data(r3)
        dxt = mv.predict(-1 * r)
        dxt_sol = [
            2.17629179331307, 7.43617021276596, 5.80395136778116,
            5.96504559270517, -6.89209726443769
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        self.assertEqual(mv.v.shape, (m, 2))
        np.testing.assert_array_equal(mv.v.T.flatten(),
                                      np.hstack((r5 - r4, r4 - r2)))
        self.assertEqual(mv.w.shape, (m, 2))
        np.testing.assert_array_equal(mv.w.T.flatten(),
                                      np.hstack((xt5 - xt4, xt4 - xt2)))

        r.set_interface_data(r6)
        xt.set_interface_data(xt6)
        mv.add(r, xt)
        r.set_interface_data(r7)
        xt.set_interface_data(xt7)
        mv.add(r, xt)
        r.set_interface_data(r8)
        xt.set_interface_data(xt8)
        mv.add(r, xt)

        n_sol = [
            1.59692513368984, -1.67045454545455, -1.19117647058823,
            0.612967914438510, -1.93649732620321, 3.87433155080215,
            -5.22727272727274, -3.11764705882354, 0.660427807486646,
            -2.01336898395721, 4.65909090909091, -6.15909090909093,
            -3.50000000000001, 0.568181818181834, -1.56818181818181,
            5.05213903743316, -7.02272727272729, -3.32352941176471,
            0.736631016042804, -2.20721925133689, 1.72192513368984,
            -1.54545454545455, 0.0588235294117627, -0.262032085561494,
            -0.561497326203206
        ]
        np.testing.assert_allclose(mv.ncurr.flatten(), n_sol)
        r.set_interface_data(r3)
        dxt = mv.predict(-1 * r)
        dxt_sol = [
            7.67847593582868, 21.1203208556145, 21.6136363636358,
            23.3649732620315, -1.94652406417126
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        self.assertEqual(mv.v.shape, (m, 5))
        np.testing.assert_array_equal(
            mv.v.T.flatten(),
            np.hstack((r8 - r7, r7 - r6, r6 - r5, r5 - r4, r4 - r2)))
        self.assertEqual(mv.w.shape, (m, 5))
        np.testing.assert_array_equal(
            mv.w.T.flatten(),
            np.hstack((xt8 - xt7, xt7 - xt6, xt6 - xt5, xt5 - xt4, xt4 - xt2)))

        r.set_interface_data(r9)
        xt.set_interface_data(xt9)
        mv.add(r, xt)
        r.set_interface_data(r10)
        xt.set_interface_data(xt10)
        mv.add(r, xt)

        r.set_interface_data(r3)
        dxt = mv.predict(-1 * r)
        dxt_sol = [
            -4.19875900720576, -5.62710168134507, -2.21637309847878,
            -0.788630904723781, -11.8953162530024
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        self.assertEqual(mv.v.shape, (m, 5))
        np.testing.assert_array_equal(
            mv.v.T.flatten(),
            np.hstack((r10 - r9, r9 - r8, r8 - r7, r7 - r6, r6 - r5)))
        self.assertEqual(mv.w.shape, (m, 5))
        np.testing.assert_array_equal(
            mv.w.T.flatten(),
            np.hstack(
                (xt10 - xt9, xt9 - xt8, xt8 - xt7, xt7 - xt6, xt6 - xt5)))

        r.set_interface_data(r13)
        xt.set_interface_data(xt13)
        mv.add(r, xt)

        r.set_interface_data(r3)
        dxt = mv.predict(-1 * r)
        dxt_sol = [
            -4.19875900720576, -5.62710168134507, -2.21637309847878,
            -0.788630904723781, -11.8953162530024
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        self.assertEqual(mv.v.shape, (m, 5))
        np.testing.assert_array_equal(
            mv.v.T.flatten(),
            np.hstack((r10 - r9, r9 - r8, r8 - r7, r7 - r6, r6 - r5)))
        self.assertEqual(mv.w.shape, (m, 5))
        np.testing.assert_array_equal(
            mv.w.T.flatten(),
            np.hstack(
                (xt10 - xt9, xt9 - xt8, xt8 - xt7, xt7 - xt6, xt6 - xt5)))

        v = mv.v
        w = mv.w

        nprev = w @ np.linalg.inv(v.T @ v) @ v.T

        # New solution step
        mv.finalize_solution_step()
        np.testing.assert_array_equal(mv.nprev.flatten(), nprev.flatten())
        mv.initialize_solution_step()
        self.assertIsNone(mv.rref)
        self.assertFalse(mv.added)
        self.assertEqual(mv.v.shape, (m, 0))
        self.assertEqual(mv.w.shape, (m, 0))
        is_ready = mv.is_ready()
        self.assertTrue(is_ready)
        np.testing.assert_allclose(mv.ncurr.flatten(), nprev.flatten())
        r.set_interface_data(r3)
        dxt = mv.predict(-1 * r)
        dxt_sol = [
            -4.19875900720576, -5.62710168134507, -2.21637309847878,
            -0.788630904723781, -11.8953162530024
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)

        r.set_interface_data(r11)
        xt.set_interface_data(xt11)
        mv.add(r, xt)

        self.assertTrue(mv.added)
        self.assertEqual(mv.v.shape, (m, 0))
        self.assertEqual(mv.w.shape, (m, 0))
        r.set_interface_data(r12)
        xt.set_interface_data(xt12)
        mv.add(r, xt)
        n_sol = [
            -1.07953029089939, 0.852682145716574, -0.00813984520949948,
            0.0950093408059783, 0.306645316253002, -1.08484565430122,
            2.54250066720043, 0.878480562227564, -0.192264923049552,
            -0.532759540966108, 0.315863802152833, 0.444989324793168,
            -0.139022328974290, -0.215427897873855, 0.649152655457700,
            0.519159772262255, -0.566019482252470, -0.0682990837114143,
            -0.0941975802864517, 0.431578596210302, -0.394248732319190,
            0.855284227381908, 1.23271950894049, -0.654857219108619,
            0.794435548438751
        ]
        np.testing.assert_allclose(mv.ncurr.flatten(), n_sol)

        r.set_interface_data(r3)
        dxt = mv.predict(-1 * r)
        dxt_sol = [
            2.04216706698691, -8.02212881416246, -4.68760564006761,
            -1.31217195979005, -8.67687483319990
        ]
        np.testing.assert_allclose(dxt.get_interface_data(), dxt_sol)
        self.assertEqual(mv.v.shape, (m, 1))
        np.testing.assert_array_equal(mv.v,
                                      r12[:, np.newaxis] - r11[:, np.newaxis])
        self.assertEqual(mv.w.shape, (m, 1))
        np.testing.assert_array_equal(
            mv.w, xt12[:, np.newaxis] - xt11[:, np.newaxis])
Пример #25
0
    def initialize(self):
        super().initialize()

        # prepare Fluent journal
        journal = f'v{self.version}.jou'
        thread_names_str = ''
        for thread_name in self.thread_ids:
            thread_names_str += ' "' + thread_name + '"'
        unsteady = '#f'
        if self.unsteady:
            unsteady = '#t'
        with open(join(self.dir_src, journal)) as infile:
            with open(join(self.dir_cfd, journal), 'w') as outfile:
                for line in infile:
                    line = line.replace('|CASE|', join(self.dir_cfd, self.case_file))
                    line = line.replace('|THREAD_NAMES|', thread_names_str)
                    line = line.replace('|UNSTEADY|', unsteady)
                    line = line.replace('|FLOW_ITERATIONS|', str(self.flow_iterations))
                    line = line.replace('|DELTA_T|', str(self.delta_t))
                    line = line.replace('|TIMESTEP_START|', str(self.timestep_start))
                    outfile.write(line)

        # prepare Fluent UDF
        if self.timestep_start == 0:
            udf = f'v{self.version}.c'
            with open(join(self.dir_src, udf)) as infile:
                with open(join(self.dir_cfd, udf), 'w') as outfile:
                    for line in infile:
                        line = line.replace('|MAX_NODES_PER_FACE|', str(self.mnpf))
                        outfile.write(line)

        # start Fluent with journal
        log = join(self.dir_cfd, 'fluent.log')
        cmd1 = f'fluent -r{self.version_bis} {self.dimensions}ddp '
        cmd2 = f'-t{self.cores} -i {journal}'

        if self.settings['fluent_gui']:
            cmd = cmd1 + cmd2
        else:
            cmd = cmd1 + '-gu ' + cmd2 + f' >> {log} 2>&1'  # TODO: does log work well?
            # cmd = cmd1 + '-gu ' + cmd2 + f' 2> >(tee -a {log}) 1>> {log}'  # TODO: specify what this option does?
        self.fluent_process = subprocess.Popen(cmd, executable='/bin/bash',
                                               shell=True, cwd=self.dir_cfd, env=self.env)

        # get general simulation info from report.sum
        self.wait_message('case_info_exported')
        report = join(self.dir_cfd, 'report.sum')
        check = 0
        with open(report, 'r') as file:
            for line in file:
                if check == 2 and 'Time' in line:
                    if 'Steady' in line and self.unsteady:
                        raise ValueError('unsteady in JSON does not match steady Fluent')
                    elif 'Unsteady' in line and not self.unsteady:
                        raise ValueError('steady in JSON does not match unsteady Fluent')
                    break
                if check == 1 and 'Space' in line:
                    if str(self.dimensions) not in line:
                        if not (self.dimensions == 2 and 'Axisymmetric' in line):
                            raise ValueError(f'dimension in JSON does not match Fluent')
                    check = 2
                if 'Model' in line and 'Settings' in line:
                    check = 1

        # get surface thread ID's from report.sum and write them to bcs.txt
        check = 0
        info = []
        with open(report, 'r') as file:
            for line in file:
                if check == 3 and line.islower():
                    name, id, _ = line.strip().split()
                    if name in self.thread_ids:
                        info.append(' '.join((name, id)))
                        self.thread_ids[name] = id

                if check == 3 and not line.islower():
                    break
                if check == 2:  # skip 1 line
                    check = 3
                if 'name' in line and check == 1:
                    check = 2
                if 'Boundary Conditions' in line:
                    check = 1
        with open(join(self.dir_cfd, 'bcs.txt'), 'w') as file:
            file.write(str(len(info)) + '\n')
            for line in info:
                file.write(line + '\n')
        self.send_message('thread_ids_written_to_file')

        # import node and face information if no restart
        if self.timestep_start == 0:
            self.wait_message('nodes_and_faces_stored')

        # create Model
        self.model = data_structure.Model()

        # create input ModelParts (nodes)
        for item in (self.settings['interface_input']):
            mp_name = item['model_part']

            # get face thread ID that corresponds to ModelPart
            for thread_name in self.thread_ids:
                if thread_name in mp_name:
                    self.model_part_thread_ids[mp_name] = self.thread_ids[thread_name]
            if mp_name not in self.model_part_thread_ids:
                raise AttributeError('Could not find thread name corresponding ' +
                                     f'to ModelPart {mp_name}')

            # read in datafile
            thread_id = self.model_part_thread_ids[mp_name]
            file_name = join(self.dir_cfd, f'nodes_timestep0_thread{thread_id}.dat')
            data = np.loadtxt(file_name, skiprows=1)
            if data.shape[1] != self.dimensions + 1:
                raise ValueError('Given dimension does not match coordinates')

            # get node coordinates and ids
            coords_tmp = np.zeros((data.shape[0], 3)) * 0.
            coords_tmp[:, :self.dimensions] = data[:, :-1]  # add column z if 2D
            ids_tmp = data[:, -1].astype(int)  # array is flattened

            # sort and remove doubles
            args = np.unique(ids_tmp, return_index=True)[1].tolist()
            x0 = coords_tmp[args, 0]
            y0 = coords_tmp[args, 1]
            z0 = coords_tmp[args, 2]
            ids = ids_tmp[args]

            # create ModelPart
            self.model.create_model_part(mp_name, x0, y0, z0, ids)

        # create output ModelParts (faces)
        for item in (self.settings['interface_output']):
            mp_name = item['model_part']

            # get face thread ID that corresponds to ModelPart
            for thread_name in self.thread_ids:
                if thread_name in mp_name:
                    self.model_part_thread_ids[mp_name] = self.thread_ids[thread_name]
            if mp_name not in self.model_part_thread_ids:
                raise AttributeError('Could not find thread name corresponding ' +
                                     f'to ModelPart {mp_name}')
            # read in datafile
            thread_id = self.model_part_thread_ids[mp_name]
            file_name = join(self.dir_cfd, f'faces_timestep0_thread{thread_id}.dat')
            data = np.loadtxt(file_name, skiprows=1)
            if data.shape[1] != self.dimensions + self.mnpf:
                raise ValueError(f'given dimension does not match coordinates')

            # get face coordinates and ids
            coords_tmp = np.zeros((data.shape[0], 3)) * 0.
            coords_tmp[:, :self.dimensions] = data[:, :-self.mnpf]  # add column z if 2D
            ids_tmp = self.get_unique_face_ids(data[:, -self.mnpf:])

            # sort and remove doubles
            args = np.unique(ids_tmp, return_index=True)[1].tolist()
            x0 = coords_tmp[args, 0]
            y0 = coords_tmp[args, 1]
            z0 = coords_tmp[args, 2]
            ids = ids_tmp[args]

            # create ModelPart
            self.model.create_model_part(mp_name, x0, y0, z0, ids)

        # create Interfaces
        self.interface_input = data_structure.Interface(self.settings['interface_input'], self.model)
        self.interface_output = data_structure.Interface(self.settings['interface_output'], self.model)