Ejemplo n.º 1
0
def test_attributes():
    """Test with different attributes."""
    table_data = [
        ['Name', 'Color', 'Type'],
        ['Avocado', 'green', 'nut'],
        ['Tomato', 'red', 'fruit'],
        ['Lettuce', 'green', 'vegetable'],
    ]
    table = AsciiTable(table_data)

    assert 31 == max(len(r) for r in table.table.splitlines())
    assert 31 == table.table_width

    table.outer_border = False
    assert 29 == max(len(r) for r in table.table.splitlines())
    assert 29 == table.table_width

    table.inner_column_border = False
    assert 27 == max(len(r) for r in table.table.splitlines())
    assert 27 == table.table_width

    table.padding_left = 0
    assert 24 == max(len(r) for r in table.table.splitlines())
    assert 24 == table.table_width

    table.padding_right = 0
    assert 21 == max(len(r) for r in table.table.splitlines())
    assert 21 == table.table_width
Ejemplo n.º 2
0
    def run(self):
        self.print_banner()
        self.print_help()

        while True:
            command = self.input()

            if command == 'addcert':
                count = self.manager.command_addcert()
                print "Successfully added %s certificates" % count

            elif command == 'settings':
                print SETTINGS

            elif command == 'help':
                self.print_banner()
                self.print_help()

            elif command == 'report':
                rows, week_start, week_end, total = self.manager.command_report()
                table = AsciiTable(rows, 'Certificates obtained %s-%s' % (week_start, week_end))
                table.outer_border = False
                print table.table
                print "\nTotal certificates obtained: %s" % total

            elif command == 'delete':
                self.manager.command_delete()

            elif command == 'exit':
                return 0
            else:
                pass
Ejemplo n.º 3
0
Archivo: nibl.py Proyecto: 2ion/nibl
def output(buf, dowrap=False):
    bbuf = [["Bot", "Pack#", "Size", "File"]] + buf
    t = AsciiTable(bbuf)
    t.inner_column_border = False
    t.outer_border = False
    if dowrap and sys.stdout.isatty():
        mw = t.column_max_width(3)
        for e in bbuf:
            if len(e[3])>mw:
                e[3] = "\n".join(wrap(e[3], mw))
    print(t.table)
    sys.stdout.flush()
Ejemplo n.º 4
0
    def info(self, options):
        """
        Display service status information.

        Usage: info
        """

        from terminaltables import AsciiTable
        rows = []

        for key, value in self.project.info().iteritems():
            rows.append([key + ':', value])

        table = AsciiTable(rows)
        table.outer_border = False
        table.inner_column_border = False
        table.inner_heading_row_border = False
        table.title = 'Dork status information'
        print table.table
