Exemplo n.º 1
0
    def run(args):

        if args.show_config:
            print(Config())
            return

        if args.generate_config:
            abstract.dump(Config(), args.generate_config)
            return

        if args.file:
            if args.config:
                cfg = Config(**abstract.load(args.config))
            else:
                cfg = Config()

            return main(cfg, args)
Exemplo n.º 2
0
            frac, _ = dblquad(load_func_psi_eta, 0, 1, 0, lambda x: 1 - x, epsrel=1e-1, epsabs=1e-1)
            da = ((xj - xi) * (yk - yi) - (xk - xi) * (yj - yi))
            f[tri] += 1 / 6 * frac * da

    f[on_boundary] = 0

    return f


array_file = 'circular_mem_54.json'
db_file = 'circular_mem_54.db'
t_start = 0
t_stop = 6e-6
atol = 1e-10

array = abstract.load(array_file)
patches = abstract.get_patches_from_array(array)
mem = array.elements[0].membranes[0]

amesh = mesh.Mesh.from_abstract(array, refn=7)
nodes = amesh.vertices
f = np.zeros((len(amesh.vertices), len(patches)))
for i, pat in enumerate(patches):
    f[:,i] = circular_patch_f_vector(amesh.vertices, amesh.triangles, amesh.on_boundary,
        pat.position[0] - mem.position[0], pat.position[1] - mem.position[1], 
        pat.radius_min, pat.radius_max, pat.theta_min, pat.theta_max)

    f[amesh.on_boundary,i] = 0

mask = f > 0
Exemplo n.º 3
0
                uavg = []
                fpp = []
                for di in d:
                    ubar = (unorm * g * di).dot(avg) / pat.area
                    uavg.append(ubar)

                    fc.append((-e_0 / 2 / (unorm * g * di + g_eff)**2).dot(avg) / pat.area)
                    fpp.append(-e_0 / 2 / (ubar + g_eff)**2)

                fcorr.append((d, unorm, uavg, fc, fpp))
                # fcorr.append(interp1d(uavg, fc, kind='cubic', bounds_error=False, fill_value=(fc[-1], fc[0])))

    return fcorr


array = abstract.load('circular_membrane.json')
fcorr = calc_es_correction(array, refn=9)



from matplotlib import pyplot as plt

for i in [0, 4, 8]:

    d, unorm, uavg, fc, fpp = fcorr[i]

    fig, ax = plt.subplots()
    ax.plot(uavg, fc)
    ax.plot(uavg, fpp, '--')
    fig.show()
Exemplo n.º 4
0
def process(job):
    ''''''
    job_id, (f, k) = job

    # get options and parameters
    c = cfg.sound_speed
    rho = cfg.fluid_rho
    array = abstract.load(cfg.array_config)
    refn = cfg.mesh_refn

    # create finite element matrix
    Gfe, _ = fem.mbk_from_abstract(array, f, refn)

    # create boundary element matrix
    hmkwrds = [
        'aprx', 'basis', 'admis', 'eta', 'eps', 'm', 'clf', 'eps_aca', 'rk',
        'q_reg', 'q_sing', 'strict'
    ]
    hmargs = {k: getattr(cfg, k) for k in hmkwrds}
    Z = bem.z_from_abstract(array, k, refn, format='HFormat', **hmargs)
    omg = 2 * np.pi * f
    Gbe = -omg**2 * 2 * rho * Z

    # define total linear system and preconditioner
    G = MbkSparseMatrix(Gfe) + Gbe
    Glu = G.lu()

    # create patch pressure load
    F = fem.f_from_abstract(array, refn)
    mesh = Mesh.from_abstract(array, refn)
    ob = mesh.on_boundary

    # solve for each source patch
    npatch = abstract.get_patch_count(array)
    source_patch = np.arange(npatch)
    dest_patch = np.arange(npatch)
    patches = abstract.get_patches_from_array(array)

    for sid in source_patch:
        # get RHS
        b = np.array(F[:, sid].todense())
        # b[ob] = 0

        # solve
        start = timer()
        # conjugate so phase is consistent with -iwt convention used by h2lib
        x = np.conj(Glu.lusolve(b))
        time_solve = timer() - start
        x[ob] = 0

        # average displacement over patches
        area = patches[sid].length_x * patches[sid].length_y
        # x_patch = (Pavg.T).dot(x) # / patch area?
        x_patch = (F.T).dot(x) / area

        # write results to database
        data = {}
        data['frequency'] = repeat(f)
        data['wavenumber'] = repeat(k)
        data['source_patch'] = repeat(sid)
        data['dest_patch'] = dest_patch
        data['displacement_real'] = np.real(x_patch)
        data['displacement_imag'] = np.imag(x_patch)
        data['time_solve'] = repeat(time_solve)

        with write_lock:
            update_db(file, **data)

    with write_lock:
        util.update_progress(file, job_id)
