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 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_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 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_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 from_conf(conf, options): import sfepy from sfepy.discrete.fem import Mesh, Domain, Field mesh = Mesh.from_file('meshes/2d/rectangle_tri.mesh', prefix_dir=sfepy.data_dir) domain = Domain('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 nodal_stress(out, pb, state, extend=False, integrals=None): ''' Calculate stresses at nodal points. ''' # Point load. mat = pb.get_materials()['Load'] P = 2.0 * mat.get_data('special', 'val')[1] # Calculate nodal stress. pb.time_update() if integrals is None: integrals = pb.get_integrals() stress = pb.evaluate('ev_cauchy_stress.ivn.Omega(Asphalt.D, u)', mode='qp', integrals=integrals, copy_materials=False) sfield = Field.from_args('stress', nm.float64, (3,), pb.domain.regions['Omega']) svar = FieldVariable('sigma', 'parameter', sfield, primary_var_name='(set-to-None)') svar.set_from_qp(stress, integrals['ivn']) print('\n==================================================================') print('Given load = %.2f N' % -P) print('\nAnalytical solution') print('===================') print('Horizontal tensile stress = %.5e MPa/mm' % (-2.*P/(nm.pi*150.))) print('Vertical compressive stress = %.5e MPa/mm' % (-6.*P/(nm.pi*150.))) print('\nFEM solution') print('============') print('Horizontal tensile stress = %.5e MPa/mm' % (svar()[0])) print('Vertical compressive stress = %.5e MPa/mm' % (-svar()[1])) print('==================================================================') return out
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 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 nodal_stress(out, pb, state, extend=False, integrals=None): """ Calculate stresses at nodal points. """ # Point load. mat = pb.get_materials()["Load"] P = 2.0 * mat.get_data("special", "val")[1] # Calculate nodal stress. pb.time_update() if integrals is None: integrals = pb.get_integrals() stress = pb.evaluate("ev_cauchy_stress.ivn.Omega(Asphalt.D, u)", mode="qp", integrals=integrals) sfield = Field.from_args("stress", nm.float64, (3,), pb.domain.regions["Omega"]) svar = FieldVariable("sigma", "parameter", sfield, primary_var_name="(set-to-None)") svar.set_data_from_qp(stress, integrals["ivn"]) print "\n==================================================================" print "Given load = %.2f N" % -P print "\nAnalytical solution" print "===================" print "Horizontal tensile stress = %.5e MPa/mm" % (-2.0 * P / (nm.pi * 150.0)) print "Vertical compressive stress = %.5e MPa/mm" % (-6.0 * P / (nm.pi * 150.0)) print "\nFEM solution" print "============" print "Horizontal tensile stress = %.5e MPa/mm" % (svar()[0][0]) print "Vertical compressive stress = %.5e MPa/mm" % (-svar()[0][1]) print "==================================================================" return out
def verify_save_dof_maps(field, cell_tasks, dof_maps, id_map, options, verbose=False): vec = pl.verify_task_dof_maps(dof_maps, id_map, field, verbose=verbose) order = options.order mesh = field.domain.mesh sfield = Field.from_args('aux', nm.float64, 'scalar', field.region, approx_order=order) aux = FieldVariable('aux', 'parameter', sfield, primary_var_name='(set-to-None)') out = aux.create_output(vec, linearization=Struct(kind='adaptive', min_level=order-1, max_level=order-1, eps=1e-8)) filename = os.path.join(options.output_dir, 'para-domains-dofs.h5') if field.is_higher_order(): out['aux'].mesh.write(filename, out=out) else: mesh.write(filename, out=out) out = Struct(name='cells', mode='cell', data=cell_tasks[:, None, None, None]) filename = os.path.join(options.output_dir, 'para-domains-cells.h5') mesh.write(filename, out={'cells' : out})
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 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 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 run(domain, order): omega = domain.create_region('Omega', 'all') bbox = domain.get_mesh_bounding_box() min_x, max_x = bbox[:, 0] min_y, max_y = bbox[:, 1] eps = 1e-8 * (max_x - min_x) 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') gamma3 = domain.create_region('Gamma3', 'vertices in y < %.10f' % (min_y + eps), 'facet') gamma4 = domain.create_region('Gamma4', 'vertices in y > %.10f' % (max_y - eps), 'facet') field = Field.from_args('fu', nm.float64, 1, omega, approx_order=order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') integral = Integral('i', order=2*order) t1 = Term.new('dw_laplace(v, u)', integral, omega, v=v, u=u) eq = Equation('eq', t1) eqs = Equations([eq]) fix1 = EssentialBC('fix1', gamma1, {'u.0' : 0.4}) fix2 = EssentialBC('fix2', gamma2, {'u.0' : 0.0}) def get_shift(ts, coors, region): return nm.ones_like(coors[:, 0]) dof_map_fun = Function('dof_map_fun', per.match_x_line) shift_fun = Function('shift_fun', get_shift) sper = LinearCombinationBC('sper', [gamma3, gamma4], {'u.0' : 'u.0'}, dof_map_fun, 'shifted_periodic', arguments=(shift_fun,)) ls = ScipyDirect({}) pb = Problem('laplace', equations=eqs, auto_solvers=None) pb.time_update(ebcs=Conditions([fix1, fix2]), lcbcs=Conditions([sper])) ev = pb.get_evaluator() nls = Newton({}, lin_solver=ls, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix) pb.set_solver(nls) state = pb.solve() return pb, state
def run(domain, order): omega = domain.create_region('Omega', 'all') bbox = domain.get_mesh_bounding_box() min_x, max_x = bbox[:, 0] min_y, max_y = bbox[:, 1] eps = 1e-8 * (max_x - min_x) 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') gamma3 = domain.create_region('Gamma3', 'vertices in y < %.10f' % (min_y + eps), 'facet') gamma4 = domain.create_region('Gamma4', 'vertices in y > %.10f' % (max_y - eps), 'facet') field = Field.from_args('fu', nm.float64, 1, omega, approx_order=order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') integral = Integral('i', order=2 * order) t1 = Term.new('dw_laplace(v, u)', integral, omega, v=v, u=u) eq = Equation('eq', t1) eqs = Equations([eq]) fix1 = EssentialBC('fix1', gamma1, {'u.0': 0.4}) fix2 = EssentialBC('fix2', gamma2, {'u.0': 0.0}) def get_shift(ts, coors, region): return nm.ones_like(coors[:, 0]) dof_map_fun = Function('dof_map_fun', per.match_x_line) shift_fun = Function('shift_fun', get_shift) sper = LinearCombinationBC('sper', [gamma3, gamma4], {'u.0': 'u.0'}, dof_map_fun, 'shifted_periodic', arguments=(shift_fun, )) ls = ScipyDirect({}) nls = Newton({}, lin_solver=ls) pb = Problem('laplace', equations=eqs) pb.set_bcs(ebcs=Conditions([fix1, fix2]), lcbcs=Conditions([sper])) pb.set_solver(nls) state = pb.solve() return pb, state
def test_project_tensors(self): from sfepy.discrete import FieldVariable from sfepy.discrete.projections import project_by_component ok = True u = FieldVariable('u', 'parameter', self.field, primary_var_name='(set-to-None)') u.set_constant(1.0) component = FieldVariable('component', 'parameter', self.field, primary_var_name='(set-to-None)') nls_options = {'eps_a': 1e-16, 'i_max': 1} u_qp = u.evaluate() u2 = FieldVariable('u2', 'parameter', self.field, primary_var_name='(set-to-None)') project_by_component(u2, u_qp, component, self.field.approx_order, nls_options=nls_options) _ok = self.compare_vectors(u(), u2()) ok = ok and _ok gu_qp = u.evaluate(mode='grad') gfield = Field.from_args('gu', nm.float64, 2, self.field.region, approx_order=self.field.approx_order) gu = FieldVariable('gu', 'parameter', gfield, primary_var_name='(set-to-None)') project_by_component(gu, gu_qp, component, gfield.approx_order, nls_options=nls_options) _ok = self.compare_vectors(gu(), nm.zeros_like(gu())) ok = ok and _ok return ok
def solve_problem(shape, dims, young, poisson, force, transform=None): domain = make_domain(dims[:2], shape, transform=transform) omega = domain.regions['Omega'] gamma1 = domain.regions['Gamma1'] gamma2 = domain.regions['Gamma2'] field = Field.from_args('fu', nm.float64, 6, omega, approx_order=1, poly_space_base='shell10x') u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') thickness = dims[2] if transform is None: pload = [[0.0, 0.0, force / shape[1], 0.0, 0.0, 0.0]] * shape[1] elif transform == 'bend': pload = [[force / shape[1], 0.0, 0.0, 0.0, 0.0, 0.0]] * shape[1] elif transform == 'twist': pload = [[0.0, force / shape[1], 0.0, 0.0, 0.0, 0.0]] * shape[1] m = Material('m', D=sh.create_elastic_tensor(young=young, poisson=poisson), values={'.drill' : 1e-7}) load = Material('load', values={'.val' : pload}) aux = Integral('i', order=3) qp_coors, qp_weights = aux.get_qp('3_8') qp_coors[:, 2] = thickness * (qp_coors[:, 2] - 0.5) qp_weights *= thickness integral = Integral('i', coors=qp_coors, weights=qp_weights, order='custom') t1 = Term.new('dw_shell10x(m.D, m.drill, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_point_load(load.val, v)', integral, gamma2, load=load, v=v) eq = Equation('balance', t1 - t2) eqs = Equations([eq]) fix_u = EssentialBC('fix_u', gamma1, {'u.all' : 0.0}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity with shell10x', equations=eqs) pb.set_bcs(ebcs=Conditions([fix_u])) pb.set_solver(nls) state = pb.solve() return pb, state, u, gamma2
def main(): from sfepy import data_dir parser = OptionParser(usage=usage, version="%prog") parser.add_option("-s", "--show", action="store_true", dest="show", default=False, help=help["show"]) options, args = parser.parse_args() mesh = Mesh.from_file(data_dir + "/meshes/2d/rectangle_tri.mesh") domain = Domain("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", 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_iso(m.lam, m.mu, 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 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 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_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 solve_problem(shape, dims, young, poisson, force, transform=None): domain = make_domain(dims[:2], shape, transform=transform) omega = domain.regions['Omega'] gamma1 = domain.regions['Gamma1'] gamma2 = domain.regions['Gamma2'] field = Field.from_args('fu', nm.float64, 6, omega, approx_order=1, poly_space_base='shell10x') u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') thickness = dims[2] if transform is None: pload = [[0.0, 0.0, force / shape[1], 0.0, 0.0, 0.0]] * shape[1] elif transform == 'bend': pload = [[force / shape[1], 0.0, 0.0, 0.0, 0.0, 0.0]] * shape[1] elif transform == 'twist': pload = [[0.0, force / shape[1], 0.0, 0.0, 0.0, 0.0]] * shape[1] m = Material('m', D=sh.create_elastic_tensor(young=young, poisson=poisson), values={'.drill' : 1e-7}) load = Material('load', values={'.val' : pload}) aux = Integral('i', order=3) qp_coors, qp_weights = aux.get_qp('3_8') qp_coors[:, 2] = thickness * (qp_coors[:, 2] - 0.5) qp_weights *= thickness integral = Integral('i', coors=qp_coors, weights=qp_weights, order='custom') t1 = Term.new('dw_shell10x(m.D, m.drill, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_point_load(load.val, v)', integral, gamma2, load=load, v=v) eq = Equation('balance', t1 - t2) eqs = Equations([eq]) fix_u = EssentialBC('fix_u', gamma1, {'u.all' : 0.0}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity with shell10x', equations=eqs, nls=nls, ls=ls) pb.time_update(ebcs=Conditions([fix_u])) state = pb.solve() return pb, state, u, gamma2
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 run(domain, order): omega = domain.create_region("Omega", "all") bbox = domain.get_mesh_bounding_box() min_x, max_x = bbox[:, 0] min_y, max_y = bbox[:, 1] eps = 1e-8 * (max_x - min_x) 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") gamma3 = domain.create_region("Gamma3", "vertices in y < %.10f" % (min_y + eps), "facet") gamma4 = domain.create_region("Gamma4", "vertices in y > %.10f" % (max_y - eps), "facet") field = Field.from_args("fu", nm.float64, 1, omega, approx_order=order) u = FieldVariable("u", "unknown", field) v = FieldVariable("v", "test", field, primary_var_name="u") integral = Integral("i", order=2 * order) t1 = Term.new("dw_laplace(v, u)", integral, omega, v=v, u=u) eq = Equation("eq", t1) eqs = Equations([eq]) fix1 = EssentialBC("fix1", gamma1, {"u.0": 0.4}) fix2 = EssentialBC("fix2", gamma2, {"u.0": 0.0}) def get_shift(ts, coors, region): return nm.ones_like(coors[:, 0]) dof_map_fun = Function("dof_map_fun", per.match_x_line) shift_fun = Function("shift_fun", get_shift) sper = LinearCombinationBC( "sper", [gamma3, gamma4], {"u.0": "u.0"}, dof_map_fun, "shifted_periodic", arguments=(shift_fun,) ) ls = ScipyDirect({}) pb = Problem("laplace", equations=eqs, auto_solvers=None) pb.time_update(ebcs=Conditions([fix1, fix2]), lcbcs=Conditions([sper])) ev = pb.get_evaluator() nls = Newton({}, lin_solver=ls, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix) pb.set_solver(nls) state = pb.solve() return pb, state
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_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 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 verify_save_dof_maps(field, cell_tasks, dof_maps, id_map, options, verbose=False): vec = pl.verify_task_dof_maps(dof_maps, id_map, field, verbose=verbose) order = options.order mesh = field.domain.mesh sfield = Field.from_args('aux', nm.float64, 'scalar', field.region, approx_order=order) aux = FieldVariable('aux', 'parameter', sfield, primary_var_name='(set-to-None)') out = aux.create_output(vec, linearization=Struct(kind='adaptive', min_level=order - 1, max_level=order - 1, eps=1e-8)) filename = os.path.join(options.output_dir, 'para-domains-dofs.h5') if field.is_higher_order(): out['aux'].mesh.write(filename, out=out) else: mesh.write(filename, out=out) out = Struct(name='cells', mode='cell', data=cell_tasks[:, None, None, None]) filename = os.path.join(options.output_dir, 'para-domains-cells.h5') mesh.write(filename, out={'cells': out})
def test_project_tensors(self): from sfepy.discrete import FieldVariable from sfepy.discrete.projections import project_by_component ok = True u = FieldVariable('u', 'parameter', self.field, primary_var_name='(set-to-None)') u.set_constant(1.0) component = FieldVariable('component', 'parameter', self.field, primary_var_name='(set-to-None)') nls_options = {'eps_a' : 1e-16, 'i_max' : 1} u_qp = u.evaluate() u2 = FieldVariable('u2', 'parameter', self.field, primary_var_name='(set-to-None)') project_by_component(u2, u_qp, component, self.field.approx_order, nls_options=nls_options) _ok = self.compare_vectors(u(), u2()) ok = ok and _ok gu_qp = u.evaluate(mode='grad') gfield = Field.from_args('gu', nm.float64, 2, self.field.region, approx_order=self.field.approx_order) gu = FieldVariable('gu', 'parameter', gfield, primary_var_name='(set-to-None)') project_by_component(gu, gu_qp, component, gfield.approx_order, nls_options=nls_options) _ok = self.compare_vectors(gu(), nm.zeros_like(gu())) ok = ok and _ok return ok
def get_fields(shape, delta_x): """Get the fields for the displacement and test function Args: shape: the shape of the domain delta_x: the mesh spacing Returns: tuple of field variables """ return pipe( np.array(shape), lambda x: gen_block_mesh( x * delta_x, x + 1, np.zeros_like(shape), verbose=False ), lambda x: Domain("domain", x), lambda x: x.create_region("region_all", "all"), lambda x: Field.from_args("fu", np.float64, "vector", x, approx_order=2), lambda x: ( FieldVariable("u", "unknown", x), FieldVariable("v", "test", x, primary_var_name="u"), ), )
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, 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(): 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 xrange(options.refine): output('refine %d...' % ii) domain = domain.refine() output('... %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) omega = domain.create_region('Omega', 'all') left = domain.create_region('Left', 'vertices in x < 0.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_u = options.order_u order_p = options.order_p rank, size = comm.Get_rank(), comm.Get_size() output('rank', rank, 'of', size) stats = Struct() timer = Timer('solve_timer') timer.start() mesh = Mesh.from_file(mesh_filename) stats.t_read_mesh = timer.stop() timer.start() if rank == 0: cell_tasks = pl.partition_mesh(mesh, size, use_metis=options.metis, verbose=True) else: cell_tasks = None stats.t_partition_mesh = timer.stop() output('creating global domain and fields...') timer.start() 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] stats.t_create_global_fields = timer.stop() output('...done in', timer.dt) output('distributing fields...') timer.start() 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) stats.t_distribute_fields_dofs = timer.stop() output('...done in', timer.dt) output('creating local problem...') timer.start() 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() stats.t_create_local_problem = timer.stop() output('...done in', timer.dt) output('allocating global system...') timer.start() 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) stats.t_allocate_global_system = timer.stop() output('...done in', timer.dt) output('creating solver...') timer.start() 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) stats.t_create_solver = timer.stop() output('...done in', timer.dt) output('solving...') timer.start() 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[...] stats.t_solve = timer.stop() output('...done in', timer.dt) output('saving solution...') timer.start() 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) stats.t_save_solution = timer.stop() output('...done in', timer.dt) stats.t_total = timer.total stats.n_dof = sizes[1] stats.n_dof_local = sizes[0] stats.n_cell = omega.shape.n_cell stats.n_cell_local = omega_gi.shape.n_cell return stats
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 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 _eval_basis_transform(self, subs): """ """ from sfepy.discrete import Integral from sfepy.discrete.fem import Mesh, FEDomain, Field transform = nm.tile(nm.eye(self.econn.shape[1]), (self.econn.shape[0], 1, 1)) if subs is None: return transform gel = self.gel ao = self.approx_order conn = [gel.conn] mesh = Mesh.from_data('a', gel.coors, None, [conn], [nm.array([0])], [gel.name]) cdomain = FEDomain('d', mesh) comega = cdomain.create_region('Omega', 'all') rcfield = Field.from_args('rc', self.dtype, 1, comega, approx_order=ao) fdomain = cdomain.refine() fomega = fdomain.create_region('Omega', 'all') rffield = Field.from_args('rf', self.dtype, 1, fomega, approx_order=ao) def assign_transform(transform, bf, subs, ef): if not len(subs): return n_sub = (subs.shape[1] - 2) // 2 for ii, sub in enumerate(subs): for ij in range(n_sub): ik = 2 * (ij + 1) fface = ef[sub[ik + 1]] mtx = transform[sub[ik]] ix, iy = nm.meshgrid(fface, fface) cbf = bf[iy, 0, ix] mtx[ix, iy] = cbf fcoors = rffield.get_coor() coors = fcoors[rffield.econn[0]] integral = Integral('i', coors=coors, weights=nm.ones_like(coors[:, 0])) rcfield.clear_qp_base() bf = rcfield.get_base('v', False, integral) if gel.name == '2_4': fsubs = subs esubs = None assign_transform(transform, bf, fsubs, rffield.efaces) else: fsubs = subs[0] esubs = subs[1] assign_transform(transform, bf, fsubs, rffield.efaces) if esubs is not None: assign_transform(transform, bf, esubs, rffield.eedges) assert_((nm.abs(transform.sum(1) - 1.0) < 1e-15).all()) return transform
def make_term_args(arg_shapes, arg_kinds, arg_types, ats_mode, domain, material_value=None, poly_space_base=None): from sfepy.base.base import basestr from sfepy.discrete import FieldVariable, Material, Variables, Materials from sfepy.discrete.fem import Field from sfepy.solvers.ts import TimeStepper from sfepy.mechanics.tensors import dim2sym omega = domain.regions['Omega'] dim = domain.shape.dim sym = dim2sym(dim) def _parse_scalar_shape(sh): if isinstance(sh, basestr): if sh == 'D': return dim elif sh == 'S': return sym elif sh == 'N': # General number ;) return 1 else: return int(sh) else: return sh def _parse_tuple_shape(sh): if isinstance(sh, basestr): return [_parse_scalar_shape(ii.strip()) for ii in sh.split(',')] else: return (int(sh), ) args = {} str_args = [] materials = [] variables = [] for ii, arg_kind in enumerate(arg_kinds): if arg_kind != 'ts': if ats_mode is not None: extended_ats = arg_types[ii] + ('/%s' % ats_mode) else: extended_ats = arg_types[ii] try: sh = arg_shapes[arg_types[ii]] except KeyError: sh = arg_shapes[extended_ats] if arg_kind.endswith('variable'): shape = _parse_scalar_shape(sh[0] if isinstance(sh, tuple) else sh) field = Field.from_args('f%d' % ii, nm.float64, shape, omega, approx_order=1, poly_space_base=poly_space_base) if arg_kind == 'virtual_variable': if sh[1] is not None: istate = arg_types.index(sh[1]) else: # Only virtual variable in arguments. istate = -1 # -> Make fake variable. var = FieldVariable('u-1', 'unknown', field) var.set_constant(0.0) variables.append(var) var = FieldVariable('v', 'test', field, primary_var_name='u%d' % istate) elif arg_kind == 'state_variable': var = FieldVariable('u%d' % ii, 'unknown', field) var.set_constant(0.0) elif arg_kind == 'parameter_variable': var = FieldVariable('p%d' % ii, 'parameter', field, primary_var_name='(set-to-None)') var.set_constant(0.0) variables.append(var) str_args.append(var.name) args[var.name] = var elif arg_kind.endswith('material'): if sh is None: # Switched-off opt_material. continue prefix = '' if isinstance(sh, basestr): aux = sh.split(':') if len(aux) == 2: prefix, sh = aux if material_value is None: material_value = 1.0 shape = _parse_tuple_shape(sh) if (len(shape) > 1) or (shape[0] > 1): if ((len(shape) == 2) and (shape[0] == shape[1]) and (material_value != 0.0)): # Identity matrix. val = nm.eye(shape[0], dtype=nm.float64) else: # Array. val = nm.empty(shape, dtype=nm.float64) val.fill(material_value) values = {'%sc%d' % (prefix, ii): val} elif (len(shape) == 1) and (shape[0] == 1): # Single scalar as a special value. values = {'.c%d' % ii: material_value} else: raise ValueError('wrong material shape! (%s)' % shape) mat = Material('m%d' % ii, values=values) materials.append(mat) str_args.append(mat.name + '.' + 'c%d' % ii) args[mat.name] = mat elif arg_kind == 'ts': ts = TimeStepper(0.0, 1.0, 1.0, 5) str_args.append('ts') args['ts'] = ts else: str_args.append('user%d' % ii) args[str_args[-1]] = None materials = Materials(materials) variables = Variables(variables) return args, str_args, materials, variables
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 main(): parser = ArgumentParser(description=__doc__) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('-b', '--basis', metavar='name', action='store', dest='basis', default='lagrange', help=help['basis']) parser.add_argument('-n', '--max-order', metavar='order', type=int, action='store', dest='max_order', default=10, help=help['max_order']) parser.add_argument('-m', '--matrix', metavar='type', action='store', dest='matrix_type', default='laplace', help=help['matrix_type']) parser.add_argument('-g', '--geometry', metavar='name', action='store', dest='geometry', default='2_4', help=help['geometry']) options = 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] 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 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__, 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 = 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 output('creating global domain and field...') tt = time.clock() domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('fu', nm.float64, 1, omega, approx_order=order) output('...done in', time.clock() - tt) 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() 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) 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') 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(): from sfepy import data_dir parser = OptionParser(usage=usage, version='%prog') parser.add_option('-s', '--show', action="store_true", dest='show', default=False, help=help['show']) options, args = parser.parse_args() mesh = Mesh.from_file(data_dir + '/meshes/2d/rectangle_tri.mesh') domain = FEDomain('domain', mesh) min_x, max_x = domain.get_mesh_bounding_box()[:, 0] eps = 1e-8 * (max_x - min_x) omega = domain.create_region('Omega', 'all') gamma1 = domain.create_region('Gamma1', 'vertices in x < %.10f' % (min_x + eps), 'facet') gamma2 = domain.create_region('Gamma2', 'vertices in x > %.10f' % (max_x - eps), 'facet') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=2) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') m = Material('m', D=stiffness_from_lame(dim=2, lam=1.0, mu=1.0)) f = Material('f', val=[[0.02], [0.01]]) integral = Integral('i', order=3) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_lvf(f.val, v)', integral, omega, f=f, v=v) eq = Equation('balance', t1 + t2) eqs = Equations([eq]) fix_u = EssentialBC('fix_u', gamma1, {'u.all': 0.0}) bc_fun = Function('shift_u_fun', shift_u_fun, extra_args={'shift': 0.01}) shift_u = EssentialBC('shift_u', gamma2, {'u.0': bc_fun}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls) pb.save_regions_as_groups('regions') pb.time_update(ebcs=Conditions([fix_u, shift_u])) vec = pb.solve() print(nls_status) pb.save_state('linear_elasticity.vtk', vec) if options.show: view = Viewer('linear_elasticity.vtk') view(vector_mode='warp_norm', rel_scaling=2, is_scalar_bar=True, is_wireframe=True)
def 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 make_term_args(arg_shapes, arg_kinds, arg_types, ats_mode, domain, material_value=None, poly_space_base=None): from sfepy.base.base import basestr from sfepy.discrete import FieldVariable, Material, Variables, Materials from sfepy.discrete.fem import Field from sfepy.solvers.ts import TimeStepper from sfepy.mechanics.tensors import dim2sym omega = domain.regions['Omega'] dim = domain.shape.dim sym = dim2sym(dim) def _parse_scalar_shape(sh): if isinstance(sh, basestr): if sh == 'D': return dim elif sh == 'D2': return dim**2 elif sh == 'S': return sym elif sh == 'N': # General number ;) return 1 else: return int(sh) else: return sh def _parse_tuple_shape(sh): if isinstance(sh, basestr): return [_parse_scalar_shape(ii.strip()) for ii in sh.split(',')] else: return (int(sh),) args = {} str_args = [] materials = [] variables = [] for ii, arg_kind in enumerate(arg_kinds): if arg_kind != 'ts': if ats_mode is not None: extended_ats = arg_types[ii] + ('/%s' % ats_mode) else: extended_ats = arg_types[ii] try: sh = arg_shapes[arg_types[ii]] except KeyError: sh = arg_shapes[extended_ats] if arg_kind.endswith('variable'): shape = _parse_scalar_shape(sh[0] if isinstance(sh, tuple) else sh) field = Field.from_args('f%d' % ii, nm.float64, shape, omega, approx_order=1, poly_space_base=poly_space_base) if arg_kind == 'virtual_variable': if sh[1] is not None: istate = arg_types.index(sh[1]) else: # Only virtual variable in arguments. istate = -1 # -> Make fake variable. var = FieldVariable('u-1', 'unknown', field) var.set_constant(0.0) variables.append(var) var = FieldVariable('v', 'test', field, primary_var_name='u%d' % istate) elif arg_kind == 'state_variable': var = FieldVariable('u%d' % ii, 'unknown', field) var.set_constant(0.0) elif arg_kind == 'parameter_variable': var = FieldVariable('p%d' % ii, 'parameter', field, primary_var_name='(set-to-None)') var.set_constant(0.0) variables.append(var) str_args.append(var.name) args[var.name] = var elif arg_kind.endswith('material'): if sh is None: # Switched-off opt_material. continue prefix = '' if isinstance(sh, basestr): aux = sh.split(':') if len(aux) == 2: prefix, sh = aux if material_value is None: material_value = 1.0 shape = _parse_tuple_shape(sh) if (len(shape) > 1) or (shape[0] > 1): if ((len(shape) == 2) and (shape[0] == shape[1]) and (material_value != 0.0)): # Identity matrix. val = nm.eye(shape[0], dtype=nm.float64) else: # Array. val = nm.empty(shape, dtype=nm.float64) val.fill(material_value) values = {'%sc%d' % (prefix, ii) : val} elif (len(shape) == 1) and (shape[0] == 1): # Single scalar as a special value. values = {'.c%d' % ii : material_value} else: raise ValueError('wrong material shape! (%s)' % shape) mat = Material('m%d' % ii, values=values) materials.append(mat) str_args.append(mat.name + '.' + 'c%d' % ii) args[mat.name] = mat elif arg_kind == 'ts': ts = TimeStepper(0.0, 1.0, 1.0, 5) str_args.append('ts') args['ts'] = ts else: str_args.append('user%d' % ii) args[str_args[-1]] = None materials = Materials(materials) variables = Variables(variables) return args, str_args, materials, variables
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