Ejemplo n.º 1
0
 def __init__(self, parameters):
     super().__init__(parameters)
     with warnings.catch_warnings():
         warnings.filterwarnings('always', category=DeprecationWarning)
         warnings.warn('SolverWrapperFluent2019R1 will no longer be maintained and tested', category=DeprecationWarning)
     self.env = tools.get_solver_env(__name__, self.dir_cfd)
     self.check_software()
Ejemplo n.º 2
0
    def setUpClass(cls):
        dir_tmp = join(os.path.dirname(__file__),
                       f'test_v614/tube{int(cls.dimension)}d')

        # perform reference calculation
        with open(join(dir_tmp, 'parameters.json')) as parameter_file:
            parameters = json.load(parameter_file)

        solver_name = parameters['type'].replace('solver_wrappers.', '')
        env = get_solver_env(solver_name, dir_tmp)

        if cls.setup_case:
            p_setup_abaqus = subprocess.Popen('sh ' +
                                              join(dir_tmp, 'setup_abaqus.sh'),
                                              cwd=dir_tmp,
                                              shell=True,
                                              env=env)
            p_setup_abaqus.wait()

        # create the solver
        solver = create_instance(parameters)
        interface_input = solver.get_interface_input()

        # give value to variables
        pressure = interface_input.get_variable_data(cls.mp_name_in,
                                                     'pressure')
        pressure[:] = cls.p
        interface_input.set_variable_data(cls.mp_name_in, 'pressure', pressure)
        traction = interface_input.get_variable_data(cls.mp_name_in,
                                                     'traction')
        traction[:, :] = cls.shear
        interface_input.set_variable_data(cls.mp_name_in, 'traction', traction)

        solver.initialize()
        # step 1, coupling 1
        solver.initialize_solution_step()
        output1_1 = solver.solve_solution_step(interface_input)
        # step 1, coupling 2
        output1_2 = solver.solve_solution_step(interface_input)
        solver.finalize_solution_step()

        # save output for comparison, as input hasn't changed these should be the same
        cls.a1_1 = output1_1.get_variable_data(cls.mp_name_out, 'displacement')
        cls.a2_1 = output1_2.get_variable_data(cls.mp_name_out, 'displacement')

        # step 2 to 4
        for i in range(3):
            solver.initialize_solution_step()
            solver.solve_solution_step(interface_input)
            solver.finalize_solution_step()
        solver.finalize()

        # get data for solver without restart
        cls.interface_y_single_run = solver.get_interface_input()
        cls.interface_x_single_run = solver.get_interface_output()
        output_single_run = solver.get_interface_output()
        cls.a1 = output_single_run.get_variable_data(cls.mp_name_out,
                                                     'displacement')
        print(f"Max disp a1: {np.max(np.abs(cls.a1), axis=0)}")
Ejemplo n.º 3
0
    def setUpClass(cls):
        dir_name = os.path.realpath(
            os.path.dirname(__file__))  # path to fluent directory
        cls.file_name = join(dir_name,
                             f'test_v{cls.version}/tube3d/parameters.json')
        cls.working_dir = join(dir_name, f'test_v{cls.version}/tube3d/CFD')

        # setup
        if cls.setup_case:
            dir_tmp = join(dir_name, f'test_v{cls.version}/tube3d')
            fluent_solver_module = f'fluent.v{cls.version}'
            env = get_solver_env(fluent_solver_module, dir_tmp)
            p = subprocess.Popen(join(dir_tmp, 'setup_fluent.sh'),
                                 cwd=dir_tmp,
                                 shell=True,
                                 env=env)
            p.wait()
Ejemplo n.º 4
0
from coconut import tools

cfd_solver = 'openfoam.v41'
csm_solver = 'abaqus.v614'
cfd_dir = './CFD'
csm_dir = './CSM'

# copy run_simulation.py script to main directory
shutil.copy('../setup_files/run_simulation.py', './')

# clean working directories
shutil.rmtree(cfd_dir, ignore_errors=True)
shutil.rmtree(csm_dir, ignore_errors=True)

# create new CFD folder
shutil.copytree('../setup_files/tube/openfoam3d', cfd_dir)
cfd_env = tools.get_solver_env(cfd_solver, cfd_dir)

subprocess.check_call('./setup_openfoam3d.sh',
                      shell=True,
                      cwd=cfd_dir,
                      env=cfd_env)

# create new CSM folder
shutil.copytree('../setup_files/tube/abaqus3d', csm_dir)
csm_env = tools.get_solver_env(csm_solver, csm_dir)
subprocess.check_call('./setup_abaqus3d.sh',
                      shell=True,
                      cwd=csm_dir,
                      env=csm_env)
Ejemplo n.º 5
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()
Ejemplo n.º 6
0
 def __init__(self, parameters):
     super().__init__(parameters)
     self.env = tools.get_solver_env(__name__, self.dir_cfd)
     self.check_software()
Ejemplo n.º 7
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
Ejemplo n.º 8
0
import shutil
import subprocess

from coconut import tools

cfd_solver = 'openfoam.v41'
csm_solver = 'kratos.structural_mechanics_application.v60'
cfd_dir = './CFD'
csm_dir = './CSM'

# copy run_simulation.py script to main directory
shutil.copy('../setup_files/run_simulation.py', './')

# clean working directories
shutil.rmtree(cfd_dir, ignore_errors=True)
shutil.rmtree(csm_dir, ignore_errors=True)

# create new CFD folder
shutil.copytree('../setup_files/tube/openfoam3d', cfd_dir)
cfd_env = tools.get_solver_env(cfd_solver, cfd_dir)
subprocess.check_call('./setup_openfoam3d.sh',
                      shell=True,
                      cwd=cfd_dir,
                      env=cfd_env)

# create new CSM folder
shutil.copytree('../setup_files/tube/kratos_structure3d', csm_dir)
Ejemplo n.º 9
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()
Ejemplo n.º 10
0
import shutil
import subprocess

from coconut import tools

csm_solver = 'abaqus.v614'
cfd_dir = './CFD'
csm_dir = './CSM'

# copy run_simulation.py script to main directory
shutil.copy('../setup_files/run_simulation.py', './')

# clean working directories
shutil.rmtree(cfd_dir, ignore_errors=True)
shutil.rmtree(csm_dir, ignore_errors=True)

# create new CFD folder
shutil.copytree('../setup_files/tube/tube_flow', cfd_dir)

# create new CSM folder
shutil.copytree('../setup_files/tube/abaqus2d', csm_dir)
csm_env = tools.get_solver_env(csm_solver, csm_dir)
subprocess.check_call('./setup_abaqus2d.sh',
                      shell=True,
                      cwd=csm_dir,
                      env=csm_env)