Exemplo n.º 5
0
def process(job):
    '''
    Process which executes a job.
    '''
    job_id, (f, k) = job

    # get options and parameters
    c = cfg.sound_speed
    rho = cfg.fluid_rho
    array = abstract.load(cfg.array_config)
    refn = cfg.mesh_refn
    use_fluid = cfg.use_fluid

    # create boundary element matrix
    if use_fluid:
        # create finite element matrix
        Gfe = fem.array_mbk_spmatrix(array, refn, f, format='csr')

        hmkwrds = [
            'format', 'aprx', 'basis', 'admis', 'eta', 'eps', 'm', 'clf',
            'eps_aca', 'rk', 'q_reg', 'q_sing', 'strict'
        ]
        hmargs = {k: getattr(cfg, k) for k in hmkwrds}
        # Z = bem.z_from_abstract(array, k, refn, format='HFormat', **hmargs)
        Z = bem.array_z_matrix(array, refn, k, **hmargs)
        omg = 2 * np.pi * f
        Gbe = -omg**2 * 2 * rho * Z

        # define total linear system and find LU decomposition
        G = MbkSparseMatrix(Gfe) + Gbe
        Glu = G.lu()
    else:

        # create finite element matrix
        Gfe = fem.array_mbk_spmatrix(array, refn, f, format='csc')

        # define total linear system and find LU decomposition
        Glu = splu(Gfe)

    # create patch pressure loads
    F = fem.array_f_spmatrix(array, refn)
    AVG = fem.array_avg_spmatrix(array, refn)
    mesh = Mesh.from_abstract(array, refn)
    ob = mesh.on_boundary

    # solve for each source patch
    npatch = abstract.get_patch_count(array)
    source_patch = np.arange(npatch)
    dest_patch = np.arange(npatch)
    # patches = abstract.get_patches_from_array(array)
    # patch_areas = np.array([p.area for p in patches])

    for sid in source_patch:
        # get RHS
        b = np.array(F[:, sid].todense())

        # solve
        start = timer()

        # conjugate so phase is consistent with -iwt convention used by h2lib
        if use_fluid:
            x = np.conj(Glu.lusolve(b))
        else:
            x = Glu.solve(b)  # doesn't work right yet...

        time_solve = timer() - start
        x[ob] = 0

        # average displacement over patches
        x_patch = (AVG.T).dot(x)

        # write patch displacement results to frequency response database
        data = {}
        data['frequency'] = repeat(f)
        data['wavenumber'] = repeat(k)
        data['source_patch'] = repeat(sid)
        data['dest_patch'] = dest_patch
        data['displacement_real'] = np.real(x_patch)
        data['displacement_imag'] = np.imag(x_patch)
        data['time_solve'] = repeat(time_solve)

        with write_lock:
            database.append_patch_to_patch_freq_resp(file, **data)

        # write node displacement results to frequency response database
        data = {}
        data['node_id'] = range(len(mesh.vertices))
        data['x'] = mesh.vertices[:, 0]
        data['y'] = mesh.vertices[:, 1]
        data['z'] = mesh.vertices[:, 2]
        data['frequency'] = repeat(f)
        data['wavenumber'] = repeat(k)
        data['source_patch'] = repeat(sid)
        data['displacement_real'] = np.real(x)
        data['displacement_imag'] = np.imag(x)

        with write_lock:
            database.append_patch_to_node_freq_resp(file, **data)

    with write_lock:
        util.update_progress(file, job_id)
Exemplo n.º 6
0
def main(cfg, args):
    '''
    Script entry point.
    '''
    # get parameters from config and args
    file = args.file
    write_over = args.write_over
    threads = args.threads if args.threads else multiprocessing.cpu_count()
    f_start, f_stop, f_step = cfg.freqs
    c = cfg.sound_speed

    # calculate job-related values
    freqs = np.arange(f_start, f_stop + f_step, f_step)
    wavenums = 2 * np.pi * freqs / c
    is_complete = None
    njobs = len(freqs)
    ijob = 0

    # check for existing file
    if os.path.isfile(file):
        if write_over:  # if file exists, write over
            # remove existing files
            os.remove(file)

            # create databases
            database.create_db(file, **cfg._asdict())
            util.create_progress_table(file, njobs)

            # append node information
            amesh = Mesh.from_abstract(abstract.load(cfg.array_config),
                                       refn=cfg.mesh_refn)
            nodes = amesh.vertices
            database.append_node(file,
                                 node_id=range(len(nodes)),
                                 x=nodes[:, 0],
                                 y=nodes[:, 1],
                                 z=nodes[:, 2])

        else:  # continue from current progress
            is_complete, ijob = util.get_progress(file)
            if np.all(is_complete): return
    else:
        # make directories if they do not exist
        file_dir = os.path.dirname(os.path.abspath(file))
        if not os.path.exists(file_dir):
            os.makedirs(file_dir)

        # create databases
        database.create_db(file, **cfg._asdict())
        util.create_progress_table(file, njobs)

        # append node information
        amesh = Mesh.from_abstract(abstract.load(cfg.array_config),
                                   refn=cfg.mesh_refn)
        nodes = amesh.vertices
        database.append_node(file,
                             node_id=range(len(nodes)),
                             x=nodes[:, 0],
                             y=nodes[:, 1],
                             z=nodes[:, 2])

    # start multiprocessing pool and run process
    try:
        write_lock = multiprocessing.Lock()

        pool = multiprocessing.Pool(threads,
                                    initializer=init_process,
                                    initargs=(write_lock, abstract.dumps(cfg),
                                              file),
                                    maxtasksperchild=1)

        jobs = util.create_jobs((freqs, 1), (wavenums, 1),
                                mode='zip',
                                is_complete=is_complete)
        result = pool.imap_unordered(run_process, jobs, chunksize=1)

        for r in tqdm(result, desc='Running', total=njobs, initial=ijob):
            pass

        postprocess(file, cfg.freq_interp)

    except Exception as e:
        print(e)
    finally:
        pool.close()
        pool.terminate()
