def main(): parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('-d', '--dims', metavar='dims', action='store', dest='dims', default='[1.0, 1.0]', help=helps['dims']) parser.add_argument('-c', '--centre', metavar='centre', action='store', dest='centre', default='[0.0, 0.0]', help=helps['centre']) parser.add_argument('-s', '--shape', metavar='shape', action='store', dest='shape', default='[11, 11]', help=helps['shape']) parser.add_argument('--show', action="store_true", dest='show', default=False, help=helps['show']) options = parser.parse_args() dims = nm.array(eval(options.dims), dtype=nm.float64) centre = nm.array(eval(options.centre), dtype=nm.float64) shape = nm.array(eval(options.shape), dtype=nm.int32) output('dimensions:', dims) output('centre: ', centre) output('shape: ', shape) mesh = gen_block_mesh(dims, shape, centre, name='block-fem') fe_domain = FEDomain('domain', mesh) pb, state = run(fe_domain, 1) pb.save_state('laplace_shifted_periodic.vtk', state) if options.show: from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.domain_specific import DomainSpecificPlot view = Viewer('laplace_shifted_periodic.vtk') view(rel_scaling=1, domain_specific={ 'u': DomainSpecificPlot('plot_warp_scalar', ['rel_scaling=1']) }, is_scalar_bar=True, is_wireframe=True, opacity=0.3)
def __call__(self, parser, namespace, value, option_string=None): if value is not None: print(value) out = {} confs = value.split(':') for conf in confs: aux = conf.split(',') var_name, fun_name = aux[:2] args = aux[2:] out[var_name] = DomainSpecificPlot(fun_name, args) setattr(namespace, self.dest, out)
def parse_domain_specific(option, opt, value, parser): if value is not None: print value out = {} confs = value.split(':') for conf in confs: aux = conf.split(',') var_name, fun_name = aux[:2] args = aux[2:] out[var_name] = DomainSpecificPlot(fun_name, args) setattr(parser.values, option.dest, out)
def main(): parser = ArgumentParser(description=__doc__.rstrip(), formatter_class=RawDescriptionHelpFormatter) parser.add_argument('output_dir', help=helps['output_dir']) parser.add_argument('-d', '--dims', metavar='l,w,t', action='store', dest='dims', default='0.2,0.01,0.001', help=helps['dims']) parser.add_argument('-n', '--nx', metavar='start,stop,step', action='store', dest='nx', default='2,103,10', help=helps['nx']) parser.add_argument('-t', '--transform', choices=['none', 'bend', 'twist'], action='store', dest='transform', default='none', help=helps['transform']) parser.add_argument('--young', metavar='float', type=float, action='store', dest='young', default=210e9, help=helps['young']) parser.add_argument('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.3, help=helps['poisson']) parser.add_argument('--force', metavar='float', type=float, action='store', dest='force', default=-1.0, help=helps['force']) parser.add_argument('-p', '--plot', action="store_true", dest='plot', default=False, help=helps['plot']) parser.add_argument('--u-scaling', metavar='float', type=float, action='store', dest='scaling', default=1.0, help=helps['scaling']) parser.add_argument('-s', '--show', action="store_true", dest='show', default=False, help=helps['show']) parser.add_argument('--silent', action='store_true', dest='silent', default=False, help=helps['silent']) options = parser.parse_args() dims = nm.array([float(ii) for ii in options.dims.split(',')], dtype=nm.float64) nxs = tuple([int(ii) for ii in options.nx.split(',')]) young = options.young poisson = options.poisson force = options.force output_dir = options.output_dir odir = lambda filename: os.path.join(output_dir, filename) filename = odir('output_log.txt') ensure_path(filename) output.set_output(filename=filename, combined=options.silent == False) output('output directory:', output_dir) output('using values:') output(" dimensions:", dims) output(" nx range:", nxs) output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' force:', options.force) output(' transform:', options.transform) if options.transform == 'none': options.transform = None u_exact = get_analytical_displacement(dims, young, force, transform=options.transform) if options.transform is None: ilog = 2 labels = ['u_3'] elif options.transform == 'bend': ilog = 0 labels = ['u_1'] elif options.transform == 'twist': ilog = [0, 1, 2] labels = ['u_1', 'u_2', 'u_3'] label = ', '.join(labels) log = [] for nx in range(*nxs): shape = (nx, 2) pb, state, u, gamma2 = solve_problem(shape, dims, young, poisson, force, transform=options.transform) dofs = u.get_state_in_region(gamma2) output('DOFs along the loaded edge:') output('\n%s' % dofs) log.append([nx - 1] + nm.array(dofs[0, ilog], ndmin=1).tolist()) pb.save_state(odir('shell10x_cantilever.vtk'), state) log = nm.array(log) output('max. %s displacement w.r.t. number of cells:' % label) output('\n%s' % log) output('analytical value:', u_exact) if options.plot: import matplotlib.pyplot as plt plt.rcParams.update({ 'lines.linewidth' : 3, 'font.size' : 16, }) fig, ax1 = plt.subplots() fig.suptitle('max. $%s$ displacement' % label) for ic in range(log.shape[1] - 1): ax1.plot(log[:, 0], log[:, ic + 1], label=r'$%s$' % labels[ic]) ax1.set_xlabel('# of cells') ax1.set_ylabel(r'$%s$' % label) ax1.grid(which='both') lines1, labels1 = ax1.get_legend_handles_labels() if u_exact is not None: ax1.hlines(u_exact, log[0, 0], log[-1, 0], 'r', 'dotted', label=r'$%s^{analytical}$' % label) ax2 = ax1.twinx() # Assume single log column. ax2.semilogy(log[:, 0], nm.abs(log[:, 1] - u_exact), 'g', label=r'$|%s - %s^{analytical}|$' % (label, label)) ax2.set_ylabel(r'$|%s - %s^{analytical}|$' % (label, label)) lines2, labels2 = ax2.get_legend_handles_labels() else: lines2, labels2 = [], [] ax1.legend(lines1 + lines2, labels1 + labels2, loc='best') plt.tight_layout() ax1.set_xlim([log[0, 0] - 2, log[-1, 0] + 2]) suffix = {None: 'straight', 'bend' : 'bent', 'twist' : 'twisted'}[options.transform] fig.savefig(odir('shell10x_cantilever_convergence_%s.png' % suffix)) plt.show() if options.show: from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.domain_specific import DomainSpecificPlot ds = {'u_disp' : DomainSpecificPlot('plot_displacements', ['rel_scaling=%f' % options.scaling])} view = Viewer(odir('shell10x_cantilever.vtk')) view(domain_specific=ds, is_scalar_bar=True, is_wireframe=True, opacity={'wireframe' : 0.5})
'vibro_acoustic3d_mid.py', 'linear_elastic_mM.py', 'time_poisson_explicit.py', '__init__.py', ] omit_dirs = [ re.compile('.*output.*/').match, ] custom = { 'diffusion/sinbc.py' : { '_t' : { 'is_wireframe' : True, 'domain_specific' : { 't' : DomainSpecificPlot('plot_warp_scalar', ['rel_scaling=1']), }, 'view' : (-160, 33, 4, [0.5, 1.22, 0.05]), 'roll' : 68, 'opacity' : {'wireframe' : 0.3}, }, '_grad' : { 'opacity' : {'surface' : 0.3}, 'view' : (-160, 33, 4, [0.5, 1.22, 0.05]), 'roll' : 68, }, }, 'acoustics/acoustics3d.py' : { '_p_1' : { 'view' : (-53, 120, 0.225, [0.021, 0.018, 0.066]), 'roll' : -177,
'roll': -120, }, '_w': { 'view': (0.0, 0.0, 0.86, [0.0, 0.0, 0.1]), 'roll': 0, }, '_g0': { 'view': (0.0, 0.0, 0.86, [0.0, 0.0, 0.1]), 'roll': 0, }, }, 'diffusion/laplace_1d.py': { '': { 'is_wireframe': True, 'domain_specific': { 't': DomainSpecificPlot('plot_warp_scalar', ['rel_scaling=1']), }, 'view': (-90, 90, 1.5, [0, 0, 0]), 'roll': 0, 'opacity': { 'wireframe': 0.3 }, }, }, 'diffusion/laplace_coupling_lcbcs.py': { '': { 'is_wireframe': True, 'domain_specific': { 'u1': DomainSpecificPlot('plot_warp_scalar', ['rel_scaling=1']), 'u2': DomainSpecificPlot('plot_warp_scalar',
omits = [ 'linear_elastic_mM.py', 'time_poisson_explicit.py', '__init__.py', ] omit_dirs = [ re.compile('.*output.*/').match, ] custom = { 'diffusion/sinbc.py' : { '_t' : { 'is_wireframe' : True, 'domain_specific' : { 't' : DomainSpecificPlot('plot_warp_scalar', ['rel_scaling=1']), }, 'view' : (-160, 33, 4, [0.5, 1.22, 0.05]), 'roll' : 68, 'opacity' : {'wireframe' : 0.3}, }, '_grad' : { 'opacity' : {'surface' : 0.3}, 'view' : (-160, 33, 4, [0.5, 1.22, 0.05]), 'roll' : 68, }, }, } def _omit(filename): omit = False
def main(): parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('-d', '--dims', metavar='dims', action='store', dest='dims', default='[1.0, 1.0]', help=helps['dims']) parser.add_argument('-c', '--centre', metavar='centre', action='store', dest='centre', default='[0.0, 0.0]', help=helps['centre']) parser.add_argument('-s', '--shape', metavar='shape', action='store', dest='shape', default='[11, 11]', help=helps['shape']) parser.add_argument('-b', '--bc-kind', metavar='kind', action='store', dest='bc_kind', choices=['free', 'cantilever', 'fixed'], default='free', help=helps['bc_kind']) parser.add_argument('-a', '--axis', metavar='0, ..., dim, or -1', type=int, action='store', dest='axis', default=-1, help=helps['axis']) parser.add_argument('--young', metavar='float', type=float, action='store', dest='young', default=200e+9, help=helps['young']) parser.add_argument('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.3, help=helps['poisson']) parser.add_argument('--density', metavar='float', type=float, action='store', dest='density', default=7800.0, help=helps['density']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_argument('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['n_eigs']) parser.add_argument('-i', '--ignore', metavar='int', type=int, action='store', dest='ignore', default=None, help=helps['ignore']) parser.add_argument('--solver', metavar='solver', action='store', dest='solver', default= \ "eig.scipy,method:'eigh',tol:1e-5,maxiter:1000", help=helps['solver']) parser.add_argument('--show', action="store_true", dest='show', default=False, help=helps['show']) #parser.add_argument('filename', nargs='?', default=None) #read block.mesh #parser.add_argument('filename', nargs='?', default="platehexat200mm.mesh") parser.add_argument('filename', nargs='?', default="block_1m.mesh") options = parser.parse_args() aux = options.solver.split(',') kwargs = {} for option in aux[1:]: key, val = option.split(':') kwargs[key.strip()] = eval(val) eig_conf = Struct(name='evp', kind=aux[0], **kwargs) output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' density:', options.density) output('displacement field approximation order:', options.order) output('requested %d eigenvalues' % options.n_eigs) output('using eigenvalue problem solver:', eig_conf.kind) output.level += 1 for key, val in six.iteritems(kwargs): output('%s: %r' % (key, val)) output.level -= 1 assert_((0.0 < options.poisson < 0.5), "Poisson's ratio must be in ]0, 0.5[!") assert_((0 < options.order), 'displacement approximation order must be at least 1!') filename = options.filename if filename is not None: mesh = Mesh.from_file(filename) dim = mesh.dim dims = nm.diff(mesh.get_bounding_box(), axis=0) else: dims = nm.array(eval(options.dims), dtype=nm.float64) dim = len(dims) centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim] shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim] output('dimensions:', dims) output('centre: ', centre) output('shape: ', shape) mesh = gen_block_mesh(dims, shape, centre, name='mesh') output('axis: ', options.axis) assert_((-dim <= options.axis < dim), 'invalid axis value!') eig_solver = Solver.any_from_conf(eig_conf) # Build the problem definition. domain = FEDomain('domain', mesh) bbox = domain.get_mesh_bounding_box() min_coor, max_coor = bbox[:, options.axis] eps = 1e-8 * (max_coor - min_coor) ax = 'xyz'[:dim][options.axis] omega = domain.create_region('Omega', 'all') """ bottom = domain.create_region('Bottom', 'vertices in (%s < %.10f)' % (ax, min_coor + eps), 'facet') bottom_top = domain.create_region('BottomTop', 'r.Bottom +v vertices in (%s > %.10f)' % (ax, max_coor - eps), 'facet') """ #import pdb; pdb.set_trace() left = domain.create_region('left', 'vertices in (x < -0.49)', 'facet') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=options.order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson) m = Material('m', D=mtx_d, rho=options.density) integral = Integral('i', order=2 * options.order) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u) eq1 = Equation('stiffness', t1) eq2 = Equation('mass', t2) lhs_eqs = Equations([eq1, eq2]) pb = Problem('modal', equations=lhs_eqs) """ if options.bc_kind == 'free': pb.time_update() n_rbm = dim * (dim + 1) // 2 elif options.bc_kind == 'cantilever': fixed = EssentialBC('Fixed', bottom, {'u.all' : 0.0}) pb.time_update(ebcs=Conditions([fixed])) n_rbm = 0 elif options.bc_kind == 'fixed': fixed = EssentialBC('Fixed', bottom_top, {'u.all' : 0.0}) pb.time_update(ebcs=Conditions([fixed])) n_rbm = 0 else: raise ValueError('unsupported BC kind! (%s)' % options.bc_kind) if options.ignore is not None: n_rbm = options.ignore """ fixed = EssentialBC('Fixed', left, {'u.all': 0.0}) pb.time_update(ebcs=Conditions([fixed])) n_rbm = 0 pb.update_materials() # Assemble stiffness and mass matrices. mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a) mtx_m = mtx_k.copy() mtx_m.data[:] = 0.0 mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m) try: eigs, svecs = eig_solver(mtx_k, mtx_m, options.n_eigs + n_rbm, eigenvectors=True) except sla.ArpackNoConvergence as ee: eigs = ee.eigenvalues svecs = ee.eigenvectors output('only %d eigenvalues converged!' % len(eigs)) output('%d eigenvalues converged (%d ignored as rigid body modes)' % (len(eigs), n_rbm)) eigs = eigs[n_rbm:] svecs = svecs[:, n_rbm:] omegas = nm.sqrt(eigs) freqs = omegas / (2 * nm.pi) output('number | eigenvalue | angular frequency ' '| frequency') for ii, eig in enumerate(eigs): output('%6d | %17.12e | %17.12e | %17.12e' % (ii + 1, eig, omegas[ii], freqs[ii])) # Make full eigenvectors (add DOFs fixed by boundary conditions). variables = pb.get_variables() vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]), dtype=nm.float64) for ii in range(svecs.shape[1]): vecs[:, ii] = variables.make_full_vec(svecs[:, ii]) # Save the eigenvectors. out = {} state = pb.create_state() for ii in range(eigs.shape[0]): state.set_full(vecs[:, ii]) aux = state.create_output_dict() strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)', integrals=Integrals([integral]), mode='el_avg', verbose=False) out['u%03d' % ii] = aux.popitem()[1] out['strain%03d' % ii] = Struct(mode='cell', data=strain) pb.save_state('eigenshapes.vtk', out=out) pb.save_regions_as_groups('regions') if len(eigs) and options.show: # Show the solution. If the approximation order is greater than 1, the # extra DOFs are simply thrown away. from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.domain_specific import DomainSpecificPlot scaling = 0.05 * dims.max() / nm.abs(vecs).max() ds = {} for ii in range(eigs.shape[0]): pd = DomainSpecificPlot('plot_displacements', [ 'rel_scaling=%s' % scaling, 'color_kind="tensors"', 'color_name="strain%03d"' % ii ]) ds['u%03d' % ii] = pd view = Viewer('eigenshapes.vtk') view(domain_specific=ds, only_names=sorted(ds.keys()), is_scalar_bar=False, is_wireframe=True)
def main(): parser = OptionParser(usage=usage, version='%prog') parser.add_option('-d', '--dims', metavar='dims', action='store', dest='dims', default='[1.0, 1.0]', help=helps['dims']) parser.add_option('-c', '--centre', metavar='centre', action='store', dest='centre', default='[0.0, 0.0]', help=helps['centre']) parser.add_option('-s', '--shape', metavar='shape', action='store', dest='shape', default='[11, 11]', help=helps['shape']) parser.add_option('-b', '--bc-kind', metavar='kind', action='store', dest='bc_kind', choices=['free', 'clamped'], default='free', help=helps['bc_kind']) parser.add_option('--young', metavar='float', type=float, action='store', dest='young', default=6.80e+10, help=helps['young']) parser.add_option('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.36, help=helps['poisson']) parser.add_option('--density', metavar='float', type=float, action='store', dest='density', default=2700.0, help=helps['density']) parser.add_option('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_option('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['order']) parser.add_option('', '--show', action="store_true", dest='show', default=False, help=helps['show']) options, args = parser.parse_args() assert_((0.0 < options.poisson < 0.5), "Poisson's ratio must be in ]0, 0.5[!") assert_((0 < options.order), 'displacement approximation order must be at least 1!') dims = nm.array(eval(options.dims), dtype=nm.float64) dim = len(dims) centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim] shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim] output('dimensions:', dims) output('centre: ', centre) output('shape: ', shape) output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' density:', options.density) # Build the problem definition. mesh = gen_block_mesh(dims, shape, centre, name='mesh') domain = FEDomain('domain', mesh) bbox = domain.get_mesh_bounding_box() min_y, max_y = bbox[:, 1] eps = 1e-8 * (max_y - min_y) omega = domain.create_region('Omega', 'all') bottom = domain.create_region('Bottom', 'vertices in (y < %.10f)' % (min_y + eps), 'facet') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=options.order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson) m = Material('m', D=mtx_d, rho=options.density) integral = Integral('i', order=2 * options.order) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u) eq1 = Equation('stiffness', t1) eq2 = Equation('mass', t2) lhs_eqs = Equations([eq1, eq2]) pb = Problem('modal', equations=lhs_eqs) if options.bc_kind == 'free': pb.time_update() n_rbm = dim * (dim + 1) / 2 else: fixed_b = EssentialBC('FixedB', bottom, {'u.all': 0.0}) pb.time_update(ebcs=Conditions([fixed_b])) n_rbm = 0 pb.update_materials() # Assemble stiffness and mass matrices. mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a) mtx_m = mtx_k.copy() mtx_m.data[:] = 0.0 mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m) try: eigs, svecs = sla.eigsh(mtx_k, k=options.n_eigs + n_rbm, M=mtx_m, which='SM', tol=1e-5, maxiter=10000) except sla.ArpackNoConvergence as ee: eigs = ee.eigenvalues svecs = ee.eigenvectors output('only %d eigenvalues converged!' % len(eigs)) eigs = eigs[n_rbm:] svecs = svecs[:, n_rbm:] output('eigenvalues:', eigs) output('eigen-frequencies:', nm.sqrt(eigs)) # Make full eigenvectors (add DOFs fixed by boundary conditions). variables = pb.get_variables() vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]), dtype=nm.float64) for ii in xrange(svecs.shape[1]): vecs[:, ii] = variables.make_full_vec(svecs[:, ii]) # Save the eigenvectors. out = {} state = pb.create_state() for ii in xrange(eigs.shape[0]): state.set_full(vecs[:, ii]) aux = state.create_output_dict() strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)', integrals=Integrals([integral]), mode='el_avg', verbose=False) out['u%03d' % ii] = aux.popitem()[1] out['strain%03d' % ii] = Struct(mode='cell', data=strain) pb.save_state('eigenshapes.vtk', out=out) pb.save_regions_as_groups('regions') if options.show: # Show the solution. If the approximation order is greater than 1, the # extra DOFs are simply thrown away. from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.domain_specific import DomainSpecificPlot scaling = 0.05 * dims.max() / nm.abs(vecs).max() ds = {} for ii in xrange(eigs.shape[0]): pd = DomainSpecificPlot('plot_displacements', [ 'rel_scaling=%s' % scaling, 'color_kind="tensors"', 'color_name="strain%03d"' % ii ]) ds['u%03d' % ii] = pd view = Viewer('eigenshapes.vtk') view(domain_specific=ds, only_names=sorted(ds.keys()), is_scalar_bar=False, is_wireframe=True)