def test_partition_of_unity(self): from sfepy.linalg import combine from sfepy.discrete import Integral, PolySpace ok = True orders = {'2_3' : 5, '2_4' : 5, '3_4' : 5, '3_8' : 5} bases = ( [ii for ii in combine([['2_4', '3_8'], ['lagrange', 'serendipity', 'bernstein']] )] + [ii for ii in combine([['2_3', '3_4'], ['lagrange', 'bernstein']])] ) for geom, poly_space_base in bases: max_order = orders[geom] for order in range(max_order + 1): if (poly_space_base == 'serendipity') and not (0 < order < 4): continue self.report('geometry: %s, base: %s, order: %d' % (geom, poly_space_base, order)) integral = Integral('i', order=2 * order) coors, _ = integral.get_qp(geom) ps = PolySpace.any_from_args('ps', self.gels[geom], order, base=poly_space_base) vals = ps.eval_base(coors) _ok = nm.allclose(vals.sum(axis=-1), 1, atol=1e-14, rtol=0.0) self.report('partition of unity:', _ok) ok = ok and _ok return ok
def get_terms(u_field, v_field, calc_stiffness, calc_prestress): """Get the terms for the equation Args: u_field: the displacement field v_field: the test function field calc_stiffness: a function to calculate the stiffness tensor calc_prestress: a function to calculate the prestress tensor Returns: a tuple of terms for the equation """ return ( Term.new( "dw_lin_elastic(m.D, v, u)", Integral("i", order=4), v_field.field.region, m=get_material(calc_stiffness, calc_prestress), v=v_field, u=u_field, ), Term.new( "dw_lin_prestress(m.stress, v)", Integral("i", order=4), v_field.field.region, m=get_material(calc_stiffness, calc_prestress), v=v_field, ), )
def from_conf(conf, options): from sfepy.discrete import Integral from sfepy.discrete.fem import Mesh, FEDomain domains = [] for filename in filename_meshes: mesh = Mesh.from_file(filename) domain = FEDomain('domain_%s' % mesh.name.replace(data_dir, ''), mesh) domain.create_region('Omega', 'all') domain.create_region('Gamma', 'vertices of surface', 'facet') domains.append(domain) integral = Integral('i', order=3) qp_coors, qp_weights = integral.get_qp('3_8') custom_integral = Integral('i', coors=qp_coors, weights=qp_weights, order='custom') test = Test(domains=domains, integral=integral, custom_integral=custom_integral, conf=conf, options=options) return test
def 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 plot_1D_snr(conf, pb, ana_qp, num_qp, io, order, orders, ir, sol_fig, axs): """ Plot 1D solutions and errors :param conf: :param io: index of order :param ir: index of refirement :param ana_qp: :param num_qp: :param order: :param orders: :param pb: :param sol_fig: :param axs: :return: """ idiff = Integral('idiff', 20) sol_fig.suptitle("Numerical and exact solutions" + build_attrs_string(conf, remove_dots=False, sep=", ")) n_cells = pb.domain.shape.n_el qps = pb.fields["f"].mapping.get_physical_qps(idiff.get_qp("1_2")[0]) fqps = qps.flatten() coors = pb.domain.mesh.coors u = pb.fields["f"].unravel_sol(pb.sol.vec) uu, xx = reconstruct_legendre_dofs(coors, None, u.swapaxes(0, 1)[:, :, None]) ax = axs[io][ir] xs = nm.linspace(conf.mstart, conf.mend, 500)[:, None] ax.set_title("o: {}, h: {}".format(order, n_cells)) ax.plot(xs, conf.analytic_sol(xs, t=nm.array(1)), label="exact", color="grey") ax.plot(xx[:, 0], uu[:, 0, 0], alpha=.5, label="num-lin") ax.plot(fqps, ana_qp.flatten(), "--", color="grey", label="exact-qp") ax.plot(fqps, num_qp.flatten(), label="num-qp") ax2 = ax.twinx() ax2.plot(fqps, nm.abs(num_qp.flatten() - ana_qp.flatten()), color="red", label="error-qp") if io < len(orders) - 1: ax.set_xticks([]) else: if ir == 0: # put only one legend lines, labels = ax.get_legend_handles_labels() lines2, labels2 = ax2.get_legend_handles_labels() sol_fig.legend(lines + lines2, labels + labels2, loc='center right')
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_normals(self): """ Check orientations of surface normals on the reference elements. """ import sfepy from sfepy.discrete import Integral from sfepy.discrete.fem import Mesh, FEDomain from sfepy.discrete.fem.poly_spaces import PolySpace from sfepy.discrete.fem.mappings import SurfaceMapping from sfepy.linalg import normalize_vectors ok = True for geom in ['2_3', '2_4', '3_4', '3_8']: mesh = Mesh.from_file('meshes/elements/%s_1.mesh' % geom, prefix_dir=sfepy.data_dir) domain = FEDomain('domain', mesh) surface = domain.create_region('Surface', 'vertices of surface', 'facet') domain.create_surface_group(surface) sd = domain.surface_groups[surface.name] coors = domain.get_mesh_coors() gel = domain.geom_els[geom].surface_facet ps = PolySpace.any_from_args('aux', gel, 1) mapping = SurfaceMapping(coors, sd.get_connectivity(), ps) integral = Integral('i', order=1) vals, weights = integral.get_qp(gel.name) # Evaluate just in the first quadrature point... geo = mapping.get_mapping(vals[:1], weights[:1]) expected = expected_normals[geom].copy() normalize_vectors(expected) _ok = nm.allclose(expected, geo.normal[:, 0, :, 0], rtol=0.0, atol=1e-14) self.report('%s: %s' % (geom, _ok)) if not _ok: self.report('expected:') self.report(expected) self.report('actual:') self.report(geo.normal[:, 0, :, 0]) ok = ok and _ok return ok
def _get_qp(geometry, order): from sfepy.discrete import Integral from sfepy.discrete.fem.geometry_element import GeometryElement aux = Integral('aux', order=order) coors, weights = aux.get_qp(geometry) true_order = aux.qps[geometry].order output('geometry:', geometry, 'order:', order, 'num. points:', coors.shape[0], 'true_order:', true_order) output('min. weight:', weights.min()) output('max. weight:', weights.max()) return GeometryElement(geometry), coors, weights
def test_hessians(self): """ Test the second partial derivatives of basis functions using finite differences. """ from sfepy.linalg import combine from sfepy.discrete import Integral, PolySpace ok = True orders = {'2_3': 3, '2_4': 3, '3_4': 4, '3_8': 3} bases = ([ ii for ii in combine([['2_3', '2_4', '3_4', '3_8'], ['lagrange']]) ]) for geom, poly_space_base in bases: self.report('geometry: %s, base: %s' % (geom, poly_space_base)) order = orders[geom] integral = Integral('i', order=order) coors, _ = integral.get_qp(geom) ps = PolySpace.any_from_args('ps', self.gels[geom], order, base=poly_space_base) dim = coors.shape[1] h1 = nm.zeros((coors.shape[0], dim, dim, ps.n_nod), nm.float64) eps = 1e-8 for ir in range(dim): cc = coors.copy() cc[:, ir] -= eps aux0 = ps.eval_base(cc, diff=1) cc[:, ir] += 2 * eps aux1 = ps.eval_base(cc, diff=1) h1[:, :, ir, :] = 0.5 * (aux1 - aux0) / eps h2 = ps.eval_base(coors, diff=2) _ok = nm.allclose(h1, h2, rtol=0, atol=50 * eps) self.report('hessians: error: %.2e ok: %s' % (nm.abs(h1 - h2).max(), _ok)) ok = ok and _ok return ok
def test_term_evaluation(self): from sfepy.discrete import Integral, FieldVariable from sfepy.terms.terms import Term integral = Integral('i', order=3) u = FieldVariable('u', 'parameter', self.field, primary_var_name='(set-to-None)') term = Term.new('d_volume(u)', integral, self.omega, u=u) term *= 10.0 term.setup() vol = term.evaluate() self.report('volume: %.8f == 2000.0' % vol) ok = nm.allclose(vol, 2000.0, rtol=1e-15, atol=0) ## vec = t1.evaluate() # Returns vector. ## vec = t1.evaluate(u=u_vec) # Returns the same vector. ## mtx = t1.evaluate(diff_var='u') # Returns matrix. ## val = t1.evaluate(v=u_vec, u=u_vec) # Forbidden - virtual variable ## # cannot have value. return ok
def _get_bqp(geometry, order): from sfepy.discrete import Integral from sfepy.discrete.fem.geometry_element import GeometryElement from sfepy.discrete.fem import Mesh, FEDomain, Field gel = GeometryElement(geometry) mesh = Mesh.from_data('aux', gel.coors, None, [gel.conn[None, :]], [[0]], [geometry]) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') surf = domain.create_region('Surf', 'vertices of surface', 'facet') field = Field.from_args('f', nm.float64, shape=1, region=omega, approx_order=1) field.setup_surface_data(surf) integral = Integral('aux', order=order) field.create_bqp('Surf', integral) sd = field.surface_data['Surf'] qp = field.qp_coors[(integral.order, sd.bkey)] output('geometry:', geometry, 'order:', order, 'num. points:', qp.vals.shape[1], 'true_order:', integral.qps[gel.surface_facet_name].order) output('min. weight:', qp.weights.min()) output('max. weight:', qp.weights.max()) return (gel, qp.vals.reshape( (-1, mesh.dim)), nm.tile(qp.weights, qp.vals.shape[0]))
def test_term_arithmetics(self): from sfepy.discrete import FieldVariable, Integral from sfepy.terms.terms import Term integral = Integral('i', order=3) u = FieldVariable('u', 'parameter', self.field, primary_var_name='(set-to-None)') t1 = Term.new('d_volume(u)', integral, self.omega, u=u) t2 = Term.new('d_surface(u)', integral, self.gamma1, u=u) expr = 2.2j * (t1 * 5.5 - 3j * t2) * 0.25 ok = len(expr) == 2 if not ok: self.report('wrong expression length!') _ok = nm.allclose(expr[0].sign, 3.025j, rtol=1e-15, atol=0) if not _ok: self.report('wrong sign of the first term!') ok = ok and _ok _ok = nm.allclose(expr[1].sign, 1.65, rtol=1e-15, atol=0) if not _ok: self.report('wrong sign of the second term!') ok = ok and _ok return ok
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 test_hessians(self): """ Test the second partial derivatives of basis functions using finite differences. """ from sfepy.linalg import combine from sfepy.discrete import Integral from sfepy.discrete.fem.poly_spaces import PolySpace ok = True orders = {'2_3' : 3, '2_4' : 3, '3_4' : 4, '3_8' : 3} bases = ([ii for ii in combine([['2_3', '2_4', '3_4', '3_8'], ['lagrange']])]) for geom, poly_space_base in bases: self.report('geometry: %s, base: %s' % (geom, poly_space_base)) order = orders[geom] integral = Integral('i', order=order) coors, _ = integral.get_qp(geom) ps = PolySpace.any_from_args('ps', self.gels[geom], order, base=poly_space_base) dim = coors.shape[1] h1 = nm.zeros((coors.shape[0], dim, dim, ps.n_nod), nm.float64) eps = 1e-8 for ir in range(dim): cc = coors.copy() cc[:, ir] -= eps aux0 = ps.eval_base(cc, diff=1) cc[:, ir] += 2 * eps aux1 = ps.eval_base(cc, diff=1) h1[:, :, ir, :] = 0.5 * (aux1 - aux0) / eps h2 = ps.eval_base(coors, diff=2) _ok = nm.allclose(h1, h2, rtol=0, atol=50*eps) self.report('hessians: error: %.2e ok: %s' % (nm.abs(h1 - h2).max(), _ok)) ok = ok and _ok return ok
def test_solving(self): from sfepy.base.base import IndexedStruct from sfepy.discrete import (FieldVariable, Material, Problem, Function, Equation, Equations, Integral) from sfepy.discrete.conditions import Conditions, EssentialBC from sfepy.terms import Term from sfepy.solvers.ls import ScipyDirect from sfepy.solvers.nls import Newton from sfepy.mechanics.matcoefs import stiffness_from_lame u = FieldVariable('u', 'unknown', self.field) v = FieldVariable('v', 'test', self.field, primary_var_name='u') m = Material('m', D=stiffness_from_lame(self.dim, 1.0, 1.0)) f = Material('f', val=[[0.02], [0.01]]) bc_fun = Function('fix_u_fun', fix_u_fun, extra_args={'extra_arg' : 'hello'}) fix_u = EssentialBC('fix_u', self.gamma1, {'u.all' : bc_fun}) shift_u = EssentialBC('shift_u', self.gamma2, {'u.0' : 0.1}) integral = Integral('i', order=3) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, self.omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_lvf(f.val, v)', integral, self.omega, f=f, v=v) eq = Equation('balance', t1 + t2) eqs = Equations([eq]) 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])) state = pb.solve() name = op.join(self.options.out_dir, 'test_high_level_solving.vtk') pb.save_state(name, state) ok = nls_status.condition == 0 if not ok: self.report('solver did not converge!') _ok = state.has_ebc() if not _ok: self.report('EBCs violated!') ok = ok and _ok return ok
def _integrate(var, val_qp): from sfepy.discrete import Integral from sfepy.discrete.common.mappings import get_jacobian integral = Integral('i', 2) det = get_jacobian(var.field, integral) val = (val_qp * det).sum(axis=1) / det.sum(axis=1) return val
def make_h1_projection_data(target, eval_data): """ Project scalar data given by a material-like `eval_data()` function to a scalar `target` field variable using the :math:`H^1` dot product. """ order = target.field.approx_order * 2 integral = Integral('i', order=order) un = target.name v = FieldVariable('v', 'test', target.field, primary_var_name=un) lhs1 = Term.new('dw_volume_dot(v, %s)' % un, integral, target.field.region, v=v, **{un: target}) lhs2 = Term.new('dw_laplace(v, %s)' % un, integral, target.field.region, v=v, **{un: target}) def _eval_data(ts, coors, mode, **kwargs): if mode == 'qp': val = eval_data(ts, coors, mode, 'val', **kwargs) gval = eval_data(ts, coors, mode, 'grad', **kwargs) return {'val': val, 'gval': gval} m = Material('m', function=_eval_data) rhs1 = Term.new('dw_volume_lvf(m.val, v)', integral, target.field.region, m=m, v=v) rhs2 = Term.new('dw_diffusion_r(m.gval, v)', integral, target.field.region, m=m, v=v) eq = Equation('projection', lhs1 + lhs2 - rhs1 - rhs2) eqs = Equations([eq]) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('aux', equations=eqs, nls=nls, ls=ls) pb.time_update() # This sets the target variable with the projection solution. pb.solve() if nls_status.condition != 0: output('H1 projection: solver did not converge!')
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_variables(self): from sfepy.discrete import FieldVariable, Integral ok = True u = FieldVariable('u', 'parameter', self.field, primary_var_name='(set-to-None)') u.set_constant(1.0) vec = u() # Nodal values. _ok = nm.allclose(vec, 1.0) self.report('set constant:', _ok) ok = _ok and ok def fun(coors): val = nm.empty_like(coors) val[:, 0] = 2 * coors[:, 1] - coors[:, 0] val[:, 1] = coors[:, 0] + 3 * coors[:, 1] return val u.set_from_function(fun) coors = u.field.get_coor() eu = u.evaluate_at(coors) _ok = nm.allclose(eu, fun(coors), rtol=0.0, atol=1e-13) self.report('set from function:', _ok) ok = _ok and ok integral = Integral('i', order=2) gu_qp = u.evaluate(mode='grad', integral=integral) # du_i/dx_j, i = column, j = row. gu = nm.array([[-1., 1.], [2., 3.]]) _ok = nm.allclose(gu_qp, gu[None, None, ...], rtol=0.0, atol=1e-13) self.report('set from function - gradient:', _ok) ok = _ok and ok u_qp = gu_qp[..., :, :1] u.set_from_qp(u_qp, integral) vu = u() _ok = (nm.allclose(vu[::2], -1, rtol=0.0, atol=1e-13) and nm.allclose(vu[1::2], 2, rtol=0.0, atol=1e-13)) self.report('set from qp:', _ok) ok = _ok and ok return ok
def test_save_ebc(self): from sfepy.discrete import (FieldVariable, Integral, Equation, Equations, Problem) from sfepy.discrete.conditions import Conditions, EssentialBC from sfepy.terms import Term name = op.join(self.options.out_dir, op.splitext(op.basename(__file__))[0]) integral = Integral('i', order=1) u = self.variables['u'] v = FieldVariable('v', 'test', u.field, primary_var_name='u') p = self.variables['p'] q = FieldVariable('q', 'test', p.field, primary_var_name='p') regions = self.problem.domain.regions omega = regions['Omega'] # Problem.save_ebc() requires to have equations defined. t1 = Term.new('dw_lin_elastic(v, u)', integral, omega, v=v, u=u) t2 = Term.new('dw_laplace(q, p)', integral, omega, q=q, p=p) eq = Equation('aux', t1 + t2) eqs = Equations([eq]) pb = Problem('test', equations=eqs, auto_solvers=False) all_ebcs = [] all_ebcs.append( EssentialBC('fix_u1', regions['RightFix'], {'u.all': nm.array([0.0, 1.0])})) all_ebcs.append( EssentialBC('fix_u2', regions['LeftStrip'], { 'u.0': 0.0, 'u.1': 1.0 })) all_ebcs.append( EssentialBC('fix_p1', regions['LeftFix'], {'p.all': 0.0})) all_ebcs.append( EssentialBC('fix_p2', regions['RightStrip'], {'p.0': 0.0})) ebcs = Conditions(all_ebcs) pb.time_update(ebcs=ebcs) pb.save_ebc(name + '_ebcs_f.vtk', ebcs=ebcs, force=True) pb.save_ebc(name + '_ebcs.vtk', ebcs=ebcs, default=-1, force=False) return True
def test_invariance_qp(self): from sfepy import data_dir from sfepy.discrete import Integral from sfepy.terms import Term from sfepy.discrete.common.mappings import get_physical_qps ok = True for name in [ 'meshes/3d/block.mesh', 'meshes/3d/cylinder.mesh', 'meshes/2d/square_quad.mesh', 'meshes/2d/square_unit_tri.mesh' ]: self.report(name) u = prepare_variable(op.join(data_dir, name), n_components=3) omega = u.field.region integral = Integral('i', order=3) qps = get_physical_qps(omega, integral) coors = qps.values term = Term.new('ev_volume_integrate(u)', integral, omega, u=u) term.setup() val1 = term.evaluate(mode='qp') val1 = val1.ravel() val2 = u.evaluate_at(coors).ravel() self.report('value: max. difference:', nm.abs(val1 - val2).max()) ok1 = nm.allclose(val1, val2, rtol=0.0, atol=1e-12) self.report('->', ok1) term = Term.new('ev_grad(u)', integral, omega, u=u) term.setup() val1 = term.evaluate(mode='qp') val1 = val1.ravel() val2 = u.evaluate_at(coors, mode='grad').ravel() self.report('gradient: max. difference:', nm.abs(val1 - val2).max()) ok2 = nm.allclose(val1, val2, rtol=0.0, atol=1e-10) self.report('->', ok2) ok = ok and ok1 and ok2 return ok
def get_term(property_array, delta_x, fields): """Get the term Args: property_array: the spatial array of property values delta_x: the grid spacing fields: the Sfepy u, v fields Returns: a new term """ return Term.new( "dw_lin_elastic_iso(m.lam, m.mu, v, u)", Integral("i", order=4), fields[0].field.region, m=_get_material(property_array, fields[0].field.region.domain, delta_x), u=fields[0], v=fields[1], )
def __init__(self, dim, approx_order, **kwargs): """ Creates Struct object with all the data necessary to test terms :param dim: dimension :param approx_order: approximation order :param kwargs: velo, diffusion or penalty for prepare_materials :return: term test scope """ if dim == 1: (field, regions), mesh = prepare_dgfield_1D(approx_order) elif dim == 2: (field, regions), mesh = prepare_field_2D(approx_order) self.field = field self.regions = regions self.mesh = mesh self.n_cell = field.n_cell self.n_nod = field.n_nod self.n_el_nod = field.n_el_nod self.u, self.v = self.prepare_variables(field) self.u.data = [(nm.zeros(self.n_nod))] self.variables = Variables([ self.u, self.v]) self.integral = Integral('i', order=approx_order * 2) self.a, self.D, self.Cw = self.prepare_materials(field, **kwargs) if dim == 1: velo = nm.array(1.0) elif dim == 2: velo = nm.array([1.0, 0]) self.burg_velo = velo.T / nm.linalg.norm(velo) self.nonlin = Material('nonlin', values={'.fun': self.burg_fun, '.dfun': self.burg_fun_d}) self.out = nm.zeros((self.n_cell, 1, self.n_el_nod, 1))
def compute_erros(analytic_fun, pb): """ Compute errors from analytical solution in conf.sol_fun and numerical solution saved in pb :param analytic_fun: analytic solution :param pb: problem with numerical solution :return: analytic_fun L2 norm, vaules of analytic_fun in qps L2 norm of difference between analytic and numerical solution relative difference values of numerical solution in qps """ idiff = Integral('idiff', 20) num_qp = pb.evaluate('ev_volume_integrate.idiff.Omega(p)', integrals=Integrals([idiff]), mode='qp', copy_materials=False, verbose=False) aux = Material('aux', function=analytic_fun) ana_qp = pb.evaluate('ev_volume_integrate_mat.idiff.Omega(aux.p, p)', aux=aux, integrals=Integrals([idiff]), mode='qp', copy_materials=False, verbose=False) field = pb.fields['f'] det = get_jacobian(field, idiff) diff_l2 = nm.sqrt((((num_qp - ana_qp)**2) * det).sum()) ana_l2 = nm.sqrt(((ana_qp**2) * det).sum()) rel_l2 = diff_l2 / ana_l2 diff_loo = nm.max(num_qp - ana_qp) ana_loo = nm.max(ana_qp) rel_loo = diff_loo / ana_loo diff_l1 = nm.sqrt((nm.abs(num_qp - ana_qp) * det).sum()) ana_l1 = nm.sqrt((nm.abs(ana_qp) * det).sum()) rel_l1 = diff_l2 / ana_l2 return ana_l2, ana_qp, diff_l2, rel_l2, num_qp
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 create_mass_matrix(field): """ Create scalar mass matrix corresponding to the given field. Returns ------- mtx : csr_matrix The mass matrix in CSR format. """ u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') integral = Integral('i', order=field.approx_order * 2) term = Term.new('dw_volume_dot(v, u)', integral, field.region, v=v, u=u) eq = Equation('aux', term) eqs = Equations([eq]) eqs.time_update(None) dummy = eqs.create_state_vector() mtx = eqs.create_matrix_graph() mtx = eqs.eval_tangent_matrices(dummy, mtx) return mtx
fields = { 'fu': ('real', 6, 'Omega', 1, 'H1', 'shell10x'), } variables = { 'u' : ('unknown field', 'fu', 0), 'v' : ('test field', 'fu', 'u'), } ebcs = { 'fix' : ('Gamma1', {'u.all' : 0.0}), } # Custom integral. 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 integrals = { 'i' : ('custom', qp_coors, qp_weights), } equations = { 'elasticity' : """dw_shell10x.i.Omega(m.D, m.drill, v, u) = dw_point_load.i.Gamma2(load.val, v)""", } solvers = {
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('--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 _gen_common_data(orders, gels, report): import sfepy from sfepy.base.base import Struct from sfepy.linalg import combine from sfepy.discrete import FieldVariable, Integral from sfepy.discrete.fem import Mesh, FEDomain, Field from sfepy.discrete.common.global_interp import get_ref_coors bases = ([ii for ii in combine([['2_4', '3_8'], ['lagrange', 'lobatto']])] + [ii for ii in combine([['2_3', '3_4'], ['lagrange']])]) for geom, poly_space_base in bases: report('geometry: %s, base: %s' % (geom, poly_space_base)) order = orders[geom] integral = Integral('i', order=order) aux = '' if geom in ['2_4', '3_8'] else 'z' mesh0 = Mesh.from_file('meshes/elements/%s_2%s.mesh' % (geom, aux), prefix_dir=sfepy.data_dir) gel = gels[geom] perms = gel.get_conn_permutations() qps, qp_weights = integral.get_qp(gel.surface_facet.name) zz = nm.zeros_like(qps[:, :1]) qps = nm.hstack(([qps] + [zz])) shift = shifts[geom] rcoors = nm.ascontiguousarray(qps + shift[:1, :] - shift[1:, :]) ccoors = nm.ascontiguousarray(qps + shift[:1, :] + shift[1:, :]) for ir, pr in enumerate(perms): for ic, pc in enumerate(perms): report('ir: %d, ic: %d' % (ir, ic)) report('pr: %s, pc: %s' % (pr, pc)) mesh = mesh0.copy() conn = mesh.get_conn(gel.name) conn[0, :] = conn[0, pr] conn[1, :] = conn[1, pc] cache = Struct(mesh=mesh) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') region = domain.create_region('Facet', rsels[geom], 'facet') field = Field.from_args('f', nm.float64, shape=1, region=omega, approx_order=order, poly_space_base=poly_space_base) var = FieldVariable('u', 'unknown', field) report('# dofs: %d' % var.n_dof) vec = nm.empty(var.n_dof, dtype=var.dtype) ap = field.ap ps = ap.interp.poly_spaces['v'] dofs = field.get_dofs_in_region(region, merge=False) edofs, fdofs = nm.unique(dofs[1]), nm.unique(dofs[2]) rrc, rcells, rstatus = get_ref_coors(field, rcoors, cache=cache) crc, ccells, cstatus = get_ref_coors(field, ccoors, cache=cache) assert_((rstatus == 0).all() and (cstatus == 0).all()) yield (geom, poly_space_base, qp_weights, mesh, ir, ic, ap, ps, rrc, rcells[0], crc, ccells[0], vec, edofs, fdofs)
'fu': ('real', 6, 'Omega', 1, 'H1', 'shell10x'), } variables = { 'u': ('unknown field', 'fu', 0), 'v': ('test field', 'fu', 'u'), } ebcs = { 'fix': ('Gamma1', { 'u.all': 0.0 }), } # Custom integral. 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 integrals = { 'i': ('custom', qp_coors, qp_weights), } equations = { 'elasticity': """dw_shell10x.i.Omega(m.D, m.drill, v, u) = dw_point_load.i.Gamma2(load.val, v)""", } solvers = {
def create_local_problem(omega_gi, orders): """ Local problem definition using a domain corresponding to the global region `omega_gi`. """ order_u, order_p = orders mesh = omega_gi.domain.mesh # All tasks have the whole mesh. bbox = mesh.get_bounding_box() min_x, max_x = bbox[:, 0] eps_x = 1e-8 * (max_x - min_x) min_y, max_y = bbox[:, 1] eps_y = 1e-8 * (max_y - min_y) mesh_i = Mesh.from_region(omega_gi, mesh, localize=True) domain_i = FEDomain('domain_i', mesh_i) omega_i = domain_i.create_region('Omega', 'all') gamma1_i = domain_i.create_region('Gamma1', 'vertices in (x < %.10f)' % (min_x + eps_x), 'facet', allow_empty=True) gamma2_i = domain_i.create_region('Gamma2', 'vertices in (x > %.10f)' % (max_x - eps_x), 'facet', allow_empty=True) gamma3_i = domain_i.create_region('Gamma3', 'vertices in (y < %.10f)' % (min_y + eps_y), 'facet', allow_empty=True) field1_i = Field.from_args('fu', nm.float64, mesh.dim, omega_i, approx_order=order_u) field2_i = Field.from_args('fp', nm.float64, 1, omega_i, approx_order=order_p) output('field 1: number of local DOFs:', field1_i.n_nod) output('field 2: number of local DOFs:', field2_i.n_nod) u_i = FieldVariable('u_i', 'unknown', field1_i, order=0) v_i = FieldVariable('v_i', 'test', field1_i, primary_var_name='u_i') p_i = FieldVariable('p_i', 'unknown', field2_i, order=1) q_i = FieldVariable('q_i', 'test', field2_i, primary_var_name='p_i') if mesh.dim == 2: alpha = 1e2 * nm.array([[0.132], [0.132], [0.092]]) else: alpha = 1e2 * nm.array([[0.132], [0.132], [0.132], [0.092], [0.092], [0.092]]) mat = Material('m', D=stiffness_from_lame(mesh.dim, lam=10, mu=5), k=1, alpha=alpha) integral = Integral('i', order=2*(max(order_u, order_p))) t11 = Term.new('dw_lin_elastic(m.D, v_i, u_i)', integral, omega_i, m=mat, v_i=v_i, u_i=u_i) t12 = Term.new('dw_biot(m.alpha, v_i, p_i)', integral, omega_i, m=mat, v_i=v_i, p_i=p_i) t21 = Term.new('dw_biot(m.alpha, u_i, q_i)', integral, omega_i, m=mat, u_i=u_i, q_i=q_i) t22 = Term.new('dw_laplace(m.k, q_i, p_i)', integral, omega_i, m=mat, q_i=q_i, p_i=p_i) eq1 = Equation('eq1', t11 - t12) eq2 = Equation('eq1', t21 + t22) eqs = Equations([eq1, eq2]) ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all' : 0.0}) ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.0' : 0.05}) def bc_fun(ts, coors, **kwargs): val = 0.3 * nm.sin(4 * nm.pi * (coors[:, 0] - min_x) / (max_x - min_x)) return val fun = Function('bc_fun', bc_fun) ebc3 = EssentialBC('ebc3', gamma3_i, {'p_i.all' : fun}) pb = Problem('problem_i', equations=eqs, active_only=False) pb.time_update(ebcs=Conditions([ebc1, ebc2, ebc3])) pb.update_materials() return pb
def main(): parser = 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 main(): from sfepy import data_dir parser = OptionParser(usage=usage, version='%prog') parser.add_option('-s', '--show', action="store_true", dest='show', default=False, help=help['show']) options, args = parser.parse_args() mesh = Mesh.from_file(data_dir + '/meshes/2d/rectangle_tri.mesh') domain = FEDomain('domain', mesh) min_x, max_x = domain.get_mesh_bounding_box()[:, 0] eps = 1e-8 * (max_x - min_x) omega = domain.create_region('Omega', 'all') gamma1 = domain.create_region('Gamma1', 'vertices in x < %.10f' % (min_x + eps), 'facet') gamma2 = domain.create_region('Gamma2', 'vertices in x > %.10f' % (max_x - eps), 'facet') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=2) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') m = Material('m', D=stiffness_from_lame(dim=2, lam=1.0, mu=1.0)) f = Material('f', val=[[0.02], [0.01]]) integral = Integral('i', order=3) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_lvf(f.val, v)', integral, omega, f=f, v=v) eq = Equation('balance', t1 + t2) eqs = Equations([eq]) fix_u = EssentialBC('fix_u', gamma1, {'u.all': 0.0}) bc_fun = Function('shift_u_fun', shift_u_fun, extra_args={'shift': 0.01}) shift_u = EssentialBC('shift_u', gamma2, {'u.0': bc_fun}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls) pb.save_regions_as_groups('regions') pb.time_update(ebcs=Conditions([fix_u, shift_u])) vec = pb.solve() print(nls_status) pb.save_state('linear_elasticity.vtk', vec) if options.show: view = Viewer('linear_elasticity.vtk') view(vector_mode='warp_norm', rel_scaling=2, is_scalar_bar=True, is_wireframe=True)
def main(): parser = ArgumentParser(description=__doc__.rstrip(), formatter_class=RawDescriptionHelpFormatter) parser.add_argument('output_dir', help=helps['output_dir']) parser.add_argument('--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))