Exemplo n.º 7
0
                        pat.theta_min)
                    y1 = pat.position[1] + pat.radius_max * np.sin(
                        pat.theta_min)
                    line0 = plt.Line2D([x0, x1], [y0, y1], c='black', lw=1)
                    ax.add_artist(line0)

                elif mem.shape.lower() in ['square', 's']:

                    patch = patches.Rectangle(width=pat.length_x,
                                              height=pat.length_y,
                                              xy=(pat.position[0],
                                                  pat.position[1]),
                                              ec='black',
                                              fill=False)
                    ax.add_patch(patch)

    ax.set_aspect('equal')
    ax.autoscale()
    ax.set_xlabel('X (m)')
    ax.set_ylabel('Y (m)')
    ax.set_title('Array patch geometry')


if __name__ == '__main__':

    file = sys.argv[1]
    array = abstract.load(file)

    fig_membranes(array)
    fig_patches(array)
Exemplo n.º 8
0
def process(job):
    ''''''
    job_id, (f, k) = job

    # get options and parameters
    c = cfg.sound_speed
    rho = cfg.fluid_rho
    array = abstract.load(cfg.array_config)
    refn = cfg.mesh_refn

    # create finite element linear operators
    Gfe, Gfe_inv = fem.mbk_linear_operators(array, f, refn)

    # create boundary element linear operators
    hmkwrds = [
        'aprx', 'basis', 'admis', 'eta', 'eps', 'm', 'clf', 'eps_aca', 'rk',
        'q_reg', 'q_sing', 'strict'
    ]
    hmargs = {k: getattr(cfg, k) for k in hmkwrds}
    Gbe, Gbe_inv = bem.z_linear_operators(array, f, c, refn, rho, **hmargs)

    # define total linear system and preconditioner
    G = Gfe + Gbe
    P = Gfe_inv
    # P = Gbe_inv * Gfe_inv
    # P = Gfe_inv * Gbe_inv
    # g = np.trace(MBK_inv.todense())
    # mem_array = array.copy()
    # mem_array.elements = [array.elements[0],]
    # Bfe, Bfe_inv = fem.mbk_from_abstract(mem_array, f, refn)
    # Bfe = Bfe.todense()
    # Bfe_inv = np.linalg.inv(Bfe)
    # Bbe = bem.z_from_abstract(mem_array, k, refn=refn, format='FullFormat').data
    # Bbe_inv = np.linalg.inv(Bbe)

    # g = np.trace(Bfe.dot(Bbe_inv)) * len(array.elements)
    # P = Gbe_inv - (1 / (1 + g)) * Gbe_inv * Gfe * Gbe_inv
    # g = np.trace(Bbe.dot(Bfe_inv)) * len(array.elements)
    # P = Gfe_inv - (1 / (1 + g)) * Gfe_inv * Gbe * Gfe_inv

    # create patch pressure load
    F = fem.f_from_abstract(array, refn)

    # solve for each source patch
    npatch = abstract.get_patch_count(array)
    source_patch = np.arange(npatch)
    dest_patch = np.arange(npatch)
    for sid in source_patch:
        # get RHS
        b = P.dot(F[:, sid].todense())

        # solve
        counter = util.Counter()
        start = timer()
        x, ecode = lgmres(G,
                          b,
                          tol=1e-6,
                          maxiter=40,
                          M=P,
                          callback=counter.increment)
        time_solve = timer() - start

        # average displacement over patches
        x_patch = (F.T).dot(x)  # / patch area?

        # write results to database
        data = {}
        data['frequency'] = repeat(f)
        data['wavenumber'] = repeat(k)
        data['source_patch'] = repeat(sid)
        data['dest_patch'] = dest_patch
        # data['source_membrane_id'] = repeat(mesh.membrane_ids[smask][0])
        # data['dest_membrane_id'] = dest_membrane_ids
        # data['source_element_id'] = repeat(mesh.element_ids[smask][0])
        # data['dest_element_id'] = dest_element_ids
        data['displacement_real'] = np.real(x_patch)
        data['displacement_imag'] = np.imag(x_patch)
        data['time_solve'] = repeat(time_solve)
        data['iterations'] = repeat(counter.count)

        with write_lock:
            update_database(file, **data)
            # add saving of metrics (solve time, lgmres steps etc.)

    with write_lock:
        util.update_progress(file, job_id)
Exemplo n.º 9
0
 def run(args):
     if args.config:
         cfg = Config(**abstract.load(args.config))
     else:
         cfg = Config()
     return main(cfg, args)