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