def main(): # Aluminium and epoxy. default_pars = '70e9,0.35,2.799e3, 3.8e9,0.27,1.142e3' default_solver_conf = ("kind='eig.scipy',method='eigsh',tol=1.0e-5," "maxiter=1000,which='LM',sigma=0.0") parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--pars', metavar='young1,poisson1,density1' ',young2,poisson2,density2', action='store', dest='pars', default=default_pars, help=helps['pars']) parser.add_argument('--conf', metavar='filename', action='store', dest='conf', default=None, help=helps['conf']) parser.add_argument('--define-kwargs', metavar='dict-like', action='store', dest='define_kwargs', default=None, help=helps['define_kwargs']) parser.add_argument('--mesh-size', type=float, metavar='float', action='store', dest='mesh_size', default=None, help=helps['mesh_size']) parser.add_argument('--unit-multipliers', metavar='c_time,c_length,c_mass', action='store', dest='unit_multipliers', default='1.0,1.0,1.0', help=helps['unit_multipliers']) parser.add_argument('--plane', action='store', dest='plane', choices=['strain', 'stress'], default='strain', help=helps['plane']) parser.add_argument('--wave-dir', metavar='float,float[,float]', action='store', dest='wave_dir', default='1.0,0.0,0.0', help=helps['wave_dir']) parser.add_argument('--mode', action='store', dest='mode', choices=['omega', 'kappa'], default='omega', help=helps['mode']) parser.add_argument('--stepper', action='store', dest='stepper', choices=['linear', 'brillouin'], default='linear', help=helps['stepper']) parser.add_argument('--range', metavar='start,stop,count', action='store', dest='range', default='0,6.4,33', help=helps['range']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_argument('--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_argument('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['n_eigs']) group = parser.add_mutually_exclusive_group() group.add_argument('--eigs-only', action='store_true', dest='eigs_only', default=False, help=helps['eigs_only']) group.add_argument('--post-process', action='store_true', dest='post_process', default=False, help=helps['post_process']) parser.add_argument('--solver-conf', metavar='dict-like', action='store', dest='solver_conf', default=default_solver_conf, help=helps['solver_conf']) parser.add_argument('--save-regions', action='store_true', dest='save_regions', default=False, help=helps['save_regions']) parser.add_argument('--save-materials', action='store_true', dest='save_materials', default=False, help=helps['save_materials']) parser.add_argument('--log-std-waves', action='store_true', dest='log_std_waves', default=False, help=helps['log_std_waves']) parser.add_argument('--no-legends', action='store_false', dest='show_legends', default=True, help=helps['no_legends']) parser.add_argument('--no-show', action='store_false', dest='show', default=True, help=helps['no_show']) parser.add_argument('--silent', action='store_true', dest='silent', default=False, help=helps['silent']) parser.add_argument('-c', '--clear', action='store_true', dest='clear', default=False, help=helps['clear']) parser.add_argument('-o', '--output-dir', metavar='path', action='store', dest='output_dir', default='output', help=helps['output_dir']) parser.add_argument('mesh_filename', default='', help=helps['mesh_filename']) options = parser.parse_args() output_dir = options.output_dir output.set_output(filename=os.path.join(output_dir,'output_log.txt'), combined=options.silent == False) if options.conf is not None: mod = import_file(options.conf) else: mod = sys.modules[__name__] apply_units = mod.apply_units define = mod.define set_wave_dir = mod.set_wave_dir setup_n_eigs = mod.setup_n_eigs build_evp_matrices = mod.build_evp_matrices save_materials = mod.save_materials get_std_wave_fun = mod.get_std_wave_fun get_stepper = mod.get_stepper process_evp_results = mod.process_evp_results options.pars = [float(ii) for ii in options.pars.split(',')] options.unit_multipliers = [float(ii) for ii in options.unit_multipliers.split(',')] options.wave_dir = [float(ii) for ii in options.wave_dir.split(',')] aux = options.range.split(',') options.range = [float(aux[0]), float(aux[1]), int(aux[2])] options.solver_conf = dict_from_string(options.solver_conf) options.define_kwargs = dict_from_string(options.define_kwargs) if options.clear: remove_files_patterns(output_dir, ['*.h5', '*.vtk', '*.txt'], ignores=['output_log.txt'], verbose=True) filename = os.path.join(output_dir, 'options.txt') ensure_path(filename) save_options(filename, [('options', vars(options))], quote_command_line=True) pars = apply_units(options.pars, options.unit_multipliers) output('material parameters with applied unit multipliers:') output(pars) if options.mode == 'omega': rng = copy(options.range) rng[:2] = apply_unit_multipliers(options.range[:2], ['wave_number', 'wave_number'], options.unit_multipliers) output('wave number range with applied unit multipliers:', rng) else: if options.stepper == 'brillouin': raise ValueError('Cannot use "brillouin" stepper in kappa mode!') rng = copy(options.range) rng[:2] = apply_unit_multipliers(options.range[:2], ['frequency', 'frequency'], options.unit_multipliers) output('frequency range with applied unit multipliers:', rng) pb, wdir, bzone, mtxs = assemble_matrices(define, mod, pars, set_wave_dir, options) dim = pb.domain.shape.dim if dim != 2: options.plane = 'strain' if options.save_regions: pb.save_regions_as_groups(os.path.join(output_dir, 'regions')) if options.save_materials: save_materials(output_dir, pb, options) conf = pb.solver_confs['eig'] eig_solver = Solver.any_from_conf(conf) n_eigs, options.n_eigs = setup_n_eigs(options, pb, mtxs) get_color = lambda ii: plt.cm.viridis((float(ii) / (options.n_eigs - 1))) plot_kwargs = [{'color' : get_color(ii), 'ls' : '', 'marker' : 'o'} for ii in range(options.n_eigs)] get_color_dim = lambda ii: plt.cm.viridis((float(ii) / (dim-1))) plot_kwargs_dim = [{'color' : get_color_dim(ii), 'ls' : '', 'marker' : 'o'} for ii in range(dim)] log_names = [] log_plot_kwargs = [] if options.log_std_waves: std_wave_fun, log_names, log_plot_kwargs = get_std_wave_fun( pb, options) else: std_wave_fun = None stepper = get_stepper(rng, pb, options) if options.mode == 'omega': eigenshapes_filename = os.path.join(output_dir, 'frequency-eigenshapes-%s.vtk' % stepper.suffix) if options.stepper == 'linear': log = Log([[r'$\lambda_{%d}$' % ii for ii in range(options.n_eigs)], [r'$\omega_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs, plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * options.n_eigs, ['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear', 'linear'], xlabels=[r'$\kappa$', r'$\kappa$'], ylabels=[r'eigenvalues $\lambda_i$', r'frequencies $\omega_i$'], show_legends=options.show_legends, is_plot=options.show, log_filename=os.path.join(output_dir, 'frequencies.txt'), aggregate=1000, sleep=0.1) else: log = Log([[r'$\kappa_{%d}$'% ii for ii in range(dim)], [r'$\omega_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs_dim, plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * dim, ['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear', 'linear'], xlabels=[r'', r''], ylabels=[r'wave vector $\kappa$', r'frequencies $\omega_i$'], show_legends=options.show_legends, is_plot=options.show, log_filename=os.path.join(output_dir, 'frequencies.txt'), aggregate=1000, sleep=0.1) for aux in stepper: if options.stepper == 'linear': iv, wmag = aux else: iv, wmag, wdir = aux output('step %d: wave vector %s' % (iv, wmag * wdir)) if options.stepper == 'brillouin': pb, _, bzone, mtxs = assemble_matrices( define, mod, pars, set_wave_dir, options, wdir=wdir) evp_mtxs = build_evp_matrices(mtxs, wmag, options.mode, pb) if options.eigs_only: eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=True) omegas, svecs, out = process_evp_results( eigs, svecs, wmag, wdir, bzone, pb, mtxs, options, std_wave_fun=std_wave_fun ) if options.stepper == 'linear': log(*out, x=[wmag, wmag]) else: log(*out, x=[iv, iv]) save_eigenvectors(eigenshapes_filename % iv, svecs, wmag, wdir, pb) gc.collect() log(save_figure=os.path.join(output_dir, 'frequencies.png')) log(finished=True) else: eigenshapes_filename = os.path.join(output_dir, 'wave-number-eigenshapes-%s.vtk' % stepper.suffix) log = Log([[r'$\kappa_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear'], xlabels=[r'$\omega$'], ylabels=[r'wave numbers $\kappa_i$'], show_legends=options.show_legends, is_plot=options.show, log_filename=os.path.join(output_dir, 'wave-numbers.txt'), aggregate=1000, sleep=0.1) for io, omega in stepper: output('step %d: frequency %s' % (io, omega)) evp_mtxs = build_evp_matrices(mtxs, omega, options.mode, pb) if options.eigs_only: eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=True) kappas, svecs, out = process_evp_results( eigs, svecs, omega, wdir, bzone, pb, mtxs, options, std_wave_fun=std_wave_fun ) log(*out, x=[omega]) save_eigenvectors(eigenshapes_filename % io, svecs, kappas, wdir, pb) gc.collect() log(save_figure=os.path.join(output_dir, 'wave-numbers.png')) log(finished=True)
def main(): # Aluminium and epoxy. default_pars = '70e9,0.35,2.799e3, 3.8e9,0.27,1.142e3' default_solver_conf = ("kind='eig.scipy',method='eigh',tol=1.0e-5," "maxiter=1000,which='LM',sigma=0.0") parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--pars', metavar='young1,poisson1,density1' ',young2,poisson2,density2', action='store', dest='pars', default=default_pars, help=helps['pars']) parser.add_argument('--conf', metavar='filename', action='store', dest='conf', default=None, help=helps['conf']) parser.add_argument('--mesh-size', type=float, metavar='float', action='store', dest='mesh_size', default=None, help=helps['mesh_size']) parser.add_argument('--unit-multipliers', metavar='c_time,c_length,c_mass', action='store', dest='unit_multipliers', default='1.0,1.0,1.0', help=helps['unit_multipliers']) parser.add_argument('--plane', action='store', dest='plane', choices=['strain', 'stress'], default='strain', help=helps['plane']) parser.add_argument('--wave-dir', metavar='float,float[,float]', action='store', dest='wave_dir', default='1.0,0.0,0.0', help=helps['wave_dir']) parser.add_argument('--mode', action='store', dest='mode', choices=['omega', 'kappa'], default='omega', help=helps['mode']) parser.add_argument('--range', metavar='start,stop,count', action='store', dest='range', default='10,100,10', help=helps['range']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_argument('--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_argument('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['n_eigs']) parser.add_argument('--eigs-only', action='store_true', dest='eigs_only', default=False, help=helps['eigs_only']) parser.add_argument('--solver-conf', metavar='dict-like', action='store', dest='solver_conf', default=default_solver_conf, help=helps['solver_conf']) parser.add_argument('--save-materials', action='store_true', dest='save_materials', default=False, help=helps['save_materials']) parser.add_argument('--log-std-waves', action='store_true', dest='log_std_waves', default=False, help=helps['log_std_waves']) parser.add_argument('--silent', action='store_true', dest='silent', default=False, help=helps['silent']) parser.add_argument('-c', '--clear', action='store_true', dest='clear', default=False, help=helps['clear']) parser.add_argument('-o', '--output-dir', metavar='path', action='store', dest='output_dir', default='output', help=helps['output_dir']) parser.add_argument('mesh_filename', default='', help=helps['mesh_filename']) options = parser.parse_args() output_dir = options.output_dir output.set_output(filename=os.path.join(output_dir, 'output_log.txt'), combined=options.silent == False) if options.conf is not None: mod = import_file(options.conf) apply_units = mod.apply_units define = mod.define set_wave_dir = mod.set_wave_dir else: apply_units = apply_units_le define = define_le set_wave_dir = set_wave_dir_le options.pars = [float(ii) for ii in options.pars.split(',')] options.unit_multipliers = [ float(ii) for ii in options.unit_multipliers.split(',') ] options.wave_dir = [float(ii) for ii in options.wave_dir.split(',')] aux = options.range.split(',') options.range = [float(aux[0]), float(aux[1]), int(aux[2])] options.solver_conf = dict_from_string(options.solver_conf) if options.clear: remove_files_patterns(output_dir, ['*.h5', '*.vtk', '*.txt'], ignores=['output_log.txt'], verbose=True) filename = os.path.join(output_dir, 'options.txt') ensure_path(filename) save_options(filename, [('options', vars(options))]) pars = apply_units(options.pars, options.unit_multipliers) output('material parameters with applied unit multipliers:') output(pars) if options.mode == 'omega': rng = copy(options.range) rng[:2] = apply_unit_multipliers(options.range[:2], ['wave_number', 'wave_number'], options.unit_multipliers) output('wave number range with applied unit multipliers:', rng) else: rng = copy(options.range) rng[:2] = apply_unit_multipliers(options.range[:2], ['frequency', 'frequency'], options.unit_multipliers) output('frequency range with applied unit multipliers:', rng) define_problem = functools.partial(define, filename_mesh=options.mesh_filename, pars=pars, approx_order=options.order, refinement_level=options.refine, solver_conf=options.solver_conf, plane=options.plane) conf = ProblemConf.from_dict(define_problem(), sys.modules[__name__]) pb = Problem.from_conf(conf) dim = pb.domain.shape.dim if dim != 2: options.plane = 'strain' wdir = nm.asarray(options.wave_dir[:dim], dtype=nm.float64) wdir = wdir / nm.linalg.norm(wdir) stepper = TimeStepper(rng[0], rng[1], dt=None, n_step=rng[2]) bbox = pb.domain.mesh.get_bounding_box() size = (bbox[1] - bbox[0]).max() scaling0 = apply_unit_multipliers([1.0], ['length'], options.unit_multipliers)[0] scaling = scaling0 if options.mesh_size is not None: scaling *= options.mesh_size / size output('scaling factor of periodic cell mesh coordinates:', scaling) output('new mesh size with applied unit multipliers:', scaling * size) pb.domain.mesh.coors[:] *= scaling pb.set_mesh_coors(pb.domain.mesh.coors, update_fields=True) bzone = 2.0 * nm.pi / (scaling * size) output('1. Brillouin zone size:', bzone * scaling0) output('1. Brillouin zone size with applied unit multipliers:', bzone) pb.time_update() pb.update_materials() if options.save_materials or options.log_std_waves: stiffness = pb.evaluate('ev_integrate_mat.2.Omega(m.D, u)', mode='el_avg', copy_materials=False, verbose=False) young, poisson = mc.youngpoisson_from_stiffness(stiffness, plane=options.plane) density = pb.evaluate('ev_integrate_mat.2.Omega(m.density, u)', mode='el_avg', copy_materials=False, verbose=False) if options.save_materials: out = {} out['young'] = Struct(name='young', mode='cell', data=young[..., None, None]) out['poisson'] = Struct(name='poisson', mode='cell', data=poisson[..., None, None]) out['density'] = Struct(name='density', mode='cell', data=density) materials_filename = os.path.join(output_dir, 'materials.vtk') pb.save_state(materials_filename, out=out) # Set the normalized wave vector direction to the material(s). set_wave_dir(pb.get_materials(), wdir) conf = pb.solver_confs['eig'] eig_solver = Solver.any_from_conf(conf) # Assemble the matrices. mtx_m = pb.mtx_a.copy() eq_m = pb.equations['M'] mtx_m = eq_m.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m) mtx_m.eliminate_zeros() mtx_k = pb.mtx_a.copy() eq_k = pb.equations['K'] mtx_k = eq_k.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_k) mtx_k.eliminate_zeros() mtx_s = pb.mtx_a.copy() eq_s = pb.equations['S'] mtx_s = eq_s.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_s) mtx_s.eliminate_zeros() mtx_r = pb.mtx_a.copy() eq_r = pb.equations['R'] mtx_r = eq_r.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_r) mtx_r.eliminate_zeros() output('symmetry checks of real blocks:') output('M - M^T:', _max_diff_csr(mtx_m, mtx_m.T)) output('K - K^T:', _max_diff_csr(mtx_k, mtx_k.T)) output('S - S^T:', _max_diff_csr(mtx_s, mtx_s.T)) output('R + R^T:', _max_diff_csr(mtx_r, -mtx_r.T)) n_eigs = options.n_eigs if options.n_eigs > mtx_k.shape[0]: options.n_eigs = mtx_k.shape[0] n_eigs = None if options.mode == 'omega': eigenshapes_filename = os.path.join( output_dir, 'frequency-eigenshapes-%s.vtk' % stepper.suffix) extra = [] extra_plot_kwargs = [] if options.log_std_waves: lam, mu = mc.lame_from_youngpoisson(young, poisson, plane=options.plane) alam = nm.average(lam) amu = nm.average(mu) adensity = nm.average(density) cp = nm.sqrt((alam + 2.0 * amu) / adensity) cs = nm.sqrt(amu / adensity) output('average p-wave speed:', cp) output('average shear wave speed:', cs) extra = [r'$\omega_p$', r'$\omega_s$'] extra_plot_kwargs = [{ 'ls': '--', 'color': 'k' }, { 'ls': '--', 'color': 'gray' }] log = Log( [[r'$\lambda_{%d}$' % ii for ii in range(options.n_eigs)], [r'$\omega_{%d}$' % ii for ii in range(options.n_eigs)] + extra], plot_kwargs=[{}, [{}] * options.n_eigs + extra_plot_kwargs], yscales=['linear', 'linear'], xlabels=[r'$\kappa$', r'$\kappa$'], ylabels=[r'eigenvalues $\lambda_i$', r'frequencies $\omega_i$'], log_filename=os.path.join(output_dir, 'frequencies.txt'), aggregate=1000, sleep=0.1) for iv, wmag in stepper: output('step %d: wave vector %s' % (iv, wmag * wdir)) mtx_a = mtx_k + wmag**2 * mtx_s + (1j * wmag) * mtx_r mtx_b = mtx_m output('A - A^H:', _max_diff_csr(mtx_a, mtx_a.H)) if options.eigs_only: eigs = eig_solver(mtx_a, mtx_b, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(mtx_a, mtx_b, n_eigs=options.n_eigs, eigenvectors=True) omegas = nm.sqrt(eigs) output('eigs, omegas:\n', nm.c_[eigs, omegas]) out = tuple(eigs) + tuple(omegas) if options.log_std_waves: out = out + (cp * wmag, cs * wmag) log(*out, x=[wmag, wmag]) save_eigenvectors(eigenshapes_filename % iv, svecs, pb) log(save_figure=os.path.join(output_dir, 'frequencies.png')) log(finished=True) else: import scipy.sparse as sps from sksparse.cholmod import cholesky eigenshapes_filename = os.path.join( output_dir, 'wave-number-eigenshapes-%s.vtk' % stepper.suffix) factor = cholesky(mtx_s) perm = factor.P() ir = nm.arange(len(perm)) mtx_p = sps.coo_matrix((nm.ones_like(perm), (ir, perm))) mtx_l = mtx_p.T * factor.L() mtx_eye = sps.eye(mtx_l.shape[0], dtype=nm.float64) output('S - LL^T:', _max_diff_csr(mtx_s, mtx_l * mtx_l.T)) log = Log([[r'$\kappa_{%d}$' % ii for ii in range(options.n_eigs)]], plot_kwargs=[{ 'ls': 'None', 'marker': 'o' }], yscales=['linear'], xlabels=[r'$\omega$'], ylabels=[r'wave numbers $\kappa_i$'], log_filename=os.path.join(output_dir, 'wave-numbers.txt'), aggregate=1000, sleep=0.1) for io, omega in stepper: output('step %d: frequency %s' % (io, omega)) mtx_a = sps.bmat([[mtx_k - omega**2 * mtx_m, None], [None, mtx_eye]]) mtx_b = sps.bmat([[1j * mtx_r, mtx_l], [mtx_l.T, None]]) output('A - A^T:', _max_diff_csr(mtx_a, mtx_a.T)) output('A - A^H:', _max_diff_csr(mtx_a, mtx_a.T)) output('B - B^H:', _max_diff_csr(mtx_b, mtx_b.H)) if options.eigs_only: eigs = eig_solver(mtx_a, mtx_b, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(mtx_a, mtx_b, n_eigs=options.n_eigs, eigenvectors=True) kappas = eigs output('kappas:\n', kappas[:, None]) out = tuple(kappas) log(*out, x=[omega]) save_eigenvectors(eigenshapes_filename % io, svecs, pb) log(save_figure=os.path.join(output_dir, 'wave-numbers.png')) log(finished=True)
def main(): # Aluminium and epoxy. default_pars = '70e9,0.35,2.799e3, 3.8e9,0.27,1.142e3' default_solver_conf = ("kind='eig.scipy',method='eigsh',tol=1.0e-5," "maxiter=1000,which='LM',sigma=0.0") parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--pars', metavar='young1,poisson1,density1' ',young2,poisson2,density2', action='store', dest='pars', default=default_pars, help=helps['pars']) parser.add_argument('--conf', metavar='filename', action='store', dest='conf', default=None, help=helps['conf']) parser.add_argument('--mesh-size', type=float, metavar='float', action='store', dest='mesh_size', default=None, help=helps['mesh_size']) parser.add_argument('--unit-multipliers', metavar='c_time,c_length,c_mass', action='store', dest='unit_multipliers', default='1.0,1.0,1.0', help=helps['unit_multipliers']) parser.add_argument('--plane', action='store', dest='plane', choices=['strain', 'stress'], default='strain', help=helps['plane']) parser.add_argument('--wave-dir', metavar='float,float[,float]', action='store', dest='wave_dir', default='1.0,0.0,0.0', help=helps['wave_dir']) parser.add_argument('--mode', action='store', dest='mode', choices=['omega', 'kappa'], default='omega', help=helps['mode']) parser.add_argument('--range', metavar='start,stop,count', action='store', dest='range', default='0,6.4,33', help=helps['range']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_argument('--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_argument('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['n_eigs']) group = parser.add_mutually_exclusive_group() group.add_argument('--eigs-only', action='store_true', dest='eigs_only', default=False, help=helps['eigs_only']) group.add_argument('--post-process', action='store_true', dest='post_process', default=False, help=helps['post_process']) parser.add_argument('--solver-conf', metavar='dict-like', action='store', dest='solver_conf', default=default_solver_conf, help=helps['solver_conf']) parser.add_argument('--save-regions', action='store_true', dest='save_regions', default=False, help=helps['save_regions']) parser.add_argument('--save-materials', action='store_true', dest='save_materials', default=False, help=helps['save_materials']) parser.add_argument('--log-std-waves', action='store_true', dest='log_std_waves', default=False, help=helps['log_std_waves']) parser.add_argument('--no-legends', action='store_false', dest='show_legends', default=True, help=helps['no_legends']) parser.add_argument('--no-show', action='store_false', dest='show', default=True, help=helps['no_show']) parser.add_argument('--silent', action='store_true', dest='silent', default=False, help=helps['silent']) parser.add_argument('-c', '--clear', action='store_true', dest='clear', default=False, help=helps['clear']) parser.add_argument('-o', '--output-dir', metavar='path', action='store', dest='output_dir', default='output', help=helps['output_dir']) parser.add_argument('mesh_filename', default='', help=helps['mesh_filename']) options = parser.parse_args() output_dir = options.output_dir output.set_output(filename=os.path.join(output_dir,'output_log.txt'), combined=options.silent == False) if options.conf is not None: mod = import_file(options.conf) else: mod = sys.modules[__name__] apply_units = mod.apply_units define = mod.define set_wave_dir = mod.set_wave_dir setup_n_eigs = mod.setup_n_eigs build_evp_matrices = mod.build_evp_matrices save_materials = mod.save_materials get_std_wave_fun = mod.get_std_wave_fun get_stepper = mod.get_stepper process_evp_results = mod.process_evp_results options.pars = [float(ii) for ii in options.pars.split(',')] options.unit_multipliers = [float(ii) for ii in options.unit_multipliers.split(',')] options.wave_dir = [float(ii) for ii in options.wave_dir.split(',')] aux = options.range.split(',') options.range = [float(aux[0]), float(aux[1]), int(aux[2])] options.solver_conf = dict_from_string(options.solver_conf) if options.clear: remove_files_patterns(output_dir, ['*.h5', '*.vtk', '*.txt'], ignores=['output_log.txt'], verbose=True) filename = os.path.join(output_dir, 'options.txt') ensure_path(filename) save_options(filename, [('options', vars(options))], quote_command_line=True) pars = apply_units(options.pars, options.unit_multipliers) output('material parameters with applied unit multipliers:') output(pars) if options.mode == 'omega': rng = copy(options.range) rng[:2] = apply_unit_multipliers(options.range[:2], ['wave_number', 'wave_number'], options.unit_multipliers) output('wave number range with applied unit multipliers:', rng) else: rng = copy(options.range) rng[:2] = apply_unit_multipliers(options.range[:2], ['frequency', 'frequency'], options.unit_multipliers) output('frequency range with applied unit multipliers:', rng) pb, wdir, bzone, mtxs = assemble_matrices(define, mod, pars, set_wave_dir, options) dim = pb.domain.shape.dim if dim != 2: options.plane = 'strain' if options.save_regions: pb.save_regions_as_groups(os.path.join(output_dir, 'regions')) if options.save_materials: save_materials(output_dir, pb, options) conf = pb.solver_confs['eig'] eig_solver = Solver.any_from_conf(conf) n_eigs, options.n_eigs = setup_n_eigs(options, pb, mtxs) get_color = lambda ii: plt.cm.viridis((float(ii) / (options.n_eigs - 1))) plot_kwargs = [{'color' : get_color(ii), 'ls' : '', 'marker' : 'o'} for ii in range(options.n_eigs)] log_names = [] log_plot_kwargs = [] if options.log_std_waves: std_wave_fun, log_names, log_plot_kwargs = get_std_wave_fun( pb, options) else: std_wave_fun = None stepper = get_stepper(rng, pb, options) if options.mode == 'omega': eigenshapes_filename = os.path.join(output_dir, 'frequency-eigenshapes-%s.vtk' % stepper.suffix) log = Log([[r'$\lambda_{%d}$' % ii for ii in range(options.n_eigs)], [r'$\omega_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs, plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * options.n_eigs, ['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear', 'linear'], xlabels=[r'$\kappa$', r'$\kappa$'], ylabels=[r'eigenvalues $\lambda_i$', r'frequencies $\omega_i$'], show_legends=options.show_legends, is_plot=options.show, log_filename=os.path.join(output_dir, 'frequencies.txt'), aggregate=1000, sleep=0.1) for iv, wmag in stepper: output('step %d: wave vector %s' % (iv, wmag * wdir)) evp_mtxs = build_evp_matrices(mtxs, wmag, options.mode, pb) if options.eigs_only: eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=True) omegas, svecs, out = process_evp_results( eigs, svecs, wmag, options.mode, wdir, bzone, pb, mtxs, std_wave_fun=std_wave_fun ) log(*out, x=[wmag, wmag]) save_eigenvectors(eigenshapes_filename % iv, svecs, wmag, wdir, pb) gc.collect() log(save_figure=os.path.join(output_dir, 'frequencies.png')) log(finished=True) else: eigenshapes_filename = os.path.join(output_dir, 'wave-number-eigenshapes-%s.vtk' % stepper.suffix) log = Log([[r'$\kappa_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear'], xlabels=[r'$\omega$'], ylabels=[r'wave numbers $\kappa_i$'], show_legends=options.show_legends, is_plot=options.show, log_filename=os.path.join(output_dir, 'wave-numbers.txt'), aggregate=1000, sleep=0.1) for io, omega in stepper: output('step %d: frequency %s' % (io, omega)) evp_mtxs = build_evp_matrices(mtxs, omega, options.mode, pb) if options.eigs_only: eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=True) kappas, svecs, out = process_evp_results( eigs, svecs, omega, options.mode, wdir, bzone, pb, mtxs, std_wave_fun=std_wave_fun ) log(*out, x=[omega]) save_eigenvectors(eigenshapes_filename % io, svecs, kappas, wdir, pb) gc.collect() log(save_figure=os.path.join(output_dir, 'wave-numbers.png')) log(finished=True)
def main(): default_vertex_opts = """color='k', label_global=12, label_local=8""" default_edge_opts = """color='b', label_global=12, label_local=8""" default_face_opts = """color='g', label_global=12, label_local=8""" default_cell_opts = """color='r', label_global=12""" default_wireframe_opts = "color='k'" parser = ArgumentParser(description=__doc__) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('--vertex-opts', metavar='dict-like', action='store', dest='vertex_opts', default=default_vertex_opts, help=helps['vertex_opts']) parser.add_argument('--edge-opts', metavar='dict-like', action='store', dest='edge_opts', default=default_edge_opts, help=helps['edge_opts']) parser.add_argument('--face-opts', metavar='dict-like', action='store', dest='face_opts', default=default_face_opts, help=helps['face_opts']) parser.add_argument('--cell-opts', metavar='dict-like', action='store', dest='cell_opts', default=default_cell_opts, help=helps['cell_opts']) parser.add_argument('--wireframe-opts', metavar='dict-like', action='store', dest='wireframe_opts', default=default_wireframe_opts, help=helps['wireframe_opts']) parser.add_argument('--no-axes', action='store_false', dest='axes', help=helps['no_axes']) parser.add_argument('-n', '--no-show', action='store_false', dest='show', help=helps['no_show']) parser.add_argument('filename') parser.add_argument('figname', nargs='?') options = parser.parse_args() entities_opts = [ dict_from_string(options.vertex_opts), dict_from_string(options.edge_opts), dict_from_string(options.face_opts), dict_from_string(options.cell_opts), ] wireframe_opts = dict_from_string(options.wireframe_opts) filename = options.filename mesh = Mesh.from_file(filename) output('Mesh:') output(' dimension: %d, vertices: %d, elements: %d' % (mesh.dim, mesh.n_nod, mesh.n_el)) domain = FEDomain('domain', mesh) output(domain.cmesh) domain.cmesh.cprint(1) dim = domain.cmesh.dim if dim == 2: entities_opts.pop(2) ax = pc.plot_cmesh(None, domain.cmesh, wireframe_opts=wireframe_opts, entities_opts=entities_opts) ax.axis('image') if not options.axes: ax.axis('off') plt.tight_layout() if options.figname: fig = ax.figure fig.savefig(options.figname, bbox_inches='tight') if options.show: plt.show()