Ejemplo n.º 5
0
def _log_config(keys, context):
    result = ''
    for key in keys:
        c = context[key].config
        items = list(c.items())
        default_config = context[key].default_config()
        tab = [(key, context[key].name, "", "", "", "", "", "")]
        for i in range((len(items) + 2) // 3):
            row_l = _log_row(items[i * 3], default_config)
            if i * 3 + 1 < len(items):
                row_m = ("|", *_log_row(items[i * 3 + 1], default_config))
            else:
                row_m = ("", "", "")
            if i * 3 + 2 < len(items):
                row_r = ("|", *_log_row(items[i * 3 + 2], default_config))
            else:
                row_r = ("", "", "")
            tab.append((*row_l, *row_m, *row_r))
        table = AsciiTable(tab)
        table.inner_column_border = False
        table.outer_border = False
        result += f'\n{table.table}\n'
    log.easy().debug(f'Configuration:{RESET}{result}')
Ejemplo n.º 6
0
def main_help():

    commands = ['database', 'sniffing', 'exploit', 'modelling', 'exit']
    description = ['Use database mode.', 'Use sniffing mode.', 'Use exploit mode.', 'Use modelling mode.', 'Quit this program']

    table_data = [['Commands', 'Description']]
    
    for i in range(len(commands) - 1):
        table_data.append([commands[i], description[i]])
            
        table = AsciiTable(table_data)
        table.inner_column_border = False
        table.inner_footing_row_border = False
        table.inner_heading_row_border = True
        table.inner_row_border = False
        table.outer_border = False
        
        msg = f"""
Core commands
=============

{table.table}\n\n"""
    return msg
Ejemplo n.º 7
0
    def do_info(self, line):
        print("\n \033[1m\033[94m[*]\033[0m Module Info\033[0m\n")
        print(''' This module can be used to generate PowerShell
 based loader (.PS1) and .EXE loader for blocked powershell.exe
 environments. It support Meterpreter Reverse HTTP, Reverse HTTPS
 staged payloads. The payload generated by this module has two output.
 The first output is PowerShell script and it can be used directly
 when available PowerShell access. The second output is C# code
 for PowerShell based loader code that will be used when powershell.exe
 is blocked. You can compile and run it, after that loader runs
 the PowerShell  based loader code using System.Management.Automation.dll.
 This module also has the ability to process patched stages.''')
        print("\n \033[1m\033[94m[*]\033[0m Module Options\033[0m")
        optionsValues = [
            ["Parameter", "Required", "Value", "Description"],
            [
                "PROTO", "Yes", mppProto,
                "Listener protocol. Accepted: http or https"
            ],
            [
                "LHOST", "Yes", mppLhost,
                "The local listener hostname or IP address"
            ], ["LPORT", "Yes", mppLport, "The local listener port."],
            [
                "ARCH", "Yes", mppArch,
                "Architecture of target system. Accepted: x86 or x64"
            ],
            [
                "SSIZE", "No", mppSsize,
                "If you patched Metasploit insert your patch size"
            ]
        ]
        optTable = AsciiTable(optionsValues)
        optTable.outer_border = False
        optTable.inner_column_border = False
        optTable.justify_columns[1] = "center"
        print("\n" + optTable.table + "\n")
Ejemplo n.º 8
0
    def getNodes(self):
        """
        List the nodes stored in the database

        Usage: getNodes [-h]

        Options:
            -h, --help             Print this message.
        """

        nodes = self.dbc.getNodes()

        table_data = [["id", "dl addresses", "nwk addresses"]]
        for node in nodes:
            table_data.append(node)

        table = AsciiTable(table_data)
        table.inner_column_border = False
        table.inner_footing_row_border = False
        table.inner_heading_row_border = True
        table.inner_row_border = False
        table.outer_border = False

        print(f"{table.table}")
Ejemplo n.º 9
0
    def post_stats(self):
        data = [
            ['Author', 'Count'],
        ]

        stats = db.execute_sql(self.author_stats)
        for row in stats.fetchall():
            data.append([row[0], row[1]])

        table_instance = AsciiTable(data)
        table_instance.inner_column_border = False
        table_instance.outer_border = False
        table_instance.justify_columns[1] = 'center'

        content = {
            'content':
            "**WEEKLY AUTHOR STATS:**```{}```".format(table_instance.table)
        }

        full_url = self.url + self.hook_id + '/' + self.hook_token + '?wait=true'
        r = requests.post(full_url, json=content)
        self.limit = int(r.headers['X-RateLimit-Limit'])
        self.remaining = int(r.headers['X-RateLimit-Remaining'])
        self.reset = int(r.headers['X-RateLimit-Reset'])
Ejemplo n.º 10
0
    async def standings(self, ctx, division, driver: str = None):
        """Show standings for the current season of the specified division."""
        division = self.config["division_map"].get(division.lower(), division.lower())
        if not get_current_season(division, self):
            await ctx.send("No seasons found for division")

        season_id = self.config["division_season"][division.lower()]
        teams_disabled = self.config["season_info"][season_id]["teams_disabled"]

        url = f"{self.config['urls']['base_url']}/api/standings/{season_id}"
        if driver:
            url += f"?driver={driver.lower()}"

        r = self.session.get(url)
        try:
            standings = json.loads(r.content)

            data = [["Pos", "Driver", "Team", "Points"]]

            if teams_disabled:
                data[0].pop(2)

            for pos in standings[0:5]:
                add_row(data, pos, teams_disabled)

            found = False
            if driver:
                try:
                    found = next(
                        iter([d for d in data if driver.lower() in d[1].lower()])
                    )
                except StopIteration:
                    pass

                if not found:
                    try:
                        info = next(
                            iter(
                                [
                                    {"index": i, "details": d}
                                    for i, d in enumerate(standings)
                                    if driver.lower() in d["name"].lower()
                                ]
                            )
                        )
                        prev_pos = standings[info["index"] - 1]
                        if prev_pos["position"] > 6:
                            data.append(["..."])
                        if prev_pos["position"] > 5:
                            add_row(data, prev_pos, teams_disabled)
                        add_row(data, info["details"], teams_disabled)
                        try:
                            next_pos = standings[info["index"] + 1]
                            add_row(data, next_pos, teams_disabled)
                        except IndexError:
                            pass
                    except StopIteration:
                        pass

            table_instance = AsciiTable(data)
            table_instance.inner_column_border = False
            table_instance.outer_border = False
            table_instance.justify_columns[3] = "center"

            season_info = self.config["season_info"][season_id]
            season = f"Name: {season_info['name']} ({season_info['start_date']} to {season_info['end_date']})"
            msg = table_instance.table
        except json.decoder.JSONDecodeError:
            season = "Error"
            msg = "There was an error retrieving the standings"

        await ctx.send(f"```{season}\n\n{msg}```")
Ejemplo n.º 11
0
def execute_status(args):
    status = get_status()
    # First rows, showing daemon status
    if status['status'] == 'running':
        status['status'] = Color('{autogreen}' + '{}'.format(status['status']) + '{/autogreen}')
    elif status['status'] == 'paused':
        status['status'] = Color('{autoyellow}' + '{}'.format(status['status']) + '{/autoyellow}')

    if status['process'] == 'running' or status['process'] == 'paused':
        status['process'] = Color('{autogreen}' + '{}'.format(status['process']) + '{/autogreen}')

    print('Daemon: {}\nProcess status: {} \n'.format(status['status'], status['process']))

    # Handle queue data
    data = status['data']
    if isinstance(data, str):
        print(data)
    elif isinstance(data, dict):
        # Format incomming data to be compatible with Terminaltables
        formatted_data = []
        formatted_data.append(['Index', 'Status', 'Code',
                               'Command', 'Path', 'Start', 'End'])
        for key, entry in sorted(data.items(), key=operator.itemgetter(0)):
            formatted_data.append(
                [
                    '#{}'.format(key),
                    entry['status'],
                    '{}'.format(entry['returncode']),
                    entry['command'],
                    entry['path'],
                    entry['start'],
                    entry['end']
                ]
            )

        # Create AsciiTable instance and define style
        table = AsciiTable(formatted_data)
        table.outer_border = False
        table.inner_column_border = False

        terminal_width = terminal_size()
        customWidth = table.column_widths
        # If the text is wider than the actual terminal size, we
        # compute a new size for the Command and Path column.
        if (reduce(lambda a, b: a+b, table.column_widths) + 10) > terminal_width[0]:
            # We have to subtract 14 because of table paddings
            left_space = math.floor((terminal_width[0] - customWidth[0] - customWidth[1] - customWidth[2] - customWidth[5] - customWidth[6] - 14)/2)

            if customWidth[3] < left_space:
                customWidth[4] = 2*left_space - customWidth[3]
            elif customWidth[4] < left_space:
                customWidth[3] = 2*left_space - customWidth[4]
            else:
                customWidth[3] = left_space
                customWidth[4] = left_space

        # Format long strings to match the console width
        for i, entry in enumerate(table.table_data):
            for j, string in enumerate(entry):
                max_width = customWidth[j]
                wrapped_string = '\n'.join(wrap(string, max_width))
                if j == 1:
                    if wrapped_string == 'done' or wrapped_string == 'running' or wrapped_string == 'paused':
                        wrapped_string = Color('{autogreen}' + '{}'.format(wrapped_string) + '{/autogreen}')
                    elif wrapped_string == 'queued':
                        wrapped_string = Color('{autoyellow}' + '{}'.format(wrapped_string) + '{/autoyellow}')
                    elif wrapped_string in ['errored', 'stopping', 'killing']:
                        wrapped_string = Color('{autored}' + '{}'.format(wrapped_string) + '{/autored}')
                elif j == 2:
                    if wrapped_string == '0' and wrapped_string != 'Code':
                        wrapped_string = Color('{autogreen}' + '{}'.format(wrapped_string) + '{/autogreen}')
                    elif wrapped_string != '0' and wrapped_string != 'Code':
                        wrapped_string = Color('{autored}' + '{}'.format(wrapped_string) + '{/autored}')

                table.table_data[i][j] = wrapped_string

        print(table.table)
    print('')
import matplotlib.pyplot as plt

g = [[0.2, 0.6, 0.2, 0], [0.4, 0.4, 0, 0.2], [0.2, 0, 0.5, 0.3],
     [0.1, 0, 0.5, 0.4]]

n = 1000

values = generator(n)

tableData = [['γ'] + values]
states_list = [st for st in range(len(g))]
for i in states_list:
    states = get_states(g, i, values)
    tableData.append(['st. (from st. ' + str(i) + ')'] + states)
    plt.title("Вероятность пребывания в состояниях (начальное состояние=" +
              str(i) + ")")
    plt.xlabel("state")
    plt.ylabel("p")
    plt.bar(states_list, [states.count(st) / n for st in states_list], 1)
    plt.xticks(states_list)
    plt.grid()
    plt.show()
resultTable = AsciiTable(tableData)
resultTable.inner_heading_row_border = True
resultTable.outer_border = False
resultTable.inner_row_border = False
print(resultTable.table)

print('Стационарное состояние:')
print(linalg.matrix_power(g, 100)[0])
Ejemplo n.º 13
0
def execute_status(args, root_dir=None):
    """Print the status of the daemon.

    This function displays the current status of the daemon as well
    as the whole queue and all available information about every entry
    in the queue.
    `terminaltables` is used to format and display the queue contents.
    `colorclass` is used to color format the various items in the queue.

    Args:
        root_dir (string): The path to the root directory the daemon is running in.
    """

    status = command_factory('status')({}, root_dir=root_dir)
    # First rows, showing daemon status
    if status['status'] == 'running':
        status['status'] = Color('{autogreen}' +
                                 '{}'.format(status['status']) +
                                 '{/autogreen}')
    elif status['status'] in ['paused']:
        status['status'] = Color('{autoyellow}' +
                                 '{}'.format(status['status']) +
                                 '{/autoyellow}')

    print('Daemon: {}\n'.format(status['status']))

    # Handle queue data
    data = status['data']
    if isinstance(data, str):
        print(data)
    elif isinstance(data, dict):
        # Format incomming data to be compatible with Terminaltables
        formatted_data = []
        formatted_data.append(
            ['Index', 'Status', 'Code', 'Command', 'Path', 'Start', 'End'])
        for key, entry in sorted(data.items(), key=operator.itemgetter(0)):
            formatted_data.append([
                '#{}'.format(key), entry['status'],
                '{}'.format(entry['returncode']), entry['command'],
                entry['path'], entry['start'], entry['end']
            ])

        # Create AsciiTable instance and define style
        table = AsciiTable(formatted_data)
        table.outer_border = False
        table.inner_column_border = False

        terminal_width = terminal_size()
        customWidth = table.column_widths
        # If the text is wider than the actual terminal size, we
        # compute a new size for the Command and Path column.
        if (reduce(lambda a, b: a + b, table.column_widths) +
                10) > terminal_width[0]:
            # We have to subtract 14 because of table paddings
            left_space = math.floor(
                (terminal_width[0] - customWidth[0] - customWidth[1] -
                 customWidth[2] - customWidth[5] - customWidth[6] - 14) / 2)

            if customWidth[3] < left_space:
                customWidth[4] = 2 * left_space - customWidth[3]
            elif customWidth[4] < left_space:
                customWidth[3] = 2 * left_space - customWidth[4]
            else:
                customWidth[3] = left_space
                customWidth[4] = left_space

        # Format long strings to match the console width
        for i, entry in enumerate(table.table_data):
            for j, string in enumerate(entry):
                max_width = customWidth[j]
                wrapped_string = '\n'.join(wrap(string, max_width))
                if j == 1:
                    if wrapped_string == 'done' or wrapped_string == 'running' or wrapped_string == 'paused':
                        wrapped_string = Color('{autogreen}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autogreen}')
                    elif wrapped_string in ['queued', 'stashed']:
                        wrapped_string = Color('{autoyellow}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autoyellow}')
                    elif wrapped_string in ['failed', 'stopping', 'killing']:
                        wrapped_string = Color('{autored}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autored}')
                elif j == 2:
                    if wrapped_string == '0' and wrapped_string != 'Code':
                        wrapped_string = Color('{autogreen}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autogreen}')
                    elif wrapped_string != '0' and wrapped_string != 'Code':
                        wrapped_string = Color('{autored}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autored}')

                table.table_data[i][j] = wrapped_string

        print(table.table)
    print('')
Ejemplo n.º 14
0
def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usernamespace):
    """Runs a model - processes the input file; builds the Yee cells; calculates update coefficients; runs main FDTD loop.

    Args:
        args (dict): Namespace with command line arguments
        currentmodelrun (int): Current model run number.
        modelend (int): Number of last model to run.
        numbermodelruns (int): Total number of model runs.
        inputfile (object): File object for the input file.
        usernamespace (dict): Namespace that can be accessed by user
                in any Python code blocks in input file.

    Returns:
        tsolve (int): Length of time (seconds) of main FDTD calculations
    """

    # Monitor memory usage
    p = psutil.Process()

    # Declare variable to hold FDTDGrid class
    global G

    # Used for naming geometry and output files
    appendmodelnumber = '' if numbermodelruns == 1 and not args.task and not args.restart else '_'+str(currentmodelrun)
    appendmodelnumberGeometry = '' if numbermodelruns == 1 and not args.task and not args.restart or args.geometry_fixed else '_'+str(currentmodelrun)

    # Normal model reading/building process; bypassed if geometry information to be reused
    if 'G' not in globals():

        # Initialise an instance of the FDTDGrid class
        G = FDTDGrid()

        # Get information about host machine
        # (need to save this info to FDTDGrid instance after it has been created)
        G.hostinfo = get_host_info()

        # Single GPU object
        if args.gpu:
            G.gpu = args.gpu

        G.inputfilename = os.path.split(inputfile.name)[1]
        G.inputdirectory = os.path.dirname(os.path.abspath(inputfile.name))
        inputfilestr = '\n--- Model {}/{}, input file: {}'.format(currentmodelrun, modelend, inputfile.name)
        if G.messages:
            print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)

        # Add the current model run to namespace that can be accessed by
        # user in any Python code blocks in input file
        usernamespace['current_model_run'] = currentmodelrun

        # Read input file and process any Python and include file commands
        processedlines = process_python_include_code(inputfile, usernamespace)

        # Print constants/variables in user-accessable namespace
        uservars = ''
        for key, value in sorted(usernamespace.items()):
            if key != '__builtins__':
                uservars += '{}: {}, '.format(key, value)
        if G.messages:
            print('Constants/variables used/available for Python scripting: {{{}}}\n'.format(uservars[:-2]))

        # Write a file containing the input commands after Python or include file commands have been processed
        if args.write_processed:
            write_processed_file(processedlines, appendmodelnumber, G)

        # Check validity of command names and that essential commands are present
        singlecmds, multicmds, geometry = check_cmd_names(processedlines)

        # Create built-in materials
        m = Material(0, 'pec')
        m.se = float('inf')
        m.type = 'builtin'
        m.averagable = False
        G.materials.append(m)
        m = Material(1, 'free_space')
        m.type = 'builtin'
        G.materials.append(m)

        # Process parameters for commands that can only occur once in the model
        process_singlecmds(singlecmds, G)

        # Process parameters for commands that can occur multiple times in the model
        if G.messages: print()
        process_multicmds(multicmds, G)

        # Estimate and check memory (RAM) usage
        G.memory_estimate_basic()
        #G.memory_check()
        #if G.messages:
        #    if G.gpu is None:
        #        print('\nMemory (RAM) required: ~{}\n'.format(human_size(G.memoryusage)))
        #    else:
        #        print('\nMemory (RAM) required: ~{} host + ~{} GPU\n'.format(human_size(G.memoryusage), human_size(G.memoryusage)))

        # Initialise an array for volumetric material IDs (solid), boolean
        # arrays for specifying materials not to be averaged (rigid),
        # an array for cell edge IDs (ID)
        G.initialise_geometry_arrays()

        # Initialise arrays for the field components
        if G.gpu is None:
            G.initialise_field_arrays()

        # Process geometry commands in the order they were given
        process_geometrycmds(geometry, G)

        # Build the PMLs and calculate initial coefficients
        if G.messages: print()
        if all(value == 0 for value in G.pmlthickness.values()):
            if G.messages:
                print('PML: switched off')
            pass  # If all the PMLs are switched off don't need to build anything
        else:
            # Set default CFS parameters for PML if not given
            if not G.cfs:
                G.cfs = [CFS()]
            if G.messages:
                if all(value == G.pmlthickness['x0'] for value in G.pmlthickness.values()):
                    pmlinfo = str(G.pmlthickness['x0'])
                else:
                    pmlinfo = ''
                    for key, value in G.pmlthickness.items():
                        pmlinfo += '{}: {}, '.format(key, value)
                    pmlinfo = pmlinfo[:-2] + ' cells'
                print('PML: formulation: {}, order: {}, thickness: {}'.format(G.pmlformulation, len(G.cfs), pmlinfo))
            pbar = tqdm(total=sum(1 for value in G.pmlthickness.values() if value > 0), desc='Building PML boundaries', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not G.progressbars)
            build_pmls(G, pbar)
            pbar.close()

        # Build the model, i.e. set the material properties (ID) for every edge
        # of every Yee cell
        if G.messages: print()
        pbar = tqdm(total=2, desc='Building main grid', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not G.progressbars)
        build_electric_components(G.solid, G.rigidE, G.ID, G)
        pbar.update()
        build_magnetic_components(G.solid, G.rigidH, G.ID, G)
        pbar.update()
        pbar.close()

        # Add PEC boundaries to invariant direction in 2D modes
        # N.B. 2D modes are a single cell slice of 3D grid
        if '2D TMx' in G.mode:
            # Ey & Ez components
            G.ID[1, 0, :, :] = 0
            G.ID[1, 1, :, :] = 0
            G.ID[2, 0, :, :] = 0
            G.ID[2, 1, :, :] = 0
        elif '2D TMy' in G.mode:
            # Ex & Ez components
            G.ID[0, :, 0, :] = 0
            G.ID[0, :, 1, :] = 0
            G.ID[2, :, 0, :] = 0
            G.ID[2, :, 1, :] = 0
        elif '2D TMz' in G.mode:
            # Ex & Ey components
            G.ID[0, :, :, 0] = 0
            G.ID[0, :, :, 1] = 0
            G.ID[1, :, :, 0] = 0
            G.ID[1, :, :, 1] = 0

        # Process any voltage sources (that have resistance) to create a new
        # material at the source location
        for voltagesource in G.voltagesources:
            voltagesource.create_material(G)

        # Initialise arrays of update coefficients to pass to update functions
        G.initialise_std_update_coeff_arrays()

        # Initialise arrays of update coefficients and temporary values if
        # there are any dispersive materials
        if Material.maxpoles != 0:
            # Update estimated memory (RAM) usage
            G.memoryusage += int(3 * Material.maxpoles * (G.nx + 1) * (G.ny + 1) * (G.nz + 1) * np.dtype(complextype).itemsize)
            G.memory_check()
            if G.messages:
                print('\nMemory (RAM) required - updated (dispersive): ~{}\n'.format(human_size(G.memoryusage)))

            G.initialise_dispersive_arrays()

        # Check there is sufficient memory to store any snapshots
        if G.snapshots:
            snapsmemsize = 0
            for snap in G.snapshots:
                # 2 x required to account for electric and magnetic fields
                snapsmemsize += (2 * snap.datasizefield)
            G.memoryusage += int(snapsmemsize)
            G.memory_check(snapsmemsize=int(snapsmemsize))
            if G.messages:
                print('\nMemory (RAM) required - updated (snapshots): ~{}\n'.format(human_size(G.memoryusage)))

        # Process complete list of materials - calculate update coefficients,
        # store in arrays, and build text list of materials/properties
        materialsdata = process_materials(G)
        if G.messages:
            print('\nMaterials:')
            materialstable = AsciiTable(materialsdata)
            materialstable.outer_border = False
            materialstable.justify_columns[0] = 'right'
            print(materialstable.table)

        # Check to see if numerical dispersion might be a problem
        results = dispersion_analysis(G)
        if results['error'] and G.messages:
            print(Fore.RED + "\nWARNING: Numerical dispersion analysis not carried out as {}".format(results['error']) + Style.RESET_ALL)
        elif results['N'] < G.mingridsampling:
            raise GeneralError("Non-physical wave propagation: Material '{}' has wavelength sampled by {} cells, less than required minimum for physical wave propagation. Maximum significant frequency estimated as {:g}Hz".format(results['material'].ID, results['N'], results['maxfreq']))
        elif results['deltavp'] and np.abs(results['deltavp']) > G.maxnumericaldisp and G.messages:
            print(Fore.RED + "\nWARNING: Potentially significant numerical dispersion. Estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength sampled by {} cells. Maximum significant frequency estimated as {:g}Hz".format(results['deltavp'], results['material'].ID, results['N'], results['maxfreq']) + Style.RESET_ALL)
        elif results['deltavp'] and G.messages:
            print("\nNumerical dispersion analysis: estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength sampled by {} cells. Maximum significant frequency estimated as {:g}Hz".format(results['deltavp'], results['material'].ID, results['N'], results['maxfreq']))

    # If geometry information to be reused between model runs
    else:
        inputfilestr = '\n--- Model {}/{}, input file (not re-processed, i.e. geometry fixed): {}'.format(currentmodelrun, modelend, inputfile.name)
        if G.messages:
            print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)

        if G.gpu is None:
            # Clear arrays for field components
            G.initialise_field_arrays()

            # Clear arrays for fields in PML
            for pml in G.pmls:
                pml.initialise_field_arrays()

    # Adjust position of simple sources and receivers if required
    if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0:
        for source in itertools.chain(G.hertziandipoles, G.magneticdipoles):
            if currentmodelrun == 1:
                if source.xcoord + G.srcsteps[0] * modelend < 0 or source.xcoord + G.srcsteps[0] * modelend > G.nx or source.ycoord + G.srcsteps[1] * modelend < 0 or source.ycoord + G.srcsteps[1] * modelend > G.ny or source.zcoord + G.srcsteps[2] * modelend < 0 or source.zcoord + G.srcsteps[2] * modelend > G.nz:
                    raise GeneralError('Source(s) will be stepped to a position outside the domain.')
            source.xcoord = source.xcoordorigin + (currentmodelrun - 1) * G.srcsteps[0]
            source.ycoord = source.ycoordorigin + (currentmodelrun - 1) * G.srcsteps[1]
            source.zcoord = source.zcoordorigin + (currentmodelrun - 1) * G.srcsteps[2]
    if G.rxsteps[0] != 0 or G.rxsteps[1] != 0 or G.rxsteps[2] != 0:
        for receiver in G.rxs:
            if currentmodelrun == 1:
                if receiver.xcoord + G.rxsteps[0] * modelend < 0 or receiver.xcoord + G.rxsteps[0] * modelend > G.nx or receiver.ycoord + G.rxsteps[1] * modelend < 0 or receiver.ycoord + G.rxsteps[1] * modelend > G.ny or receiver.zcoord + G.rxsteps[2] * modelend < 0 or receiver.zcoord + G.rxsteps[2] * modelend > G.nz:
                    raise GeneralError('Receiver(s) will be stepped to a position outside the domain.')
            receiver.xcoord = receiver.xcoordorigin + (currentmodelrun - 1) * G.rxsteps[0]
            receiver.ycoord = receiver.ycoordorigin + (currentmodelrun - 1) * G.rxsteps[1]
            receiver.zcoord = receiver.zcoordorigin + (currentmodelrun - 1) * G.rxsteps[2]

    # Write files for any geometry views and geometry object outputs
    if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only and G.messages:
        print(Fore.RED + '\nWARNING: No geometry views or geometry objects to output found.' + Style.RESET_ALL)
    if G.geometryviews and (not args.geometry_fixed or currentmodelrun == 1):
        if G.messages: print()
        for i, geometryview in enumerate(G.geometryviews):
            geometryview.set_filename(appendmodelnumberGeometry, G)
            pbar = tqdm(total=geometryview.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry view file {}/{}, {}'.format(i + 1, len(G.geometryviews), os.path.split(geometryview.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not G.progressbars)
            geometryview.write_vtk(G, pbar)
            pbar.close()
    if G.geometryobjectswrite:
        for i, geometryobject in enumerate(G.geometryobjectswrite):
            pbar = tqdm(total=geometryobject.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry object file {}/{}, {}'.format(i + 1, len(G.geometryobjectswrite), os.path.split(geometryobject.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not G.progressbars)
            geometryobject.write_hdf5(G, pbar)
            pbar.close()

    # If only writing geometry information
    if args.geometry_only:
        tsolve = 0

    # Run simulation
    else:
        # Output filename
        inputdirectory, inputfilename = os.path.split(os.path.join(G.inputdirectory, G.inputfilename))
        if G.outputdirectory is None:
            outputdir = inputdirectory
        else:
            outputdir = G.outputdirectory
        # Save current directory
        curdir = os.getcwd()
        os.chdir(inputdirectory)
        outputdir = os.path.abspath(outputdir)
        if not os.path.isdir(outputdir):
            os.mkdir(outputdir)
            if G.messages:
                print('\nCreated output directory: {}'.format(outputdir))
        # Restore current directory
        os.chdir(curdir)
        basename, ext = os.path.splitext(inputfilename)
        outputfile = os.path.join(outputdir, basename + appendmodelnumber + '.out')
        if G.messages:
            print('\nOutput file: {}\n'.format(outputfile))

        # Main FDTD solving functions for either CPU or GPU
        if G.gpu is None:
            tsolve = solve_cpu(currentmodelrun, modelend, G)
        else:
            tsolve, memsolve = solve_gpu(currentmodelrun, modelend, G)

        # Write an output file in HDF5 format
        write_hdf5_outputfile(outputfile, G)

        # Write any snapshots to file
        if G.snapshots:
            # Create directory and construct filename from user-supplied name and model run number
            snapshotdir = os.path.join(G.inputdirectory, os.path.splitext(G.inputfilename)[0] + '_snaps' + appendmodelnumber)
            if not os.path.exists(snapshotdir):
                os.mkdir(snapshotdir)

            if G.messages: print()
            for i, snap in enumerate(G.snapshots):
                snap.filename = os.path.abspath(os.path.join(snapshotdir, snap.basefilename + '.vti'))
                pbar = tqdm(total=snap.vtkdatawritesize, leave=True, unit='byte', unit_scale=True, desc='Writing snapshot file {} of {}, {}'.format(i + 1, len(G.snapshots), os.path.split(snap.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not G.progressbars)
                snap.write_vtk_imagedata(pbar, G)
                pbar.close()
            if G.messages: print()

        if G.messages:
            if G.gpu is None:
                print('Memory (RAM) used: ~{}'.format(human_size(p.memory_info().rss)))
            else:
                print('Memory (RAM) used: ~{} host + ~{} GPU'.format(human_size(p.memory_info().rss), human_size(memsolve)))
            print('Solving time [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=tsolve)))

    # If geometry information to be reused between model runs then FDTDGrid
    # class instance must be global so that it persists
    if not args.geometry_fixed or currentmodelrun is modelend:
        del G

    return tsolve
Ejemplo n.º 15
0
def test_attributes():
    table_data = [['Name', 'Color', 'Type'], ['Avocado', 'green', 'nut'],
                  ['Tomato', 'red', 'fruit'],
                  ['Lettuce', 'green', 'vegetable'], ['Watermelon', 'green']]
    table = AsciiTable(table_data)

    table.justify_columns[0] = 'right'
    expected = dedent("""\
        +------------+-------+-----------+
        |       Name | Color | Type      |
        +------------+-------+-----------+
        |    Avocado | green | nut       |
        |     Tomato | red   | fruit     |
        |    Lettuce | green | vegetable |
        | Watermelon | green |           |
        +------------+-------+-----------+""")
    assert expected == table.table

    table.justify_columns[2] = 'center'
    expected = dedent("""\
        +------------+-------+-----------+
        |       Name | Color |    Type   |
        +------------+-------+-----------+
        |    Avocado | green |    nut    |
        |     Tomato | red   |   fruit   |
        |    Lettuce | green | vegetable |
        | Watermelon | green |           |
        +------------+-------+-----------+""")
    assert expected == table.table

    table.inner_heading_row_border = False
    expected = dedent("""\
        +------------+-------+-----------+
        |       Name | Color |    Type   |
        |    Avocado | green |    nut    |
        |     Tomato | red   |   fruit   |
        |    Lettuce | green | vegetable |
        | Watermelon | green |           |
        +------------+-------+-----------+""")
    assert expected == table.table

    table.title = 'Foods'
    table.inner_column_border = False
    expected = dedent("""\
        +Foods-------------------------+
        |       Name  Color     Type   |
        |    Avocado  green     nut    |
        |     Tomato  red      fruit   |
        |    Lettuce  green  vegetable |
        | Watermelon  green            |
        +------------------------------+""")
    assert expected == table.table

    table.outer_border = False
    expected = ('       Name  Color     Type   \n'
                '    Avocado  green     nut    \n'
                '     Tomato  red      fruit   \n'
                '    Lettuce  green  vegetable \n'
                ' Watermelon  green            ')
    assert expected == table.table

    table.outer_border = True
    table.inner_row_border = True
    expected = dedent("""\
        +Foods-------------------------+
        |       Name  Color     Type   |
        +------------------------------+
        |    Avocado  green     nut    |
        +------------------------------+
        |     Tomato  red      fruit   |
        +------------------------------+
        |    Lettuce  green  vegetable |
        +------------------------------+
        | Watermelon  green            |
        +------------------------------+""")
    assert expected == table.table

    table.title = False
    table.inner_column_border = True
    table.inner_heading_row_border = False  # Ignored due to inner_row_border.
    table.inner_row_border = True
    expected = dedent("""\
        +------------+-------+-----------+
        |       Name | Color |    Type   |
        +------------+-------+-----------+
        |    Avocado | green |    nut    |
        +------------+-------+-----------+
        |     Tomato | red   |   fruit   |
        +------------+-------+-----------+
        |    Lettuce | green | vegetable |
        +------------+-------+-----------+
        | Watermelon | green |           |
        +------------+-------+-----------+""")
    assert expected == table.table

    table.outer_border = False
    expected = ('       Name | Color |    Type   \n'
                '------------+-------+-----------\n'
                '    Avocado | green |    nut    \n'
                '------------+-------+-----------\n'
                '     Tomato | red   |   fruit   \n'
                '------------+-------+-----------\n'
                '    Lettuce | green | vegetable \n'
                '------------+-------+-----------\n'
                ' Watermelon | green |           ')
    assert expected == table.table
Ejemplo n.º 16
0
def test_attributes():
    """Test table attributes."""
    table_data = [
        ['Name', 'Color', 'Type'],
        ['Avocado', 'green', 'nut'],
        ['Tomato', 'red', 'fruit'],
        ['Lettuce', 'green', 'vegetable'],
        ['Watermelon', 'green']
    ]
    table = AsciiTable(table_data)

    table.justify_columns[0] = 'right'
    expected = dedent("""\
        +------------+-------+-----------+
        |       Name | Color | Type      |
        +------------+-------+-----------+
        |    Avocado | green | nut       |
        |     Tomato | red   | fruit     |
        |    Lettuce | green | vegetable |
        | Watermelon | green |           |
        +------------+-------+-----------+""")
    assert expected == table.table

    table.justify_columns[2] = 'center'
    expected = dedent("""\
        +------------+-------+-----------+
        |       Name | Color |    Type   |
        +------------+-------+-----------+
        |    Avocado | green |    nut    |
        |     Tomato | red   |   fruit   |
        |    Lettuce | green | vegetable |
        | Watermelon | green |           |
        +------------+-------+-----------+""")
    assert expected == table.table

    table.inner_heading_row_border = False
    expected = dedent("""\
        +------------+-------+-----------+
        |       Name | Color |    Type   |
        |    Avocado | green |    nut    |
        |     Tomato | red   |   fruit   |
        |    Lettuce | green | vegetable |
        | Watermelon | green |           |
        +------------+-------+-----------+""")
    assert expected == table.table

    table.title = 'Foods'
    table.inner_column_border = False
    expected = dedent("""\
        +Foods-------------------------+
        |       Name  Color     Type   |
        |    Avocado  green     nut    |
        |     Tomato  red      fruit   |
        |    Lettuce  green  vegetable |
        | Watermelon  green            |
        +------------------------------+""")
    assert expected == table.table

    table.outer_border = False
    expected = (
        '       Name  Color     Type   \n'
        '    Avocado  green     nut    \n'
        '     Tomato  red      fruit   \n'
        '    Lettuce  green  vegetable \n'
        ' Watermelon  green            '
    )
    assert expected == table.table

    table.outer_border = True
    table.inner_row_border = True
    expected = dedent("""\
        +Foods-------------------------+
        |       Name  Color     Type   |
        +------------------------------+
        |    Avocado  green     nut    |
        +------------------------------+
        |     Tomato  red      fruit   |
        +------------------------------+
        |    Lettuce  green  vegetable |
        +------------------------------+
        | Watermelon  green            |
        +------------------------------+""")
    assert expected == table.table

    table.title = False
    table.inner_column_border = True
    table.inner_heading_row_border = False  # Ignored due to inner_row_border.
    table.inner_row_border = True
    expected = dedent("""\
        +------------+-------+-----------+
        |       Name | Color |    Type   |
        +------------+-------+-----------+
        |    Avocado | green |    nut    |
        +------------+-------+-----------+
        |     Tomato | red   |   fruit   |
        +------------+-------+-----------+
        |    Lettuce | green | vegetable |
        +------------+-------+-----------+
        | Watermelon | green |           |
        +------------+-------+-----------+""")
    assert expected == table.table

    table.outer_border = False
    expected = (
        '       Name | Color |    Type   \n'
        '------------+-------+-----------\n'
        '    Avocado | green |    nut    \n'
        '------------+-------+-----------\n'
        '     Tomato | red   |   fruit   \n'
        '------------+-------+-----------\n'
        '    Lettuce | green | vegetable \n'
        '------------+-------+-----------\n'
        ' Watermelon | green |           '
    )
    assert expected == table.table
Ejemplo n.º 17
0
def generatePrintTable(PField):
    resultTable = AsciiTable(PField)
    resultTable.inner_heading_row_border = True
    resultTable.outer_border = True
    resultTable.inner_row_border = True
    print(resultTable.table)
Ejemplo n.º 18
0
def print_summary(row_data):
    table = AsciiTable([row_data])
    table.outer_border = False
    table.padding_left = 10
    table.padding_right = 2
    print(table.table)
Ejemplo n.º 19
0
def format_key_values(key_values: KeyValuesType,
                      title: Optional[str] = None,
                      formatter: Callable[[Any], str] = str,
                      delimiter_char: str = '=') -> str:
    """
    Format key value sequence into str.

    The basic usage, to format a :class:`Config`, a dict or a list of tuples:

    >>> print(format_key_values(Config(a=123, b=Config(value=456))))
    a         123
    b.value   456
    >>> print(format_key_values({'a': 123, 'b': {'value': 456}}))
    a   123
    b   {'value': 456}
    >>> print(format_key_values([('a', 123), ('b', {'value': 456})]))
    a   123
    b   {'value': 456}

    To add a title and a delimiter:

    >>> print(format_key_values(Config(a=123, b=Config(value=456)),
    ...                         title='short title'))
    short title
    =============
    a         123
    b.value   456
    >>> print(format_key_values({'a': 123, 'b': {'value': 456}},
    ...                         title='long long long title'))
    long long long title
    ====================
    a   123
    b   {'value': 456}

    Args:
        key_values: The sequence of key values, may be a :class:`Config`,
            a dict, or a list of (key, value) pairs.
            If it is a :class:`Config`, it will be flatten via
            :meth:`Config.to_flatten_dict()`.
        title: If specified, will prepend a title and a horizontal delimiter
            to the front of returned string.
        formatter: The function to format values.
        delimiter_char: The character to use for the delimiter between title
            and config key values.

    Returns:
        The formatted str.
    """
    if len(delimiter_char) != 1:
        raise ValueError(f'`delimiter_char` must be one character: '
                         f'got {delimiter_char!r}')

    if isinstance(key_values, Config):
        key_values = config_to_dict(key_values, flatten=True)

    if hasattr(key_values, 'items'):
        data = [(key, formatter(value)) for key, value in key_values.items()]
    else:
        data = [(key, formatter(value)) for key, value in key_values]

    # use the terminaltables.AsciiTable to format our key values
    table = AsciiTable(data)
    table.padding_left = 0
    table.padding_right = 3
    table.inner_column_border = False
    table.inner_footing_row_border = False
    table.inner_heading_row_border = False
    table.inner_row_border = False
    table.outer_border = False
    lines = [line.rstrip() for line in table.table.split('\n')]

    # prepend a title
    if title is not None:
        max_length = max(max(map(len, lines)), len(title))
        delim = delimiter_char * max_length
        lines = [title, delim] + lines

    return '\n'.join(lines)
Ejemplo n.º 20
0
def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
    """Runs a model - processes the input file; builds the Yee cells; calculates update coefficients; runs main FDTD loop.

    Args:
        args (dict): Namespace with command line arguments
        modelrun (int): Current model run number.
        numbermodelruns (int): Total number of model runs.
        inputfile (str): Name of the input file to open.
        usernamespace (dict): Namespace that can be accessed by user in any Python code blocks in input file.

    Returns:
        tsolve (int): Length of time (seconds) of main FDTD calculations
    """

    # Monitor memory usage
    p = psutil.Process()

    # Declare variable to hold FDTDGrid class
    global G

    # Normal model reading/building process; bypassed if geometry information to be reused
    if 'G' not in globals():
        inputfilestr = '\n--- Model {} of {}, input file: {}'.format(modelrun, numbermodelruns, inputfile)
        print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)

        # Add the current model run to namespace that can be accessed by user in any Python code blocks in input file
        usernamespace['current_model_run'] = modelrun

        # Read input file and process any Python or include commands
        processedlines = process_python_include_code(inputfile, usernamespace)

        # Print constants/variables in user-accessable namespace
        uservars = ''
        for key, value in sorted(usernamespace.items()):
            if key != '__builtins__':
                uservars += '{}: {}, '.format(key, value)
        print('Constants/variables used/available for Python scripting: {{{}}}\n'.format(uservars[:-2]))

        # Write a file containing the input commands after Python or include commands have been processed
        if args.write_processed:
            write_processed_file(inputfile, modelrun, numbermodelruns, processedlines)

        # Check validity of command names and that essential commands are present
        singlecmds, multicmds, geometry = check_cmd_names(processedlines)

        # Initialise an instance of the FDTDGrid class
        G = FDTDGrid()
        G.inputfilename = os.path.split(inputfile)[1]
        G.inputdirectory = os.path.dirname(os.path.abspath(inputfile))

        # Create built-in materials
        m = Material(0, 'pec')
        m.se = float('inf')
        m.type = 'builtin'
        m.averagable = False
        G.materials.append(m)
        m = Material(1, 'free_space')
        m.type = 'builtin'
        G.materials.append(m)

        # Process parameters for commands that can only occur once in the model
        process_singlecmds(singlecmds, G)

        # Process parameters for commands that can occur multiple times in the model
        print()
        process_multicmds(multicmds, G)

        # Initialise an array for volumetric material IDs (solid), boolean arrays for specifying materials not to be averaged (rigid),
        # an array for cell edge IDs (ID)
        G.initialise_geometry_arrays()

        # Initialise arrays for the field components
        G.initialise_field_arrays()

        # Process geometry commands in the order they were given
        process_geometrycmds(geometry, G)

        # Build the PMLs and calculate initial coefficients
        print()
        if all(value == 0 for value in G.pmlthickness.values()):
            if G.messages:
                print('PML boundaries: switched off')
            pass  # If all the PMLs are switched off don't need to build anything
        else:
            if G.messages:
                if all(value == G.pmlthickness['xminus'] for value in G.pmlthickness.values()):
                    pmlinfo = G.pmlthickness['xminus']
                else:
                    pmlinfo = ''
                    for key, value in G.pmlthickness.items():
                        pmlinfo += '{}: {}, '.format(key, value)
                    pmlinfo = pmlinfo[:-2]
                print('PML boundaries: {} cells'.format(pmlinfo))
            pbar = tqdm(total=sum(1 for value in G.pmlthickness.values() if value > 0), desc='Building PML boundaries', ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable)
            build_pmls(G, pbar)
            pbar.close()

        # Build the model, i.e. set the material properties (ID) for every edge of every Yee cell
        print()
        pbar = tqdm(total=2, desc='Building main grid', ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable)
        build_electric_components(G.solid, G.rigidE, G.ID, G)
        pbar.update()
        build_magnetic_components(G.solid, G.rigidH, G.ID, G)
        pbar.update()
        pbar.close()

        # Process any voltage sources (that have resistance) to create a new material at the source location
        for voltagesource in G.voltagesources:
            voltagesource.create_material(G)

        # Initialise arrays of update coefficients to pass to update functions
        G.initialise_std_update_coeff_arrays()

        # Initialise arrays of update coefficients and temporary values if there are any dispersive materials
        if Material.maxpoles != 0:
            G.initialise_dispersive_arrays()

        # Process complete list of materials - calculate update coefficients, store in arrays, and build text list of materials/properties
        materialsdata = process_materials(G)
        if G.messages:
            materialstable = AsciiTable(materialsdata)
            materialstable.outer_border = False
            materialstable.justify_columns[0] = 'right'
            print(materialstable.table)

        # Check to see if numerical dispersion might be a problem
        results = dispersion_analysis(G)
        if results['deltavp'] and np.abs(results['deltavp']) > G.maxnumericaldisp:
            print(Fore.RED + "\nWARNING: Potentially significant numerical dispersion. Largest physical phase-velocity error is {:.2f}% in material '{}' with wavelength sampled by {} cells (maximum significant frequency {:g}Hz)".format(results['deltavp'], results['material'].ID, round_value(results['N']), results['maxfreq']) + Style.RESET_ALL)
        elif results['deltavp']:
            print("\nNumerical dispersion analysis: largest physical phase-velocity error is {:.2f}% in material '{}' with wavelength sampled by {} cells (maximum significant frequency {:g}Hz)".format(results['deltavp'], results['material'].ID, round_value(results['N']), results['maxfreq']))

    # If geometry information to be reused between model runs
    else:
        inputfilestr = '\n--- Model {} of {}, input file (not re-processed, i.e. geometry fixed): {}'.format(modelrun, numbermodelruns, inputfile)
        print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)

        # Clear arrays for field components
        G.initialise_field_arrays()

        # Clear arrays for fields in PML
        for pml in G.pmls:
            pml.initialise_field_arrays()

    # Adjust position of simple sources and receivers if required
    if G.srcsteps[0] > 0 or G.srcsteps[1] > 0 or G.srcsteps[2] > 0:
        for source in itertools.chain(G.hertziandipoles, G.magneticdipoles):
            if modelrun == 1:
                if source.xcoord + G.srcsteps[0] * (numbermodelruns - 1) > G.nx or source.ycoord + G.srcsteps[1] * (numbermodelruns - 1) > G.ny or source.zcoord + G.srcsteps[2] * (numbermodelruns - 1) > G.nz:
                    raise GeneralError('Source(s) will be stepped to a position outside the domain.')
            source.xcoord = source.xcoordorigin + (modelrun - 1) * G.srcsteps[0]
            source.ycoord = source.ycoordorigin + (modelrun - 1) * G.srcsteps[1]
            source.zcoord = source.zcoordorigin + (modelrun - 1) * G.srcsteps[2]
    if G.rxsteps[0] > 0 or G.rxsteps[1] > 0 or G.rxsteps[2] > 0:
        for receiver in G.rxs:
            if modelrun == 1:
                if receiver.xcoord + G.rxsteps[0] * (numbermodelruns - 1) > G.nx or receiver.ycoord + G.rxsteps[1] * (numbermodelruns - 1) > G.ny or receiver.zcoord + G.rxsteps[2] * (numbermodelruns - 1) > G.nz:
                    raise GeneralError('Receiver(s) will be stepped to a position outside the domain.')
            receiver.xcoord = receiver.xcoordorigin + (modelrun - 1) * G.rxsteps[0]
            receiver.ycoord = receiver.ycoordorigin + (modelrun - 1) * G.rxsteps[1]
            receiver.zcoord = receiver.zcoordorigin + (modelrun - 1) * G.rxsteps[2]

    # Write files for any geometry views and geometry object outputs
    if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only:
        print(Fore.RED + '\nWARNING: No geometry views or geometry objects to output found.' + Style.RESET_ALL)
    if G.geometryviews:
        print()
        for i, geometryview in enumerate(G.geometryviews):
            geometryview.set_filename(modelrun, numbermodelruns, G)
            pbar = tqdm(total=geometryview.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry view file {} of {}, {}'.format(i + 1, len(G.geometryviews), os.path.split(geometryview.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable)
            geometryview.write_vtk(modelrun, numbermodelruns, G, pbar)
            pbar.close()
    if G.geometryobjectswrite:

        for i, geometryobject in enumerate(G.geometryobjectswrite):
            pbar = tqdm(total=geometryobject.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry object file {} of {}, {}'.format(i + 1, len(G.geometryobjectswrite), os.path.split(geometryobject.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable)
            geometryobject.write_hdf5(G, pbar)
            pbar.close()

    # Run simulation (if not doing geometry only)
    if not args.geometry_only:

        # Prepare any snapshot files
        for snapshot in G.snapshots:
            snapshot.prepare_vtk_imagedata(modelrun, numbermodelruns, G)

        # Output filename
        inputfileparts = os.path.splitext(inputfile)
        if numbermodelruns == 1:
            outputfile = inputfileparts[0] + '.out'
        else:
            outputfile = inputfileparts[0] + str(modelrun) + '.out'
        print('\nOutput file: {}\n'.format(outputfile))

        ####################################
        #  Start - Main FDTD calculations  #
        ####################################
        tsolvestart = perf_counter()

        # Absolute time
        abstime = 0

        for timestep in tqdm(range(G.iterations), desc='Running simulation, model ' + str(modelrun) + ' of ' + str(numbermodelruns), ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable):
            # Store field component values for every receiver and transmission line
            store_outputs(timestep, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)

            # Write any snapshots to file
            for i, snap in enumerate(G.snapshots):
                if snap.time == timestep + 1:
                    snapiters = 36 * (((snap.xf - snap.xs) / snap.dx) * ((snap.yf - snap.ys) / snap.dy) * ((snap.zf - snap.zs) / snap.dz))
                    pbar = tqdm(total=snapiters, leave=False, unit='byte', unit_scale=True, desc='  Writing snapshot file {} of {}, {}'.format(i + 1, len(G.snapshots), os.path.split(snap.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable)
                    snap.write_vtk_imagedata(G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G, pbar)
                    pbar.close()

            # Update electric field components
            if Material.maxpoles == 0:  # All materials are non-dispersive so do standard update
                update_electric(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
            elif Material.maxpoles == 1:  # If there are any dispersive materials do 1st part of dispersive update (it is split into two parts as it requires present and updated electric field values).
                update_electric_dispersive_1pole_A(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
            elif Material.maxpoles > 1:
                update_electric_dispersive_multipole_A(G.nx, G.ny, G.nz, G.nthreads, Material.maxpoles, G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)

            # Update electric field components with the PML correction
            for pml in G.pmls:
                pml.update_electric(G)

            # Update electric field components from sources (update any Hertzian dipole sources last)
            for source in G.voltagesources + G.transmissionlines + G.hertziandipoles:
                source.update_electric(abstime, G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G)

            # If there are any dispersive materials do 2nd part of dispersive update (it is split into two parts as it requires present and updated electric field values). Therefore it can only be completely updated after the electric field has been updated by the PML and source updates.
            if Material.maxpoles == 1:
                update_electric_dispersive_1pole_B(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez)
            elif Material.maxpoles > 1:
                update_electric_dispersive_multipole_B(G.nx, G.ny, G.nz, G.nthreads, Material.maxpoles, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez)

            # Increment absolute time value
            abstime += 0.5 * G.dt

            # Update magnetic field components
            update_magnetic(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsH, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)

            # Update magnetic field components with the PML correction
            for pml in G.pmls:
                pml.update_magnetic(G)

            # Update magnetic field components from sources
            for source in G.transmissionlines + G.magneticdipoles:
                source.update_magnetic(abstime, G.updatecoeffsH, G.ID, G.Hx, G.Hy, G.Hz, G)

            # Increment absolute time value
            abstime += 0.5 * G.dt

        tsolve = int(perf_counter() - tsolvestart)

        # Write an output file in HDF5 format
        write_hdf5_outputfile(outputfile, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)

        ##################################
        #  End - Main FDTD calculations  #
        ##################################

    if G.messages:
        print('Memory (RAM) used: ~{}'.format(human_size(p.memory_info().rss)))

    # If geometry information to be reused between model runs then FDTDGrid class instance must be global so that it persists
    if not args.geometry_fixed:
        del G

    # Return time to complete solving if in benchmarking mode
    if args.benchmark:
        return tsolve
Ejemplo n.º 21
0
def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usernamespace):
    """Runs a model - processes the input file; builds the Yee cells; calculates update coefficients; runs main FDTD loop.

    Args:
        args (dict): Namespace with command line arguments
        currentmodelrun (int): Current model run number.
        modelend (int): Number of last model to run.
        numbermodelruns (int): Total number of model runs.
        inputfile (object): File object for the input file.
        usernamespace (dict): Namespace that can be accessed by user in any Python code blocks in input file.

    Returns:
        tsolve (int): Length of time (seconds) of main FDTD calculations
    """

    # Monitor memory usage
    p = psutil.Process()

    # Declare variable to hold FDTDGrid class
    global G

    # Used for naming geometry and output files
    appendmodelnumber = '' if numbermodelruns == 1 and not args.task and not args.restart else str(currentmodelrun)
    
    # Normal model reading/building process; bypassed if geometry information to be reused
    if 'G' not in globals():

        # Initialise an instance of the FDTDGrid class
        G = FDTDGrid()

        G.inputfilename = os.path.split(inputfile.name)[1]
        G.inputdirectory = os.path.dirname(os.path.abspath(inputfile.name))
        inputfilestr = '\n--- Model {}/{}, input file: {}'.format(currentmodelrun, modelend, inputfile.name)
        print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)

        # Add the current model run to namespace that can be accessed by user in any Python code blocks in input file
        usernamespace['current_model_run'] = currentmodelrun

        # Read input file and process any Python and include file commands
        processedlines = process_python_include_code(inputfile, usernamespace)

        # Print constants/variables in user-accessable namespace
        uservars = ''
        for key, value in sorted(usernamespace.items()):
            if key != '__builtins__':
                uservars += '{}: {}, '.format(key, value)
        print('Constants/variables used/available for Python scripting: {{{}}}\n'.format(uservars[:-2]))

        # Write a file containing the input commands after Python or include file commands have been processed
        if args.write_processed:
            write_processed_file(processedlines, appendmodelnumber, G)

        # Check validity of command names and that essential commands are present
        singlecmds, multicmds, geometry = check_cmd_names(processedlines)

        # Create built-in materials
        m = Material(0, 'pec')
        m.se = float('inf')
        m.type = 'builtin'
        m.averagable = False
        G.materials.append(m)
        m = Material(1, 'free_space')
        m.type = 'builtin'
        G.materials.append(m)

        # Process parameters for commands that can only occur once in the model
        process_singlecmds(singlecmds, G)

        # Process parameters for commands that can occur multiple times in the model
        print()
        process_multicmds(multicmds, G)

        # Initialise an array for volumetric material IDs (solid), boolean arrays for specifying materials not to be averaged (rigid),
        # an array for cell edge IDs (ID)
        G.initialise_geometry_arrays()

        # Initialise arrays for the field components
        G.initialise_field_arrays()

        # Process geometry commands in the order they were given
        process_geometrycmds(geometry, G)

        # Build the PMLs and calculate initial coefficients
        print()
        if all(value == 0 for value in G.pmlthickness.values()):
            if G.messages:
                print('PML boundaries: switched off')
            pass  # If all the PMLs are switched off don't need to build anything
        else:
            if G.messages:
                if all(value == G.pmlthickness['x0'] for value in G.pmlthickness.values()):
                    pmlinfo = str(G.pmlthickness['x0']) + ' cells'
                else:
                    pmlinfo = ''
                    for key, value in G.pmlthickness.items():
                        pmlinfo += '{}: {} cells, '.format(key, value)
                    pmlinfo = pmlinfo[:-2]
                print('PML boundaries: {}'.format(pmlinfo))
            pbar = tqdm(total=sum(1 for value in G.pmlthickness.values() if value > 0), desc='Building PML boundaries', ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable)
            build_pmls(G, pbar)
            pbar.close()

        # Build the model, i.e. set the material properties (ID) for every edge of every Yee cell
        print()
        pbar = tqdm(total=2, desc='Building main grid', ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable)
        build_electric_components(G.solid, G.rigidE, G.ID, G)
        pbar.update()
        build_magnetic_components(G.solid, G.rigidH, G.ID, G)
        pbar.update()
        pbar.close()

        # Process any voltage sources (that have resistance) to create a new material at the source location
        for voltagesource in G.voltagesources:
            voltagesource.create_material(G)

        # Initialise arrays of update coefficients to pass to update functions
        G.initialise_std_update_coeff_arrays()

        # Initialise arrays of update coefficients and temporary values if there are any dispersive materials
        if Material.maxpoles != 0:
            G.initialise_dispersive_arrays()

        # Process complete list of materials - calculate update coefficients, store in arrays, and build text list of materials/properties
        materialsdata = process_materials(G)
        if G.messages:
            print('\nMaterials:')
            materialstable = AsciiTable(materialsdata)
            materialstable.outer_border = False
            materialstable.justify_columns[0] = 'right'
            print(materialstable.table)

        # Check to see if numerical dispersion might be a problem
        results = dispersion_analysis(G)
        if not results['waveform']:
            print(Fore.RED + "\nWARNING: Numerical dispersion analysis not carried out as either no waveform detected or waveform does not fit within specified time window and is therefore being truncated." + Style.RESET_ALL)
        elif results['N'] < G.mingridsampling:
            raise GeneralError("Non-physical wave propagation: Material '{}' has wavelength sampled by {} cells, less than required minimum for physical wave propagation. Maximum significant frequency estimated as {:g}Hz".format(results['material'].ID, results['N'], results['maxfreq']))
        elif results['deltavp'] and np.abs(results['deltavp']) > G.maxnumericaldisp:
            print(Fore.RED + "\nWARNING: Potentially significant numerical dispersion. Estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength sampled by {} cells. Maximum significant frequency estimated as {:g}Hz".format(results['deltavp'], results['material'].ID, results['N'], results['maxfreq']) + Style.RESET_ALL)
        elif results['deltavp'] and G.messages:
            print("\nNumerical dispersion analysis: estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength sampled by {} cells. Maximum significant frequency estimated as {:g}Hz".format(results['deltavp'], results['material'].ID, results['N'], results['maxfreq']))

    # If geometry information to be reused between model runs
    else:
        inputfilestr = '\n--- Model {}/{}, input file (not re-processed, i.e. geometry fixed): {}'.format(currentmodelrun, modelend, inputfile.name)
        print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)

        # Clear arrays for field components
        G.initialise_field_arrays()

        # Clear arrays for fields in PML
        for pml in G.pmls:
            pml.initialise_field_arrays()

    # Adjust position of simple sources and receivers if required
    if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0:
        for source in itertools.chain(G.hertziandipoles, G.magneticdipoles):
            if currentmodelrun == 1:
                if source.xcoord + G.srcsteps[0] * modelend < 0 or source.xcoord + G.srcsteps[0] * modelend > G.nx or source.ycoord + G.srcsteps[1] * modelend < 0 or source.ycoord + G.srcsteps[1] * modelend > G.ny or source.zcoord + G.srcsteps[2] * modelend < 0 or source.zcoord + G.srcsteps[2] * modelend > G.nz:
                    raise GeneralError('Source(s) will be stepped to a position outside the domain.')
            source.xcoord = source.xcoordorigin + (currentmodelrun - 1) * G.srcsteps[0]
            source.ycoord = source.ycoordorigin + (currentmodelrun - 1) * G.srcsteps[1]
            source.zcoord = source.zcoordorigin + (currentmodelrun - 1) * G.srcsteps[2]
    if G.rxsteps[0] != 0 or G.rxsteps[1] != 0 or G.rxsteps[2] != 0:
        for receiver in G.rxs:
            if currentmodelrun == 1:
                if receiver.xcoord + G.rxsteps[0] * modelend < 0 or receiver.xcoord + G.rxsteps[0] * modelend > G.nx or receiver.ycoord + G.rxsteps[1] * modelend < 0 or receiver.ycoord + G.rxsteps[1] * modelend > G.ny or receiver.zcoord + G.rxsteps[2] * modelend < 0 or receiver.zcoord + G.rxsteps[2] * modelend > G.nz:
                    raise GeneralError('Receiver(s) will be stepped to a position outside the domain.')
            receiver.xcoord = receiver.xcoordorigin + (currentmodelrun - 1) * G.rxsteps[0]
            receiver.ycoord = receiver.ycoordorigin + (currentmodelrun - 1) * G.rxsteps[1]
            receiver.zcoord = receiver.zcoordorigin + (currentmodelrun - 1) * G.rxsteps[2]

    # Write files for any geometry views and geometry object outputs
    if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only:
        print(Fore.RED + '\nWARNING: No geometry views or geometry objects to output found.' + Style.RESET_ALL)
    if G.geometryviews:
        print()
        for i, geometryview in enumerate(G.geometryviews):
            geometryview.set_filename(appendmodelnumber, G)
            pbar = tqdm(total=geometryview.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry view file {}/{}, {}'.format(i + 1, len(G.geometryviews), os.path.split(geometryview.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable)
            geometryview.write_vtk(G, pbar)
            pbar.close()
    if G.geometryobjectswrite:
        for i, geometryobject in enumerate(G.geometryobjectswrite):
            pbar = tqdm(total=geometryobject.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry object file {}/{}, {}'.format(i + 1, len(G.geometryobjectswrite), os.path.split(geometryobject.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable)
            geometryobject.write_hdf5(G, pbar)
            pbar.close()

    # If only writing geometry information
    if args.geometry_only:
        tsolve = 0

    # Run simulation
    else:
        # Prepare any snapshot files
        for snapshot in G.snapshots:
            snapshot.prepare_vtk_imagedata(appendmodelnumber, G)

        # Output filename
        inputfileparts = os.path.splitext(os.path.join(G.inputdirectory, G.inputfilename))
        outputfile = inputfileparts[0] + appendmodelnumber + '.out'
        print('\nOutput file: {}\n'.format(outputfile))

        # Main FDTD solving functions for either CPU or GPU
        tsolve = solve_cpu(currentmodelrun, modelend, G)

        # Write an output file in HDF5 format
        write_hdf5_outputfile(outputfile, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)

        if G.messages:
            print('Memory (RAM) used: ~{}'.format(human_size(p.memory_info().rss)))
            print('Solving time [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=tsolve)))

        # If geometry information to be reused between model runs then FDTDGrid class instance must be global so that it persists
        if not args.geometry_fixed:
            del G

    return tsolve
Ejemplo n.º 22
0
Just prints sample text and exits.
"""

from __future__ import print_function

from terminaltables import AsciiTable, DoubleTable


table_data = [
    ['Platform', 'Years', 'Notes'],
    ['Mk5', '2007-2009', '\033[37;41mUnavailable\033[0m'],
    ['MKVI', '2009-2013', 'Might actually be Mk5.'],
]
table = AsciiTable(table_data, 'wangbin')
print()
print(table.table)

table = DoubleTable(table_data, 'Jetta SportWagen')
table.inner_row_border = True
table.justify_columns[2] = 'right'
print()
print(table.table)

table.outer_border = False
table.justify_columns[1] = 'center'
print()
print(table.table)

print()
Ejemplo n.º 23
0
"""Simple example usage of terminaltables without any other dependencies.

Just prints sample text and exits.
"""

from __future__ import print_function

from terminaltables import AsciiTable, DoubleTable

table_data = [
    ['Platform', 'Years', 'Notes'],
    ['Mk5', '2007-2009', '\033[37;41mUnavailable\033[0m'],
    ['MKVI', '2009-2013', 'Might actually be Mk5.'],
]
table = AsciiTable(table_data, 'wangbin')
print()
print(table.table)

table = DoubleTable(table_data, 'Jetta SportWagen')
table.inner_row_border = True
table.justify_columns[2] = 'right'
print()
print(table.table)

table.outer_border = False
table.justify_columns[1] = 'center'
print()
print(table.table)

print()
Ejemplo n.º 24
0
def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
    """Runs a model - processes the input file; builds the Yee cells; calculates update coefficients; runs main FDTD loop.

    Args:
        args (dict): Namespace with command line arguments
        modelrun (int): Current model run number.
        numbermodelruns (int): Total number of model runs.
        inputfile (str): Name of the input file to open.
        usernamespace (dict): Namespace that can be accessed by user in any Python code blocks in input file.

    Returns:
        tsolve (int): Length of time (seconds) of main FDTD calculations
    """

    # Monitor memory usage
    p = psutil.Process()

    # Declare variable to hold FDTDGrid class
    global G

    # Normal model reading/building process; bypassed if geometry information to be reused
    if 'G' not in globals():
        inputfilestr = '\n--- Model {}/{}, input file: {}'.format(
            modelrun, numbermodelruns, inputfile)
        print(Fore.GREEN + '{} {}\n'.format(
            inputfilestr, '-' *
            (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)

        # Add the current model run to namespace that can be accessed by user in any Python code blocks in input file
        usernamespace['current_model_run'] = modelrun

        # Read input file and process any Python or include commands
        processedlines = process_python_include_code(inputfile, usernamespace)

        # Print constants/variables in user-accessable namespace
        uservars = ''
        for key, value in sorted(usernamespace.items()):
            if key != '__builtins__':
                uservars += '{}: {}, '.format(key, value)
        print(
            'Constants/variables used/available for Python scripting: {{{}}}\n'
            .format(uservars[:-2]))

        # Write a file containing the input commands after Python or include commands have been processed
        if args.write_processed:
            write_processed_file(inputfile, modelrun, numbermodelruns,
                                 processedlines)

        # Check validity of command names and that essential commands are present
        singlecmds, multicmds, geometry = check_cmd_names(processedlines)

        # Initialise an instance of the FDTDGrid class
        G = FDTDGrid()
        G.inputfilename = os.path.split(inputfile)[1]
        G.inputdirectory = os.path.dirname(os.path.abspath(inputfile))

        # Create built-in materials
        m = Material(0, 'pec')
        m.se = float('inf')
        m.type = 'builtin'
        m.averagable = False
        G.materials.append(m)
        m = Material(1, 'free_space')
        m.type = 'builtin'
        G.materials.append(m)

        # Process parameters for commands that can only occur once in the model
        process_singlecmds(singlecmds, G)

        # Process parameters for commands that can occur multiple times in the model
        print()
        process_multicmds(multicmds, G)

        # Initialise an array for volumetric material IDs (solid), boolean arrays for specifying materials not to be averaged (rigid),
        # an array for cell edge IDs (ID)
        G.initialise_geometry_arrays()

        # Initialise arrays for the field components
        G.initialise_field_arrays()

        # Process geometry commands in the order they were given
        process_geometrycmds(geometry, G)

        # Build the PMLs and calculate initial coefficients
        print()
        if all(value == 0 for value in G.pmlthickness.values()):
            if G.messages:
                print('PML boundaries: switched off')
            pass  # If all the PMLs are switched off don't need to build anything
        else:
            if G.messages:
                if all(value == G.pmlthickness['x0']
                       for value in G.pmlthickness.values()):
                    pmlinfo = str(G.pmlthickness['x0']) + ' cells'
                else:
                    pmlinfo = ''
                    for key, value in G.pmlthickness.items():
                        pmlinfo += '{}: {} cells, '.format(key, value)
                    pmlinfo = pmlinfo[:-2]
                print('PML boundaries: {}'.format(pmlinfo))
            pbar = tqdm(total=sum(1 for value in G.pmlthickness.values()
                                  if value > 0),
                        desc='Building PML boundaries',
                        ncols=get_terminal_width() - 1,
                        file=sys.stdout,
                        disable=G.tqdmdisable)
            build_pmls(G, pbar)
            pbar.close()

        # Build the model, i.e. set the material properties (ID) for every edge of every Yee cell
        print()
        pbar = tqdm(total=2,
                    desc='Building main grid',
                    ncols=get_terminal_width() - 1,
                    file=sys.stdout,
                    disable=G.tqdmdisable)
        build_electric_components(G.solid, G.rigidE, G.ID, G)
        pbar.update()
        build_magnetic_components(G.solid, G.rigidH, G.ID, G)
        pbar.update()
        pbar.close()

        # Process any voltage sources (that have resistance) to create a new material at the source location
        for voltagesource in G.voltagesources:
            voltagesource.create_material(G)

        # Initialise arrays of update coefficients to pass to update functions
        G.initialise_std_update_coeff_arrays()

        # Initialise arrays of update coefficients and temporary values if there are any dispersive materials
        if Material.maxpoles != 0:
            G.initialise_dispersive_arrays()

        # Process complete list of materials - calculate update coefficients, store in arrays, and build text list of materials/properties
        materialsdata = process_materials(G)
        if G.messages:
            materialstable = AsciiTable(materialsdata)
            materialstable.outer_border = False
            materialstable.justify_columns[0] = 'right'
            print(materialstable.table)

        # Check to see if numerical dispersion might be a problem
        results = dispersion_analysis(G)
        if all(value == False for value in results.values()):
            print(
                '\nNumerical dispersion analysis: No waveform present in model'
            )
        elif results['N'] < G.mingridsampling:
            raise GeneralError(
                "Non-physical wave propagation: Material '{}' has a wavelength sampled by {} cells, less than required minimum for physical wave propagation. Maximum significant frequency estimated as {:g}Hz"
                .format(results['material'].ID, results['N'],
                        results['maxfreq']))
        elif results['deltavp'] and np.abs(
                results['deltavp']) > G.maxnumericaldisp:
            print(
                Fore.RED +
                "\nWARNING: Potentially significant numerical dispersion. Estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength is sampled by {} cells. Maximum significant frequency estimated as {:g}Hz"
                .format(results['deltavp'], results['material'].ID,
                        results['N'], results['maxfreq']) + Style.RESET_ALL)
        elif results['deltavp']:
            print(
                "\nNumerical dispersion analysis: estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength is sampled by {} cells. Maximum significant frequency estimated as {:g}Hz"
                .format(results['deltavp'], results['material'].ID,
                        results['N'], results['maxfreq']))

    # If geometry information to be reused between model runs
    else:
        inputfilestr = '\n--- Model {}/{}, input file not re-processed, i.e. geometry fixed: {}'.format(
            modelrun, numbermodelruns, inputfile)
        print(Fore.GREEN + '{} {}\n'.format(
            inputfilestr, '-' *
            (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)

        # Clear arrays for field components
        G.initialise_field_arrays()

        # Clear arrays for fields in PML
        for pml in G.pmls:
            pml.initialise_field_arrays()

    # Adjust position of simple sources and receivers if required
    if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0:
        for source in itertools.chain(G.hertziandipoles, G.magneticdipoles):
            if modelrun == 1:
                if source.xcoord + G.srcsteps[0] * (
                        numbermodelruns -
                        1) < 0 or source.xcoord + G.srcsteps[0] * (
                            numbermodelruns -
                            1) > G.nx or source.ycoord + G.srcsteps[1] * (
                                numbermodelruns -
                                1) < 0 or source.ycoord + G.srcsteps[1] * (
                                    numbermodelruns - 1
                                ) > G.ny or source.zcoord + G.srcsteps[2] * (
                                    numbermodelruns -
                                    1) < 0 or source.zcoord + G.srcsteps[2] * (
                                        numbermodelruns - 1) > G.nz:
                    raise GeneralError(
                        'Source(s) will be stepped to a position outside the domain.'
                    )
            source.xcoord = source.xcoordorigin + (modelrun -
                                                   1) * G.srcsteps[0]
            source.ycoord = source.ycoordorigin + (modelrun -
                                                   1) * G.srcsteps[1]
            source.zcoord = source.zcoordorigin + (modelrun -
                                                   1) * G.srcsteps[2]
    if G.rxsteps[0] != 0 or G.rxsteps[1] != 0 or G.rxsteps[2] != 0:
        for receiver in G.rxs:
            if modelrun == 1:
                if receiver.xcoord + G.rxsteps[0] * (
                        numbermodelruns -
                        1) < 0 or receiver.xcoord + G.rxsteps[0] * (
                            numbermodelruns -
                            1) > G.nx or receiver.ycoord + G.rxsteps[1] * (
                                numbermodelruns -
                                1) < 0 or receiver.ycoord + G.rxsteps[1] * (
                                    numbermodelruns - 1
                                ) > G.ny or receiver.zcoord + G.rxsteps[2] * (
                                    numbermodelruns - 1
                                ) < 0 or receiver.zcoord + G.rxsteps[2] * (
                                    numbermodelruns - 1) > G.nz:
                    raise GeneralError(
                        'Receiver(s) will be stepped to a position outside the domain.'
                    )
            receiver.xcoord = receiver.xcoordorigin + (modelrun -
                                                       1) * G.rxsteps[0]
            receiver.ycoord = receiver.ycoordorigin + (modelrun -
                                                       1) * G.rxsteps[1]
            receiver.zcoord = receiver.zcoordorigin + (modelrun -
                                                       1) * G.rxsteps[2]

    # Write files for any geometry views and geometry object outputs
    if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only:
        print(
            Fore.RED +
            '\nWARNING: No geometry views or geometry objects to output found.'
            + Style.RESET_ALL)
    if G.geometryviews:
        print()
        for i, geometryview in enumerate(G.geometryviews):
            geometryview.set_filename(modelrun, numbermodelruns, G)
            pbar = tqdm(total=geometryview.datawritesize,
                        unit='byte',
                        unit_scale=True,
                        desc='Writing geometry view file {}/{}, {}'.format(
                            i + 1, len(G.geometryviews),
                            os.path.split(geometryview.filename)[1]),
                        ncols=get_terminal_width() - 1,
                        file=sys.stdout,
                        disable=G.tqdmdisable)
            geometryview.write_vtk(modelrun, numbermodelruns, G, pbar)
            pbar.close()
    if G.geometryobjectswrite:

        for i, geometryobject in enumerate(G.geometryobjectswrite):
            pbar = tqdm(total=geometryobject.datawritesize,
                        unit='byte',
                        unit_scale=True,
                        desc='Writing geometry object file {}/{}, {}'.format(
                            i + 1, len(G.geometryobjectswrite),
                            os.path.split(geometryobject.filename)[1]),
                        ncols=get_terminal_width() - 1,
                        file=sys.stdout,
                        disable=G.tqdmdisable)
            geometryobject.write_hdf5(G, pbar)
            pbar.close()

    # Run simulation (if not doing geometry only)
    if not args.geometry_only:

        # Prepare any snapshot files
        for snapshot in G.snapshots:
            snapshot.prepare_vtk_imagedata(modelrun, numbermodelruns, G)

        # Output filename
        inputfileparts = os.path.splitext(inputfile)
        if numbermodelruns == 1:
            outputfile = inputfileparts[0] + '.out'
        else:
            outputfile = inputfileparts[0] + str(modelrun) + '.out'
        print('\nOutput file: {}\n'.format(outputfile))

        ####################################
        #  Start - Main FDTD calculations  #
        ####################################
        tsolvestart = perf_counter()

        # Absolute time
        abstime = 0

        for timestep in tqdm(range(G.iterations),
                             desc='Running simulation, model ' +
                             str(modelrun) + '/' + str(numbermodelruns),
                             ncols=get_terminal_width() - 1,
                             file=sys.stdout,
                             disable=G.tqdmdisable):
            # Store field component values for every receiver and transmission line
            store_outputs(timestep, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)

            # Write any snapshots to file
            for i, snap in enumerate(G.snapshots):
                if snap.time == timestep + 1:
                    snapiters = 36 * (((snap.xf - snap.xs) / snap.dx) *
                                      ((snap.yf - snap.ys) / snap.dy) *
                                      ((snap.zf - snap.zs) / snap.dz))
                    pbar = tqdm(
                        total=snapiters,
                        leave=False,
                        unit='byte',
                        unit_scale=True,
                        desc='  Writing snapshot file {} of {}, {}'.format(
                            i + 1, len(G.snapshots),
                            os.path.split(snap.filename)[1]),
                        ncols=get_terminal_width() - 1,
                        file=sys.stdout,
                        disable=G.tqdmdisable)
                    snap.write_vtk_imagedata(G.Ex, G.Ey, G.Ez, G.Hx, G.Hy,
                                             G.Hz, G, pbar)
                    pbar.close()

            # Update electric field components
            if Material.maxpoles == 0:  # All materials are non-dispersive so do standard update
                update_electric(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsE,
                                G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
            elif Material.maxpoles == 1:  # If there are any dispersive materials do 1st part of dispersive update (it is split into two parts as it requires present and updated electric field values).
                update_electric_dispersive_1pole_A(G.nx, G.ny, G.nz,
                                                   G.nthreads, G.updatecoeffsE,
                                                   G.updatecoeffsdispersive,
                                                   G.ID, G.Tx, G.Ty, G.Tz,
                                                   G.Ex, G.Ey, G.Ez, G.Hx,
                                                   G.Hy, G.Hz)
            elif Material.maxpoles > 1:
                update_electric_dispersive_multipole_A(
                    G.nx, G.ny, G.nz, G.nthreads, Material.maxpoles,
                    G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx,
                    G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)

            # Update electric field components with the PML correction
            for pml in G.pmls:
                pml.update_electric(G)

            # Update electric field components from sources (update any Hertzian dipole sources last)
            for source in G.voltagesources + G.transmissionlines + G.hertziandipoles:
                source.update_electric(abstime, G.updatecoeffsE, G.ID, G.Ex,
                                       G.Ey, G.Ez, G)

            # If there are any dispersive materials do 2nd part of dispersive update (it is split into two parts as it requires present and updated electric field values). Therefore it can only be completely updated after the electric field has been updated by the PML and source updates.
            if Material.maxpoles == 1:
                update_electric_dispersive_1pole_B(G.nx, G.ny, G.nz,
                                                   G.nthreads,
                                                   G.updatecoeffsdispersive,
                                                   G.ID, G.Tx, G.Ty, G.Tz,
                                                   G.Ex, G.Ey, G.Ez)
            elif Material.maxpoles > 1:
                update_electric_dispersive_multipole_B(
                    G.nx, G.ny, G.nz, G.nthreads, Material.maxpoles,
                    G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex,
                    G.Ey, G.Ez)

            # Increment absolute time value
            abstime += 0.5 * G.dt

            # Update magnetic field components
            update_magnetic(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsH,
                            G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)

            # Update magnetic field components with the PML correction
            for pml in G.pmls:
                pml.update_magnetic(G)

            # Update magnetic field components from sources
            for source in G.transmissionlines + G.magneticdipoles:
                source.update_magnetic(abstime, G.updatecoeffsH, G.ID, G.Hx,
                                       G.Hy, G.Hz, G)

            # Increment absolute time value
            abstime += 0.5 * G.dt

        tsolve = int(perf_counter() - tsolvestart)

        # Write an output file in HDF5 format
        write_hdf5_outputfile(outputfile, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz,
                              G)

        ##################################
        #  End - Main FDTD calculations  #
        ##################################

    if G.messages:
        print('Memory (RAM) used: ~{}'.format(human_size(p.memory_info().rss)))

    # If geometry information to be reused between model runs then FDTDGrid class instance must be global so that it persists
    if not args.geometry_fixed:
        del G

    # Return time to complete solving if in benchmarking mode
    if args.benchmark:
        return tsolve
Ejemplo n.º 25
0
    async def result(self, ctx):
        """Show your points from the most recent race."""
        league = self._find_league(ctx)

        if league:
            with open(f"{league}-details.json") as infile:
                details = json.load(infile)

            player = self._find_player(ctx)
            if player:
                totals = {"points": 0, "price": 0, "picked": 0}

                headers = [
                    "Name", "Turbo", "Mega", "Points", "Price", "Picked %"
                ]
                data = [headers]
                player_details = details[str(player)]
                for entry in player_details["drivers"]:
                    data.append([
                        entry["name"], "Yes" if entry["short_name"]
                        == player_details["turbo"] else "No",
                        "Yes" if entry["short_name"] == player_details["mega"]
                        else "No",
                        format_float(entry["score"]),
                        format_float(entry["price"]),
                        format_float(entry["picked"])
                    ])

                    totals["points"] += entry["score"]
                    totals["price"] += entry["price"]
                    totals["picked"] += entry["picked"]

                data.append([])
                team = player_details["team"]
                data.append([
                    team["name"], "", "",
                    format_float(team["score"]),
                    format_float(team["price"]),
                    format_float(team["picked"])
                ])

                totals["points"] += team["score"]
                totals["price"] += team["price"]
                totals["picked"] += team["picked"]

                totals["picked"] = round(totals["picked"] / 6, 1)

                data.append([])
                data.append([
                    "Total/Average", "", "",
                    format_float(round(totals["points"], 1)),
                    format_float(round(totals["price"], 1)),
                    format_float(round(totals["picked"], 1))
                ])

                table_instance = AsciiTable(data)
                table_instance.inner_column_border = False
                table_instance.outer_border = False
                table_instance.justify_columns[1] = "center"
                table_instance.justify_columns[2] = "right"
                table_instance.justify_columns[3] = "right"
                table_instance.justify_columns[4] = "right"

                msg = "```{}```".format(table_instance.table)
            else:
                msg = f"Player not found."
        else:
            msg = f"League {league} not found."

        await ctx.send(msg)
Ejemplo n.º 26
0
def main():
    default_in_path = "/usr/include/linux"
    mode_config = {
        "capability":
        ["capability.h", "cap_data.json", "#define (CAP_[A-Z_]+)\s+(\d+)"],
        "bitflags":
        ["if.h", "bitflag_data.json", "IFF_([A-Z_]+)\s+=\s1<<(\d+)"],
        "nw_types":
        ["if_arp.h", "type_data.json", "#define ARPHRD_([\w]+)\s+(\d+)"]
    }

    in_lam = lambda a: "/".join((default_in_path, a))
    out_lam = lambda a: os.path.normpath(
        os.path.join(os.path.dirname(__file__), os.path.pardir, "etc", a))

    def addDefaults():
        res = [['mode', 'default input', 'default output']]
        for mode in mode_config:
            desc = []
            val = mode_config[mode]
            desc.append(mode)
            desc.append(in_lam(val[0]))
            desc.append(out_lam(val[1]))
            res.append(desc)
        return res

    description = "{} {}\n{}".format(
        "Update the available names and",
        "corresponding bit values from C headers for a", "specified type.")
    epilog = "Currently available modes are:"

    table = AsciiTable(addDefaults())
    # Do not use any borders at all
    table.outer_border = False
    table.inner_column_border = False
    table.inner_heading_row_border = False

    epilog = "\n".join((epilog, table.table))
    # RawDescriptionHelpFormatter causes new lines and blank spaces in
    # description to be printed as well.
    parser = argparse.ArgumentParser(
        prog=sys.argv[0],
        description=description,
        epilog=epilog,
        formatter_class=argparse.RawDescriptionHelpFormatter)

    description = "select the type to update."
    parser.add_argument('mode',
                        metavar="mode",
                        help=description,
                        choices=mode_config.keys(),
                        type=str)

    description = "The C header used as input file."
    parser.add_argument("-i", "--input", type=str, help=description)

    description = "The output file in JSON format."
    parser.add_argument("-o", "--output", type=str, help=description)

    args = parser.parse_args()

    config = mode_config[args.mode]
    #set default parameters
    arg_in = in_lam(config[0])
    if args.input:
        arg_in = args.input
    arg_out = out_lam(config[1])
    if args.output:
        arg_out = args.output

    try:
        with open(arg_in, "r") as fi:
            file_data = fi.read()
    except EnvironmentError as e:
        exit("Cannot open file {}: {}".format(arg_in, str(e)))

    assert file_data

    # read all system-available capabilities/iface-types/iface-flags from
    # the input file into the dictionary
    regex = re.compile(config[2], re.MULTILINE)
    data = OrderedDict()
    for m in re.finditer(regex, file_data):
        val_int = int(m.group(2))
        val_name = str(m.group(1))
        data[val_name] = val_int
    if not data:
        exit("No {} information found in {}".format(args.mode, arg_in))

    #write dictionary to output file in JSON encoded format
    try:
        with open(arg_out, "w") as fi:
            json.dump(data, fi, indent=4, sort_keys=True)
            print("Wrote {} data to {}\n".format(args.mode, arg_out))
    except EnvironmentError as e:
        exit("Cannot write file {}: {}".format(arg_out, str(e)))