def from_conf(conf, options): import sfepy from sfepy.discrete.fem import Mesh, FEDomain, Field mesh = Mesh.from_file('meshes/2d/rectangle_tri.mesh', prefix_dir=sfepy.data_dir) domain = FEDomain('domain', mesh) dim = domain.shape.dim 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) test = Test(conf=conf, options=options, dim=dim, omega=omega, gamma1=gamma1, gamma2=gamma2, field=field) return test
def _get_bqp(geometry, order): from sfepy.discrete import Integral from sfepy.discrete.fem.geometry_element import GeometryElement from sfepy.discrete.fem import Mesh, FEDomain, Field gel = GeometryElement(geometry) mesh = Mesh.from_data('aux', gel.coors, None, [gel.conn[None, :]], [[0]], [geometry]) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') surf = domain.create_region('Surf', 'vertices of surface', 'facet') field = Field.from_args('f', nm.float64, shape=1, region=omega, approx_order=1) field.setup_surface_data(surf) integral = Integral('aux', order=order) field.create_bqp('Surf', integral) sd = field.surface_data['Surf'] qp = field.qp_coors[(integral.order, sd.bkey)] output('geometry:', geometry, 'order:', order, 'num. points:', qp.vals.shape[1], 'true_order:', integral.qps[gel.surface_facet_name].order) output('min. weight:', qp.weights.min()) output('max. weight:', qp.weights.max()) return (gel, qp.vals.reshape((-1, mesh.dim)), nm.tile(qp.weights, qp.vals.shape[0]))
def test_entity_volumes(self): import sfepy from sfepy.discrete.fem import Mesh, FEDomain from sfepy.discrete.common import Field from sfepy.discrete import Integral mesh = Mesh.from_file('meshes/3d/special/cross3d.mesh', prefix_dir=sfepy.data_dir) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') gamma = domain.create_region('Gamma', 'vertices of surface', 'facet') top = domain.create_region('Top', 'cell 2') vfield = Field.from_args('v', nm.float64, 'scalar', omega, approx_order=1) sfield = Field.from_args('s', nm.float64, 'scalar', gamma, approx_order=1) integral = Integral('i', order=3) vgeo, _ = vfield.get_mapping(omega, integral, 'volume') domain.create_surface_group(gamma) sgeo, _ = sfield.get_mapping(gamma, integral, 'surface') evols = mesh.cmesh.get_volumes(1) fvols = mesh.cmesh.get_volumes(2) # Approximate for non-planar faces. cvols = mesh.cmesh.get_volumes(3) ok = True _ok = abs(cvols.sum() - vgeo.volume.sum()) < 1e-15 self.report('total cell volume: %s (ok: %s)' % (cvols.sum(), _ok)) ok = _ok and ok top_evols = nm.array([ 1. , 1. , 1. , 1. , 0.7211102550927979, 0.7211102550927979, 0.7211102550927979, 0.7211102550927979, 1.16619037896906 , 1.16619037896906 , 1.16619037896906 , 1.16619037896906 ]) _ok = nm.allclose(top_evols, evols[top.edges], rtol=0.0, atol=1e-15) self.report('total top cell edge length: %s (ok: %s)' % (evols[top.edges].sum(), _ok)) ok = _ok and ok i1 = [5, 6, 8, 9] i2 = nm.setdiff1d(nm.arange(len(gamma.faces)), i1) aux = fvols[gamma.faces] - sgeo.volume.ravel() _ok = nm.allclose(aux[i1], 0.10560208437556773, rtol=0.0, atol=1e-15) ok = _ok and ok self.report('non-planar faces diff: %s (ok: %s)' % (aux[i1], _ok)) _ok = (nm.abs(aux[i2]) < 1e-15).all() self.report('max. planar faces diff: %s (ok: %s)' % (nm.abs(aux[i2]).max(), _ok)) ok = _ok and ok return ok
def test_interpolation_two_meshes(self): from sfepy import data_dir from sfepy.discrete import Variables from sfepy.discrete.fem import Mesh, FEDomain, Field m1 = Mesh.from_file(data_dir + '/meshes/3d/block.mesh') m2 = Mesh.from_file(data_dir + '/meshes/3d/cube_medium_tetra.mesh') m2.coors[:] *= 2.0 bbox = m1.get_bounding_box() dd = bbox[1,:] - bbox[0,:] data = nm.sin(4.0 * nm.pi * m1.coors[:,0:1] / dd[0]) \ * nm.cos(4.0 * nm.pi * m1.coors[:,1:2] / dd[1]) variables1 = { 'u' : ('unknown field', 'scalar_tp', 0), 'v' : ('test field', 'scalar_tp', 'u'), } variables2 = { 'u' : ('unknown field', 'scalar_si', 0), 'v' : ('test field', 'scalar_si', 'u'), } d1 = FEDomain('d1', m1) omega1 = d1.create_region('Omega', 'all') field1 = Field.from_args('scalar_tp', nm.float64, (1,1), omega1, approx_order=1) ff1 = {field1.name : field1} d2 = FEDomain('d2', m2) omega2 = d2.create_region('Omega', 'all') field2 = Field.from_args('scalar_si', nm.float64, (1,1), omega2, approx_order=0) ff2 = {field2.name : field2} vv1 = Variables.from_conf(transform_variables(variables1), ff1) u1 = vv1['u'] u1.set_from_mesh_vertices(data) vv2 = Variables.from_conf(transform_variables(variables2), ff2) u2 = vv2['u'] # Performs interpolation, if other field differs from self.field # or, in particular, is defined on a different mesh. u2.set_from_other(u1, strategy='interpolation', close_limit=0.1) fname = in_dir(self.options.out_dir) u1.save_as_mesh(fname('test_mesh_interp_block_scalar.vtk')) u2.save_as_mesh(fname('test_mesh_interp_cube_scalar.vtk')) return True
def test_evaluate_at(self): from sfepy import data_dir from sfepy.discrete.fem import Mesh from sfepy.discrete import Variables from sfepy.discrete.fem import FEDomain, Field meshes = { 'tp' : Mesh.from_file(data_dir + '/meshes/3d/block.mesh'), } datas = gen_datas(meshes) fields = { 'scalar_tp' : ((1,1), 'Omega', 1), 'vector_tp' : ((3,1), 'Omega', 1), } ok = True for field_name in ['scalar_tp', 'vector_tp']: d = FEDomain('d', meshes['tp']) d.create_region('Omega', 'all') f = fields[field_name] field = Field.from_args('f', nm.complex128, f[0], d.regions[f[1]], approx_order=f[2]) ff = {field.name : field} vv = Variables.from_conf(transform_variables(variables), ff) u = vv['u'] bbox = d.get_mesh_bounding_box() t = nm.expand_dims(nm.linspace(0, 1, 100), 1) coors = nm.expand_dims(bbox[1] - bbox[0], 0) * t + bbox[0] data_r = datas[field_name] data_i = 2. / (1 + datas[field_name]) u.set_from_mesh_vertices(data_r) vals_r = u.evaluate_at(coors) u.set_from_mesh_vertices(data_i) vals_i = u.evaluate_at(coors) u.set_from_mesh_vertices(data_r + data_i * 1j) vals = u.evaluate_at(coors) _ok = nm.allclose(vals_r + vals_i * 1j, vals, rtol=0.0, atol=1e-12) _ok = _ok and nm.abs(vals).sum() > 1 self.report('evaluating complex field %s: %s' % (field_name, _ok)) ok = ok and _ok return ok
def make_domain(dims, shape, transform=None): """ Generate a 2D rectangle domain in 3D space, define regions. """ xmin = (-0.5 + 1e-12) * dims[0] xmax = (0.5 - 1e-12) * dims[0] mesh = make_mesh(dims, shape, transform=transform) domain = FEDomain('domain', mesh) domain.create_region('Omega', 'all') domain.create_region('Gamma1', 'vertices in (x < %.14f)' % xmin, 'facet') domain.create_region('Gamma2', 'vertices in (x > %.14f)' % xmax, 'facet') return domain
def do_interpolation(m2, m1, data, field_name, force=False): """Interpolate data from m1 to m2. """ from sfepy.discrete import Variables from sfepy.discrete.fem import FEDomain, Field fields = { 'scalar_si' : ((1,1), 'Omega', 2), 'vector_si' : ((3,1), 'Omega', 2), 'scalar_tp' : ((1,1), 'Omega', 1), 'vector_tp' : ((3,1), 'Omega', 1), } d1 = FEDomain('d1', m1) omega1 = d1.create_region('Omega', 'all') f = fields[field_name] field1 = Field.from_args('f', nm.float64, f[0], d1.regions[f[1]], approx_order=f[2]) ff = {field1.name : field1} vv = Variables.from_conf(transform_variables(variables), ff) u1 = vv['u'] u1.set_from_mesh_vertices(data) d2 = FEDomain('d2', m2) omega2 = d2.create_region('Omega', 'all') field2 = Field.from_args('f', nm.float64, f[0], d2.regions[f[1]], approx_order=f[2]) ff2 = {field2.name : field2} vv2 = Variables.from_conf(transform_variables(variables), ff2) u2 = vv2['u'] if not force: # Performs interpolation, if other field differs from self.field # or, in particular, is defined on a different mesh. u2.set_from_other(u1, strategy='interpolation', close_limit=0.5) else: coors = u2.field.get_coor() vals = u1.evaluate_at(coors, close_limit=0.5) u2.set_data(vals) return u1, u2
def main(): parser = ArgumentParser(description=__doc__.rstrip(), formatter_class=RawDescriptionHelpFormatter) parser.add_argument('filename', help=helps['filename']) parser.add_argument('-d', '--detailed', action='store_true', dest='detailed', default=False, help=helps['detailed']) options = parser.parse_args() mesh = Mesh.from_file(options.filename) output(mesh.cmesh) output('element types:', mesh.descs) output('nodal BCs:', sorted(mesh.nodal_bcs.keys())) bbox = mesh.get_bounding_box() output('bounding box:\n%s' % '\n'.join('%s: [%14.7e, %14.7e]' % (name, bbox[0, ii], bbox[1, ii]) for ii, name in enumerate('xyz'[:mesh.dim]))) output('centre: [%s]' % ', '.join('%14.7e' % ii for ii in 0.5 * (bbox[0] + bbox[1]))) output('coordinates mean: [%s]' % ', '.join('%14.7e' % ii for ii in mesh.coors.mean(0))) if not options.detailed: return domain = FEDomain(mesh.name, mesh) for dim in range(1, mesh.cmesh.tdim + 1): volumes = mesh.cmesh.get_volumes(dim) output('volumes of %d %dD entities:\nmin: %.7e mean: %.7e median:' ' %.7e max: %.7e' % (mesh.cmesh.num[dim], dim, volumes.min(), volumes.mean(), nm.median(volumes), volumes.max())) euler = lambda mesh: nm.dot(mesh.cmesh.num, [1, -1, 1, -1]) ec = euler(mesh) output('Euler characteristic:', ec) graph = mesh.create_conn_graph(verbose=False) n_comp, _ = graph_components(graph.shape[0], graph.indptr, graph.indices) output('number of connected components:', n_comp) if mesh.dim > 1: region = domain.create_region('surf', 'vertices of surface', 'facet') surf_mesh = Mesh.from_region(region, mesh, localize=True, is_surface=True) FEDomain(surf_mesh.name, surf_mesh) # Calls CMesh.setup_entities(). sec = euler(surf_mesh) output('surface Euler characteristic:', sec) if mesh.dim == 3: output('surface genus:', (2.0 - sec) / 2.0) surf_graph = surf_mesh.create_conn_graph(verbose=False) n_comp, _ = graph_components(surf_graph.shape[0], surf_graph.indptr, surf_graph.indices) output('number of connected surface components:', n_comp)
def test_projection_iga_fem(self): from sfepy.discrete import FieldVariable from sfepy.discrete.fem import FEDomain, Field from sfepy.discrete.iga.domain import IGDomain from sfepy.mesh.mesh_generators import gen_block_mesh from sfepy.discrete.iga.domain_generators import gen_patch_block_domain from sfepy.discrete.projections import (make_l2_projection, make_l2_projection_data) shape = [10, 12, 12] dims = [5, 6, 6] centre = [0, 0, 0] degrees = [2, 2, 2] nurbs, bmesh, regions = gen_patch_block_domain(dims, shape, centre, degrees, cp_mode='greville', name='iga') ig_domain = IGDomain('iga', nurbs, bmesh, regions=regions) ig_omega = ig_domain.create_region('Omega', 'all') ig_field = Field.from_args('iga', nm.float64, 1, ig_omega, approx_order='iga', poly_space_base='iga') ig_u = FieldVariable('ig_u', 'parameter', ig_field, primary_var_name='(set-to-None)') mesh = gen_block_mesh(dims, shape, centre, name='fem') fe_domain = FEDomain('fem', mesh) fe_omega = fe_domain.create_region('Omega', 'all') fe_field = Field.from_args('fem', nm.float64, 1, fe_omega, approx_order=2) fe_u = FieldVariable('fe_u', 'parameter', fe_field, primary_var_name='(set-to-None)') def _eval_data(ts, coors, mode, **kwargs): return nm.prod(coors**2, axis=1)[:, None, None] make_l2_projection_data(ig_u, _eval_data) make_l2_projection(fe_u, ig_u) # This calls ig_u.evaluate_at(). coors = 0.5 * nm.random.rand(20, 3) * dims ig_vals = ig_u.evaluate_at(coors) fe_vals = fe_u.evaluate_at(coors) ok = nm.allclose(ig_vals, fe_vals, rtol=0.0, atol=1e-12) if not ok: self.report('iga-fem projection failed!') self.report('coors:') self.report(coors) self.report('iga fem diff:') self.report(nm.c_[ig_vals, fe_vals, nm.abs(ig_vals - fe_vals)]) return ok
def from_conf(conf, options): from sfepy.discrete import Integral from sfepy.discrete.fem import Mesh, FEDomain domains = [] for filename in filename_meshes: mesh = Mesh.from_file(filename) domain = FEDomain('domain_%s' % mesh.name.replace(data_dir, ''), mesh) domain.create_region('Omega', 'all') domain.create_region('Gamma', 'vertices of surface', 'facet') domains.append(domain) integral = Integral('i', order=3) test = Test(domains=domains, integral=integral, conf=conf, options=options) return test
def from_conf(conf, options): mesh = Mesh.from_file('meshes/2d/square_unit_tri.mesh', prefix_dir=sfepy.data_dir) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('linear', nm.float64, 'scalar', omega, approx_order=1) test = Test(conf=conf, options=options, omega=omega, field=field) return test
def test_normals(self): """ Check orientations of surface normals on the reference elements. """ import sfepy from sfepy.discrete import Integral from sfepy.discrete.fem import Mesh, FEDomain from sfepy.discrete.fem.poly_spaces import PolySpace from sfepy.discrete.fem.mappings import SurfaceMapping from sfepy.linalg import normalize_vectors ok = True for geom in ['2_3', '2_4', '3_4', '3_8']: mesh = Mesh.from_file('meshes/elements/%s_1.mesh' % geom, prefix_dir=sfepy.data_dir) domain = FEDomain('domain', mesh) surface = domain.create_region('Surface', 'vertices of surface', 'facet') domain.create_surface_group(surface) sd = domain.surface_groups[surface.name] coors = domain.get_mesh_coors() gel = domain.geom_els[geom].surface_facet ps = PolySpace.any_from_args('aux', gel, 1) mapping = SurfaceMapping(coors, sd.get_connectivity(), ps) integral = Integral('i', order=1) vals, weights = integral.get_qp(gel.name) # Evaluate just in the first quadrature point... geo = mapping.get_mapping(vals[:1], weights[:1]) expected = expected_normals[geom].copy() normalize_vectors(expected) _ok = nm.allclose(expected, geo.normal[:, 0, :, 0], rtol=0.0, atol=1e-14) self.report('%s: %s' % (geom, _ok)) if not _ok: self.report('expected:') self.report(expected) self.report('actual:') self.report(geo.normal[:, 0, :, 0]) ok = ok and _ok return ok
def test_invariance_qp(self): from sfepy import data_dir from sfepy.discrete import Variables, Integral from sfepy.discrete.fem import Mesh, FEDomain, Field from sfepy.terms import Term from sfepy.discrete.common.mappings import get_physical_qps mesh = Mesh.from_file(data_dir + '/meshes/3d/block.mesh') bbox = mesh.get_bounding_box() dd = bbox[1,:] - bbox[0,:] data = nm.sin(4.0 * nm.pi * mesh.coors[:,0:1] / dd[0]) \ * nm.cos(4.0 * nm.pi * mesh.coors[:,1:2] / dd[1]) variables = { 'u' : ('unknown field', 'scalar_tp', 0), 'v' : ('test field', 'scalar_tp', 'u'), } domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('scalar_tp', nm.float64, 1, omega, approx_order=1) ff = {field.name : field} vv = Variables.from_conf(transform_variables(variables), ff) u = vv['u'] u.set_from_mesh_vertices(data) integral = Integral('i', order=2) term = Term.new('ev_volume_integrate(u)', integral, omega, u=u) term.setup() val1 = term.evaluate(mode='qp') val1 = val1.ravel() qps = get_physical_qps(omega, integral) coors = qps.values val2 = u.evaluate_at(coors).ravel() self.report('max. difference:', nm.abs(val1 - val2).max()) ok = nm.allclose(val1, val2, rtol=0.0, atol=1e-12) self.report('invariance in qp: %s' % ok) return ok
def prepare_variable(filename, n_components): from sfepy.discrete import FieldVariable from sfepy.discrete.fem import Mesh, FEDomain, Field mesh = Mesh.from_file(filename) bbox = mesh.get_bounding_box() dd = bbox[1, :] - bbox[0, :] data = nm.sin(4.0 * nm.pi * mesh.coors[:, 0:1] / dd[0]) * nm.cos(4.0 * nm.pi * mesh.coors[:, 1:2] / dd[1]) domain = FEDomain("domain", mesh) omega = domain.create_region("Omega", "all") field = Field.from_args("field", nm.float64, n_components, omega, approx_order=2) u = FieldVariable("u", "parameter", field, primary_var_name="(set-to-None)") u.set_from_mesh_vertices(data * nm.arange(1, n_components + 1)[None, :]) return u
def test_projection_tri_quad(self): from sfepy.discrete.projections import make_l2_projection source = FieldVariable('us', 'unknown', self.field) coors = self.field.get_coor() vals = nm.sin(2.0 * nm.pi * coors[:,0] * coors[:,1]) source.set_data(vals) name = op.join(self.options.out_dir, 'test_projection_tri_quad_source.vtk') source.save_as_mesh(name) mesh = Mesh.from_file('meshes/2d/square_quad.mesh', prefix_dir=sfepy.data_dir) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('bilinear', nm.float64, 'scalar', omega, approx_order=1) target = FieldVariable('ut', 'unknown', field) make_l2_projection(target, source) name = op.join(self.options.out_dir, 'test_projection_tri_quad_target.vtk') target.save_as_mesh(name) bbox = self.field.domain.get_mesh_bounding_box() x = nm.linspace(bbox[0, 0] + 0.001, bbox[1, 0] - 0.001, 20) y = nm.linspace(bbox[0, 1] + 0.001, bbox[1, 1] - 0.001, 20) xx, yy = nm.meshgrid(x, y) test_coors = nm.c_[xx.ravel(), yy.ravel()].copy() vec1 = source.evaluate_at(test_coors) vec2 = target.evaluate_at(test_coors) ok = (nm.abs(vec1 - vec2) < 0.01).all() return ok
def prepare_variable(filename, n_components): from sfepy.discrete import FieldVariable from sfepy.discrete.fem import Mesh, FEDomain, Field mesh = Mesh.from_file(filename) bbox = mesh.get_bounding_box() dd = bbox[1,:] - bbox[0,:] data = (nm.sin(4.0 * nm.pi * mesh.coors[:,0:1] / dd[0]) * nm.cos(4.0 * nm.pi * mesh.coors[:,1:2] / dd[1])) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('field', nm.float64, n_components, omega, approx_order=2) u = FieldVariable('u', 'parameter', field, primary_var_name='(set-to-None)') u.set_from_mesh_vertices(nm.c_[tuple([data] * n_components)]) return u
def main(): parser = OptionParser(usage=usage, version='%prog') parser.add_option('-b', '--basis', metavar='name', action='store', dest='basis', default='lagrange', help=help['basis']) parser.add_option('-n', '--max-order', metavar='order', type=int, action='store', dest='max_order', default=10, help=help['max_order']) parser.add_option('-m', '--matrix', metavar='type', action='store', dest='matrix_type', default='laplace', help=help['matrix_type']) parser.add_option('-g', '--geometry', metavar='name', action='store', dest='geometry', default='2_4', help=help['geometry']) options, args = parser.parse_args() dim, n_ep = int(options.geometry[0]), int(options.geometry[2]) output('reference element geometry:') output(' dimension: %d, vertices: %d' % (dim, n_ep)) n_c = {'laplace' : 1, 'elasticity' : dim}[options.matrix_type] output('matrix type:', options.matrix_type) output('number of variable components:', n_c) output('polynomial space:', options.basis) output('max. order:', options.max_order) mesh = Mesh.from_file(data_dir + '/meshes/elements/%s_1.mesh' % options.geometry) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') orders = nm.arange(1, options.max_order + 1, dtype=nm.int) conds = [] order_fix = 0 if options.geometry in ['2_4', '3_8'] else 1 for order in orders: output('order:', order, '...') field = Field.from_args('fu', nm.float64, n_c, omega, approx_order=order, space='H1', poly_space_base=options.basis) to = field.approx_order quad_order = 2 * (max(to - order_fix, 0)) output('quadrature order:', quad_order) integral = Integral('i', order=quad_order) qp, _ = integral.get_qp(options.geometry) output('number of quadrature points:', qp.shape[0]) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') m = Material('m', lam=1.0, mu=1.0) if options.matrix_type == 'laplace': term = Term.new('dw_laplace(m.mu, v, u)', integral, omega, m=m, v=v, u=u) n_zero = 1 else: assert_(options.matrix_type == 'elasticity') term = Term.new('dw_lin_elastic_iso(m.lam, m.mu, v, u)', integral, omega, m=m, v=v, u=u) n_zero = (dim + 1) * dim / 2 term.setup() output('assembling...') tt = time.clock() mtx, iels = term.evaluate(mode='weak', diff_var='u') output('...done in %.2f s' % (time.clock() - tt)) mtx = mtx[0][0, 0] try: assert_(nm.max(nm.abs(mtx - mtx.T)) < 1e-10) except: from sfepy.base.base import debug; debug() output('matrix shape:', mtx.shape) eigs = eig(mtx, method='eig.sgscipy', eigenvectors=False) eigs.sort() # Zero 'true' zeros. eigs[:n_zero] = 0.0 ii = nm.where(eigs < 0.0)[0] if len(ii): output('matrix is not positive semi-definite!') ii = nm.where(eigs[n_zero:] < 1e-12)[0] if len(ii): output('matrix has more than %d zero eigenvalues!' % n_zero) output('smallest eigs:\n', eigs[:10]) ii = nm.where(eigs > 0.0)[0] emin, emax = eigs[ii[[0, -1]]] output('min:', emin, 'max:', emax) cond = emax / emin conds.append(cond) output('condition number:', cond) output('...done') plt.figure(1) plt.semilogy(orders, conds) plt.xticks(orders, orders) plt.xlabel('polynomial order') plt.ylabel('condition number') plt.grid() plt.figure(2) plt.loglog(orders, conds) plt.xticks(orders, orders) plt.xlabel('polynomial order') plt.ylabel('condition number') plt.grid() plt.show()
Equations, Problem) from sfepy.discrete.fem import Mesh, FEDomain, Field from sfepy.terms import Term from sfepy.discrete.conditions import Conditions, EssentialBC from sfepy.solvers.ls import ScipyDirect from sfepy.solvers.nls import Newton from sfepy.postprocess.viewer import Viewer from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson from sfepy.mechanics.tensors import get_von_mises_stress mesh = Mesh.from_file('meshes/voronoi_foam.vtk') domain = FEDomain('domain', mesh) min_z, max_z = domain.get_mesh_bounding_box()[:, 2] eps = 5 omega = domain.create_region('Omega', 'all') bot = domain.create_region('Bot', 'vertices in z < %.10f' % (min_z + eps), 'vertex') top = domain.create_region('Top', 'vertices in z > %.10f' % (max_z - eps), 'vertex') field = Field.from_args('fu', np.float64, 'vector', omega, approx_order=1) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') # these are for stainless steel 316L m = Material('m', D=stiffness_from_youngpoisson(dim=3, young=1.93e9, poisson=0.275), rho=8000.0)
def load_and_plot_fun(folder, filename, exact=None): """ Parameters ---------- folder : str folder where to look for files filename : str used in {name}.i.vtk, i = 0,1, ... tns - 1 number of time steps exact : callable exact solution at the last frame """ in_file = head(glob(pjoin(folder, "*.vtk"))) coors, data = load_state_1D_vtk(in_file) approx_order = data.shape[0] - 1 dmesh = Mesh.from_file(in_file) domain = FEDomain("", dmesh) omega = domain.create_region('Omega', 'all') field = DGField('f', nm.float64, 'scalar', omega, approx_order=approx_order) # Sufficient quadrature order for the analytical expression. idiff = Integral('idiff', 20) u = FieldVariable("u", "unknown", field) eqs = Equations( [Equation('balance', SurfaceTerm("s()", "u", idiff, omega, u=u))]) pb = Problem("err_est", equations=eqs) u.set_data(field.ravel_sol(data.swapaxes(0, 1))) num_qp = pb.evaluate('ev_volume_integrate.idiff.Omega(u)', u=u, integrals=Integrals([idiff]), mode='qp') aux = Material('aux', function=sol_fun) ana_qp = pb.evaluate('ev_volume_integrate_mat.idiff.Omega(aux.u, u)', aux=aux, u=u, integrals=Integrals([idiff]), mode='qp') qps = pb.fields["f"].mapping.get_physical_qps(idiff.get_qp("1_2")[0]) fqps = qps.flatten() plt.figure("Reconstructed solution") plt.gca().set_ylim(-.5, 3.) ww_approx, xx = reconstruct_legendre_dofs(coors, None, data) ww_exact = exact(xx) XN = xx[-1] X1 = xx[0] plt.plot([X1, XN], [2, 2], 'grey', alpha=.6) plt.plot([X1, XN], [0, 0], 'grey', alpha=.6) plt.plot(fqps, ana_qp.flatten(), label="$p_{exact}(1, x)$") plt.plot(fqps, num_qp.flatten(), label="$p_h(1, x)$") plt.legend() plt.show()
def create_local_problem(omega_gi, order): """ Local problem definition using a domain corresponding to the global region `omega_gi`. """ mesh = omega_gi.domain.mesh # All tasks have the whole mesh. bbox = mesh.get_bounding_box() min_x, max_x = bbox[:, 0] eps_x = 1e-8 * (max_x - min_x) mesh_i = Mesh.from_region(omega_gi, mesh, localize=True) domain_i = FEDomain('domain_i', mesh_i) omega_i = domain_i.create_region('Omega', 'all') gamma1_i = domain_i.create_region('Gamma1', 'vertices in (x < %.10f)' % (min_x + eps_x), 'facet', allow_empty=True) gamma2_i = domain_i.create_region('Gamma2', 'vertices in (x > %.10f)' % (max_x - eps_x), 'facet', allow_empty=True) field_i = Field.from_args('fu', nm.float64, 1, omega_i, approx_order=order) output('number of local field DOFs:', field_i.n_nod) u_i = FieldVariable('u_i', 'unknown', field_i) v_i = FieldVariable('v_i', 'test', field_i, primary_var_name='u_i') integral = Integral('i', order=2*order) mat = Material('m', lam=10, mu=5) t1 = Term.new('dw_laplace(m.lam, v_i, u_i)', integral, omega_i, m=mat, v_i=v_i, u_i=u_i) def _get_load(coors): val = nm.ones_like(coors[:, 0]) for coor in coors.T: val *= nm.sin(4 * nm.pi * coor) return val def get_load(ts, coors, mode=None, **kwargs): if mode == 'qp': return {'val' : _get_load(coors).reshape(coors.shape[0], 1, 1)} load = Material('load', function=Function('get_load', get_load)) t2 = Term.new('dw_volume_lvf(load.val, v_i)', integral, omega_i, load=load, v_i=v_i) eq = Equation('balance', t1 - 100 * t2) eqs = Equations([eq]) ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all' : 0.0}) ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.all' : 0.1}) pb = Problem('problem_i', equations=eqs, active_only=False) pb.time_update(ebcs=Conditions([ebc1, ebc2])) pb.update_materials() return pb
def solve_problem(mesh_filename, options, comm): order_u = options.order_u order_p = options.order_p rank, size = comm.Get_rank(), comm.Get_size() output('rank', rank, 'of', size) mesh = Mesh.from_file(mesh_filename) if rank == 0: cell_tasks = pl.partition_mesh(mesh, size, use_metis=options.metis, verbose=True) else: cell_tasks = None domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field1 = Field.from_args('fu', nm.float64, mesh.dim, omega, approx_order=order_u) field2 = Field.from_args('fp', nm.float64, 1, omega, approx_order=order_p) fields = [field1, field2] output('distributing fields...') tt = time.clock() lfds, gfds = pl.distribute_fields_dofs(fields, cell_tasks, is_overlap=True, use_expand_dofs=True, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('creating local problem...') tt = time.clock() cells = lfds[0].cells omega_gi = Region.from_cells(cells, domain) omega_gi.finalize() omega_gi.update_shape() pb = create_local_problem(omega_gi, [order_u, order_p]) variables = pb.get_variables() state = State(variables) state.fill(0.0) state.apply_ebc() output('...done in', time.clock() - tt) output('allocating global system...') tt = time.clock() sizes, drange, pdofs = pl.setup_composite_dofs(lfds, fields, variables, verbose=True) pmtx, psol, prhs = pl.create_petsc_system(pb.mtx_a, sizes, pdofs, drange, is_overlap=True, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('creating solver...') tt = time.clock() conf = Struct(method='bcgsl', precond='jacobi', sub_precond=None, i_max=10000, eps_a=1e-50, eps_r=1e-6, eps_d=1e4, verbose=True) status = {} ls = PETScKrylovSolver(conf, comm=comm, mtx=pmtx, status=status) field_ranges = {} for ii, variable in enumerate(variables.iter_state(ordered=True)): field_ranges[variable.name] = lfds[ii].petsc_dofs_range ls.set_field_split(field_ranges, comm=comm) ev = PETScParallelEvaluator(pb, pdofs, drange, True, psol, comm, verbose=True) nls_status = {} conf = Struct(method='newtonls', i_max=5, eps_a=0, eps_r=1e-5, eps_s=0.0, verbose=True) nls = PETScNonlinearSolver(conf, pmtx=pmtx, prhs=prhs, comm=comm, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix, lin_solver=ls, status=nls_status) output('...done in', time.clock() - tt) output('solving...') tt = time.clock() state = pb.create_state() state.apply_ebc() ev.psol_i[...] = state() ev.gather(psol, ev.psol_i) psol = nls(psol) ev.scatter(ev.psol_i, psol) sol0_i = ev.psol_i[...] output('...done in', time.clock() - tt) output('saving solution...') tt = time.clock() state.set_full(sol0_i) out = state.create_output_dict() filename = os.path.join(options.output_dir, 'sol_%02d.h5' % comm.rank) pb.domain.mesh.write(filename, io='auto', out=out) gather_to_zero = pl.create_gather_to_zero(psol) psol_full = gather_to_zero(psol) if comm.rank == 0: sol = psol_full[...].copy() u = FieldVariable('u', 'parameter', field1, primary_var_name='(set-to-None)') remap = gfds[0].id_map ug = sol[remap] p = FieldVariable('p', 'parameter', field2, primary_var_name='(set-to-None)') remap = gfds[1].id_map pg = sol[remap] if (((order_u == 1) and (order_p == 1)) or (options.linearization == 'strip')): out = u.create_output(ug) out.update(p.create_output(pg)) filename = os.path.join(options.output_dir, 'sol.h5') mesh.write(filename, io='auto', out=out) else: out = u.create_output(ug, linearization=Struct(kind='adaptive', min_level=0, max_level=order_u, eps=1e-3)) filename = os.path.join(options.output_dir, 'sol_u.h5') out['u'].mesh.write(filename, io='auto', out=out) out = p.create_output(pg, linearization=Struct(kind='adaptive', min_level=0, max_level=order_p, eps=1e-3)) filename = os.path.join(options.output_dir, 'sol_p.h5') out['p'].mesh.write(filename, io='auto', out=out) output('...done in', time.clock() - tt)
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 range(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 main(): from sfepy import data_dir parser = OptionParser(usage=usage, version='%prog') parser.add_option('--diffusivity', metavar='float', type=float, action='store', dest='diffusivity', default=1e-5, help=helps['diffusivity']) parser.add_option('--ic-max', metavar='float', type=float, action='store', dest='ic_max', default=2.0, help=helps['ic_max']) parser.add_option('--order', metavar='int', type=int, action='store', dest='order', default=2, help=helps['order']) parser.add_option('-r', '--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_option('-p', '--probe', action="store_true", dest='probe', default=False, help=helps['probe']) parser.add_option('-s', '--show', action="store_true", dest='show', default=False, help=helps['show']) options, args = parser.parse_args() assert_((0 < options.order), 'temperature approximation order must be at least 1!') output('using values:') output(' diffusivity:', options.diffusivity) output(' max. IC value:', options.ic_max) output('uniform mesh refinement level:', options.refine) mesh = Mesh.from_file(data_dir + '/meshes/3d/cylinder.mesh') domain = FEDomain('domain', mesh) if options.refine > 0: for ii in range(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.00001', 'facet') right = domain.create_region('Right', 'vertices in x > 0.099999', 'facet') field = Field.from_args('fu', nm.float64, 'scalar', omega, approx_order=options.order) T = FieldVariable('T', 'unknown', field, history=1) s = FieldVariable('s', 'test', field, primary_var_name='T') m = Material('m', diffusivity=options.diffusivity * nm.eye(3)) integral = Integral('i', order=2*options.order) t1 = Term.new('dw_diffusion(m.diffusivity, s, T)', integral, omega, m=m, s=s, T=T) t2 = Term.new('dw_volume_dot(s, dT/dt)', integral, omega, s=s, T=T) eq = Equation('balance', t1 + t2) eqs = Equations([eq]) # Boundary conditions. ebc1 = EssentialBC('T1', left, {'T.0' : 2.0}) ebc2 = EssentialBC('T2', right, {'T.0' : -2.0}) # Initial conditions. def get_ic(coors, ic): x, y, z = coors.T return 2 - 40.0 * x + options.ic_max * nm.sin(4 * nm.pi * x / 0.1) ic_fun = Function('ic_fun', get_ic) ic = InitialCondition('ic', omega, {'T.0' : ic_fun}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({'is_linear' : True}, lin_solver=ls, status=nls_status) pb = Problem('heat', equations=eqs, nls=nls, ls=ls) pb.set_bcs(ebcs=Conditions([ebc1, ebc2])) pb.set_ics(Conditions([ic])) tss = SimpleTimeSteppingSolver({'t0' : 0.0, 't1' : 100.0, 'n_step' : 11}, problem=pb) tss.init_time() if options.probe: # Prepare probe data. probes, labels = gen_lines(pb) ev = pb.evaluate order = 2 * (options.order - 1) gfield = Field.from_args('gu', nm.float64, 'vector', omega, approx_order=options.order - 1) dvel = FieldVariable('dvel', 'parameter', gfield, primary_var_name='(set-to-None)') cfield = Field.from_args('gu', nm.float64, 'scalar', omega, approx_order=options.order - 1) component = FieldVariable('component', 'parameter', cfield, primary_var_name='(set-to-None)') nls_options = {'eps_a' : 1e-16, 'i_max' : 1} if options.show: plt.ion() # Solve the problem using the time stepping solver. suffix = tss.ts.suffix for step, time, state in tss(): if options.probe: # Probe the solution. dvel_qp = ev('ev_diffusion_velocity.%d.Omega(m.diffusivity, T)' % order, copy_materials=False, mode='qp') project_by_component(dvel, dvel_qp, component, order, nls_options=nls_options) all_results = [] for ii, probe in enumerate(probes): fig, results = probe_results(ii, T, dvel, probe, labels[ii]) all_results.append(results) plt.tight_layout() fig.savefig('time_poisson_interactive_probe_%s.png' % (suffix % step), bbox_inches='tight') if options.show: plt.draw() for ii, results in enumerate(all_results): output('probe %d (%s):' % (ii, probes[ii].name)) 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
def solve_problem(mesh_filename, options, comm): order = options.order rank, size = comm.Get_rank(), comm.Get_size() output('rank', rank, 'of', size) mesh = Mesh.from_file(mesh_filename) if rank == 0: cell_tasks = pl.partition_mesh(mesh, size, use_metis=options.metis, verbose=True) else: cell_tasks = None domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('fu', nm.float64, 1, omega, approx_order=order) output('distributing field %s...' % field.name) tt = time.clock() lfds, gfds = pl.distribute_fields_dofs([field], cell_tasks, is_overlap=True, comm=comm, verbose=True) lfd = lfds[0] output('...done in', time.clock() - tt) if rank == 0: dof_maps = gfds[0].dof_maps id_map = gfds[0].id_map if options.verify: verify_save_dof_maps(field, cell_tasks, dof_maps, id_map, options, verbose=True) if options.plot: ppd.plot_partitioning([None, None], field, cell_tasks, gfds[0], options.output_dir, size) output('creating local problem...') tt = time.clock() omega_gi = Region.from_cells(lfd.cells, field.domain) omega_gi.finalize() omega_gi.update_shape() pb = create_local_problem(omega_gi, order) output('...done in', time.clock() - tt) variables = pb.get_variables() eqs = pb.equations u_i = variables['u_i'] field_i = u_i.field if options.plot: ppd.plot_local_dofs([None, None], field, field_i, omega_gi, options.output_dir, rank) output('allocating global system...') tt = time.clock() sizes, drange = pl.get_sizes(lfd.petsc_dofs_range, field.n_nod, 1) output('sizes:', sizes) output('drange:', drange) pdofs = pl.get_local_ordering(field_i, lfd.petsc_dofs_conn) output('pdofs:', pdofs) pmtx, psol, prhs = pl.create_petsc_system(pb.mtx_a, sizes, pdofs, drange, is_overlap=True, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('evaluating local problem...') tt = time.clock() state = State(variables) state.fill(0.0) state.apply_ebc() rhs_i = eqs.eval_residuals(state()) # This must be after pl.create_petsc_system() call! mtx_i = eqs.eval_tangent_matrices(state(), pb.mtx_a) output('...done in', time.clock() - tt) output('assembling global system...') tt = time.clock() pl.apply_ebc_to_matrix(mtx_i, u_i.eq_map.eq_ebc) pl.assemble_rhs_to_petsc(prhs, rhs_i, pdofs, drange, is_overlap=True, comm=comm, verbose=True) pl.assemble_mtx_to_petsc(pmtx, mtx_i, pdofs, drange, is_overlap=True, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('creating solver...') tt = time.clock() conf = Struct(method='cg', precond='gamg', sub_precond=None, i_max=10000, eps_a=1e-50, eps_r=1e-5, eps_d=1e4, verbose=True) status = {} ls = PETScKrylovSolver(conf, comm=comm, mtx=pmtx, status=status) output('...done in', time.clock() - tt) output('solving...') tt = time.clock() psol = ls(prhs, psol, conf) psol_i = pl.create_local_petsc_vector(pdofs) gather, scatter = pl.create_gather_scatter(pdofs, psol_i, psol, comm=comm) scatter(psol_i, psol) sol0_i = state() - psol_i[...] psol_i[...] = sol0_i gather(psol, psol_i) output('...done in', time.clock() - tt) output('saving solution...') tt = time.clock() u_i.set_data(sol0_i) out = u_i.create_output() filename = os.path.join(options.output_dir, 'sol_%02d.h5' % comm.rank) pb.domain.mesh.write(filename, io='auto', out=out) gather_to_zero = pl.create_gather_to_zero(psol) psol_full = gather_to_zero(psol) if comm.rank == 0: sol = psol_full[...].copy()[id_map] u = FieldVariable('u', 'parameter', field, primary_var_name='(set-to-None)') filename = os.path.join(options.output_dir, 'sol.h5') if (order == 1) or (options.linearization == 'strip'): out = u.create_output(sol) mesh.write(filename, io='auto', out=out) else: out = u.create_output(sol, linearization=Struct(kind='adaptive', min_level=0, max_level=order, eps=1e-3)) out['u'].mesh.write(filename, io='auto', out=out) output('...done in', time.clock() - tt) if options.show: plt.show()
def from_conf(conf, options): from sfepy.discrete import FieldVariable, Variables, Problem from sfepy.discrete.fem import Mesh, FEDomain, Field mesh = Mesh.from_file(data_dir + '/meshes/2d/square_unit_tri.mesh') domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') domain.create_region('Left', 'vertices in (x < -0.499)', 'facet') domain.create_region( 'LeftStrip', 'vertices in (x < -0.499)' ' & (y > -0.199) & (y < 0.199)', 'facet') domain.create_region('LeftFix', 'r.Left -v r.LeftStrip', 'facet') domain.create_region('Right', 'vertices in (x > 0.499)', 'facet') domain.create_region( 'RightStrip', 'vertices in (x > 0.499)' ' & (y > -0.199) & (y < 0.199)', 'facet') domain.create_region('RightFix', 'r.Right -v r.RightStrip', 'facet') fu = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=2) u = FieldVariable('u', 'unknown', fu) fp = Field.from_args('fp', nm.float64, 'scalar', omega, approx_order=2) p = FieldVariable('p', 'unknown', fp) pb = Problem('test', domain=domain, fields=[fu, fp], auto_conf=False) test = Test(problem=pb, variables=Variables([u, p]), conf=conf, options=options) return test
def main(): parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('-s', '--scale', metavar='scale', action='store', dest='scale', default=None, help=helps['scale']) parser.add_argument('-c', '--center', metavar='center', action='store', dest='center', default=None, help=helps['center']) parser.add_argument('-r', '--refine', metavar='level', action='store', type=int, dest='refine', default=0, help=helps['refine']) parser.add_argument('-f', '--format', metavar='format', action='store', type=str, dest='format', default=None, help=helps['format']) parser.add_argument('-l', '--list', action='store_true', dest='list', help=helps['list']) parser.add_argument('-m', '--merge', action='store_true', dest='merge', help=helps['merge']) parser.add_argument('-t', '--tri-tetra', action='store_true', dest='tri_tetra', help=helps['tri-tetra']) parser.add_argument('-2', '--2d', action='store_true', dest='force_2d', help=helps['2d']) parser.add_argument('--save-per-mat', action='store_true', dest='save_per_mat', help=helps['save-per-mat']) parser.add_argument('--remesh', metavar='options', action='store', dest='remesh', default=None, help=helps['remesh']) parser.add_argument('filename_in') parser.add_argument('filename_out') options = parser.parse_args() if options.list: output('Supported readable mesh formats:') output('--------------------------------') output_mesh_formats('r') output('') output('Supported writable mesh formats:') output('--------------------------------') output_mesh_formats('w') sys.exit(0) scale = _parse_val_or_vec(options.scale, 'scale', parser) center = _parse_val_or_vec(options.center, 'center', parser) filename_in = options.filename_in filename_out = options.filename_out if options.remesh: import tempfile import shlex import subprocess dirname = tempfile.mkdtemp() is_surface = options.remesh.startswith('q') if is_surface: mesh = Mesh.from_file(filename_in) domain = FEDomain(mesh.name, mesh) region = domain.create_region('surf', 'vertices of surface', 'facet') surf_mesh = Mesh.from_region(region, mesh, localize=True, is_surface=True) filename = op.join(dirname, 'surf.mesh') surf_mesh.write(filename, io='auto') else: import shutil shutil.copy(filename_in, dirname) filename = op.join(dirname, op.basename(filename_in)) qopts = ''.join(options.remesh.split()) # Remove spaces. command = 'tetgen -BFENkACp%s %s' % (qopts, filename) args = shlex.split(command) subprocess.call(args) root, ext = op.splitext(filename) mesh = Mesh.from_file(root + '.1.vtk') remove_files(dirname) else: mesh = Mesh.from_file(filename_in) if options.force_2d: data = list(mesh._get_io_data()) data[0] = data[0][:, :2] mesh = Mesh.from_data(mesh.name, *data) if scale is not None: if len(scale) == 1: tr = nm.eye(mesh.dim, dtype=nm.float64) * scale elif len(scale) == mesh.dim: tr = nm.diag(scale) else: raise ValueError('bad scale! (%s)' % scale) mesh.transform_coors(tr) if center is not None: cc = 0.5 * mesh.get_bounding_box().sum(0) shift = center - cc tr = nm.c_[nm.eye(mesh.dim, dtype=nm.float64), shift[:, None]] mesh.transform_coors(tr) if options.refine > 0: domain = FEDomain(mesh.name, mesh) output('initial mesh: %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) for ii in range(options.refine): output('refine %d...' % ii) domain = domain.refine() output('... %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) mesh = domain.mesh if options.tri_tetra > 0: conns = None for k, new_desc in [('3_8', '3_4'), ('2_4', '2_3')]: if k in mesh.descs: conns = mesh.get_conn(k) break if conns is not None: nelo = conns.shape[0] output('initial mesh: %d elements' % nelo) new_conns = elems_q2t(conns) nn = new_conns.shape[0] // nelo new_cgroups = nm.repeat(mesh.cmesh.cell_groups, nn) output('new mesh: %d elements' % new_conns.shape[0]) mesh = Mesh.from_data(mesh.name, mesh.coors, mesh.cmesh.vertex_groups, [new_conns], [new_cgroups], [new_desc]) if options.merge: desc = mesh.descs[0] coor, ngroups, conns = fix_double_nodes(mesh.coors, mesh.cmesh.vertex_groups, mesh.get_conn(desc), 1e-9) mesh = Mesh.from_data(mesh.name + '_merged', coor, ngroups, [conns], [mesh.cmesh.cell_groups], [desc]) if options.save_per_mat: desc = mesh.descs[0] conns, cgroups = mesh.get_conn(desc), mesh.cmesh.cell_groups coors, ngroups = mesh.coors, mesh.cmesh.vertex_groups mat_ids = nm.unique(cgroups) for mat_id in mat_ids: idxs = nm.where(cgroups == mat_id)[0] imesh = Mesh.from_data(mesh.name + '_matid_%d' % mat_id, coors, ngroups, [conns[idxs]], [cgroups[idxs]], [desc]) fbase, fext = op.splitext(filename_out) ifilename_out = '%s_matid_%d%s' % (fbase, mat_id, fext) io = MeshIO.for_format(ifilename_out, format=options.format, writable=True) output('writing %s...' % ifilename_out) imesh.write(ifilename_out, io=io) output('...done') io = MeshIO.for_format(filename_out, format=options.format, writable=True) cell_types = ', '.join(supported_cell_types[io.format]) output('writing [%s] %s...' % (cell_types, filename_out)) mesh.write(filename_out, io=io) output('...done')
def main(): from sfepy import data_dir parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('--diffusivity', metavar='float', type=float, action='store', dest='diffusivity', default=1e-5, help=helps['diffusivity']) parser.add_argument('--ic-max', metavar='float', type=float, action='store', dest='ic_max', default=2.0, help=helps['ic_max']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=2, help=helps['order']) parser.add_argument('-r', '--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_argument('-p', '--probe', action="store_true", dest='probe', default=False, help=helps['probe']) parser.add_argument('-s', '--show', action="store_true", dest='show', default=False, help=helps['show']) options = parser.parse_args() assert_((0 < options.order), 'temperature approximation order must be at least 1!') output('using values:') output(' diffusivity:', options.diffusivity) output(' max. IC value:', options.ic_max) output('uniform mesh refinement level:', options.refine) mesh = Mesh.from_file(data_dir + '/meshes/3d/cylinder.mesh') domain = FEDomain('domain', mesh) if options.refine > 0: for ii in range(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.00001', 'facet') right = domain.create_region('Right', 'vertices in x > 0.099999', 'facet') field = Field.from_args('fu', nm.float64, 'scalar', omega, approx_order=options.order) T = FieldVariable('T', 'unknown', field, history=1) s = FieldVariable('s', 'test', field, primary_var_name='T') m = Material('m', diffusivity=options.diffusivity * nm.eye(3)) integral = Integral('i', order=2 * options.order) t1 = Term.new('dw_diffusion(m.diffusivity, s, T)', integral, omega, m=m, s=s, T=T) t2 = Term.new('dw_volume_dot(s, dT/dt)', integral, omega, s=s, T=T) eq = Equation('balance', t1 + t2) eqs = Equations([eq]) # Boundary conditions. ebc1 = EssentialBC('T1', left, {'T.0': 2.0}) ebc2 = EssentialBC('T2', right, {'T.0': -2.0}) # Initial conditions. def get_ic(coors, ic): x, y, z = coors.T return 2 - 40.0 * x + options.ic_max * nm.sin(4 * nm.pi * x / 0.1) ic_fun = Function('ic_fun', get_ic) ic = InitialCondition('ic', omega, {'T.0': ic_fun}) pb = Problem('heat', equations=eqs) pb.set_bcs(ebcs=Conditions([ebc1, ebc2])) pb.set_ics(Conditions([ic])) state0 = pb.get_initial_state() init_fun, prestep_fun, _poststep_fun = pb.get_tss_functions(state0) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({'is_linear': True}, lin_solver=ls, status=nls_status) tss = SimpleTimeSteppingSolver({ 't0': 0.0, 't1': 100.0, 'n_step': 11 }, nls=nls, context=pb, verbose=True) pb.set_solver(tss) if options.probe: # Prepare probe data. probes, labels = gen_probes(pb) ev = pb.evaluate order = 2 * (options.order - 1) gfield = Field.from_args('gu', nm.float64, 'vector', omega, approx_order=options.order - 1) dvel = FieldVariable('dvel', 'parameter', gfield, primary_var_name='(set-to-None)') cfield = Field.from_args('gu', nm.float64, 'scalar', omega, approx_order=options.order - 1) component = FieldVariable('component', 'parameter', cfield, primary_var_name='(set-to-None)') nls_options = {'eps_a': 1e-16, 'i_max': 1} suffix = tss.ts.suffix def poststep_fun(ts, vec): _poststep_fun(ts, vec) # Probe the solution. dvel_qp = ev('ev_diffusion_velocity.%d.Omega(m.diffusivity, T)' % order, copy_materials=False, mode='qp') project_by_component(dvel, dvel_qp, component, order, nls_options=nls_options) all_results = [] for ii, probe in enumerate(probes): fig, results = probe_results(ii, T, dvel, probe, labels[ii]) all_results.append(results) plt.tight_layout() fig.savefig('time_poisson_interactive_probe_%s.png' % (suffix % ts.step), bbox_inches='tight') for ii, results in enumerate(all_results): output('probe %d (%s):' % (ii, probes[ii].name)) 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 else: poststep_fun = _poststep_fun pb.time_update(tss.ts) state0.apply_ebc() # This is required if {'is_linear' : True} is passed to Newton. mtx = prepare_matrix(pb, state0) pb.try_presolve(mtx) tss_status = IndexedStruct() tss(state0.get_vec(pb.active_only), init_fun=init_fun, prestep_fun=prestep_fun, poststep_fun=poststep_fun, status=tss_status) output(tss_status) if options.show: plt.show()
def main(): parser = OptionParser(usage=usage, version='%prog') parser.add_option('-b', '--basis', metavar='name', action='store', dest='basis', default='lagrange', help=help['basis']) parser.add_option('-n', '--max-order', metavar='order', type=int, action='store', dest='max_order', default=10, help=help['max_order']) parser.add_option('-m', '--matrix', metavar='type', action='store', dest='matrix_type', default='laplace', help=help['matrix_type']) parser.add_option('-g', '--geometry', metavar='name', action='store', dest='geometry', default='2_4', help=help['geometry']) options, args = parser.parse_args() dim, n_ep = int(options.geometry[0]), int(options.geometry[2]) output('reference element geometry:') output(' dimension: %d, vertices: %d' % (dim, n_ep)) n_c = {'laplace': 1, 'elasticity': dim}[options.matrix_type] output('matrix type:', options.matrix_type) output('number of variable components:', n_c) output('polynomial space:', options.basis) output('max. order:', options.max_order) mesh = Mesh.from_file(data_dir + '/meshes/elements/%s_1.mesh' % options.geometry) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') orders = nm.arange(1, options.max_order + 1, dtype=nm.int) conds = [] order_fix = 0 if options.geometry in ['2_4', '3_8'] else 1 for order in orders: output('order:', order, '...') field = Field.from_args('fu', nm.float64, n_c, omega, approx_order=order, space='H1', poly_space_base=options.basis) to = field.approx_order quad_order = 2 * (max(to - order_fix, 0)) output('quadrature order:', quad_order) integral = Integral('i', order=quad_order) qp, _ = integral.get_qp(options.geometry) output('number of quadrature points:', qp.shape[0]) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') m = Material('m', D=stiffness_from_lame(dim, 1.0, 1.0), mu=1.0) if options.matrix_type == 'laplace': term = Term.new('dw_laplace(m.mu, v, u)', integral, omega, m=m, v=v, u=u) n_zero = 1 else: assert_(options.matrix_type == 'elasticity') term = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) n_zero = (dim + 1) * dim / 2 term.setup() output('assembling...') tt = time.clock() mtx, iels = term.evaluate(mode='weak', diff_var='u') output('...done in %.2f s' % (time.clock() - tt)) mtx = mtx[0][0, 0] try: assert_(nm.max(nm.abs(mtx - mtx.T)) < 1e-10) except: from sfepy.base.base import debug debug() output('matrix shape:', mtx.shape) eigs = eig(mtx, method='eig.sgscipy', eigenvectors=False) eigs.sort() # Zero 'true' zeros. eigs[:n_zero] = 0.0 ii = nm.where(eigs < 0.0)[0] if len(ii): output('matrix is not positive semi-definite!') ii = nm.where(eigs[n_zero:] < 1e-12)[0] if len(ii): output('matrix has more than %d zero eigenvalues!' % n_zero) output('smallest eigs:\n', eigs[:10]) ii = nm.where(eigs > 0.0)[0] emin, emax = eigs[ii[[0, -1]]] output('min:', emin, 'max:', emax) cond = emax / emin conds.append(cond) output('condition number:', cond) output('...done') plt.figure(1) plt.semilogy(orders, conds) plt.xticks(orders, orders) plt.xlabel('polynomial order') plt.ylabel('condition number') plt.grid() plt.figure(2) plt.loglog(orders, conds) plt.xticks(orders, orders) plt.xlabel('polynomial order') plt.ylabel('condition number') plt.grid() plt.show()
def main(argv): if argv is None: argv = sys.argv[1:] args = parser.parse_args(argv) # vvvvvvvvvvvvvvvv # approx_order = 2 # ^^^^^^^^^^^^^^^^ # # Setup output names outputs_folder = "../outputs" domain_name = "domain_1D" problem_name = "iburgers_1D" output_folder = pjoin(outputs_folder, problem_name, str(approx_order)) output_format = "vtk" save_timestn = 100 clear_folder(pjoin(output_folder, "*." + output_format)) configure_output({ 'output_screen': True, 'output_log_name': pjoin(output_folder, f"last_run_{problem_name}_{approx_order}.txt") }) # ------------ # | Get mesh | # ------------ X1 = 0. XN = 1. n_nod = 100 n_el = n_nod - 1 mesh = get_gen_1D_mesh_hook(X1, XN, n_nod).read(None) # ----------------------------- # | Create problem components | # ----------------------------- integral = Integral('i', order=approx_order * 2) domain = FEDomain(domain_name, mesh) omega = domain.create_region('Omega', 'all') left = domain.create_region('Gamma1', 'vertices in x == %.10f' % X1, 'vertex') right = domain.create_region('Gamma2', 'vertices in x == %.10f' % XN, 'vertex') field = DGField('dgfu', nm.float64, 'scalar', omega, approx_order=approx_order) u = FieldVariable('u', 'unknown', field, history=1) v = FieldVariable('v', 'test', field, primary_var_name='u') MassT = DotProductVolumeTerm("adv_vol(v, u)", "v, u", integral, omega, u=u, v=v) velo = nm.array(1.0) def adv_fun(u): vu = velo.T * u[..., None] return vu def adv_fun_d(u): v1 = velo.T * nm.ones(u.shape + (1, )) return v1 burg_velo = velo.T / nm.linalg.norm(velo) def burg_fun(u): vu = burg_velo * u[..., None]**2 return vu def burg_fun_d(u): v1 = 2 * burg_velo * u[..., None] return v1 StiffT = NonlinearScalarDotGradTerm("burgers_stiff(f, df, u, v)", "fun , fun_d, u[-1], v", integral, omega, u=u, v=v, fun=burg_fun, fun_d=burg_fun_d) alpha = Material('alpha', val=[.0]) # FluxT = AdvectDGFluxTerm("adv_lf_flux(a.val, v, u)", "a.val, v, u[-1]", # integral, omega, u=u, v=v, a=a, alpha=alpha) FluxT = NonlinearHyperbolicDGFluxTerm("burgers_lf_flux(f, df, u, v)", "fun , fun_d, v, u[-1]", integral, omega, u=u, v=v, fun=burg_fun, fun_d=burg_fun_d) eq = Equation('balance', MassT - StiffT + FluxT) eqs = Equations([eq]) # ------------------------------ # | Create boundary conditions | # ------------------------------ left_fix_u = EssentialBC('left_fix_u', left, {'u.all': 1.0}) right_fix_u = EssentialBC('right_fix_u', right, {'u.all': 0.0}) # ---------------------------- # | Create initial condition | # ---------------------------- def ghump(x): """ Nice gaussian. """ return nm.exp(-200 * x**2) def ic_wrap(x, ic=None): return ghump(x - .3) ic_fun = Function('ic_fun', ic_wrap) ics = InitialCondition('ic', omega, {'u.0': ic_fun}) # ------------------ # | Create problem | # ------------------ pb = Problem(problem_name, equations=eqs, conf=Struct(options={"save_times": save_timestn}, ics={}, ebcs={}, epbcs={}, lcbcs={}, materials={}), active_only=False) pb.setup_output(output_dir=output_folder, output_format=output_format) pb.set_ics(Conditions([ics])) # ------------------ # | Create limiter | # ------------------ limiter = MomentLimiter1D # --------------------------- # | Set time discretization | # --------------------------- CFL = .2 max_velo = nm.max(nm.abs(velo)) t0 = 0 t1 = .2 dx = nm.min(mesh.cmesh.get_volumes(1)) dt = dx / max_velo * CFL / (2 * approx_order + 1) tn = int(nm.ceil((t1 - t0) / dt)) dtdx = dt / dx # ------------------ # | Create solver | # ------------------ ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({'is_linear': True}, lin_solver=ls, status=nls_status) tss_conf = { 't0': t0, 't1': t1, 'n_step': tn, 'limiters': { "dgfu": limiter } } tss = TVDRK3StepSolver(tss_conf, nls=nls, context=pb, verbose=True) # --------- # | Solve | # --------- pb.set_solver(tss) state_end = pb.solve() output("Solved equation \n\n\t\t u_t - div(f(u))) = 0\n") output(f"With IC: {ic_fun.name}") # output("and EBCs: {}".format(pb.ebcs.names)) # output("and EPBCS: {}".format(pb.epbcs.names)) output("-------------------------------------") output(f"Approximation order is {approx_order}") output(f"Space divided into {mesh.n_el} cells, " + f"{len(mesh.coors)} steps, step size is {dx}") output(f"Time divided into {tn - 1} nodes, {tn} steps, step size is {dt}") output(f"CFL coefficient was {CFL} and " + f"order correction {1 / (2 * approx_order + 1)}") output(f"Courant number c = max(abs(u)) * dt/dx = {max_velo * dtdx}") output("------------------------------------------") output(f"Time stepping solver is {tss.name}") output(f"Limiter used: {limiter.name}") output("======================================") # ---------- # | Plot 1D| # ---------- load_and_plot_fun(output_folder, domain_name, t0, t1, min(tn, save_timestn), ic_fun)
def _gen_common_data(orders, gels, report): import sfepy from sfepy.base.base import Struct from sfepy.linalg import combine from sfepy.discrete import FieldVariable, Integral from sfepy.discrete.fem import Mesh, FEDomain, Field from sfepy.discrete.common.global_interp import get_ref_coors bases = ([ii for ii in combine([['2_4', '3_8'], ['lagrange', 'lobatto']])] + [ii for ii in combine([['2_3', '3_4'], ['lagrange']])]) for geom, poly_space_base in bases: report('geometry: %s, base: %s' % (geom, poly_space_base)) order = orders[geom] integral = Integral('i', order=order) aux = '' if geom in ['2_4', '3_8'] else 'z' mesh0 = Mesh.from_file('meshes/elements/%s_2%s.mesh' % (geom, aux), prefix_dir=sfepy.data_dir) gel = gels[geom] perms = gel.get_conn_permutations() qps, qp_weights = integral.get_qp(gel.surface_facet.name) zz = nm.zeros_like(qps[:, :1]) qps = nm.hstack(([qps] + [zz])) shift = shifts[geom] rcoors = nm.ascontiguousarray(qps + shift[:1, :] - shift[1:, :]) ccoors = nm.ascontiguousarray(qps + shift[:1, :] + shift[1:, :]) for ir, pr in enumerate(perms): for ic, pc in enumerate(perms): report('ir: %d, ic: %d' % (ir, ic)) report('pr: %s, pc: %s' % (pr, pc)) mesh = mesh0.copy() conn = mesh.cmesh.get_conn(mesh0.cmesh.tdim, 0).indices conn = conn.reshape((mesh0.n_el, -1)) conn[0, :] = conn[0, pr] conn[1, :] = conn[1, pc] conn2 = mesh.get_conn(gel.name) assert_((conn == conn2).all()) cache = Struct(mesh=mesh) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') region = domain.create_region('Facet', rsels[geom], 'facet') field = Field.from_args('f', nm.float64, shape=1, region=omega, approx_order=order, poly_space_base=poly_space_base) var = FieldVariable('u', 'unknown', field) report('# dofs: %d' % var.n_dof) vec = nm.empty(var.n_dof, dtype=var.dtype) ps = field.poly_space dofs = field.get_dofs_in_region(region, merge=False) edofs, fdofs = nm.unique(dofs[1]), nm.unique(dofs[2]) rrc, rcells, rstatus = get_ref_coors(field, rcoors, cache=cache) crc, ccells, cstatus = get_ref_coors(field, ccoors, cache=cache) assert_((rstatus == 0).all() and (cstatus == 0).all()) yield (geom, poly_space_base, qp_weights, mesh, ir, ic, field, ps, rrc, rcells[0], crc, ccells[0], vec, edofs, fdofs)
def create_local_problem(omega_gi, order): """ Local problem definition using a domain corresponding to the global region `omega_gi`. """ mesh = omega_gi.domain.mesh # All tasks have the whole mesh. bbox = mesh.get_bounding_box() min_x, max_x = bbox[:, 0] eps_x = 1e-8 * (max_x - min_x) mesh_i = Mesh.from_region(omega_gi, mesh, localize=True) domain_i = FEDomain('domain_i', mesh_i) omega_i = domain_i.create_region('Omega', 'all') gamma1_i = domain_i.create_region('Gamma1', 'vertices in (x < %.10f)' % (min_x + eps_x), 'facet', allow_empty=True) gamma2_i = domain_i.create_region('Gamma2', 'vertices in (x > %.10f)' % (max_x - eps_x), 'facet', allow_empty=True) field_i = Field.from_args('fu', nm.float64, 1, omega_i, approx_order=order) output('number of local field DOFs:', field_i.n_nod) u_i = FieldVariable('u_i', 'unknown', field_i) v_i = FieldVariable('v_i', 'test', field_i, primary_var_name='u_i') integral = Integral('i', order=2 * order) mat = Material('m', lam=10, mu=5) t1 = Term.new('dw_laplace(m.lam, v_i, u_i)', integral, omega_i, m=mat, v_i=v_i, u_i=u_i) def _get_load(coors): val = nm.ones_like(coors[:, 0]) for coor in coors.T: val *= nm.sin(4 * nm.pi * coor) return val def get_load(ts, coors, mode=None, **kwargs): if mode == 'qp': return {'val': _get_load(coors).reshape(coors.shape[0], 1, 1)} load = Material('load', function=Function('get_load', get_load)) t2 = Term.new('dw_volume_lvf(load.val, v_i)', integral, omega_i, load=load, v_i=v_i) eq = Equation('balance', t1 - 100 * t2) eqs = Equations([eq]) ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all': 0.0}) ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.all': 0.1}) pb = Problem('problem_i', equations=eqs, active_only=False) pb.time_update(ebcs=Conditions([ebc1, ebc2])) pb.update_materials() return pb
def _gen_common_data(orders, gels, report): import sfepy from sfepy.base.base import Struct from sfepy.linalg import combine from sfepy.discrete import FieldVariable, Integral from sfepy.discrete.fem import Mesh, FEDomain, Field from sfepy.discrete.common.global_interp import get_ref_coors bases = ([ii for ii in combine([['2_4', '3_8'], ['lagrange', 'lobatto']])] + [ii for ii in combine([['2_3', '3_4'], ['lagrange']])]) for geom, poly_space_base in bases: report('geometry: %s, base: %s' % (geom, poly_space_base)) order = orders[geom] integral = Integral('i', order=order) aux = '' if geom in ['2_4', '3_8'] else 'z' mesh0 = Mesh.from_file('meshes/elements/%s_2%s.mesh' % (geom, aux), prefix_dir=sfepy.data_dir) gel = gels[geom] perms = gel.get_conn_permutations() qps, qp_weights = integral.get_qp(gel.surface_facet.name) zz = nm.zeros_like(qps[:, :1]) qps = nm.hstack(([qps] + [zz])) shift = shifts[geom] rcoors = nm.ascontiguousarray(qps + shift[:1, :] - shift[1:, :]) ccoors = nm.ascontiguousarray(qps + shift[:1, :] + shift[1:, :]) for ir, pr in enumerate(perms): for ic, pc in enumerate(perms): report('ir: %d, ic: %d' % (ir, ic)) report('pr: %s, pc: %s' % (pr, pc)) mesh = mesh0.copy() conn = mesh.get_conn(gel.name) conn[0, :] = conn[0, pr] conn[1, :] = conn[1, pc] cache = Struct(mesh=mesh) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') region = domain.create_region('Facet', rsels[geom], 'facet') field = Field.from_args('f', nm.float64, shape=1, region=omega, approx_order=order, poly_space_base=poly_space_base) var = FieldVariable('u', 'unknown', field) report('# dofs: %d' % var.n_dof) vec = nm.empty(var.n_dof, dtype=var.dtype) ap = field.ap ps = ap.interp.poly_spaces['v'] dofs = field.get_dofs_in_region(region, merge=False) edofs, fdofs = nm.unique(dofs[1]), nm.unique(dofs[2]) rrc, rcells, rstatus = get_ref_coors(field, rcoors, cache=cache) crc, ccells, cstatus = get_ref_coors(field, ccoors, cache=cache) assert_((rstatus == 0).all() and (cstatus == 0).all()) yield (geom, poly_space_base, qp_weights, mesh, ir, ic, ap, ps, rrc, rcells[0], crc, ccells[0], vec, edofs, fdofs)
def main(): from sfepy import data_dir parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('--young', metavar='float', type=float, action='store', dest='young', default=2000.0, help=helps['young']) parser.add_argument('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.4, help=helps['poisson']) parser.add_argument('--load', metavar='float', type=float, action='store', dest='load', default=-1000.0, help=helps['load']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_argument('-r', '--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_argument('-s', '--show', action="store_true", dest='show', default=False, help=helps['show']) parser.add_argument('-p', '--probe', action="store_true", dest='probe', default=False, help=helps['probe']) options = 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 range(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 = AutoDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs) pb.set_bcs(ebcs=Conditions([xsym, ysym])) pb.set_solver(nls) # 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 main(cli_args): dims = parse_argument_list(cli_args.dims, float) shape = parse_argument_list(cli_args.shape, int) centre = parse_argument_list(cli_args.centre, float) material_parameters = parse_argument_list(cli_args.material_parameters, float) order = cli_args.order ts_vals = cli_args.ts.split(',') ts = { 't0' : float(ts_vals[0]), 't1' : float(ts_vals[1]), 'n_step' : int(ts_vals[2])} do_plot = cli_args.plot ### Mesh and regions ### mesh = gen_block_mesh( dims, shape, centre, name='block', verbose=False) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') lbn, rtf = domain.get_mesh_bounding_box() box_regions = define_box_regions(3, lbn, rtf) regions = dict([ [r, domain.create_region(r, box_regions[r][0], box_regions[r][1])] for r in box_regions]) ### Fields ### scalar_field = Field.from_args( 'fu', np.float64, 'scalar', omega, approx_order=order-1) vector_field = Field.from_args( 'fv', np.float64, 'vector', omega, approx_order=order) u = FieldVariable('u', 'unknown', vector_field, history=1) v = FieldVariable('v', 'test', vector_field, primary_var_name='u') p = FieldVariable('p', 'unknown', scalar_field, history=1) q = FieldVariable('q', 'test', scalar_field, primary_var_name='p') ### Material ### c10, c01 = material_parameters m = Material( 'm', mu=2*c10, kappa=2*c01, ) ### Boundary conditions ### x_sym = EssentialBC('x_sym', regions['Left'], {'u.0' : 0.0}) y_sym = EssentialBC('y_sym', regions['Near'], {'u.1' : 0.0}) z_sym = EssentialBC('z_sym', regions['Bottom'], {'u.2' : 0.0}) disp_fun = Function('disp_fun', get_displacement) displacement = EssentialBC( 'displacement', regions['Right'], {'u.0' : disp_fun}) ebcs = Conditions([x_sym, y_sym, z_sym, displacement]) ### Terms and equations ### integral = Integral('i', order=2*order) term_neohook = Term.new( 'dw_tl_he_neohook(m.mu, v, u)', integral, omega, m=m, v=v, u=u) term_mooney = Term.new( 'dw_tl_he_mooney_rivlin(m.kappa, v, u)', integral, omega, m=m, v=v, u=u) term_pressure = Term.new( 'dw_tl_bulk_pressure(v, u, p)', integral, omega, v=v, u=u, p=p) term_volume_change = Term.new( 'dw_tl_volume(q, u)', integral, omega, q=q, u=u, term_mode='volume') term_volume = Term.new( 'dw_volume_integrate(q)', integral, omega, q=q) eq_balance = Equation('balance', term_neohook+term_mooney+term_pressure) eq_volume = Equation('volume', term_volume_change-term_volume) equations = Equations([eq_balance, eq_volume]) ### Solvers ### ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton( {'i_max' : 5}, 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) if do_plot: plot_graphs( material_parameters, axial_stress, axial_displacement, undeformed_length=dims[0])
def save_basis_on_mesh(mesh, options, output_dir, lin, permutations=None, suffix=''): if permutations is not None: mesh = mesh.copy() gel = GeometryElement(mesh.descs[0]) perms = gel.get_conn_permutations()[permutations] conn = mesh.cmesh.get_cell_conn() n_el, n_ep = conn.num, gel.n_vertex offsets = nm.arange(n_el) * n_ep conn.indices[:] = conn.indices.take((perms + offsets[:, None]).ravel()) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('f', nm.float64, shape=1, region=omega, approx_order=options.max_order, poly_space_base=options.basis) var = FieldVariable('u', 'unknown', field) if options.plot_dofs: import sfepy.postprocess.plot_dofs as pd import sfepy.postprocess.plot_cmesh as pc ax = pc.plot_wireframe(None, mesh.cmesh) ax = pd.plot_global_dofs(ax, field.get_coor(), field.econn) ax = pd.plot_local_dofs(ax, field.get_coor(), field.econn) if options.dofs is not None: ax = pd.plot_nodes(ax, field.get_coor(), field.econn, field.poly_space.nodes, get_dofs(options.dofs, var.n_dof)) pd.plt.show() output('dofs: %d' % var.n_dof) vec = nm.empty(var.n_dof, dtype=var.dtype) n_digit, _format = get_print_info(var.n_dof, fill='0') name_template = os.path.join(output_dir, 'dof_%s%s.vtk' % (_format, suffix)) for ip in get_dofs(options.dofs, var.n_dof): output('dof %d...' % ip) vec.fill(0.0) vec[ip] = 1.0 var.set_data(vec) if options.derivative == 0: out = var.create_output(vec, linearization=lin) else: out = create_expression_output('ev_grad.ie.Elements(u)', 'u', 'f', {'f' : field}, None, Variables([var]), mode='qp', verbose=False, min_level=lin.min_level, max_level=lin.max_level, eps=lin.eps) name = name_template % ip ensure_path(name) out['u'].mesh.write(name, out=out) output('...done (%s)' % name)
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=6.80e+10, help=helps['young']) parser.add_argument('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.36, help=helps['poisson']) parser.add_argument('--density', metavar='float', type=float, action='store', dest='density', default=2700.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) 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') 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 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 solve_problem(mesh_filename, options, comm): order_u = options.order_u order_p = options.order_p rank, size = comm.Get_rank(), comm.Get_size() output('rank', rank, 'of', size) mesh = Mesh.from_file(mesh_filename) if rank == 0: cell_tasks = pl.partition_mesh(mesh, size, use_metis=options.metis, verbose=True) else: cell_tasks = None output('creating global domain and fields...') tt = time.clock() domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field1 = Field.from_args('fu', nm.float64, mesh.dim, omega, approx_order=order_u) field2 = Field.from_args('fp', nm.float64, 1, omega, approx_order=order_p) fields = [field1, field2] output('...done in', time.clock() - tt) output('distributing fields...') tt = time.clock() distribute = pl.distribute_fields_dofs lfds, gfds = distribute(fields, cell_tasks, is_overlap=True, use_expand_dofs=True, save_inter_regions=options.save_inter_regions, output_dir=options.output_dir, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('creating local problem...') tt = time.clock() cells = lfds[0].cells omega_gi = Region.from_cells(cells, domain) omega_gi.finalize() omega_gi.update_shape() pb = create_local_problem(omega_gi, [order_u, order_p]) variables = pb.get_variables() state = State(variables) state.fill(0.0) state.apply_ebc() output('...done in', time.clock() - tt) output('allocating global system...') tt = time.clock() sizes, drange, pdofs = pl.setup_composite_dofs(lfds, fields, variables, verbose=True) pmtx, psol, prhs = pl.create_petsc_system(pb.mtx_a, sizes, pdofs, drange, is_overlap=True, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('creating solver...') tt = time.clock() conf = Struct(method='bcgsl', precond='jacobi', sub_precond='none', i_max=10000, eps_a=1e-50, eps_r=1e-6, eps_d=1e4, verbose=True) status = {} ls = PETScKrylovSolver(conf, comm=comm, mtx=pmtx, status=status) field_ranges = {} for ii, variable in enumerate(variables.iter_state(ordered=True)): field_ranges[variable.name] = lfds[ii].petsc_dofs_range ls.set_field_split(field_ranges, comm=comm) ev = PETScParallelEvaluator(pb, pdofs, drange, True, psol, comm, verbose=True) nls_status = {} conf = Struct(method='newtonls', i_max=5, eps_a=0, eps_r=1e-5, eps_s=0.0, verbose=True) nls = PETScNonlinearSolver(conf, pmtx=pmtx, prhs=prhs, comm=comm, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix, lin_solver=ls, status=nls_status) output('...done in', time.clock() - tt) output('solving...') tt = time.clock() state = pb.create_state() state.apply_ebc() ev.psol_i[...] = state() ev.gather(psol, ev.psol_i) psol = nls(psol) ev.scatter(ev.psol_i, psol) sol0_i = ev.psol_i[...] output('...done in', time.clock() - tt) output('saving solution...') tt = time.clock() state.set_full(sol0_i) out = state.create_output_dict() filename = os.path.join(options.output_dir, 'sol_%02d.h5' % comm.rank) pb.domain.mesh.write(filename, io='auto', out=out) gather_to_zero = pl.create_gather_to_zero(psol) psol_full = gather_to_zero(psol) if comm.rank == 0: sol = psol_full[...].copy() u = FieldVariable('u', 'parameter', field1, primary_var_name='(set-to-None)') remap = gfds[0].id_map ug = sol[remap] p = FieldVariable('p', 'parameter', field2, primary_var_name='(set-to-None)') remap = gfds[1].id_map pg = sol[remap] if (((order_u == 1) and (order_p == 1)) or (options.linearization == 'strip')): out = u.create_output(ug) out.update(p.create_output(pg)) filename = os.path.join(options.output_dir, 'sol.h5') mesh.write(filename, io='auto', out=out) else: out = u.create_output(ug, linearization=Struct(kind='adaptive', min_level=0, max_level=order_u, eps=1e-3)) filename = os.path.join(options.output_dir, 'sol_u.h5') out['u'].mesh.write(filename, io='auto', out=out) out = p.create_output(pg, linearization=Struct(kind='adaptive', min_level=0, max_level=order_p, eps=1e-3)) filename = os.path.join(options.output_dir, 'sol_p.h5') out['p'].mesh.write(filename, io='auto', out=out) output('...done in', time.clock() - tt)
def solve_problem(mesh_filename, options, comm): order = options.order rank, size = comm.Get_rank(), comm.Get_size() output('rank', rank, 'of', size) mesh = Mesh.from_file(mesh_filename) if rank == 0: cell_tasks = pl.partition_mesh(mesh, size, use_metis=options.metis, verbose=True) else: cell_tasks = None domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('fu', nm.float64, 1, omega, approx_order=order) output('distributing field %s...' % field.name) tt = time.clock() distribute = pl.distribute_fields_dofs lfds, gfds = distribute([field], cell_tasks, is_overlap=True, save_inter_regions=options.save_inter_regions, output_dir=options.output_dir, comm=comm, verbose=True) lfd = lfds[0] output('...done in', time.clock() - tt) if rank == 0: dof_maps = gfds[0].dof_maps id_map = gfds[0].id_map if options.verify: verify_save_dof_maps(field, cell_tasks, dof_maps, id_map, options, verbose=True) if options.plot: ppd.plot_partitioning([None, None], field, cell_tasks, gfds[0], options.output_dir, size) output('creating local problem...') tt = time.clock() omega_gi = Region.from_cells(lfd.cells, field.domain) omega_gi.finalize() omega_gi.update_shape() pb = create_local_problem(omega_gi, order) output('...done in', time.clock() - tt) variables = pb.get_variables() eqs = pb.equations u_i = variables['u_i'] field_i = u_i.field if options.plot: ppd.plot_local_dofs([None, None], field, field_i, omega_gi, options.output_dir, rank) output('allocating global system...') tt = time.clock() sizes, drange = pl.get_sizes(lfd.petsc_dofs_range, field.n_nod, 1) output('sizes:', sizes) output('drange:', drange) pdofs = pl.get_local_ordering(field_i, lfd.petsc_dofs_conn) output('pdofs:', pdofs) pmtx, psol, prhs = pl.create_petsc_system(pb.mtx_a, sizes, pdofs, drange, is_overlap=True, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('evaluating local problem...') tt = time.clock() state = State(variables) state.fill(0.0) state.apply_ebc() rhs_i = eqs.eval_residuals(state()) # This must be after pl.create_petsc_system() call! mtx_i = eqs.eval_tangent_matrices(state(), pb.mtx_a) output('...done in', time.clock() - tt) output('assembling global system...') tt = time.clock() pl.apply_ebc_to_matrix(mtx_i, u_i.eq_map.eq_ebc) pl.assemble_rhs_to_petsc(prhs, rhs_i, pdofs, drange, is_overlap=True, comm=comm, verbose=True) pl.assemble_mtx_to_petsc(pmtx, mtx_i, pdofs, drange, is_overlap=True, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('creating solver...') tt = time.clock() conf = Struct(method='cg', precond='gamg', sub_precond=None, i_max=10000, eps_a=1e-50, eps_r=1e-5, eps_d=1e4, verbose=True) status = {} ls = PETScKrylovSolver(conf, comm=comm, mtx=pmtx, status=status) output('...done in', time.clock() - tt) output('solving...') tt = time.clock() psol = ls(prhs, psol, conf) psol_i = pl.create_local_petsc_vector(pdofs) gather, scatter = pl.create_gather_scatter(pdofs, psol_i, psol, comm=comm) scatter(psol_i, psol) sol0_i = state() - psol_i[...] psol_i[...] = sol0_i gather(psol, psol_i) output('...done in', time.clock() - tt) output('saving solution...') tt = time.clock() u_i.set_data(sol0_i) out = u_i.create_output() filename = os.path.join(options.output_dir, 'sol_%02d.h5' % comm.rank) pb.domain.mesh.write(filename, io='auto', out=out) gather_to_zero = pl.create_gather_to_zero(psol) psol_full = gather_to_zero(psol) if comm.rank == 0: sol = psol_full[...].copy()[id_map] u = FieldVariable('u', 'parameter', field, primary_var_name='(set-to-None)') filename = os.path.join(options.output_dir, 'sol.h5') if (order == 1) or (options.linearization == 'strip'): out = u.create_output(sol) mesh.write(filename, io='auto', out=out) else: out = u.create_output(sol, linearization=Struct(kind='adaptive', min_level=0, max_level=order, eps=1e-3)) out['u'].mesh.write(filename, io='auto', out=out) output('...done in', time.clock() - tt) if options.show: plt.show()
def main(): parser = OptionParser(usage=usage, version="%prog " + sfepy.__version__) parser.add_option("-m", "--mesh", action="store_true", dest="save_mesh", default=False, help="save surface mesh") parser.add_option("-n", "--no-surface", action="store_true", dest="no_surface", default=False, help="do not output surface [default: %default]") (options, args) = parser.parse_args() if (len(args) == 2): filename_in = args[0] filename_out = args[1] else: parser.print_help(), return if (filename_in == '-'): file_in = sys.stdin else: file_in = open(filename_in, "r") mesh = Mesh.from_file(filename_in) if (filename_in != '-'): file_in.close() domain = FEDomain('domain', mesh) if options.save_mesh: region = domain.create_region('surf', 'vertices of surface', 'facet') surf_mesh = Mesh.from_region(region, mesh, localize=True, is_surface=True) aux = edit_filename(filename_in, prefix='surf_', new_ext='.mesh') surf_mesh.write(aux, io='auto') if domain.has_faces(): domain.fix_element_orientation() lst, surf_faces = get_surface_faces(domain) if options.no_surface: return gr_s = surface_graph(surf_faces, mesh.n_nod) n_comp, comps = surface_components(gr_s, surf_faces) output('number of surface components:', n_comp) ccs, comps = comps, nm.zeros((0, 1), nm.int32) for cc in ccs: comps = nm.concatenate((comps, cc[:, nm.newaxis]), 0) out = nm.concatenate((lst, comps), 1) if (filename_out == '-'): file_out = sys.stdout else: file_out = open(filename_out, "w") for row in out: file_out.write('%d %d %d\n' % (row[0], row[1], row[2])) if (filename_out != '-'): file_out.close()
def create_local_problem(omega_gi, orders): """ Local problem definition using a domain corresponding to the global region `omega_gi`. """ order_u, order_p = orders mesh = omega_gi.domain.mesh # All tasks have the whole mesh. bbox = mesh.get_bounding_box() min_x, max_x = bbox[:, 0] eps_x = 1e-8 * (max_x - min_x) min_y, max_y = bbox[:, 1] eps_y = 1e-8 * (max_y - min_y) mesh_i = Mesh.from_region(omega_gi, mesh, localize=True) domain_i = FEDomain('domain_i', mesh_i) omega_i = domain_i.create_region('Omega', 'all') gamma1_i = domain_i.create_region('Gamma1', 'vertices in (x < %.10f)' % (min_x + eps_x), 'facet', allow_empty=True) gamma2_i = domain_i.create_region('Gamma2', 'vertices in (x > %.10f)' % (max_x - eps_x), 'facet', allow_empty=True) gamma3_i = domain_i.create_region('Gamma3', 'vertices in (y < %.10f)' % (min_y + eps_y), 'facet', allow_empty=True) field1_i = Field.from_args('fu', nm.float64, mesh.dim, omega_i, approx_order=order_u) field2_i = Field.from_args('fp', nm.float64, 1, omega_i, approx_order=order_p) output('field 1: number of local DOFs:', field1_i.n_nod) output('field 2: number of local DOFs:', field2_i.n_nod) u_i = FieldVariable('u_i', 'unknown', field1_i, order=0) v_i = FieldVariable('v_i', 'test', field1_i, primary_var_name='u_i') p_i = FieldVariable('p_i', 'unknown', field2_i, order=1) q_i = FieldVariable('q_i', 'test', field2_i, primary_var_name='p_i') if mesh.dim == 2: alpha = 1e2 * nm.array([[0.132], [0.132], [0.092]]) else: alpha = 1e2 * nm.array([[0.132], [0.132], [0.132], [0.092], [0.092], [0.092]]) mat = Material('m', D=stiffness_from_lame(mesh.dim, lam=10, mu=5), k=1, alpha=alpha) integral = Integral('i', order=2*(max(order_u, order_p))) t11 = Term.new('dw_lin_elastic(m.D, v_i, u_i)', integral, omega_i, m=mat, v_i=v_i, u_i=u_i) t12 = Term.new('dw_biot(m.alpha, v_i, p_i)', integral, omega_i, m=mat, v_i=v_i, p_i=p_i) t21 = Term.new('dw_biot(m.alpha, u_i, q_i)', integral, omega_i, m=mat, u_i=u_i, q_i=q_i) t22 = Term.new('dw_laplace(m.k, q_i, p_i)', integral, omega_i, m=mat, q_i=q_i, p_i=p_i) eq1 = Equation('eq1', t11 - t12) eq2 = Equation('eq1', t21 + t22) eqs = Equations([eq1, eq2]) ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all' : 0.0}) ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.0' : 0.05}) def bc_fun(ts, coors, **kwargs): val = 0.3 * nm.sin(4 * nm.pi * (coors[:, 0] - min_x) / (max_x - min_x)) return val fun = Function('bc_fun', bc_fun) ebc3 = EssentialBC('ebc3', gamma3_i, {'p_i.all' : fun}) pb = Problem('problem_i', equations=eqs, active_only=False) pb.time_update(ebcs=Conditions([ebc1, ebc2, ebc3])) pb.update_materials() return pb
n_nod = 100 n_el = n_nod - 1 coors = nm.linspace(X1, XN, n_nod).reshape((n_nod, 1)) conn = nm.arange(n_nod, dtype=nm.int32).repeat(2)[1:-1].reshape((-1, 2)) mat_ids = nm.zeros(n_nod - 1, dtype=nm.int32) descs = ['1_2'] mesh = Mesh.from_data('uniform_1D{}'.format(n_nod), coors, None, [conn], [mat_ids], descs) # ----------------------------- # | Create problem components | # ----------------------------- integral = Integral('i', order=approx_order * 2) domain = FEDomain(domain_name, mesh) omega = domain.create_region('Omega', 'all') left = domain.create_region('Gamma1', 'vertices in x == %.10f' % X1, 'vertex') right = domain.create_region('Gamma2', 'vertices in x == %.10f' % XN, 'vertex') field = DGField('dgfu', nm.float64, 'scalar', omega, approx_order=approx_order) u = FieldVariable('u', 'unknown', field, history=1) v = FieldVariable('v', 'test', field, primary_var_name='u') MassT = DotProductVolumeTerm("adv_vol(v, u)", "v, u", integral, omega, u=u, v=v) velo = nm.array(1.0)
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=6.80e+10, help=helps['young']) parser.add_argument('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.36, help=helps['poisson']) parser.add_argument('--density', metavar='float', type=float, action='store', dest='density', default=2700.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) 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') 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 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 save_basis_on_mesh(mesh, options, output_dir, lin, permutations=None, suffix=''): if permutations is not None: mesh = mesh.copy() gel = GeometryElement(mesh.descs[0]) perms = gel.get_conn_permutations()[permutations] conn = mesh.cmesh.get_cell_conn() n_el, n_ep = conn.num, gel.n_vertex offsets = nm.arange(n_el) * n_ep conn.indices[:] = conn.indices.take((perms + offsets[:, None]).ravel()) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('f', nm.float64, shape=1, region=omega, approx_order=options.max_order, poly_space_base=options.basis) var = FieldVariable('u', 'unknown', field) if options.plot_dofs: import sfepy.postprocess.plot_dofs as pd import sfepy.postprocess.plot_cmesh as pc ax = pc.plot_wireframe(None, mesh.cmesh) ax = pd.plot_global_dofs(ax, field.get_coor(), field.econn) ax = pd.plot_local_dofs(ax, field.get_coor(), field.econn) if options.dofs is not None: ax = pd.plot_nodes(ax, field.get_coor(), field.econn, field.poly_space.nodes, get_dofs(options.dofs, var.n_dof)) pd.plt.show() output('dofs: %d' % var.n_dof) vec = nm.empty(var.n_dof, dtype=var.dtype) n_digit, _format = get_print_info(var.n_dof, fill='0') name_template = os.path.join(output_dir, 'dof_%s%s.vtk' % (_format, suffix)) for ip in get_dofs(options.dofs, var.n_dof): output('dof %d...' % ip) vec.fill(0.0) vec[ip] = 1.0 var.set_data(vec) if options.derivative == 0: out = var.create_output(vec, linearization=lin) else: out = create_expression_output('ev_grad.ie.Elements(u)', 'u', 'f', {'f': field}, None, Variables([var]), mode='qp', verbose=False, min_level=lin.min_level, max_level=lin.max_level, eps=lin.eps) name = name_template % ip ensure_path(name) out['u'].mesh.write(name, out=out) output('...done (%s)' % name)
def _solve(self, property_array): """ Solve the Sfepy problem for one sample. Args: property_array: array of shape (n_x, n_y, 2) where the last index is for Lame's parameter and shear modulus, respectively. Returns: the strain field of shape (n_x, n_y, 2) where the last index represents the x and y displacements """ shape = property_array.shape[:-1] mesh = self._get_mesh(shape) domain = Domain('domain', mesh) region_all = domain.create_region('region_all', 'all') field = Field.from_args( 'fu', np.float64, 'vector', region_all, # pylint: disable=no-member approx_order=2) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') m = self._get_material(property_array, domain) integral = Integral('i', order=4) t1 = Term.new('dw_lin_elastic_iso(m.lam, m.mu, v, u)', integral, region_all, m=m, v=v, u=u) eq = Equation('balance_of_forces', t1) eqs = Equations([eq]) epbcs, functions = self._get_periodicBCs(domain) ebcs = self._get_displacementBCs(domain) lcbcs = self._get_linear_combinationBCs(domain) ls = ScipyDirect({}) pb = Problem('elasticity', equations=eqs, functions=functions) pb.time_update(ebcs=ebcs, epbcs=epbcs, lcbcs=lcbcs) ev = pb.get_evaluator() nls = Newton({}, lin_solver=ls, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix) try: pb.set_solvers_instances(ls, nls) except AttributeError: pb.set_solver(nls) vec = pb.solve() u = vec.create_output_dict()['u'].data u_reshape = np.reshape(u, (tuple(x + 1 for x in shape) + u.shape[-1:])) dims = domain.get_mesh_bounding_box().shape[1] strain = np.squeeze( pb.evaluate( 'ev_cauchy_strain.{dim}.region_all(u)'.format(dim=dims), mode='el_avg', copy_materials=False)) strain_reshape = np.reshape(strain, (shape + strain.shape[-1:])) stress = np.squeeze( pb.evaluate( 'ev_cauchy_stress.{dim}.region_all(m.D, u)'.format(dim=dims), mode='el_avg', copy_materials=False)) stress_reshape = np.reshape(stress, (shape + stress.shape[-1:])) return strain_reshape, u_reshape, stress_reshape
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)
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() options_probe = True folder = str(uuid.uuid4()) os.mkdir(folder) os.chdir(folder) file = open('README.txt', 'w') file.write('DIMENSIONS\n') file.write('Lx = '+str(dims[0])+' Ly = '+str(dims[1])+' Lz = '+str(dims[2])+'\n') file.write('DISCRETIZATION (NX, NY, NZ)\n') file.write(str(NX)+' '+str(NY)+' '+str(NZ)+'\n') file.write('MATERIALS\n') file.write(str(E_f)+' '+str(nu_f)+' '+str(E_m)+' '+str(nu_m)+'\n') #mesh = Mesh.from_file(data_dir + '/meshes/2d/rectangle_tri.mesh') mesh = mesh_generators.gen_block_mesh(dims,shape,centre,name='block') domain = FEDomain('domain', mesh) min_x, max_x = domain.get_mesh_bounding_box()[:,0] min_y, max_y = domain.get_mesh_bounding_box()[:,1] min_z, max_z = domain.get_mesh_bounding_box()[:,2] eps = 1e-8 * (max_x - min_x) print min_x, max_x print min_y, max_y print min_z, max_z R1 = domain.create_region('Ym', 'vertices in z < %.10f' % (max_z/2)) R2 = domain.create_region('Yf', 'vertices in z >= %.10f' % (min_z/2)) omega = domain.create_region('Omega', 'all') gamma1 = domain.create_region('Left', 'vertices in x < %.10f' % (min_x + eps), 'facet') gamma2 = domain.create_region('Right', 'vertices in x > %.10f' % (max_x - eps), 'facet') gamma3 = domain.create_region('Front', 'vertices in y < %.10f' % (min_y + eps), 'facet') gamma4 = domain.create_region('Back', 'vertices in y > %.10f' % (max_y - eps), 'facet') gamma5 = domain.create_region('Bottom', 'vertices in z < %.10f' % (min_z + eps), 'facet') gamma6 = domain.create_region('Top', 'vertices in z > %.10f' % (max_z - 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') mu=1.1 lam=1.0 m = Material('m', lam=lam, mu=mu) f = Material('f', val=[[0.0], [0.0],[-1.0]]) load = Material('Load',val=[[0.0],[0.0],[-Load]]) D = stiffness_from_lame(3,lam, mu) mat = Material('Mat', D=D) get_mat = Function('get_mat1',get_mat1) get_mat_f = Function('get_mat_f',get_mat1) integral = Integral('i', order=3) s_integral = Integral('is',order=2) t1 = Term.new('dw_lin_elastic(Mat.D, v, u)', integral, omega, Mat=mat, v=v, u=u) t2 = Term.new('dw_volume_lvf(f.val, v)', integral, omega, f=f, v=v) #t3 = Term.new('DotProductSurfaceTerm(Load.val, v)',s_integral,gamma5,Load=load,v=v) t3 = Term.new('dw_surface_ltr( Load.val, v )',s_integral,gamma6,Load=load,v=v) eq = Equation('balance', t1 + t2 + t3) eqs = Equations([eq]) fix_u = EssentialBC('fix_u', gamma1, {'u.all' : 0.0}) left_bc = EssentialBC('Left', gamma1, {'u.0' : 0.0}) right_bc = EssentialBC('Right', gamma2, {'u.0' : 0.0}) back_bc = EssentialBC('Front', gamma3, {'u.1' : 0.0}) front_bc = EssentialBC('Back', gamma4, {'u.1' : 0.0}) bottom_bc = EssentialBC('Bottom', gamma5, {'u.all' : 0.0}) top_bc = EssentialBC('Top', gamma6, {'u.2' : 0.2}) bc=[left_bc,right_bc,back_bc,front_bc,bottom_bc] #bc=[bottom_bc,top_bc] ############################## # ##### SOLVER SECTION ##### ############################## conf = Struct(method='bcgsl', precond='jacobi', sub_precond=None, i_max=10000, eps_a=1e-50, eps_r=1e-10, eps_d=1e4, verbose=True) ls = PETScKrylovSolver(conf) file.write(str(ls.name)+' '+str(ls.conf.method)+' '+str(ls.conf.precond)+' '+str(ls.conf.eps_r)+' '+str(ls.conf.i_max)+'\n' ) nls_status = IndexedStruct() nls = Newton({'i_max':1,'eps_a':1e-10}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls) dd=pb.get_materials()['Mat'] dd.set_function(get_mat1) #xload = pb.get_materials()['f'] #xload.set_function(get_mat_f) pb.save_regions_as_groups('regions') pb.time_update(ebcs=Conditions(bc)) vec = pb.solve() print nls_status file.write('TIME TO SOLVE\n') file.write(str(nls.status.time_stats['solve'])+'\n') file.write('TIME TO CREATE MATRIX\n') file.write(str(nls.status.time_stats['matrix'])+'\n') ev = pb.evaluate out = vec.create_output_dict() strain = ev('ev_cauchy_strain.3.Omega(u)', mode='el_avg') stress = ev('ev_cauchy_stress.3.Omega(Mat.D, u)', mode='el_avg', copy_materials=False) out['cauchy_strain'] = Struct(name='output_data', mode='cell', data=strain, dofs=None) out['cauchy_stress'] = Struct(name='output_data', mode='cell', data=stress, dofs=None) pb.save_state('strain.vtk', out=out) print nls_status file.close()
def from_conf(conf, options): from sfepy.discrete import FieldVariable, Variables, Problem from sfepy.discrete.fem import Mesh, FEDomain, Field mesh = Mesh.from_file(data_dir + '/meshes/2d/square_unit_tri.mesh') domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') domain.create_region('Left', 'vertices in (x < -0.499)', 'facet') domain.create_region('LeftStrip', 'vertices in (x < -0.499)' ' & (y > -0.199) & (y < 0.199)', 'facet') domain.create_region('LeftFix', 'r.Left -v r.LeftStrip', 'facet') domain.create_region('Right', 'vertices in (x > 0.499)', 'facet') domain.create_region('RightStrip', 'vertices in (x > 0.499)' ' & (y > -0.199) & (y < 0.199)', 'facet') domain.create_region('RightFix', 'r.Right -v r.RightStrip', 'facet') fu = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=2) u = FieldVariable('u', 'unknown', fu) fp = Field.from_args('fp', nm.float64, 'scalar', omega, approx_order=2) p = FieldVariable('p', 'unknown', fp) pb = Problem('test', domain=domain, fields=[fu, fp], auto_conf=False, auto_solvers=False) test = Test(problem=pb, variables=Variables([u, p]), conf=conf, options=options) return test
def main(): from sfepy import data_dir parser = ArgumentParser() parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('-s', '--show', action="store_true", dest='show', default=False, help=helps['show']) options = 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 test_linearization(self): from sfepy.base.base import Struct from sfepy.discrete.fem import Mesh, FEDomain, Field from sfepy import data_dir geometries = ['2_3', '2_4', '3_4', '3_8'] approx_orders = [1, 2] funs = [nm.cos, nm.sin, lambda x: x] ok = True for geometry in geometries: name = os.path.join(data_dir, 'meshes/elements/%s_1.mesh' % geometry) mesh = Mesh.from_file(name) domain = FEDomain('', mesh) domain = domain.refine() domain.mesh.write(self.join('linearizer-%s-0.mesh' % geometry)) omega = domain.create_region('Omega', 'all') for approx_order in approx_orders: for dpn in [1, mesh.dim]: self.report('geometry: %s, approx. order: %d, dpn: %d' % (geometry, approx_order, dpn)) field = Field.from_args('fu', nm.float64, dpn, omega, approx_order=approx_order) cc = field.get_coor() dofs = nm.zeros((field.n_nod, dpn), dtype=nm.float64) for ic in range(dpn): dofs[:, ic] = funs[ic](3 * (cc[:, 0] * cc[:, 1])) vmesh, vdofs, level = field.linearize(dofs, min_level=0, max_level=3, eps=1e-2) if approx_order == 1: _ok = level == 0 else: _ok = level > 0 self.report('max. refinement level: %d: %s' % (level, _ok)) ok = ok and _ok rdofs = nm.zeros((vmesh.n_nod, dpn), dtype=nm.float64) cc = vmesh.coors for ic in range(dpn): rdofs[:, ic] = funs[ic](3 * (cc[:, 0] * cc[:, 1])) _ok = nm.allclose(rdofs, vdofs, rtol=0.0, atol=0.03) self.report('interpolation: %s' % _ok) ok = ok and _ok out = { 'u' : Struct(name='output_data', mode='vertex', data=vdofs, var_name='u', dofs=None) } name = self.join('linearizer-%s-%d-%d' % (geometry, approx_order, dpn)) vmesh.write(name + '.mesh') vmesh.write(name + '.vtk', out=out) return ok
def create_local_problem(omega_gi, orders): """ Local problem definition using a domain corresponding to the global region `omega_gi`. """ order_u, order_p = orders mesh = omega_gi.domain.mesh # All tasks have the whole mesh. bbox = mesh.get_bounding_box() min_x, max_x = bbox[:, 0] eps_x = 1e-8 * (max_x - min_x) min_y, max_y = bbox[:, 1] eps_y = 1e-8 * (max_y - min_y) mesh_i = Mesh.from_region(omega_gi, mesh, localize=True) domain_i = FEDomain('domain_i', mesh_i) omega_i = domain_i.create_region('Omega', 'all') gamma1_i = domain_i.create_region('Gamma1', 'vertices in (x < %.10f)' % (min_x + eps_x), 'facet', allow_empty=True) gamma2_i = domain_i.create_region('Gamma2', 'vertices in (x > %.10f)' % (max_x - eps_x), 'facet', allow_empty=True) gamma3_i = domain_i.create_region('Gamma3', 'vertices in (y < %.10f)' % (min_y + eps_y), 'facet', allow_empty=True) field1_i = Field.from_args('fu', nm.float64, mesh.dim, omega_i, approx_order=order_u) field2_i = Field.from_args('fp', nm.float64, 1, omega_i, approx_order=order_p) output('field 1: number of local DOFs:', field1_i.n_nod) output('field 2: number of local DOFs:', field2_i.n_nod) u_i = FieldVariable('u_i', 'unknown', field1_i, order=0) v_i = FieldVariable('v_i', 'test', field1_i, primary_var_name='u_i') p_i = FieldVariable('p_i', 'unknown', field2_i, order=1) q_i = FieldVariable('q_i', 'test', field2_i, primary_var_name='p_i') if mesh.dim == 2: alpha = 1e2 * nm.array([[0.132], [0.132], [0.092]]) else: alpha = 1e2 * nm.array([[0.132], [0.132], [0.132], [0.092], [0.092], [0.092]]) mat = Material('m', D=stiffness_from_lame(mesh.dim, lam=10, mu=5), k=1, alpha=alpha) integral = Integral('i', order=2 * (max(order_u, order_p))) t11 = Term.new('dw_lin_elastic(m.D, v_i, u_i)', integral, omega_i, m=mat, v_i=v_i, u_i=u_i) t12 = Term.new('dw_biot(m.alpha, v_i, p_i)', integral, omega_i, m=mat, v_i=v_i, p_i=p_i) t21 = Term.new('dw_biot(m.alpha, u_i, q_i)', integral, omega_i, m=mat, u_i=u_i, q_i=q_i) t22 = Term.new('dw_laplace(m.k, q_i, p_i)', integral, omega_i, m=mat, q_i=q_i, p_i=p_i) eq1 = Equation('eq1', t11 - t12) eq2 = Equation('eq1', t21 + t22) eqs = Equations([eq1, eq2]) ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all': 0.0}) ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.0': 0.05}) def bc_fun(ts, coors, **kwargs): val = 0.3 * nm.sin(4 * nm.pi * (coors[:, 0] - min_x) / (max_x - min_x)) return val fun = Function('bc_fun', bc_fun) ebc3 = EssentialBC('ebc3', gamma3_i, {'p_i.all': fun}) pb = Problem('problem_i', equations=eqs, active_only=False) pb.time_update(ebcs=Conditions([ebc1, ebc2, ebc3])) pb.update_materials() return pb