def test_material_functions(self): from sfepy.fem import Material problem = self.problem conf = problem.conf ts = problem.get_default_ts(step=0) conf_mat1 = conf.get_item_by_name('materials', 'mf1') mat1 = Material.from_conf(conf_mat1, problem.functions) mat1.time_update(ts, None, mode='normal', problem=problem) coors = problem.domain.get_mesh_coors() assert_(nm.all(coors[:, 0] == mat1.get_data(None, None, 'x_0'))) conf_mat2 = conf.get_item_by_name('materials', 'mf2') mat2 = Material.from_conf(conf_mat2, problem.functions) mat2.time_update(ts, None, mode='normal', problem=problem) assert_(nm.all(coors[:, 1] == mat2.get_data(None, None, 'x_1'))) materials = problem.get_materials() materials.time_update(ts, problem.equations, mode='normal', problem=problem) mat3 = materials['mf3'] key = mat3.get_keys(region_name='Omega')[0] assert_(nm.all(mat3.get_data(key, 0, 'a') == 10.0)) assert_(nm.all(mat3.get_data(key, 0, 'b') == 2.0)) assert_(mat3.get_data(None, None, 'c') == 'ahoj') return True
def test_material_functions(self): from sfepy.fem import Material problem = self.problem conf = problem.conf ts = problem.get_default_ts(step=0) conf_mat1 = conf.get_item_by_name('materials', 'mf1') mat1 = Material.from_conf(conf_mat1, problem.functions) mat1.time_update(ts, None, mode='normal', problem=problem) coors = problem.domain.get_mesh_coors() assert_(nm.all(coors[:,0] == mat1.get_data(None, None, 'x_0'))) conf_mat2 = conf.get_item_by_name('materials', 'mf2') mat2 = Material.from_conf(conf_mat2, problem.functions) mat2.time_update(ts, None, mode='normal', problem=problem) assert_(nm.all(coors[:,1] == mat2.get_data(None, None, 'x_1'))) materials = problem.get_materials() materials.time_update(ts, problem.equations, mode='normal', problem=problem) mat3 = materials['mf3'] key = mat3.get_keys(region_name='Omega')[0] assert_(nm.all(mat3.get_data(key, 0, 'a') == 10.0)) assert_(nm.all(mat3.get_data(key, 0, 'b') == 2.0)) assert_(mat3.get_data(None, None, 'c') == 'ahoj') return True
def test_solving(self): from sfepy.base.base import IndexedStruct from sfepy.fem \ import FieldVariable, Material, ProblemDefinition, \ Function, Equation, Equations, Integral from sfepy.fem.conditions import Conditions, EssentialBC from sfepy.terms import Term from sfepy.solvers.ls import ScipyDirect from sfepy.solvers.nls import Newton u = FieldVariable('u', 'unknown', self.field, self.dim) v = FieldVariable('v', 'test', self.field, self.dim, primary_var_name='u') m = Material('m', lam=1.0, mu=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_iso(m.lam, m.mu, 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 = ProblemDefinition('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 test_boundary_fluxes( self ): import os.path as op from sfepy.linalg import rotation_matrix2d from sfepy.fem.evaluate import BasicEvaluator from sfepy.fem import Material problem = self.problem angles = [0, 30, 45] region_names = ['Left', 'Right', 'Gamma'] values = [5.0, -5.0, 0.0] variables = problem.get_variables() get_state = variables.get_state_part_view state = self.state.copy(deep=True) problem.time_update(ebcs={}, epbcs={}) # problem.save_ebc( 'aux.vtk' ) state.apply_ebc() ev = BasicEvaluator( problem ) aux = ev.eval_residual(state()) field = variables['t'].field conf_m = problem.conf.get_item_by_name('materials', 'm') m = Material.from_conf(conf_m, problem.functions) name = op.join( self.options.out_dir, op.split( problem.domain.mesh.name )[1] + '_%02d.mesh' ) orig_coors = problem.get_mesh_coors().copy() ok = True for ia, angle in enumerate( angles ): self.report( '%d: mesh rotation %d degrees' % (ia, angle) ) problem.domain.mesh.transform_coors( rotation_matrix2d( angle ), ref_coors = orig_coors ) problem.set_mesh_coors(problem.domain.mesh.coors, update_fields=True) problem.domain.mesh.write( name % angle, io = 'auto' ) for ii, region_name in enumerate( region_names ): flux_term = 'd_surface_flux.i2.%s( m.K, t )' % region_name val1 = problem.evaluate(flux_term, t=variables['t'], m=m) rvec = get_state( aux, 't', True ) reg = problem.domain.regions[region_name] nods = field.get_dofs_in_region(reg, merge=True) val2 = rvec[nods].sum() # Assume 1 dof per node. ok = ok and ((abs( val1 - values[ii] ) < 1e-10) and (abs( val2 - values[ii] ) < 1e-10)) self.report( ' %d. %s: %e == %e == %e'\ % (ii, region_name, val1, val2, values[ii]) ) # Restore original coordinates. problem.domain.mesh.transform_coors(rotation_matrix2d(0), ref_coors=orig_coors) problem.set_mesh_coors(problem.domain.mesh.coors, update_fields=True) return ok
def test_boundary_fluxes(self): import os.path as op from sfepy.linalg import rotation_matrix2d from sfepy.fem.evaluate import BasicEvaluator from sfepy.fem import Material problem = self.problem angles = [0, 30, 45] region_names = ['Left', 'Right', 'Gamma'] values = [5.0, -5.0, 0.0] variables = problem.get_variables() get_state = variables.get_state_part_view state = self.state.copy(deep=True) problem.time_update(ebcs={}, epbcs={}) # problem.save_ebc( 'aux.vtk' ) state.apply_ebc() ev = BasicEvaluator(problem) aux = ev.eval_residual(state()) field = variables['t'].field conf_m = problem.conf.get_item_by_name('materials', 'm') m = Material.from_conf(conf_m, problem.functions) name = op.join(self.options.out_dir, op.split(problem.domain.mesh.name)[1] + '_%02d.mesh') orig_coors = problem.get_mesh_coors().copy() ok = True for ia, angle in enumerate(angles): self.report('%d: mesh rotation %d degrees' % (ia, angle)) problem.domain.mesh.transform_coors(rotation_matrix2d(angle), ref_coors=orig_coors) problem.set_mesh_coors(problem.domain.mesh.coors, update_fields=True) problem.domain.mesh.write(name % angle, io='auto') for ii, region_name in enumerate(region_names): flux_term = 'd_surface_flux.i2.%s( m.K, t )' % region_name val1 = problem.evaluate(flux_term, t=variables['t'], m=m) rvec = get_state(aux, 't', True) reg = problem.domain.regions[region_name] nods = field.get_dofs_in_region(reg, merge=True) val2 = rvec[nods].sum() # Assume 1 dof per node. ok = ok and ((abs(val1 - values[ii]) < 1e-10) and (abs(val2 - values[ii]) < 1e-10)) self.report( ' %d. %s: %e == %e == %e'\ % (ii, region_name, val1, val2, values[ii]) ) # Restore original coordinates. problem.domain.mesh.transform_coors(rotation_matrix2d(0), ref_coors=orig_coors) problem.set_mesh_coors(problem.domain.mesh.coors, update_fields=True) return ok
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, 1, 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 = ProblemDefinition('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 test_boundary_fluxes(self): from sfepy.fem.evaluate import BasicEvaluator from sfepy.fem import Material problem = self.problem region_names = ['Gamma'] variables = problem.get_variables() get_state = variables.get_state_part_view state = self.state.copy(deep=True) problem.time_update(ebcs={}, epbcs={}) ## problem.save_ebc( 'aux.vtk' ) state.apply_ebc() ev = BasicEvaluator(problem) aux = ev.eval_residual(state()) field = variables['t'].field conf_m = problem.conf.get_item_by_name('materials', 'm') m = Material.from_conf(conf_m, problem.functions) ok = True for ii, region_name in enumerate(region_names): flux_term = 'd_surface_flux.1.%s( m.K, t )' % region_name val1 = problem.evaluate(flux_term, t=variables['t'], m=m) rvec = get_state(aux, 't', True) reg = problem.domain.regions[region_name] nods = field.get_dofs_in_region(reg, merge=True) val2 = rvec[nods].sum() # Assume 1 dof per node. eps = 1e-2 ok = ok and ((abs(val1 - val2) < eps)) self.report( '%d. %s: |%e - %e| = %e < %.2e'\ % (ii, region_name, val1, val2, abs( val1 - val2 ), eps) ) return ok
def test_boundary_fluxes( self ): from sfepy.fem.evaluate import BasicEvaluator from sfepy.fem import Material problem = self.problem region_names = ['Gamma'] variables = problem.get_variables() get_state = variables.get_state_part_view state = self.state.copy(deep=True) problem.time_update(ebcs={}, epbcs={}) ## problem.save_ebc( 'aux.vtk' ) state.apply_ebc() ev = BasicEvaluator( problem ) aux = ev.eval_residual(state()) field = variables['t'].field conf_m = problem.conf.get_item_by_name('materials', 'm') m = Material.from_conf(conf_m, problem.functions) ok = True for ii, region_name in enumerate( region_names ): flux_term = 'd_surface_flux.1.%s( m.K, t )' % region_name val1 = problem.evaluate(flux_term, t=variables['t'], m=m) rvec = get_state( aux, 't', True ) reg = problem.domain.regions[region_name] nods = field.get_dofs_in_region(reg, merge=True) val2 = rvec[nods].sum() # Assume 1 dof per node. eps = 1e-2 ok = ok and ((abs( val1 - val2 ) < eps)) self.report( '%d. %s: |%e - %e| = %e < %.2e'\ % (ii, region_name, val1, val2, abs( val1 - val2 ), eps) ) return ok
def make_term_args(arg_shapes, arg_kinds, arg_types, ats_mode, domain): from sfepy.base.base import basestr from sfepy.fem import Field, FieldVariable, Material, Variables, Materials 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 5 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 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) 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, shape) var.set_constant(0.0) variables.append(var) var = FieldVariable('v', 'test', field, shape, primary_var_name='u%d' % istate) elif arg_kind == 'state_variable': var = FieldVariable('u%d' % ii, 'unknown', field, shape) var.set_constant(0.0) elif arg_kind == 'parameter_variable': var = FieldVariable('p%d' % ii, 'parameter', field, shape, 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 shape = _parse_tuple_shape(sh) if (len(shape) > 1) or (shape[0] > 1): # Array. values = { '%sc%d' % (prefix, ii): nm.ones(shape, dtype=nm.float64) } elif (len(shape) == 1) and (shape[0] == 1): # Single scalar as a special value. values = {'.c%d' % ii: 1.0} 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 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(): 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', 'nodes in x < %.10f' % (min_x + eps)) gamma2 = domain.create_region('Gamma2', 'nodes in x > %.10f' % (max_x - eps)) field = H1NodalVolumeField('fu', nm.float64, 'vector', omega, approx_order=2) u = FieldVariable('u', 'unknown', field, mesh.dim) v = FieldVariable('v', 'test', field, mesh.dim, 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 = ProblemDefinition('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 = 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 = Domain('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, n_c) v = FieldVariable('v', 'test', field, n_c, 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()