def test_volume_tl(self): from sfepy.discrete import FieldVariable fu = self.problem.fields['vector'] fq = self.problem.fields['scalar'] var_u = FieldVariable('u', 'parameter', fu, primary_var_name='(set-to-None)') var_q = FieldVariable('q', 'test', fq, primary_var_name='(set-to-None)') var_u.set_data(nm.linspace(0, 0.004, var_u.n_dof)) vval = self.problem.evaluate('dw_tl_volume.i.Omega( q, u )', term_mode='volume', q=var_q, u=var_u) sval = self.problem.evaluate('d_tl_volume_surface.i.Gamma( u )', u=var_u) ok = abs(vval - sval) < 1e-14 self.report('TL: by volume: %e == by surface: %e -> %s' % (vval, sval, ok)) return ok
def from_conf(conf, options): from sfepy.discrete import FieldVariable, Variables, Problem from sfepy.discrete.fem import Mesh, FEDomain, Field mesh = Mesh.from_file(data_dir + '/meshes/2d/square_unit_tri.mesh') domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') domain.create_region('Left', 'vertices in (x < -0.499)', 'facet') domain.create_region( 'LeftStrip', 'vertices in (x < -0.499)' ' & (y > -0.199) & (y < 0.199)', 'facet') domain.create_region('LeftFix', 'r.Left -v r.LeftStrip', 'facet') domain.create_region('Right', 'vertices in (x > 0.499)', 'facet') domain.create_region( 'RightStrip', 'vertices in (x > 0.499)' ' & (y > -0.199) & (y < 0.199)', 'facet') domain.create_region('RightFix', 'r.Right -v r.RightStrip', 'facet') fu = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=2) u = FieldVariable('u', 'unknown', fu) fp = Field.from_args('fp', nm.float64, 'scalar', omega, approx_order=2) p = FieldVariable('p', 'unknown', fp) pb = Problem('test', domain=domain, fields=[fu, fp], auto_conf=False) test = Test(problem=pb, variables=Variables([u, p]), conf=conf, options=options) return test
def test_surface_evaluate(self): from sfepy.discrete import FieldVariable problem = self.problem us = problem.get_variables()['us'] vec = nm.empty(us.n_dof, dtype=us.dtype) vec[:] = 1.0 us.set_data(vec) expr = 'ev_surface_integrate.i.Left( us )' val = problem.evaluate(expr, us=us) ok1 = nm.abs(val - 1.0) < 1e-15 self.report('with unknown: %s, value: %s, ok: %s' % (expr, val, ok1)) ps1 = FieldVariable('ps1', 'parameter', us.get_field(), primary_var_name='(set-to-None)') ps1.set_data(vec) expr = 'ev_surface_integrate.i.Left( ps1 )' val = problem.evaluate(expr, ps1=ps1) ok2 = nm.abs(val - 1.0) < 1e-15 self.report('with parameter: %s, value: %s, ok: %s' % (expr, val, ok2)) ok2 = True return ok1 and ok2
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 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 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 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_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 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 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 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_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 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 create_subequations(self, var_names, known_var_names=None): """ Create sub-equations containing only terms with the given virtual variables. Parameters ---------- var_names : list The list of names of virtual variables. known_var_names : list The list of names of (already) known state variables. Returns ------- subequations : Equations instance The sub-equations. """ from sfepy.discrete import FieldVariable known_var_names = get_default(known_var_names, []) objs = [] for iv, var_name in enumerate(var_names): terms = [ term.copy(name=term.name) for eq in self for term in eq.terms if term.get_virtual_name() == var_name ] # Make parameter variables from known state variables in terms # arguments. for known_name in known_var_names: for term in terms: if known_name in term.arg_names: ii = term.arg_names.index(known_name) state = self.variables[known_name] par = FieldVariable(known_name, 'parameter', state.field, primary_var_name='(set-to-None)') term.args[ii] = par term._kwargs[known_name] = par par.set_data(state()) new_terms = Terms(terms) objs.append(Equation('eq_%d' % iv, new_terms)) subequations = Equations(objs) return subequations
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_volume(self): from sfepy.discrete import FieldVariable ok = True field_map = {'u': 'vector', 'p': 'scalar'} volumes = {} avg = 0.0 for key, term in expressions.items(): var_name = key[-1] field = self.problem.fields[field_map[var_name]] var = FieldVariable(var_name, 'parameter', field, primary_var_name='(set-to-None)') val = self.problem.evaluate(term, **{var_name: var}) volumes[key] = val avg += val avg /= len(volumes) for key, val in volumes.items(): err = nm.abs(avg - val) / nm.abs(avg) _ok = err < 1e-12 self.report('"' "%s" '" - volume: %e' % (key, val)) self.report('"' "%s" '" - relative volume difference: %e -> %s' % (key, err, _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 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 create_subequations(self, var_names, known_var_names=None): """ Create sub-equations containing only terms with the given virtual variables. Parameters ---------- var_names : list The list of names of virtual variables. known_var_names : list The list of names of (already) known state variables. Returns ------- subequations : Equations instance The sub-equations. """ from sfepy.discrete import FieldVariable known_var_names = get_default(known_var_names, []) objs = [] for iv, var_name in enumerate(var_names): terms = [term.copy(name=term.name) for eq in self for term in eq.terms if term.get_virtual_name() == var_name] # Make parameter variables from known state variables in terms # arguments. for known_name in known_var_names: for term in terms: if known_name in term.arg_names: ii = term.arg_names.index(known_name) state = self.variables[known_name] par = FieldVariable(known_name, 'parameter', state.field, primary_var_name='(set-to-None)') term.args[ii] = par term._kwargs[known_name] = par par.set_data(state()) new_terms = Terms(terms) objs.append(Equation('eq_%d' % iv, new_terms)) subequations = Equations(objs) return subequations
def test_variables(self): from sfepy.discrete import FieldVariable 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) ## print u() ## print u.get_vector() # Coefficient vector w.r.t. the field space basis. ## print u(gamma1) ## print u.get_vector(gamma2) 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 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 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 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 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 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_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 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
def get_volume(problem, field_name, region_name, quad_order=1): """ Get volume of a given region using integration defined by a given field. Both the region and the field have to be defined in `problem`. """ from sfepy.discrete import FieldVariable field = problem.fields[field_name] var = FieldVariable('u', 'parameter', field, 1, primary_var_name='(set-to-None)') vol = problem.evaluate('d_volume.%d.%s( u )' % (quad_order, region_name), u=var) return vol
def test_continuity(self): from sfepy.base.base import Struct from sfepy.mesh.mesh_generators import gen_block_mesh from sfepy.discrete import FieldVariable from sfepy.discrete.fem import FEDomain, Field from sfepy.discrete.projections import make_l2_projection_data import sfepy.discrete.fem.refine_hanging as rh dims = [1.5, 2.0, 1.3] shape = [3, 3, 3] centre = [0.0, 0.0, 0.0] probe_gens = {"2_4": _gen_lines_2_4, "3_8": _gen_grid_3_8} ok = True for key in self.gel_names: gel = self.gels[key] probe_gen = probe_gens[key] perms = gel.get_conn_permutations() dim = gel.dim for io, order in enumerate(range(1, 4)): mesh00 = gen_block_mesh(dims[:dim], shape[:dim], centre[:dim], name="block") for ip, perm in enumerate(perms): self.report("geometry: %s, order: %d, permutation: %d: %s" % (key, order, ip, perm)) mesh0 = mesh00.copy() conn = mesh0.cmesh.get_conn(dim, 0).indices conn = conn.reshape((mesh0.n_el, -1)) conn[-1, :] = conn[-1, perm] domain0 = FEDomain("d", mesh0) refine = nm.zeros(mesh0.n_el, dtype=nm.uint8) refine[:-1] = 1 subs = None domain, subs = rh.refine(domain0, refine, subs=subs) omega = domain.create_region("Omega", "all") field = Field.from_args("fu", nm.float64, 1, omega, approx_order=order) field.substitute_dofs(subs) uvar = FieldVariable("u", "parameter", field, primary_var_name="(set-to-None)") field.restore_dofs(store=True) field.substitute_dofs(subs=None, restore=True) make_l2_projection_data(uvar, eval_fun) field.restore_dofs() bbox = domain.get_mesh_bounding_box() eps = 1e-7 save = False for ii, (probe0, probe1) in enumerate(probe_gen(bbox, eps)): probe0.set_options(close_limit=0.0) probe1.set_options(close_limit=0.0) pars0, vals0 = probe0(uvar) pars1, vals1 = probe1(uvar) assert_(nm.allclose(pars0, pars1, atol=1e-14, rtol=0.0)) _ok = nm.allclose(vals0, vals1, atol=20.0 * eps, rtol=0.0) if not _ok: save = True self.report("probe %d failed! (max. error: %e)" % (ii, nm.abs(vals0 - vals1).max())) ok = ok and _ok if (ip == 0) or save: out = uvar.create_output() filenames = _build_filenames(self.options.out_dir, key, order, ip) domain.mesh.write(filenames[0], out=out) linearization = Struct(kind="adaptive", min_level=0, max_level=4, eps=1e-2) out = uvar.create_output(linearization=linearization) val = out["u"] mesh = val.get("mesh", domain.mesh) mesh.write(filenames[1], out=out) return ok
def save_basis_on_mesh(mesh, options, output_dir, lin, permutations=None, suffix=''): if permutations is not None: mesh = mesh.copy() gel = GeometryElement(mesh.descs[0]) perms = gel.get_conn_permutations()[permutations] conn = mesh.cmesh.get_cell_conn() n_el, n_ep = conn.num, gel.n_vertex offsets = nm.arange(n_el) * n_ep conn.indices[:] = conn.indices.take((perms + offsets[:, None]).ravel()) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('f', nm.float64, shape=1, region=omega, approx_order=options.max_order, poly_space_base=options.basis) var = FieldVariable('u', 'unknown', field) if options.plot_dofs: import sfepy.postprocess.plot_dofs as pd import sfepy.postprocess.plot_cmesh as pc ax = pc.plot_wireframe(None, mesh.cmesh) ax = pd.plot_global_dofs(ax, field.get_coor(), field.econn) ax = pd.plot_local_dofs(ax, field.get_coor(), field.econn) if options.dofs is not None: ax = pd.plot_nodes(ax, field.get_coor(), field.econn, field.poly_space.nodes, get_dofs(options.dofs, var.n_dof)) pd.plt.show() output('dofs: %d' % var.n_dof) vec = nm.empty(var.n_dof, dtype=var.dtype) n_digit, _format = get_print_info(var.n_dof, fill='0') name_template = os.path.join(output_dir, 'dof_%s%s.vtk' % (_format, suffix)) for ip in get_dofs(options.dofs, var.n_dof): output('dof %d...' % ip) vec.fill(0.0) vec[ip] = 1.0 var.set_data(vec) if options.derivative == 0: out = var.create_output(vec, linearization=lin) else: out = create_expression_output('ev_grad.ie.Elements(u)', 'u', 'f', {'f' : field}, None, Variables([var]), mode='qp', verbose=False, min_level=lin.min_level, max_level=lin.max_level, eps=lin.eps) name = name_template % ip ensure_path(name) out['u'].mesh.write(name, out=out) output('...done (%s)' % name)
def solve_problem(mesh_filename, options, comm): order = options.order rank, size = comm.Get_rank(), comm.Get_size() output('rank', rank, 'of', size) mesh = Mesh.from_file(mesh_filename) if rank == 0: cell_tasks = pl.partition_mesh(mesh, size, use_metis=options.metis, verbose=True) else: cell_tasks = None domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') field = Field.from_args('fu', nm.float64, 1, omega, approx_order=order) output('distributing field %s...' % field.name) tt = time.clock() distribute = pl.distribute_fields_dofs lfds, gfds = distribute([field], cell_tasks, is_overlap=True, save_inter_regions=options.save_inter_regions, output_dir=options.output_dir, comm=comm, verbose=True) lfd = lfds[0] output('...done in', time.clock() - tt) if rank == 0: dof_maps = gfds[0].dof_maps id_map = gfds[0].id_map if options.verify: verify_save_dof_maps(field, cell_tasks, dof_maps, id_map, options, verbose=True) if options.plot: ppd.plot_partitioning([None, None], field, cell_tasks, gfds[0], options.output_dir, size) output('creating local problem...') tt = time.clock() omega_gi = Region.from_cells(lfd.cells, field.domain) omega_gi.finalize() omega_gi.update_shape() pb = create_local_problem(omega_gi, order) output('...done in', time.clock() - tt) variables = pb.get_variables() eqs = pb.equations u_i = variables['u_i'] field_i = u_i.field if options.plot: ppd.plot_local_dofs([None, None], field, field_i, omega_gi, options.output_dir, rank) output('allocating global system...') tt = time.clock() sizes, drange = pl.get_sizes(lfd.petsc_dofs_range, field.n_nod, 1) output('sizes:', sizes) output('drange:', drange) pdofs = pl.get_local_ordering(field_i, lfd.petsc_dofs_conn) output('pdofs:', pdofs) pmtx, psol, prhs = pl.create_petsc_system(pb.mtx_a, sizes, pdofs, drange, is_overlap=True, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('evaluating local problem...') tt = time.clock() state = State(variables) state.fill(0.0) state.apply_ebc() rhs_i = eqs.eval_residuals(state()) # This must be after pl.create_petsc_system() call! mtx_i = eqs.eval_tangent_matrices(state(), pb.mtx_a) output('...done in', time.clock() - tt) output('assembling global system...') tt = time.clock() pl.apply_ebc_to_matrix(mtx_i, u_i.eq_map.eq_ebc) pl.assemble_rhs_to_petsc(prhs, rhs_i, pdofs, drange, is_overlap=True, comm=comm, verbose=True) pl.assemble_mtx_to_petsc(pmtx, mtx_i, pdofs, drange, is_overlap=True, comm=comm, verbose=True) output('...done in', time.clock() - tt) output('creating solver...') tt = time.clock() conf = Struct(method='cg', precond='gamg', sub_precond=None, i_max=10000, eps_a=1e-50, eps_r=1e-5, eps_d=1e4, verbose=True) status = {} ls = PETScKrylovSolver(conf, comm=comm, mtx=pmtx, status=status) output('...done in', time.clock() - tt) output('solving...') tt = time.clock() psol = ls(prhs, psol, conf) psol_i = pl.create_local_petsc_vector(pdofs) gather, scatter = pl.create_gather_scatter(pdofs, psol_i, psol, comm=comm) scatter(psol_i, psol) sol0_i = state() - psol_i[...] psol_i[...] = sol0_i gather(psol, psol_i) output('...done in', time.clock() - tt) output('saving solution...') tt = time.clock() u_i.set_data(sol0_i) out = u_i.create_output() filename = os.path.join(options.output_dir, 'sol_%02d.h5' % comm.rank) pb.domain.mesh.write(filename, io='auto', out=out) gather_to_zero = pl.create_gather_to_zero(psol) psol_full = gather_to_zero(psol) if comm.rank == 0: sol = psol_full[...].copy()[id_map] u = FieldVariable('u', 'parameter', field, primary_var_name='(set-to-None)') filename = os.path.join(options.output_dir, 'sol.h5') if (order == 1) or (options.linearization == 'strip'): out = u.create_output(sol) mesh.write(filename, io='auto', out=out) else: out = u.create_output(sol, linearization=Struct(kind='adaptive', min_level=0, max_level=order, eps=1e-3)) out['u'].mesh.write(filename, io='auto', out=out) output('...done in', time.clock() - tt) if options.show: plt.show()
def create_local_problem(omega_gi, 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 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 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 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 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 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)