def refine_mesh(filename, level): """ Uniformly refine `level`-times a mesh given by `filename`. The refined mesh is saved to a file with name constructed from base name of `filename` and `level`-times appended `'_r'` suffix. Parameters ---------- filename : str The mesh file name. level : int The refinement level. """ import os from sfepy.base.base import output from sfepy.discrete.fem import Mesh, FEDomain if level > 0: mesh = Mesh.from_file(filename) domain = FEDomain(mesh.name, mesh) for ii in range(level): output('refine %d...' % ii) domain = domain.refine() output('... %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) suffix = os.path.splitext(filename)[1] filename = domain.name + suffix domain.mesh.write(filename, io='auto') return filename
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 _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 refine_mesh(filename, level): """ Uniformly refine `level`-times a mesh given by `filename`. The refined mesh is saved to a file with name constructed from base name of `filename` and `level`-times appended `'_r'` suffix. Parameters ---------- filename : str The mesh file name. level : int The refinement level. """ import os from sfepy.base.base import output from sfepy.discrete.fem import Mesh, FEDomain if level > 0: mesh = Mesh.from_file(filename) domain = FEDomain(mesh.name, mesh) for ii in range(level): output('refine %d...' % ii) domain = domain.refine() output('... %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) suffix = os.path.splitext(filename)[1] filename = domain.name + suffix domain.mesh.write(filename, io='auto') return filename
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 solveLaplaceEquationTetrahedral(mesh, meshVTK, boundaryPoints, boundaryConditions): """ mesh: path to a 3D mesh / sfepy mesh """ if isinstance(mesh, str): mesh = Mesh.from_file(mesh) #Set domains domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') boundary = domain.create_region( 'gamma', 'vertex %s' % ','.join(map(str, range(meshVTK.GetNumberOfPoints()))), 'facet') #set fields field = Field.from_args('fu', np.float64, 1, omega, approx_order=1) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') m = Material('m', val=[1.]) #Define element integrals integral = Integral('i', order=3) #Equations defining t1 = Term.new('dw_laplace( v, u )', integral, omega, v=v, u=u) eq = Equation('balance', t1) eqs = Equations([eq]) heatBoundary = boundaryConditions points = boundaryPoints #Boundary conditions c = ClosestPointStupid(points, heatBoundary, meshVTK) def u_fun(ts, coors, bc=None, problem=None, c=c): c.distances = [] v = np.zeros(len(coors)) for i, p in enumerate(coors): v[i] = c.interpolate(p) #c.findClosestPoint(p) return v bc_fun = Function('u_fun', u_fun) fix1 = EssentialBC('fix_u', boundary, {'u.all': bc_fun}) #Solve problem ls = ScipyDirect({}) nls = Newton({}, lin_solver=ls) pb = Problem('heat', equations=eqs) pb.set_bcs(ebcs=Conditions([fix1])) pb.set_solver(nls) state = pb.solve(verbose=False, save_results=False) u = state.get_parts()['u'] return u
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 refine_region(domain0, region0, region1): """ Coarse cell sub_cells[ii, 0] in mesh0 is split into sub_cells[ii, 1:] in mesh1. The new fine cells are interleaved among the original coarse cells so that the indices of the coarse cells do not change. The cell groups are preserved. The vertex groups are preserved only in the coarse (non-refined) cells. """ if region1 is None: return domain0, None mesh0 = domain0.mesh mesh1 = Mesh.from_region(region1, mesh0) domain1 = FEDomain('d', mesh1) domain1r = domain1.refine() mesh1r = domain1r.mesh n_cell = region1.shape.n_cell n_sub = 4 if mesh0.cmesh.tdim == 2 else 8 sub_cells = nm.empty((n_cell, n_sub + 1), dtype=nm.uint32) sub_cells[:, 0] = region1.cells sub_cells[:, 1] = region1.cells aux = nm.arange((n_sub - 1) * n_cell, dtype=nm.uint32) sub_cells[:, 2:] = mesh0.n_el + aux.reshape((n_cell, -1)) coors0, vgs0, conns0, mat_ids0, descs0 = mesh0._get_io_data() coors, vgs, _conns, _mat_ids, descs = mesh1r._get_io_data() # Preserve vertex groups of non-refined cells. vgs[:len(vgs0)] = vgs0 def _interleave_refined(c0, c1): if c1.ndim == 1: c0 = c0[:, None] c1 = c1[:, None] n_row, n_col = c1.shape n_new = region0.shape.n_cell + n_row out = nm.empty((n_new, n_col), dtype=c0.dtype) out[region0.cells] = c0[region0.cells] out[region1.cells] = c1[::n_sub] aux = c1.reshape((-1, n_col * n_sub)) out[mesh0.n_el:] = aux[:, n_col:].reshape((-1, n_col)) return out conn = _interleave_refined(conns0[0], _conns[0]) mat_id = _interleave_refined(mat_ids0[0], _mat_ids[0]).squeeze() mesh = Mesh.from_data('a', coors, vgs, [conn], [mat_id], descs) domain = FEDomain('d', mesh) return domain, sub_cells
def refine_region(domain0, region0, region1): """ Coarse cell sub_cells[ii, 0] in mesh0 is split into sub_cells[ii, 1:] in mesh1. The new fine cells are interleaved among the original coarse cells so that the indices of the coarse cells do not change. The cell groups are preserved. The vertex groups are preserved only in the coarse (non-refined) cells. """ if region1 is None: return domain0, None mesh0 = domain0.mesh mesh1 = Mesh.from_region(region1, mesh0) domain1 = FEDomain('d', mesh1) domain1r = domain1.refine() mesh1r = domain1r.mesh n_cell = region1.shape.n_cell n_sub = 4 if mesh0.cmesh.tdim == 2 else 8 sub_cells = nm.empty((n_cell, n_sub + 1), dtype=nm.uint32) sub_cells[:, 0] = region1.cells sub_cells[:, 1] = region1.cells aux = nm.arange((n_sub - 1) * n_cell, dtype=nm.uint32) sub_cells[:, 2:] = mesh0.n_el + aux.reshape((n_cell, -1)) coors0, vgs0, conns0, mat_ids0, descs0 = mesh0._get_io_data() coors, vgs, _conns, _mat_ids, descs = mesh1r._get_io_data() # Preserve vertex groups of non-refined cells. vgs[:len(vgs0)] = vgs0 def _interleave_refined(c0, c1): if c1.ndim == 1: c0 = c0[:, None] c1 = c1[:, None] n_row, n_col = c1.shape n_new = region0.shape.n_cell + n_row out = nm.empty((n_new, n_col), dtype=c0.dtype) out[region0.cells] = c0[region0.cells] out[region1.cells] = c1[::n_sub] aux = c1.reshape((-1, n_col * n_sub)) out[mesh0.n_el:] = aux[:, n_col:].reshape((-1, n_col)) return out conn = _interleave_refined(conns0[0], _conns[0]) mat_id = _interleave_refined(mat_ids0[0], _mat_ids[0]).squeeze() mesh = Mesh.from_data('a', coors, vgs, [conn], [mat_id], descs) domain = FEDomain('d', mesh) return domain, sub_cells
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 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 prepare_dgfield(approx_order, mesh): domain = FEDomain("test_domain", mesh) omega = domain.create_region('Omega', 'all') regions = {} if mesh.dim > 1: left = domain.create_region('left', 'vertices in x == 0', 'edge') right = domain.create_region('right', 'vertices in x == 1', 'edge') bottom = domain.create_region('bottom', 'vertices in y == 0', 'edge') top = domain.create_region('top', 'vertices in y == 1', 'edge') regions.update({"top": top, "bottom": bottom}) else: left = domain.create_region('left', 'vertices in x == 0', 'vertex') right = domain.create_region('right', 'vertices in x == 1', 'vertex') regions.update({"left": left, "right": right, "omega" : omega}) field = DGField('dgfu', nm.float64, 'scalar', omega, approx_order=approx_order) return field, regions
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 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 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_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_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_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 test_refine_3_8(self): mesh = Mesh('3_8', data_dir + '/meshes/elements/3_8_1.mesh') domain = refine(FEDomain('domain', mesh), self.options.out_dir, 1) ok = compare_mesh('3_8', domain.mesh.coors, domain.mesh.conns[0]) return ok
def main(): parser = ArgumentParser(description=__doc__) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('filename') options = parser.parse_args() filename = options.filename mesh = Mesh.from_file(filename) output('Mesh:') output(' dimension: %d, vertices: %d, elements: %d' % (mesh.dim, mesh.n_nod, mesh.n_el)) domain = FEDomain('domain', mesh) output(domain.cmesh) domain.cmesh.cprint(1) dim = domain.cmesh.dim entities_opts = [ {'color' : 'k', 'label_global' : 12, 'label_local' : 8}, {'color' : 'b', 'label_global' : 12, 'label_local' : 8}, {'color' : 'g', 'label_global' : 12, 'label_local' : 8}, {'color' : 'r', 'label_global' : 12}, ] if dim == 2: entities_opts.pop(2) pc.plot_cmesh(None, domain.cmesh, wireframe_opts = {'color' : 'k'}, entities_opts=entities_opts) plt.show()
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 test_refine_hexa(self): mesh = Mesh('mesh_hexa', data_dir + '/meshes/various_formats/abaqus_hex.inp') domain = FEDomain('domain', mesh) refine(domain, self.options.out_dir) return True
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 test_refine_hexa(self): filename = data_dir + '/meshes/various_formats/abaqus_hex.inp' mesh = Mesh.from_file(filename) domain = FEDomain('domain', mesh) refine(domain, self.options.out_dir) return True
def test_refine_3_4(self): mesh = Mesh.from_file(data_dir + '/meshes/elements/3_4_1.mesh') domain = refine(FEDomain('domain', mesh), self.options.out_dir, 1) ok = compare_mesh('3_4', domain.mesh.coors, domain.mesh.get_conn('3_4')) return ok
def main(): parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('-d', '--dims', metavar='dims', action='store', dest='dims', default='[1.0, 1.0]', help=helps['dims']) parser.add_argument('-c', '--centre', metavar='centre', action='store', dest='centre', default='[0.0, 0.0]', help=helps['centre']) parser.add_argument('-s', '--shape', metavar='shape', action='store', dest='shape', default='[11, 11]', help=helps['shape']) parser.add_argument('--show', action="store_true", dest='show', default=False, help=helps['show']) options = parser.parse_args() dims = nm.array(eval(options.dims), dtype=nm.float64) centre = nm.array(eval(options.centre), dtype=nm.float64) shape = nm.array(eval(options.shape), dtype=nm.int32) output('dimensions:', dims) output('centre: ', centre) output('shape: ', shape) mesh = gen_block_mesh(dims, shape, centre, name='block-fem') fe_domain = FEDomain('domain', mesh) pb, state = run(fe_domain, 1) pb.save_state('laplace_shifted_periodic.vtk', state) if options.show: from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.domain_specific import DomainSpecificPlot view = Viewer('laplace_shifted_periodic.vtk') view(rel_scaling=1, domain_specific={ 'u': DomainSpecificPlot('plot_warp_scalar', ['rel_scaling=1']) }, is_scalar_bar=True, is_wireframe=True, opacity=0.3)
def 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 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 mesh_hook(mesh, mode): """ Load and refine a mesh here. """ if mode == 'read': mesh = Mesh.from_file(base_mesh) domain = FEDomain(mesh.name, mesh) for ii in range(3): output('refine %d...' % ii) domain = domain.refine() output('... %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) domain.mesh.name = '2_4_2_refined' return domain.mesh elif mode == 'write': pass
def mesh_hook(mesh, mode): """ Load and refine a mesh here. """ if mode == 'read': mesh = Mesh.from_file(base_mesh) domain = FEDomain(mesh.name, mesh) for ii in range(3): output('refine %d...' % ii) domain = domain.refine() output('... %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) domain.mesh.name = '2_4_2_refined' return domain.mesh elif mode == 'write': pass
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 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 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) qp_coors, qp_weights = integral.get_qp('3_8') custom_integral = Integral('i', coors=qp_coors, weights=qp_weights, order='custom') test = Test(domains=domains, integral=integral, custom_integral=custom_integral, conf=conf, options=options) return test
def linear_projection(pb, cval): from sfepy.discrete import (FieldVariable, Material, Integral, Equation, Equations, Problem) from sfepy.discrete.fem import Mesh, FEDomain, Field from sfepy.terms import Term from sfepy.solvers.ls import ScipyDirect from sfepy.solvers.nls import Newton from sfepy.base.base import IndexedStruct mesh = Mesh.from_file(pb.conf.filename_mesh) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('scf', nm.float64, 'scalar', omega, approx_order=1) g = FieldVariable('g', 'unknown', field) f = FieldVariable('f', 'test', field, primary_var_name='g') integral = Integral('i', order=2) m = Material('m', function=set_grad) t1 = Term.new('dw_volume_dot(f, g)', integral, omega, f=f, g=g) t2 = Term.new('dw_volume_lvf(m.cs, f)', integral, omega, m=m, f=f) eq = Equation('balance', t1 - t2) eqs = Equations([eq]) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({'eps_a': 1e-15}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs) pb.set_solver(nls) out = nm.empty((g.n_dof, cval.shape[2]), dtype=nm.float64) for ii in range(cval.shape[2]): pb.data = nm.ascontiguousarray(cval[:, :, ii, :]) pb.time_update() state = pb.solve() out[:, ii] = state.get_parts()['g'] return out
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 main(): parser = OptionParser(usage=usage, version='%prog') options, args = parser.parse_args() if len(args) == 1: filename = args[0] else: parser.print_help(), return mesh = Mesh.from_file(filename) output('Mesh:') output(' dimension: %d, vertices: %d, elements: %d' % (mesh.dim, mesh.n_nod, mesh.n_el)) domain = FEDomain('domain', mesh) output(domain.cmesh) domain.cmesh.cprint(1) dim = domain.cmesh.dim entities_opts = [ { 'color': 'k', 'label_global': 12, 'label_local': 8 }, { 'color': 'b', 'label_global': 12, 'label_local': 8 }, { 'color': 'g', 'label_global': 12, 'label_local': 8 }, { 'color': 'r', 'label_global': 12 }, ] if dim == 2: entities_opts.pop(2) pc.plot_cmesh(None, domain.cmesh, wireframe_opts={'color': 'k'}, entities_opts=entities_opts) plt.show()
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 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 from_conf( conf, options ): from sfepy import data_dir from sfepy.discrete.fem import Mesh, FEDomain from sfepy.discrete import Functions mesh = Mesh.from_file(data_dir + '/meshes/various_formats/abaqus_tet.inp') mesh.nodal_bcs['set0'] = [0, 7] domain = FEDomain('test domain', mesh) conf_functions = { 'get_vertices' : (get_vertices,), 'get_cells' : (get_cells,), } functions = Functions.from_conf(transform_functions(conf_functions)) test = Test(conf=conf, options=options, domain=domain, functions=functions) return test
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 main(): parser = OptionParser(usage=usage, version='%prog') options, args = parser.parse_args() if len(args) == 1: filename = args[0] else: parser.print_help(), return mesh = Mesh.from_file(filename) output('Mesh:') output(' dimension: %d, vertices: %d, elements: %d' % (mesh.dim, mesh.n_nod, mesh.n_el)) domain = FEDomain('domain', mesh) output(domain.cmesh) domain.cmesh.cprint(1) dim = domain.cmesh.dim ax = pc.plot_wireframe(None, domain.cmesh) ax = pc.plot_entities(ax, domain.cmesh, 0, 'k') ax = pc.label_global_entities(ax, domain.cmesh, 0, 'k', 12) ax = pc.label_local_entities(ax, domain.cmesh, 0, 'k', 8) ax = pc.plot_entities(ax, domain.cmesh, 1, 'b') ax = pc.label_global_entities(ax, domain.cmesh, 1, 'b', 12) ax = pc.label_local_entities(ax, domain.cmesh, 1, 'b', 8) if dim == 3: ax = pc.plot_entities(ax, domain.cmesh, 2, 'g') ax = pc.label_global_entities(ax, domain.cmesh, 2, 'g', 12) ax = pc.label_local_entities(ax, domain.cmesh, 2, 'g', 8) ax = pc.plot_entities(ax, domain.cmesh, dim, 'r') ax = pc.label_global_entities(ax, domain.cmesh, dim, 'r', 12) pc.plt.show()
def test_laplace_shifted_periodic(self): import numpy as nm from sfepy.mesh.mesh_generators import gen_block_mesh from sfepy.discrete.fem import FEDomain from examples.diffusion.laplace_shifted_periodic import run dims = [2.0, 1.0] shape = [21, 11] centre = [0.0, 0.0] mesh = gen_block_mesh(dims, shape, centre, name='block-fem') fe_domain = FEDomain('domain', mesh) pb, state = run(fe_domain, 3) gamma3 = pb.domain.regions['Gamma3'] gamma4 = pb.domain.regions['Gamma4'] field = pb.fields['fu'] # Check that the shift equals to one. i3 = field.get_dofs_in_region(gamma3, merge=True) i4 = field.get_dofs_in_region(gamma4, merge=True) i_corners = nm.array([0, shape[0] - 1]) ii = nm.setdiff1d(nm.arange(len(i3)), i_corners) vals = state() shift = vals[i3] - vals[i4] ok = (shift[i_corners] == 0.0).all() ok = ok and nm.allclose(shift[ii], 1.0, rtol=0.0, atol=1e-14) if not ok: self.report('wrong shift:', shift) return ok
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(): 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()
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: mesh = triangulate(mesh, verbose=True) if options.merge: desc = mesh.descs[0] coor, ngroups, conns = fix_double_nodes(mesh.coors, mesh.cmesh.vertex_groups, mesh.get_conn(desc)) 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 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
def main(): parser = OptionParser(usage=usage) parser.add_option('-s', '--scale', metavar='scale', action='store', dest='scale', default=None, help=help['scale']) parser.add_option('-c', '--center', metavar='center', action='store', dest='center', default=None, help=help['center']) parser.add_option('-r', '--refine', metavar='level', action='store', type=int, dest='refine', default=0, help=help['refine']) parser.add_option('-f', '--format', metavar='format', action='store', type='string', dest='format', default=None, help=help['format']) parser.add_option('-l', '--list', action='store_true', dest='list', help=help['list']) (options, args) = 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) if len(args) != 2: parser.print_help() sys.exit(1) scale = _parse_val_or_vec(options.scale, 'scale', parser) center = _parse_val_or_vec(options.center, 'center', parser) filename_in, filename_out = args mesh = Mesh.from_file(filename_in) 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 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(): 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_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 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 main(): parser = ArgumentParser(description=__doc__.rstrip(), formatter_class=RawDescriptionHelpFormatter) parser.add_argument('output_dir', help=helps['output_dir']) parser.add_argument('--dims', metavar='dims', action='store', dest='dims', default='1.0,1.0,1.0', help=helps['dims']) parser.add_argument('--shape', metavar='shape', action='store', dest='shape', default='7,7,7', help=helps['shape']) parser.add_argument('--centre', metavar='centre', action='store', dest='centre', default='0.0,0.0,0.0', help=helps['centre']) parser.add_argument('-3', '--3d', action='store_true', dest='is_3d', default=False, help=helps['3d']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) options = parser.parse_args() dim = 3 if options.is_3d else 2 dims = nm.array(eval(options.dims), dtype=nm.float64)[:dim] shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim] centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim] output('dimensions:', dims) output('shape: ', shape) output('centre: ', centre) mesh0 = gen_block_mesh(dims, shape, centre, name='block-fem', verbose=True) domain0 = FEDomain('d', mesh0) bbox = domain0.get_mesh_bounding_box() min_x, max_x = bbox[:, 0] eps = 1e-8 * (max_x - min_x) cnt = (shape[0] - 1) // 2 g0 = 0.5 * dims[0] grading = nm.array([g0 / 2**ii for ii in range(cnt)]) + eps + centre[0] - g0 domain, subs = refine_towards_facet(domain0, grading, '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, 1, omega, approx_order=options.order) if subs is not None: field.substitute_dofs(subs) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') integral = Integral('i', order=2*options.order) t1 = Term.new('dw_laplace(v, u)', integral, omega, v=v, u=u) eq = Equation('eq', t1) eqs = Equations([eq]) def u_fun(ts, coors, bc=None, problem=None): """ Define a displacement depending on the y coordinate. """ if coors.shape[1] == 2: min_y, max_y = bbox[:, 1] y = (coors[:, 1] - min_y) / (max_y - min_y) val = (max_y - min_y) * nm.cos(3 * nm.pi * y) else: min_y, max_y = bbox[:, 1] min_z, max_z = bbox[:, 2] y = (coors[:, 1] - min_y) / (max_y - min_y) z = (coors[:, 2] - min_z) / (max_z - min_z) val = ((max_y - min_y) * (max_z - min_z) * nm.cos(3 * nm.pi * y) * (1.0 + 3.0 * (z - 0.5)**2)) return val bc_fun = Function('u_fun', u_fun) fix1 = EssentialBC('shift_u', gamma1, {'u.0' : bc_fun}) fix2 = EssentialBC('fix2', gamma2, {'u.all' : 0.0}) ls = ScipyDirect({}) nls = Newton({}, lin_solver=ls) pb = Problem('heat', equations=eqs, nls=nls, ls=ls) pb.time_update(ebcs=Conditions([fix1, fix2])) state = pb.solve() if subs is not None: field.restore_dofs() filename = os.path.join(options.output_dir, 'hanging.vtk') ensure_path(filename) pb.save_state(filename, state) if options.order > 1: pb.save_state(filename, state, linearization=Struct(kind='adaptive', min_level=0, max_level=8, eps=1e-3))
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 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)