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 drawstate(self, state): # draw the object with sfepy's viewer # state can be obtained from prob.solve() self.prob.save_state('curr_run_demo.vtk', state) view = Viewer('curr_run_demo.vtk') view(vector_mode='warp_norm', rel_scaling=2, is_scalar_bar=True, is_wireframe=True)
def view_file(filename, filter_names, options, view=None): if view is None: if options.show: offscreen = False else: offscreen = get_default(options.offscreen, True) view = Viewer(filename, watch=options.watch, ffmpeg_options=options.ffmpeg_options, output_dir=options.output_dir, offscreen=offscreen) if options.only_names is not None: options.only_names = options.only_names.split(',') view(show=options.show, is_3d=options.is_3d, view=options.view, roll=options.roll, parallel_projection=options.parallel_projection, fgcolor=options.fgcolor, bgcolor=options.bgcolor, colormap=options.colormap, layout=options.layout, scalar_mode=options.scalar_mode, vector_mode=options.vector_mode, rel_scaling=options.rel_scaling, clamping=options.clamping, ranges=options.ranges, is_scalar_bar=options.is_scalar_bar, is_wireframe=options.is_wireframe, opacity=options.opacity, subdomains_args=options.subdomains_args, rel_text_width=options.rel_text_width, fig_filename=options.filename, resolution=options.resolution, filter_names=filter_names, only_names=options.only_names, group_names=options.group_names, step=options.step, time=options.time, anti_aliasing=options.anti_aliasing, domain_specific=options.domain_specific) else: view.set_source_filename(filename) view.save_image(options.filename) return view
def main(): from sfepy import data_dir parser = OptionParser(usage=usage, version='%prog') parser.add_option('-s', '--show', action="store_true", dest='show', default=False, help=help['show']) options, args = parser.parse_args() mesh = Mesh.from_file(data_dir + '/meshes/2d/rectangle_tri.mesh') domain = FEDomain('domain', mesh) min_x, max_x = domain.get_mesh_bounding_box()[:, 0] eps = 1e-8 * (max_x - min_x) omega = domain.create_region('Omega', 'all') gamma1 = domain.create_region('Gamma1', 'vertices in x < %.10f' % (min_x + eps), 'facet') gamma2 = domain.create_region('Gamma2', 'vertices in x > %.10f' % (max_x - eps), 'facet') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=2) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') m = Material('m', D=stiffness_from_lame(dim=2, lam=1.0, mu=1.0)) f = Material('f', val=[[0.02], [0.01]]) integral = Integral('i', order=3) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_lvf(f.val, v)', integral, omega, f=f, v=v) eq = Equation('balance', t1 + t2) eqs = Equations([eq]) fix_u = EssentialBC('fix_u', gamma1, {'u.all': 0.0}) bc_fun = Function('shift_u_fun', shift_u_fun, extra_args={'shift': 0.01}) shift_u = EssentialBC('shift_u', gamma2, {'u.0': bc_fun}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls) pb.save_regions_as_groups('regions') pb.time_update(ebcs=Conditions([fix_u, shift_u])) vec = pb.solve() print(nls_status) pb.save_state('linear_elasticity.vtk', vec) if options.show: view = Viewer('linear_elasticity.vtk') view(vector_mode='warp_norm', rel_scaling=2, is_scalar_bar=True, is_wireframe=True)
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})
def generate_images(images_dir, examples_dir): """ Generate images from results of running examples found in `examples_dir` directory. The generated images are stored to `images_dir`, """ from sfepy.applications import solve_pde from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.utils import mlab prefix = output.prefix output_dir = tempfile.mkdtemp() trunk = os.path.join(output_dir, 'result') options = Struct(output_filename_trunk=trunk, output_format='vtk', save_ebc=False, save_ebc_nodes=False, save_regions=False, save_field_meshes=False, save_regions_as_groups=False, solve_not=False) default_views = {'' : {}} ensure_path(images_dir + os.path.sep) view = Viewer('', offscreen=False) for ex_filename in locate_files('*.py', examples_dir): if _omit(ex_filename): continue output.level = 0 output.prefix = prefix ebase = ex_filename.replace(examples_dir, '')[1:] output('trying "%s"...' % ebase) try: problem, state = solve_pde(ex_filename, options=options) except KeyboardInterrupt: raise except: problem = None output('***** failed! *****') if problem is not None: if ebase in custom: views = custom[ebase] else: views = default_views tsolver = problem.get_time_solver() if tsolver.ts is None: suffix = None else: suffix = tsolver.ts.suffix % (tsolver.ts.n_step - 1) filename = problem.get_output_name(suffix=suffix) for suffix, kwargs in views.iteritems(): fig_filename = _get_fig_filename(ebase, images_dir, suffix) fname = edit_filename(filename, suffix=suffix) output('displaying results from "%s"' % fname) disp_name = fig_filename.replace(sfepy.data_dir, '') output('to "%s"...' % disp_name.lstrip(os.path.sep)) view.filename = fname view(scene=view.scene, show=False, is_scalar_bar=True, **kwargs) view.save_image(fig_filename) mlab.clf() output('...done') remove_files(output_dir) output('...done')
def generate_images(images_dir, examples_dir): """ Generate images from results of running examples found in `examples_dir` directory. The generated images are stored to `images_dir`, """ from sfepy.applications import solve_pde from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.utils import mlab prefix = output.prefix output_dir = tempfile.mkdtemp() trunk = os.path.join(output_dir, 'result') options = Struct(output_filename_trunk=trunk, output_format='vtk', save_ebc=False, save_ebc_nodes=False, save_regions=False, save_field_meshes=False, save_regions_as_groups=False, solve_not=False) default_views = {'': {}} ensure_path(images_dir + os.path.sep) view = Viewer('', offscreen=False) for ex_filename in locate_files('*.py', examples_dir): if _omit(ex_filename): continue output.level = 0 output.prefix = prefix ebase = ex_filename.replace(examples_dir, '')[1:] output('trying "%s"...' % ebase) try: problem, state = solve_pde(ex_filename, options=options) except KeyboardInterrupt: raise except: problem = None output('***** failed! *****') if problem is not None: if ebase in custom: views = custom[ebase] else: views = default_views tsolver = problem.get_time_solver() if tsolver.ts is None: suffix = None else: suffix = tsolver.ts.suffix % (tsolver.ts.n_step - 1) filename = problem.get_output_name(suffix=suffix) for suffix, kwargs in six.iteritems(views): fig_filename = _get_fig_filename(ebase, images_dir, suffix) fname = edit_filename(filename, suffix=suffix) output('displaying results from "%s"' % fname) disp_name = fig_filename.replace(sfepy.data_dir, '') output('to "%s"...' % disp_name.lstrip(os.path.sep)) view.filename = fname view(scene=view.scene, show=False, is_scalar_bar=True, **kwargs) view.save_image(fig_filename) mlab.clf() output('...done') remove_files(output_dir) output('...done')
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(): from sfepy import data_dir parser = OptionParser(usage=usage, version='%prog') parser.add_option('--young', metavar='float', type=float, action='store', dest='young', default=2000.0, help=helps['young']) parser.add_option('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.4, help=helps['poisson']) parser.add_option('--load', metavar='float', type=float, action='store', dest='load', default=-1000.0, help=helps['load']) parser.add_option('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_option('-r', '--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_option('-s', '--show', action="store_true", dest='show', default=False, help=helps['show']) parser.add_option('-p', '--probe', action="store_true", dest='probe', default=False, help=helps['probe']) 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!') output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' vertical load:', options.load) output('uniform mesh refinement level:', options.refine) # Build the problem definition. mesh = Mesh.from_file(data_dir + '/meshes/2d/its2D.mesh') domain = FEDomain('domain', mesh) if options.refine > 0: for ii in xrange(options.refine): output('refine %d...' % ii) domain = domain.refine() output('... %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) omega = domain.create_region('Omega', 'all') left = domain.create_region('Left', 'vertices in x < 0.001', 'facet') bottom = domain.create_region('Bottom', 'vertices in y < 0.001', 'facet') top = domain.create_region('Top', 'vertex 2', 'vertex') 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') D = stiffness_from_youngpoisson(2, options.young, options.poisson) asphalt = Material('Asphalt', D=D) load = Material('Load', values={'.val': [0.0, options.load]}) integral = Integral('i', order=2 * options.order) integral0 = Integral('i', order=0) t1 = Term.new('dw_lin_elastic(Asphalt.D, v, u)', integral, omega, Asphalt=asphalt, v=v, u=u) t2 = Term.new('dw_point_load(Load.val, v)', integral0, top, Load=load, v=v) eq = Equation('balance', t1 - t2) eqs = Equations([eq]) xsym = EssentialBC('XSym', bottom, {'u.1': 0.0}) ysym = EssentialBC('YSym', left, {'u.0': 0.0}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls) pb.time_update(ebcs=Conditions([xsym, ysym])) # Solve the problem. state = pb.solve() output(nls_status) # Postprocess the solution. out = state.create_output_dict() out = stress_strain(out, pb, state, extend=True) pb.save_state('its2D_interactive.vtk', out=out) gdata = geometry_data['2_3'] nc = len(gdata.coors) integral_vn = Integral('ivn', coors=gdata.coors, weights=[gdata.volume / nc] * nc) nodal_stress(out, pb, state, integrals=Integrals([integral_vn])) if options.probe: # Probe the solution. probes, labels = gen_lines(pb) sfield = Field.from_args('sym_tensor', nm.float64, 3, omega, approx_order=options.order - 1) stress = FieldVariable('stress', 'parameter', sfield, primary_var_name='(set-to-None)') strain = FieldVariable('strain', 'parameter', sfield, primary_var_name='(set-to-None)') cfield = Field.from_args('component', nm.float64, 1, omega, approx_order=options.order - 1) component = FieldVariable('component', 'parameter', cfield, primary_var_name='(set-to-None)') ev = pb.evaluate order = 2 * (options.order - 1) strain_qp = ev('ev_cauchy_strain.%d.Omega(u)' % order, mode='qp') stress_qp = ev('ev_cauchy_stress.%d.Omega(Asphalt.D, u)' % order, mode='qp', copy_materials=False) project_by_component(strain, strain_qp, component, order) project_by_component(stress, stress_qp, component, order) all_results = [] for ii, probe in enumerate(probes): fig, results = probe_results(u, strain, stress, probe, labels[ii]) fig.savefig('its2D_interactive_probe_%d.png' % ii) all_results.append(results) for ii, results in enumerate(all_results): output('probe %d:' % ii) output.level += 2 for key, res in ordered_iteritems(results): output(key + ':') val = res[1] output(' min: %+.2e, mean: %+.2e, max: %+.2e' % (val.min(), val.mean(), val.max())) output.level -= 2 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 view = Viewer('its2D_interactive.vtk') view(vector_mode='warp_norm', rel_scaling=1, is_scalar_bar=True, is_wireframe=True)
def FarField(eltype, points, boundary, lcar, epsilon, meshfile, thickness=None, verbose=False): """ This function determines a geometric factor F within a single element. The element type can be triangular, quadrilateral, tetrahedral or hexahedral. For these types eltype is set to "CTRIA3", "CQUAD4" "CTETRA" and "CHEXA8" respectively. The vertices of the element are provided in the input parameter points. The input parameter boundary is of boolean type and has the same size as points. Those points which are part of the conductive interface CI are flagged True. Epsilon sets a tolerance to determine which mesh vertices are considered part of the FF boundary. The meshing of the element is stored in a location provided by meshfile. Parameters ---------- eltype: string 'CTRIA3' for triangular surface elements, 'CQUAD4' for quadrilateral surface elements, 'CTETRA' for tetrahedral volume elements. 'CHEXA8' for hexahedral volume elements. points: array like Array containing the coordinates of the element boundary: array like Array containing the entries of the boundary points lcar: float Characteristic length value provided to gmsh for mesh sizing. epsilon: float Numerical tolerance on criterion for far field boundary meshfile: string Filename and location for storing temporary mesh file verbose: boolean Indicate whether intermediate results should be displayed or not Returns ------- : array like Array with boolean entries stating True for those items on the boundary and False otherwise """ if verbose is True: output.set_output(quiet=False) else: output.set_output(quiet=True) if (eltype == "CTRIA3") or (eltype == "CQUAD4"): sdim = 2 else: sdim = 3 boundpnts = [] for i in range(len(points)): if boundary[i]: boundpnts.append(points[i]) mesh = sfedis.fem.Mesh.from_file(meshfile) domain = sfedis.fem.FEDomain('domain', mesh) c = sfedis.Material('c', val=1.0) omega = domain.create_region('Omega', 'all') if verbose is True: coors = mesh.coors fixed_vert = _is_on_bound(coors, bound=boundpnts, sdim=sdim, epsilon=epsilon) print "fixed vertices:" print fixed_vert is_on_bound = sfedis.Functions([ sfedis.Function('_is_on_bound', _is_on_bound, extra_args={ 'bound': boundpnts, 'sdim': sdim, 'epsilon': lcar / 100. }), ]) fixed = domain.create_region('fixed', 'vertices by _is_on_bound', 'facet', functions=is_on_bound, add_to_regions=True) field_t = sfedis.fem.Field.from_args('temperature', np.float64, 'scalar', omega, approx_order=2) t = sfedis.FieldVariable('t', 'unknown', field_t, 1) s = sfedis.FieldVariable('s', 'test', field_t, 1, primary_var_name='t') integral = sfedis.Integral('i', order=4) term1 = Term.new('dw_laplace(s, t)', integral, omega, s=s, t=t) term2 = Term.new('dw_volume_integrate(c.val, s)', integral, omega, c=c, s=s) # heat source term for 1st step of far field eq = sfedis.Equation('temperature', term1 - term2) eqs = sfedis.Equations([eq]) t_fixed = EssentialBC('t_fixed', fixed, {'t.0': 0.0}) ls = ScipyDirect({}) nls = Newton({'i_max': 1, 'eps_a': 1e-10}, lin_solver=ls) pb = sfedis.Problem('temperature', equations=eqs, nls=nls, ls=ls) pb.time_update(ebcs=Conditions([ t_fixed, ])) temperature = pb.solve() out = temperature.create_output_dict() if verbose is True: pb.save_state('result.vtk', out=out) view = Viewer('result.vtk') view(is_wireframe=True, rel_scaling=1, is_scalar_bar=True) print "Maximum temperature: %f" % np.max(out['t'].data) data = [i[0] for i in out['t'].data] FF = _get_far(eltype, points, data, mesh, sdim, epsilon) str1 = ''.join(str(v) + ', ' for v in FF)[:-2] try: far = domain.create_region('far', 'vertex %s' % str1, 'facet', add_to_regions=True) except Exception as e: print "Far field region creation failed!" print(e) t.reset() s.reset() return area_source = pb.evaluate('d_surface.3.far(t)') fluxval = 1.0 / (area_source) c2 = sfedis.Material( 'c2', val=fluxval ) # So that total heat at the far field is 1W equally distributed over all elements term1A = Term.new('dw_laplace(c.val, s, t)', integral, omega, c=c, s=s, t=t) term2A = Term.new('dw_surface_integrate(c2.val, s)', integral, far, c2=c2, s=s) eq2 = sfedis.Equation('temperature2', term1A - term2A) eqs2 = sfedis.Equations([eq2]) pb2 = sfedis.Problem('temperature2', equations=eqs2, nls=nls, ls=ls) pb2.time_update(ebcs=Conditions([ t_fixed, ])) temperature2 = pb2.solve() out2 = temperature2.create_output_dict() volume = pb2.evaluate('d_volume.3.Omega(t)') t_int = pb2.evaluate('ev_volume_integrate.3.Omega(t)') avg_t = t_int / volume F = 1.0 / avg_t if verbose is True: print "Average temperature: %f" % avg_t if thickness: 'Correction factor 1e-3 is due to geometry in mm instead of m' F = F * thickness * 1e-3 if verbose is True: pb.save_state('result.vtk', out=out2) view = Viewer('result.vtk') view(is_wireframe=True, rel_scaling=1, is_scalar_bar=True) t.reset() s.reset() return F
nls_status = IndexedStruct() nls = Newton({'i_max': 20}, lin_solver=ls, status=nls_status) ### Problem ### pb = Problem('hyper', equations=equations) pb.set_bcs(ebcs=ebcs) pb.set_ics(ics=Conditions([])) tss = SimpleTimeSteppingSolver(ts, nls=nls, context=pb) pb.set_solver(tss) ### Solution ### axial_stress = [] axial_displacement = [] def stress_strain_fun(*args, **kwargs): return stress_strain(*args, order=order, global_stress=axial_stress, global_displacement=axial_displacement, **kwargs) pb.solve(save_results=True, post_process_hook=stress_strain_fun) show = True if show: view = Viewer('voronoi_foam_%f.vtk' % z_displacement) view(vector_mode='warp_norm', rel_scaling=1, is_scalar_bar=True, 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)