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 __init__(self, *args, **kwargs): Term.__init__(self, *args, **kwargs) igs = self.region.igs self.mtx_t = {}.fromkeys(igs, None) self.membrane_geo = {}.fromkeys(igs, None) self.bfg = {}.fromkeys(igs, None)
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 set_integral(self, integral): """ Set the term integral. """ if (integral.mode != 'custom') or (integral.coors.shape[1] != 3): raise ValueError("dw_shell10x term requires 'custom' 3D integral!") Term.set_integral(self, integral)
def get_fargs(self, mat, kappa, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs): from sfepy.discrete.variables import create_adof_conn, expand_basis geo, _ = self.get_mapping(state) n_el, n_qp, dim, n_en, n_c = self.get_data_shape(virtual) ebf = expand_basis(geo.bf, dim) mat = Term.tile_mat(mat, n_el) gmat = _build_wave_strain_op(kappa, ebf) if diff_var is None: econn = state.field.get_econn('volume', self.region) adc = create_adof_conn(nm.arange(state.n_dof, dtype=nm.int32), econn, n_c, 0) vals = state()[adc] # Same as nm.einsum('qij,cj->cqi', gmat[0], vals)[..., None] aux = dot_sequences(gmat, vals[:, None, :, None]) out_qp = dot_sequences(gmat, dot_sequences(mat, aux), 'ATB') fmode = 0 else: out_qp = dot_sequences(gmat, dot_sequences(mat, gmat), 'ATB') fmode = 1 return out_qp, geo, fmode
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 function(self, out, state, diff_var, field, region, D): D = Term.tile_mat(D, out.shape[0]) if diff_var is not None: # matrix mode # outR = out.copy()[..., 0:1] out = self._function_matrix(out, state, diff_var, field, region, D) # vals, ielsi, ielsj = out[:3] # from scipy.sparse import coo_matrix # extra = coo_matrix((vals, (ielsi, ielsj)), # shape=2*(field.n_el_nod * field.n_cell,)) # M = extra.toarray() # u = state.data[0] # Mu = nm.dot(M, u).reshape((field.n_cell, field.n_el_nod)) # # outR = self._function_residual(outR, state, diff_var, field, # region, D).squeeze() # from matplotlib import pyplot as plt # plt.imshow((Mu - outR).T, aspect="auto") # plt.colorbar() # # nbrhd_idx = field.get_facet_neighbor_idx(region, state.eq_map) # bcells = nm.where(nbrhd_idx[:, :, 0] < 0)[0], # plt.vlines(bcells, -.5, 15, alpha=.3) # plt.show() else: # residual mode out = self._function_residual(out, state, diff_var, field, region, D) status = None return out, status
def get_fargs(self, traction, virtual, mode=None, term_mode=None, diff_var=None, **kwargs): sg, _ = self.get_mapping(virtual) if traction is not None: n_el, _, _, _, _ = self.get_data_shape(virtual) traction = Term.tile_mat(traction, n_el) if traction is None: traction = nm.zeros((0, 0, 0, 0), dtype=nm.float64) if mode == 'weak': return traction, sg elif mode == 'eval': val = self.get(virtual, 'val') return traction, val, sg else: raise ValueError('unsupported evaluation mode in %s! (%s)' % (self.name, mode))
def get_fargs(self, force_pars, normal, anchor, bounds, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs): sg, _ = self.get_mapping(virtual) assert_((force_pars >= 0.0).all(), 'force parameters must be non-negative!') force_pars = Term.tile_mat(force_pars, sg.shape[0]) if self.cp is None: self.cp = ContactPlane(anchor, normal, bounds) qps = self.get_physical_qps() qp_coors = qps.values u_qp = self.get(state, 'val').reshape(qp_coors.shape) # Deformed QP coordinates. coors = u_qp + qp_coors force = nm.zeros(coors.shape[0], dtype=nm.float64) k, f0, eps, a = self._get_force_pars(force_pars, force.shape) # Active points in contact change with displacements! ii = self.cp.mask_points(qp_coors) if diff_var is None: if ii.any(): d = self.cp.get_distance(coors[ii]) # Force in the plane normal direction. force[ii] = self.smooth_f(d, k[ii], f0[ii], a[ii], eps[ii], 0) fmode = 0 else: if ii.any(): d = self.cp.get_distance(coors[ii]) # Force in the plane normal direction derivative. force[ii] = self.smooth_f(d, k[ii], f0[ii], a[ii], eps[ii], 1) fmode = 1 force.shape = qps.shape[:2] + (1, 1) return force, self.cp.normal, sg, fmode
def eval_real(self, shape, fargs, mode='eval', term_mode=None, diff_var=None, **kwargs): if diff_var is None: if mode == 'eval': out = 0.0 else: out = nm.zeros(shape, dtype=nm.float64) iter_kernel = fargs for ii, fargs in iter_kernel(): out1, status = Term.eval_real(self, shape, fargs, mode=mode, term_mode=term_mode, diff_var=diff_var, **kwargs) out += out1 else: out, status = Term.eval_real(self, shape, fargs, mode=mode, term_mode=term_mode, diff_var=diff_var, **kwargs) return out, status
def get_fargs(self, mat, kappa, gvar, evar, mode=None, term_mode=None, diff_var=None, **kwargs): from sfepy.discrete.variables import create_adof_conn, expand_basis geo, _ = self.get_mapping(evar) n_el, n_qp, dim, n_en, n_c = self.get_data_shape(gvar) ebf = expand_basis(geo.bf, dim) mat = Term.tile_mat(mat, n_el) gmat = _build_wave_strain_op(kappa, ebf) emat = _build_cauchy_strain_op(geo.bfg) if diff_var is None: avar = evar if self.mode == 'ge' else gvar econn = avar.field.get_econn('volume', self.region) adc = create_adof_conn(nm.arange(avar.n_dof, dtype=nm.int32), econn, n_c, 0) vals = avar()[adc] if self.mode == 'ge': # Same as aux = self.get(avar, 'cauchy_strain'), aux = dot_sequences(emat, vals[:, None, :, None]) out_qp = dot_sequences(gmat, dot_sequences(mat, aux), 'ATB') else: aux = dot_sequences(gmat, vals[:, None, :, None]) out_qp = dot_sequences(emat, dot_sequences(mat, aux), 'ATB') fmode = 0 else: if self.mode == 'ge': out_qp = dot_sequences(gmat, dot_sequences(mat, emat), 'ATB') else: out_qp = dot_sequences(emat, dot_sequences(mat, gmat), 'ATB') fmode = 1 return out_qp, geo, fmode
def __init__(self, *args, **kwargs): Term.__init__(self, *args, **kwargs) self.cs = None
def __init__(self, *args, **kwargs): Term.__init__(self, *args, **kwargs) self.stress_cache = None
def __init__(self, *args, **kwargs): Term.__init__(self, *args, **kwargs) self.mtx_t = None self.membrane_geo = None self.bfg = None
def __init__(self, *args, **kwargs): Term.__init__(self, *args, **kwargs) igs = self.region.igs self.stress_cache = {}.fromkeys(igs, None)
def __init__(self, *args, **kwargs): Term.__init__(self, *args, **kwargs) self.cp = None
def __init__(self, *args, **kwargs): Term.__init__(self, *args, **kwargs) self.detect = 2 self.ci = None
def get_fargs(self, force_pars, centre, radius, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs): sg, _ = self.get_mapping(virtual) assert_((force_pars >= 0.0).all(), 'force parameters must be non-negative!') force_pars = Term.tile_mat(force_pars, sg.shape[0]) if self.cs is None: self.cs = ContactSphere(centre, radius) qps = self.get_physical_qps() qp_coors = qps.values u_qp = self.get(state, 'val').reshape(qp_coors.shape) # Deformed QP coordinates. coors = u_qp + qp_coors force = nm.zeros(coors.shape[0], dtype=nm.float64) normals = nm.zeros((coors.shape[0], 3), dtype=nm.float64) fd = None k, f0, eps, a = self._get_force_pars(force_pars, force.shape) # Active points in contact change with displacements! ii = self.cs.mask_points(coors, nm.abs(eps.min())) if diff_var is None: if ii.any(): d, normals[ii] = self.cs.get_distance(coors[ii]) force[ii] = self.smooth_f(d, k[ii], f0[ii], a[ii], eps[ii], 0) fmode = 0 else: if ii.any(): d, normals[ii] = self.cs.get_distance(coors[ii]) # Force derivative. force[ii] = self.smooth_f(d, k[ii], f0[ii], a[ii], eps[ii], 1) # Force / (R - d). aux = self.smooth_f(d, k[ii], f0[ii], a[ii], eps[ii], 0) fd = nm.zeros_like(force) fd[ii] = aux / (self.cs.radius - d) fd.shape = qps.shape[:2] + (1, 1) fmode = 1 force.shape = qps.shape[:2] + (1, 1) normals.shape = qps.shape[:2] + (3, 1) return force, normals, fd, sg, fmode