def get_parametrized_conf(filename, args): import importlib prefix = "" problem_module_name = filename.replace(".py", "").strip("\\.") \ .replace("\\", ".").replace("/", ".") if not problem_module_name.startswith(prefix): problem_module_name = prefix + problem_module_name problem_module = importlib.import_module(problem_module_name) dg_args = { dg_par_name: args.__dict__[dg_par_name] for dg_par_name in param_names + ["mesh_file", "order"] if args.__dict__[dg_par_name] is not None } if hasattr(problem_module, "define"): mod = sys.modules[problem_module_name] # noinspection PyCallingNonCallable problem_conf = ProblemConf.from_dict(problem_module.define(**dg_args), mod, verbose=args.verbose) if args.mesh_file is not None: problem_conf.options.absolute_mesh_path = True else: output("Problem file is not parametrized, arguments ignored") problem_conf = ProblemConf.from_file(filename, verbose=False) problem_conf.verbose = args.verbose return problem_conf
def assemble_matrices(define, mod, pars, set_wave_dir, options, wdir=None): """ Assemble the blocks of dispersion eigenvalue problem matrices. """ define_dict = define(filename_mesh=options.mesh_filename, pars=pars, approx_order=options.order, refinement_level=options.refine, solver_conf=options.solver_conf, plane=options.plane, post_process=options.post_process, **options.define_kwargs) conf = ProblemConf.from_dict(define_dict, mod) pb = Problem.from_conf(conf) pb.dispersion_options = options pb.set_output_dir(options.output_dir) dim = pb.domain.shape.dim # Set the normalized wave vector direction to the material(s). if wdir is None: wdir = nm.asarray(options.wave_dir[:dim], dtype=nm.float64) wdir = wdir / nm.linalg.norm(wdir) set_wave_dir(pb, wdir) 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() # Assemble the matrices. mtxs = {} for key, eq in pb.equations.iteritems(): mtxs[key] = mtx = pb.mtx_a.copy() mtx = eq.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx) mtx.eliminate_zeros() output_array_stats(mtx.data, 'nonzeros in %s' % key) output('symmetry checks:') output('%s - %s^T:' % (key, key), max_diff_csr(mtx, mtx.T)) output('%s - %s^H:' % (key, key), max_diff_csr(mtx, mtx.H)) return pb, wdir, bzone, mtxs
def test_stokes_slip_bc(self): import scipy.sparse as sp from sfepy.base.conf import ProblemConf from sfepy.discrete import Problem import examples.navier_stokes.stokes_slip_bc as ssb conf = ProblemConf.from_dict(ssb.define(), ssb) pb = Problem.from_conf(conf, init_solvers=False) pb.time_update() variables = pb.get_variables() adi = variables.adi lcdi = variables.lcdi mtx = variables.mtx_lcbc ok = adi.var_names == lcdi.var_names self.report('same adi-lcdi ordering:', ok) ublock = mtx[adi.indx['u']] ir, ic = ublock.nonzero() ir += adi.indx['u'].start i0, i1 = adi.indx['u'].start, adi.indx['u'].stop _ok0 = (i0 <= ir).all() and (ir < i1).all() self.report('u block rows in [%d %d[: %s' % (i0, i1, _ok0)) i0, i1 = lcdi.indx['u'].start, lcdi.indx['u'].stop _ok1 = (i0 <= ic).all() and (ic < i1).all() self.report('u block cols in [%d %d[: %s' % (i0, i1, _ok1)) ok = ok and _ok0 and _ok1 pblock = mtx[adi.indx['p']] ir, ic, iv = sp.find(pblock) ir += adi.indx['p'].start i0, i1 = adi.indx['p'].start, adi.indx['p'].stop _ok0 = (i0 <= ir).all() and (ir < i1).all() self.report('p block rows in [%d %d[: %s' % (i0, i1, _ok0)) i0, i1 = lcdi.indx['p'].start, lcdi.indx['p'].stop _ok1 = (i0 <= ic).all() and (ic < i1).all() self.report('p block cols in [%d %d[: %s' % (i0, i1, _ok1)) ok = ok and _ok0 and _ok1 _ok0 = (len(ir) == adi.n_dof['p']) self.report('p block size correct:', _ok0) _ok1 = ((ir - adi.indx['p'].start) == (ic - lcdi.indx['p'].start)).all() self.report('p block diagonal:', _ok1) _ok2 = (iv == 1.0).all() self.report('p block identity:', _ok2) ok = ok and _ok0 and _ok1 and _ok2 return ok
def assemble_matrices(define, mod, pars, set_wave_dir, options): """ Assemble the blocks of dispersion eigenvalue problem matrices. """ 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, post_process=options.post_process) conf = ProblemConf.from_dict(define_problem(), mod) pb = Problem.from_conf(conf) pb.dispersion_options = options pb.set_output_dir(options.output_dir) dim = pb.domain.shape.dim # Set the normalized wave vector direction to the material(s). wdir = nm.asarray(options.wave_dir[:dim], dtype=nm.float64) wdir = wdir / nm.linalg.norm(wdir) set_wave_dir(pb, wdir) 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() # Assemble the matrices. mtxs = {} for key, eq in pb.equations.iteritems(): mtxs[key] = mtx = pb.mtx_a.copy() mtx = eq.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx) mtx.eliminate_zeros() output_array_stats(mtx.data, 'nonzeros in %s' % key) output('symmetry checks:') output('%s - %s^T:' % (key, key), max_diff_csr(mtx, mtx.T)) output('%s - %s^H:' % (key, key), max_diff_csr(mtx, mtx.H)) return pb, wdir, bzone, mtxs
def eval_homogenized_coefs( self ): if self.cached_coefs is not None: return self.cached_coefs opts = self.app_options if opts.homogeneous: rtm = opts.region_to_material mat_region = rtm.keys()[0] mat_name = rtm[mat_region] self.problem.update_materials() mat = self.problem.materials[mat_name] coefs = mat.get_data( mat_region, 0, opts.tensor_names ) else: dc = opts.dispersion_conf dconf = ProblemConf.from_dict( dc['input'], dc['module'] ) dconf.materials = self.conf.materials dconf.fe = self.conf.fe dconf.regions.update( self.conf.regions ) dconf.options['output_dir'] = self.problem.output_dir volume = opts.volume(self.problem, 'Y') problem = ProblemDefinition.from_conf(dconf, init_equations=False) he = HomogenizationEngine( problem, self.options, volume = volume ) coefs = he() ## print coefs ## pause() output.prefix = self.output_prefix self.cached_coefs = coefs return coefs
def __call__(self): return ProblemConf.from_dict(self.conf.__dict__, import_file(__file__))
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(argv): if argv is None: argv = sys.argv[1:] parser = create_argument_parser() args = parser.parse_args(argv) prefix = "" problem_module_name = args.problem_file.replace(".py", "").strip("\\.") \ .replace("\\", ".").replace("/", ".") if not problem_module_name.startswith(prefix): problem_module_name = prefix + problem_module_name problem_module = importlib.import_module(problem_module_name) mesh = None if args.mesh_file is not None: mesh = str(Path(args.mesh_file)) refines = parse_str2tuple_default(args.refines, (1, 2, 3, 4, 5)) orders = parse_str2tuple_default(args.orders, (0, 1, 2, 3, 4)) if problem_module.dim == 1: sol_fig, axs = plt.subplots(len(orders), len(refines), figsize=(18, 10)) mod = sys.modules[problem_module_name] results = [] for ir, refine in enumerate(refines): if mesh is not None: gen_mesh = refine_mesh(mesh, refine) else: gen_mesh = refine for io, order in enumerate(orders): conf = ProblemConf.from_dict(problem_module.define( filename_mesh=gen_mesh, approx_order=order, adflux=args.adflux, limit=args.limit, cw=args.cw, diffcoef=args.diffcoef, diffscheme=args.diffscheme, cfl=args.cfl, dt=args.dt, ), mod, verbose=args.verbose) conf.options.absolute_mesh_path = True if args.output_dir is None: base_output_folder = Path(outputs_folder) / "conv_tests_out" /\ conf.example_name elif "{}" in args.output_dir: base_output_folder = Path( args.output_dir.format(conf.example_name)) else: base_output_folder = Path(args.output_dir) output_folder = base_output_folder / ("h" + str(refine)) output_folder = output_folder / ("o" + str(order)) configure_output({ 'output_screen': not args.no_output_screen, 'output_log_name': str(output_folder / "last_run.txt") }) output("----------------Running--------------------------") output("{}: {}".format(conf.example_name, time.asctime())) output('refine:', refine, 'order:', order) h, n_cells, pb, vols = create_problem(conf) output_format = pjoin( str(output_folder), "sol-h{:02d}o{:02d}.*.{}".format( n_cells, order, "vtk" if problem_module.dim == 1 else "msh")) output("Output set to {}, clearing.".format(output_format)) clear_folder(output_format, confirm=False, doit=True) ensure_path(output_format) pb, elapsed = run_calc(pb, output_format) output("{}: {}".format(conf.example_name, time.asctime())) output("------------------Finished------------------\n\n") ana_l2, ana_qp, diff_l2, rel_l2, num_qp = compute_erros( conf.sol_fun, pb) n_dof = pb.fields["f"].n_nod result = (h, n_cells, nm.mean(vols), order, n_dof, ana_l2, diff_l2, rel_l2, elapsed, getattr(pb.ts_conf, "cour", nm.NAN), getattr(pb.ts_conf, "dt", nm.NAN), getattr(pb.solver.status.nls_status, "err", nm.NAN), getattr(pb.solver.status.nls_status, "n_iter", nm.NAN)) results.append(result) if problem_module.dim == 1: plot_1D_snr(conf, pb, ana_qp, num_qp, io, order, orders, ir, sol_fig, axs) sol_fig.savefig( base_output_folder / ("err-sol-i20" + build_attrs_string(conf) + ".png"), dpi=100) err_df = create_error_df(conf, pb, results) err_df.to_csv(base_output_folder / "results.csv") err_df.to_csv(base_output_folder.parent / (base_output_folder.name + "_results.csv")) output(err_df) conv_fig = plot_conv_results(base_output_folder, conf, err_df, save=True) conv_fig.savefig(base_output_folder / "results.png", dpi=200) if args.doplot: plt.show()