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 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_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 _get_fixed_displacementsBCs(self, domain): """ Fix the left top and bottom points in x, y and z Args: domain: an Sfepy domain Returns: the Sfepy boundary conditions """ min_xyz = domain.get_mesh_bounding_box()[0] max_xyz = domain.get_mesh_bounding_box()[1] kwargs = {} fix_points_dict = {'u.0': 0.0, 'u.1': 0.0} if len(min_xyz) == 3: kwargs = {'z': (max_xyz[2], min_xyz[2])} fix_points_dict['u.2'] = 0.0 fix_x_points_ = self._subdomain_func(x=(min_xyz[0],), y=(max_xyz[1], min_xyz[1]), **kwargs) fix_x_points = Function('fix_x_points', fix_x_points_) region_fix_points = domain.create_region( 'region_fix_points', 'vertices by fix_x_points', 'vertex', functions=Functions([fix_x_points])) return EssentialBC('fix_points_BC', region_fix_points, fix_points_dict)
def _get_shift_displacementsBCs(self, domain): """ Fix the right top and bottom points in x, y and z Args: domain: an Sfepy domain Returns: the Sfepy boundary conditions """ min_xyz = domain.get_mesh_bounding_box()[0] max_xyz = domain.get_mesh_bounding_box()[1] kwargs = {} if len(min_xyz) == 3: kwargs = {'z': (max_xyz[2], min_xyz[2])} displacement = self.macro_strain * (max_xyz[0] - min_xyz[0]) shift_points_dict = {'u.0': displacement} shift_x_points_ = self._subdomain_func(x=(max_xyz[0],), y=(max_xyz[1], min_xyz[1]), **kwargs) shift_x_points = Function('shift_x_points', shift_x_points_) region_shift_points = domain.create_region( 'region_shift_points', 'vertices by shift_x_points', 'vertex', functions=Functions([shift_x_points])) return EssentialBC('shift_points_BC', region_shift_points, shift_points_dict)
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 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 func(min_xyz, max_xyz): return pipe( dict(z_points=(max_xyz[2], min_xyz[2])) if len(min_xyz) == 3 else dict(), lambda x: subdomain_func( x_points=x_points_f(min_xyz, max_xyz), y_points=(max_xyz[1], min_xyz[1]), **x, ), lambda x: Function(f"{name}_x_points", x), lambda x: domain.create_region( f"region_{name}_points", f"vertices by {name}_x_points", "vertex", functions=Functions([x]), ), lambda x: EssentialBC( f"{name}_points_BC", x, points_dict_f(min_xyz, max_xyz) ), )
def get_bc(domain, delta_x, index, cond): """Make a displacement boundary condition Args: domain: the Sfepy domain delta_x: the mesh spacing index: the index (either 0 or 1) depends on direction of axes cond: the BC dictionary Returns: the Sfepy boundary condition """ return pipe( Function("fix_points", subdomain(index, domain, delta_x * 1e-3)), lambda x: domain.create_region( "region_fix_points", "vertices by fix_points", "vertex", functions=Functions([x]), ), lambda x: EssentialBC("fix_points_BC", x, cond), )
def test_ebcs(self): from sfepy.discrete.conditions import Conditions, EssentialBC variables = self.variables regions = self.problem.domain.regions all_ebcs = [] all_ebcs.append( EssentialBC('fix_u1', regions['LeftFix'], {'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['RightFix'], {'p.all': 0.0})) all_ebcs.append( EssentialBC('fix_p2', regions['RightStrip'], {'p.0': 0.0})) all_ebcs.append([ EssentialBC('fix_p3', regions['Right'], {'p.0': 0.0}), EssentialBC('fix_u3', regions['Left'], { 'u.0': 0.0, 'u.1': 1.0 }) ]) ok = True for ii, bcs in enumerate(all_ebcs): if not isinstance(bcs, list): bcs = [bcs] ebcs = Conditions(bcs) variables.equation_mapping(ebcs=ebcs, epbcs=None, ts=None, functions=None) vec = init_vec(variables) variables.apply_ebc(vec) ok = check_vec(self, vec, ii, ok, ebcs, variables) return ok
FluxT = NonlinearHyperbolicDGFluxTerm("burgess_lf_flux(f, df, u, v)", "fun , fun_d, v, u[-1]", integral, omega, u=u, v=v, fun=burg_fun, fun_d=burg_fun_d) eq = Equation('balance', MassT - StiffT + FluxT) eqs = Equations([eq]) # ------------------------------ # | Create bounrady conditions | # ------------------------------ left_fix_u = EssentialBC('left_fix_u', left, {'u.all': 1.0}) right_fix_u = EssentialBC('right_fix_u', right, {'u.all': 0.0}) # ---------------------------- # | Create initial condition | # ---------------------------- def ic_wrap(x, ic=None): return ghump(x - .3) ic_fun = Function('ic_fun', ic_wrap) ics = InitialCondition('ic', omega, {'u.0': ic_fun}) # ------------------ # | Create problem |
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 create_local_problem(omega_gi, order): """ Local problem definition using a domain corresponding to the global region `omega_gi`. """ mesh = omega_gi.domain.mesh # All tasks have the whole mesh. bbox = mesh.get_bounding_box() min_x, max_x = bbox[:, 0] eps_x = 1e-8 * (max_x - min_x) mesh_i = Mesh.from_region(omega_gi, mesh, localize=True) domain_i = FEDomain('domain_i', mesh_i) omega_i = domain_i.create_region('Omega', 'all') gamma1_i = domain_i.create_region('Gamma1', 'vertices in (x < %.10f)' % (min_x + eps_x), 'facet', allow_empty=True) gamma2_i = domain_i.create_region('Gamma2', 'vertices in (x > %.10f)' % (max_x - eps_x), 'facet', allow_empty=True) field_i = Field.from_args('fu', nm.float64, 1, omega_i, approx_order=order) output('number of local field DOFs:', field_i.n_nod) u_i = FieldVariable('u_i', 'unknown', field_i) v_i = FieldVariable('v_i', 'test', field_i, primary_var_name='u_i') integral = Integral('i', order=2 * order) mat = Material('m', lam=10, mu=5) t1 = Term.new('dw_laplace(m.lam, v_i, u_i)', integral, omega_i, m=mat, v_i=v_i, u_i=u_i) def _get_load(coors): val = nm.ones_like(coors[:, 0]) for coor in coors.T: val *= nm.sin(4 * nm.pi * coor) return val def get_load(ts, coors, mode=None, **kwargs): if mode == 'qp': return {'val': _get_load(coors).reshape(coors.shape[0], 1, 1)} load = Material('load', function=Function('get_load', get_load)) t2 = Term.new('dw_volume_lvf(load.val, v_i)', integral, omega_i, load=load, v_i=v_i) eq = Equation('balance', t1 - 100 * t2) eqs = Equations([eq]) ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all': 0.0}) ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.all': 0.1}) pb = Problem('problem_i', equations=eqs, active_only=False) pb.time_update(ebcs=Conditions([ebc1, ebc2])) pb.update_materials() return pb
def main(cli_args): dims = parse_argument_list(cli_args.dims, float) shape = parse_argument_list(cli_args.shape, int) centre = parse_argument_list(cli_args.centre, float) material_parameters = parse_argument_list(cli_args.material_parameters, float) order = cli_args.order ts_vals = cli_args.ts.split(',') ts = { 't0': float(ts_vals[0]), 't1': float(ts_vals[1]), 'n_step': int(ts_vals[2]) } do_plot = cli_args.plot ### Mesh and regions ### mesh = gen_block_mesh(dims, shape, centre, name='block', verbose=False) domain = FEDomain('domain', mesh) omega = domain.create_region('Omega', 'all') lbn, rtf = domain.get_mesh_bounding_box() box_regions = define_box_regions(3, lbn, rtf) regions = dict( [[r, domain.create_region(r, box_regions[r][0], box_regions[r][1])] for r in box_regions]) ### Fields ### scalar_field = Field.from_args('fu', np.float64, 'scalar', omega, approx_order=order - 1) vector_field = Field.from_args('fv', np.float64, 'vector', omega, approx_order=order) u = FieldVariable('u', 'unknown', vector_field, history=1) v = FieldVariable('v', 'test', vector_field, primary_var_name='u') p = FieldVariable('p', 'unknown', scalar_field, history=1) q = FieldVariable('q', 'test', scalar_field, primary_var_name='p') ### Material ### c10, c01 = material_parameters m = Material( 'm', mu=2 * c10, kappa=2 * c01, ) ### Boundary conditions ### x_sym = EssentialBC('x_sym', regions['Left'], {'u.0': 0.0}) y_sym = EssentialBC('y_sym', regions['Near'], {'u.1': 0.0}) z_sym = EssentialBC('z_sym', regions['Bottom'], {'u.2': 0.0}) disp_fun = Function('disp_fun', get_displacement) displacement = EssentialBC('displacement', regions['Right'], {'u.0': disp_fun}) ebcs = Conditions([x_sym, y_sym, z_sym, displacement]) ### Terms and equations ### integral = Integral('i', order=2 * order) term_neohook = Term.new('dw_tl_he_neohook(m.mu, v, u)', integral, omega, m=m, v=v, u=u) term_mooney = Term.new('dw_tl_he_mooney_rivlin(m.kappa, v, u)', integral, omega, m=m, v=v, u=u) term_pressure = Term.new('dw_tl_bulk_pressure(v, u, p)', integral, omega, v=v, u=u, p=p) term_volume_change = Term.new('dw_tl_volume(q, u)', integral, omega, q=q, u=u, term_mode='volume') term_volume = Term.new('dw_volume_integrate(q)', integral, omega, q=q) eq_balance = Equation('balance', term_neohook + term_mooney + term_pressure) eq_volume = Equation('volume', term_volume_change - term_volume) equations = Equations([eq_balance, eq_volume]) ### Solvers ### ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({'i_max': 5}, lin_solver=ls, status=nls_status) ### Problem ### pb = Problem('hyper', equations=equations) pb.set_bcs(ebcs=ebcs) pb.set_ics(ics=Conditions([])) tss = SimpleTimeSteppingSolver(ts, nls=nls, context=pb) pb.set_solver(tss) ### Solution ### axial_stress = [] axial_displacement = [] def stress_strain_fun(*args, **kwargs): return stress_strain(*args, order=order, global_stress=axial_stress, global_displacement=axial_displacement, **kwargs) pb.solve(save_results=True, post_process_hook=stress_strain_fun) if do_plot: plot_graphs(material_parameters, axial_stress, axial_displacement, undeformed_length=dims[0])
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 FarField(eltype, points, boundary, lcar, epsilon, meshfile, thickness=None, verbose=False): """ This function determines a geometric factor F within a single element. The element type can be triangular, quadrilateral, tetrahedral or hexahedral. For these types eltype is set to "CTRIA3", "CQUAD4" "CTETRA" and "CHEXA8" respectively. The vertices of the element are provided in the input parameter points. The input parameter boundary is of boolean type and has the same size as points. Those points which are part of the conductive interface CI are flagged True. Epsilon sets a tolerance to determine which mesh vertices are considered part of the FF boundary. The meshing of the element is stored in a location provided by meshfile. Parameters ---------- eltype: string 'CTRIA3' for triangular surface elements, 'CQUAD4' for quadrilateral surface elements, 'CTETRA' for tetrahedral volume elements. 'CHEXA8' for hexahedral volume elements. points: array like Array containing the coordinates of the element boundary: array like Array containing the entries of the boundary points lcar: float Characteristic length value provided to gmsh for mesh sizing. epsilon: float Numerical tolerance on criterion for far field boundary meshfile: string Filename and location for storing temporary mesh file verbose: boolean Indicate whether intermediate results should be displayed or not Returns ------- : array like Array with boolean entries stating True for those items on the boundary and False otherwise """ if verbose is True: output.set_output(quiet=False) else: output.set_output(quiet=True) if (eltype == "CTRIA3") or (eltype == "CQUAD4"): sdim = 2 else: sdim = 3 boundpnts = [] for i in range(len(points)): if boundary[i]: boundpnts.append(points[i]) mesh = sfedis.fem.Mesh.from_file(meshfile) domain = sfedis.fem.FEDomain('domain', mesh) c = sfedis.Material('c', val=1.0) omega = domain.create_region('Omega', 'all') if verbose is True: coors = mesh.coors fixed_vert = _is_on_bound(coors, bound=boundpnts, sdim=sdim, epsilon=epsilon) print "fixed vertices:" print fixed_vert is_on_bound = sfedis.Functions([ sfedis.Function('_is_on_bound', _is_on_bound, extra_args={ 'bound': boundpnts, 'sdim': sdim, 'epsilon': lcar / 100. }), ]) fixed = domain.create_region('fixed', 'vertices by _is_on_bound', 'facet', functions=is_on_bound, add_to_regions=True) field_t = sfedis.fem.Field.from_args('temperature', np.float64, 'scalar', omega, approx_order=2) t = sfedis.FieldVariable('t', 'unknown', field_t, 1) s = sfedis.FieldVariable('s', 'test', field_t, 1, primary_var_name='t') integral = sfedis.Integral('i', order=4) term1 = Term.new('dw_laplace(s, t)', integral, omega, s=s, t=t) term2 = Term.new('dw_volume_integrate(c.val, s)', integral, omega, c=c, s=s) # heat source term for 1st step of far field eq = sfedis.Equation('temperature', term1 - term2) eqs = sfedis.Equations([eq]) t_fixed = EssentialBC('t_fixed', fixed, {'t.0': 0.0}) ls = ScipyDirect({}) nls = Newton({'i_max': 1, 'eps_a': 1e-10}, lin_solver=ls) pb = sfedis.Problem('temperature', equations=eqs, nls=nls, ls=ls) pb.time_update(ebcs=Conditions([ t_fixed, ])) temperature = pb.solve() out = temperature.create_output_dict() if verbose is True: pb.save_state('result.vtk', out=out) view = Viewer('result.vtk') view(is_wireframe=True, rel_scaling=1, is_scalar_bar=True) print "Maximum temperature: %f" % np.max(out['t'].data) data = [i[0] for i in out['t'].data] FF = _get_far(eltype, points, data, mesh, sdim, epsilon) str1 = ''.join(str(v) + ', ' for v in FF)[:-2] try: far = domain.create_region('far', 'vertex %s' % str1, 'facet', add_to_regions=True) except Exception as e: print "Far field region creation failed!" print(e) t.reset() s.reset() return area_source = pb.evaluate('d_surface.3.far(t)') fluxval = 1.0 / (area_source) c2 = sfedis.Material( 'c2', val=fluxval ) # So that total heat at the far field is 1W equally distributed over all elements term1A = Term.new('dw_laplace(c.val, s, t)', integral, omega, c=c, s=s, t=t) term2A = Term.new('dw_surface_integrate(c2.val, s)', integral, far, c2=c2, s=s) eq2 = sfedis.Equation('temperature2', term1A - term2A) eqs2 = sfedis.Equations([eq2]) pb2 = sfedis.Problem('temperature2', equations=eqs2, nls=nls, ls=ls) pb2.time_update(ebcs=Conditions([ t_fixed, ])) temperature2 = pb2.solve() out2 = temperature2.create_output_dict() volume = pb2.evaluate('d_volume.3.Omega(t)') t_int = pb2.evaluate('ev_volume_integrate.3.Omega(t)') avg_t = t_int / volume F = 1.0 / avg_t if verbose is True: print "Average temperature: %f" % avg_t if thickness: 'Correction factor 1e-3 is due to geometry in mm instead of m' F = F * thickness * 1e-3 if verbose is True: pb.save_state('result.vtk', out=out2) view = Viewer('result.vtk') view(is_wireframe=True, rel_scaling=1, is_scalar_bar=True) t.reset() s.reset() return F
def set_bc_impl(ts, coors, bc=None, problem=None, **kwargs): x = coors[:, 0] y = coors[:, 1] val = np.sin(x / np.pi) * np.sin(y / np.pi) # val = 0*x # val = 0.0001*np.ones(x.size) return val # fix_u = EssentialBC('fix_u', omega, {'u.all' : 0.0}) # bc1 = EssentialBC('Gamma_Left', gammaL, {'t.0' : -20.0}) # bc2 = EssentialBC('Gamma_Right', gammaR, {'t.0' : 20.0}) set_bc_fun = Function('set_bc_impl', set_bc_impl) bc1 = EssentialBC('Gamma_Left', gammaL, {'t.0': set_bc_fun}) bc2 = EssentialBC('Gamma_Right', gammaR, {'t.0': set_bc_fun}) bc3 = EssentialBC('Gamma_Top', gammaT, {'t.0': set_bc_fun}) bc4 = EssentialBC('Gamma_Bottom', gammaB, {'t.0': set_bc_fun}) ls = ScipyDirect({}) nls_status = IndexedStruct() newtonConfig = {'i_max': 10, 'eps_a': 1e-10, 'eps_r': 1} nls = Newton(newtonConfig, lin_solver=ls, status=nls_status) pb = Problem('Poisson', equations=eqs, nls=nls, ls=ls) pb.save_regions_as_groups('regions') # pb.time_update(ebcs=Conditions([fix_u, t1, t2]))
m = Material('m', D=stiffness_from_youngpoisson(dim=3, young=6.8e10, poisson=0.36), rho=2700.0) integral = Integral('i', order=1) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) eq1 = Equation('balance_of_forces', t1) eqs = Equations([eq1]) z_displacements = np.linspace(0, 0.05, 6) vm_stresses = np.zeros([len(z_displacements), 2]) for i, z_displacement in enumerate(z_displacements): fix_bot = EssentialBC('fix_bot', bot, {'u.all': 0.0}) fix_top = EssentialBC('fix_top', top, { 'u.[0,1]': 0.0, 'u.[2]': -z_displacement }) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) # 'i_max': 1, 'eps_a': 1e-10 pb = Problem('elasticity', equations=eqs) pb.save_regions_as_groups('regions') pb.set_bcs(ebcs=Conditions([fix_bot, fix_top]))
def main(argv=None): options = parse_args(argv=argv) # vvvvvvvvvvvvvvvv # approx_order = 2 # ^^^^^^^^^^^^^^^^ # # Setup output names outputs_folder = options.output_dir domain_name = "domain_1D" problem_name = "iburgers_1D" output_folder = pjoin(outputs_folder, problem_name, str(approx_order)) output_format = "vtk" save_timestn = 100 clear_folder(pjoin(output_folder, "*." + output_format)) configure_output({ 'output_screen': True, 'output_log_name': pjoin(output_folder, f"last_run_{problem_name}_{approx_order}.txt") }) # ------------ # | Get mesh | # ------------ X1 = 0. XN = 1. n_nod = 100 n_el = n_nod - 1 mesh = get_gen_1D_mesh_hook(X1, XN, n_nod).read(None) # ----------------------------- # | Create problem components | # ----------------------------- integral = Integral('i', order=approx_order * 2) domain = FEDomain(domain_name, mesh) omega = domain.create_region('Omega', 'all') left = domain.create_region('Gamma1', 'vertices in x == %.10f' % X1, 'vertex') right = domain.create_region('Gamma2', 'vertices in x == %.10f' % XN, 'vertex') field = DGField('dgfu', nm.float64, 'scalar', omega, approx_order=approx_order) u = FieldVariable('u', 'unknown', field, history=1) v = FieldVariable('v', 'test', field, primary_var_name='u') MassT = Term.new('dw_dot(v, u)', integral, omega, u=u, v=v) velo = nm.array(1.0) def adv_fun(u): vu = velo.T * u[..., None] return vu def adv_fun_d(u): v1 = velo.T * nm.ones(u.shape + (1, )) return v1 burg_velo = velo.T / nm.linalg.norm(velo) def burg_fun(u): vu = burg_velo * u[..., None]**2 return vu def burg_fun_d(u): v1 = 2 * burg_velo * u[..., None] return v1 StiffT = Term.new('dw_ns_dot_grad_s(fun, fun_d, u[-1], v)', integral, omega, u=u, v=v, fun=burg_fun, fun_d=burg_fun_d) # alpha = Material('alpha', val=[.0]) # FluxT = AdvectDGFluxTerm("adv_lf_flux(a.val, v, u)", "a.val, v, u[-1]", # integral, omega, u=u, v=v, a=a, alpha=alpha) FluxT = Term.new('dw_dg_nonlinear_laxfrie_flux(fun, fun_d, v, u[-1])', integral, omega, u=u, v=v, fun=burg_fun, fun_d=burg_fun_d) eq = Equation('balance', MassT - StiffT + FluxT) eqs = Equations([eq]) # ------------------------------ # | Create boundary conditions | # ------------------------------ left_fix_u = EssentialBC('left_fix_u', left, {'u.all': 1.0}) right_fix_u = EssentialBC('right_fix_u', right, {'u.all': 0.0}) # ---------------------------- # | Create initial condition | # ---------------------------- def ghump(x): """ Nice gaussian. """ return nm.exp(-200 * x**2) def ic_wrap(x, ic=None): return ghump(x - .3) ic_fun = Function('ic_fun', ic_wrap) ics = InitialCondition('ic', omega, {'u.0': ic_fun}) # ------------------ # | Create problem | # ------------------ pb = Problem(problem_name, equations=eqs, conf=Struct(options={"save_times": save_timestn}, ics={}, ebcs={}, epbcs={}, lcbcs={}, materials={}), active_only=False) pb.setup_output(output_dir=output_folder, output_format=output_format) pb.set_ics(Conditions([ics])) # ------------------ # | Create limiter | # ------------------ limiter = MomentLimiter1D # --------------------------- # | Set time discretization | # --------------------------- CFL = .2 max_velo = nm.max(nm.abs(velo)) t0 = 0 t1 = .2 dx = nm.min(mesh.cmesh.get_volumes(1)) dt = dx / max_velo * CFL / (2 * approx_order + 1) tn = int(nm.ceil((t1 - t0) / dt)) dtdx = dt / dx # ------------------ # | Create solver | # ------------------ ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({'is_linear': True}, lin_solver=ls, status=nls_status) tss_conf = { 't0': t0, 't1': t1, 'n_step': tn, 'limiters': { "dgfu": limiter } } tss = TVDRK3StepSolver(tss_conf, nls=nls, context=pb, verbose=True) # --------- # | Solve | # --------- pb.set_solver(tss) state_end = pb.solve() output("Solved equation \n\n\t\t u_t - div(f(u))) = 0\n") output(f"With IC: {ic_fun.name}") # output("and EBCs: {}".format(pb.ebcs.names)) # output("and EPBCS: {}".format(pb.epbcs.names)) output("-------------------------------------") output(f"Approximation order is {approx_order}") output(f"Space divided into {mesh.n_el} cells, " + f"{len(mesh.coors)} steps, step size is {dx}") output(f"Time divided into {tn - 1} nodes, {tn} steps, step size is {dt}") output(f"CFL coefficient was {CFL} and " + f"order correction {1 / (2 * approx_order + 1)}") output(f"Courant number c = max(abs(u)) * dt/dx = {max_velo * dtdx}") output("------------------------------------------") output(f"Time stepping solver is {tss.name}") output(f"Limiter used: {limiter.name}") output("======================================") # ---------- # | Plot 1D| # ---------- if options.plot: load_and_plot_fun(output_folder, domain_name, t0, t1, min(tn, save_timestn), ic_fun)
def main(): parser = ArgumentParser(description=__doc__.rstrip(), formatter_class=RawDescriptionHelpFormatter) parser.add_argument('output_dir', help=helps['output_dir']) parser.add_argument('--dims', metavar='dims', action='store', dest='dims', default='1.0,1.0,1.0', help=helps['dims']) parser.add_argument('--shape', metavar='shape', action='store', dest='shape', default='7,7,7', help=helps['shape']) parser.add_argument('--centre', metavar='centre', action='store', dest='centre', default='0.0,0.0,0.0', help=helps['centre']) parser.add_argument('-3', '--3d', action='store_true', dest='is_3d', default=False, help=helps['3d']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) options = parser.parse_args() dim = 3 if options.is_3d else 2 dims = nm.array(eval(options.dims), dtype=nm.float64)[:dim] shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim] centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim] output('dimensions:', dims) output('shape: ', shape) output('centre: ', centre) mesh0 = gen_block_mesh(dims, shape, centre, name='block-fem', verbose=True) domain0 = FEDomain('d', mesh0) bbox = domain0.get_mesh_bounding_box() min_x, max_x = bbox[:, 0] eps = 1e-8 * (max_x - min_x) cnt = (shape[0] - 1) // 2 g0 = 0.5 * dims[0] grading = nm.array([g0 / 2**ii for ii in range(cnt)]) + eps + centre[0] - g0 domain, subs = refine_towards_facet(domain0, grading, 'x <') omega = domain.create_region('Omega', 'all') gamma1 = domain.create_region('Gamma1', 'vertices in (x < %.10f)' % (min_x + eps), 'facet') gamma2 = domain.create_region('Gamma2', 'vertices in (x > %.10f)' % (max_x - eps), 'facet') field = Field.from_args('fu', nm.float64, 1, omega, approx_order=options.order) if subs is not None: field.substitute_dofs(subs) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') integral = Integral('i', order=2*options.order) t1 = Term.new('dw_laplace(v, u)', integral, omega, v=v, u=u) eq = Equation('eq', t1) eqs = Equations([eq]) def u_fun(ts, coors, bc=None, problem=None): """ Define a displacement depending on the y coordinate. """ if coors.shape[1] == 2: min_y, max_y = bbox[:, 1] y = (coors[:, 1] - min_y) / (max_y - min_y) val = (max_y - min_y) * nm.cos(3 * nm.pi * y) else: min_y, max_y = bbox[:, 1] min_z, max_z = bbox[:, 2] y = (coors[:, 1] - min_y) / (max_y - min_y) z = (coors[:, 2] - min_z) / (max_z - min_z) val = ((max_y - min_y) * (max_z - min_z) * nm.cos(3 * nm.pi * y) * (1.0 + 3.0 * (z - 0.5)**2)) return val bc_fun = Function('u_fun', u_fun) fix1 = EssentialBC('shift_u', gamma1, {'u.0' : bc_fun}) fix2 = EssentialBC('fix2', gamma2, {'u.all' : 0.0}) ls = ScipyDirect({}) nls = Newton({}, lin_solver=ls) pb = Problem('heat', equations=eqs, nls=nls, ls=ls) pb.time_update(ebcs=Conditions([fix1, fix2])) state = pb.solve() if subs is not None: field.restore_dofs() filename = os.path.join(options.output_dir, 'hanging.vtk') ensure_path(filename) pb.save_state(filename, state) if options.order > 1: pb.save_state(filename, state, linearization=Struct(kind='adaptive', min_level=0, max_level=8, eps=1e-3))
def main(): parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('-d', '--dims', metavar='dims', action='store', dest='dims', default='[1.0, 1.0]', help=helps['dims']) parser.add_argument('-c', '--centre', metavar='centre', action='store', dest='centre', default='[0.0, 0.0]', help=helps['centre']) parser.add_argument('-s', '--shape', metavar='shape', action='store', dest='shape', default='[11, 11]', help=helps['shape']) parser.add_argument('-b', '--bc-kind', metavar='kind', action='store', dest='bc_kind', choices=['free', 'cantilever', 'fixed'], default='free', help=helps['bc_kind']) parser.add_argument('-a', '--axis', metavar='0, ..., dim, or -1', type=int, action='store', dest='axis', default=-1, help=helps['axis']) parser.add_argument('--young', metavar='float', type=float, action='store', dest='young', default=200e+9, help=helps['young']) parser.add_argument('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.3, help=helps['poisson']) parser.add_argument('--density', metavar='float', type=float, action='store', dest='density', default=7800.0, help=helps['density']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_argument('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['n_eigs']) parser.add_argument('-i', '--ignore', metavar='int', type=int, action='store', dest='ignore', default=None, help=helps['ignore']) parser.add_argument('--solver', metavar='solver', action='store', dest='solver', default= \ "eig.scipy,method:'eigh',tol:1e-5,maxiter:1000", help=helps['solver']) parser.add_argument('--show', action="store_true", dest='show', default=False, help=helps['show']) #parser.add_argument('filename', nargs='?', default=None) #read block.mesh #parser.add_argument('filename', nargs='?', default="platehexat200mm.mesh") parser.add_argument('filename', nargs='?', default="block_1m.mesh") options = parser.parse_args() aux = options.solver.split(',') kwargs = {} for option in aux[1:]: key, val = option.split(':') kwargs[key.strip()] = eval(val) eig_conf = Struct(name='evp', kind=aux[0], **kwargs) output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' density:', options.density) output('displacement field approximation order:', options.order) output('requested %d eigenvalues' % options.n_eigs) output('using eigenvalue problem solver:', eig_conf.kind) output.level += 1 for key, val in six.iteritems(kwargs): output('%s: %r' % (key, val)) output.level -= 1 assert_((0.0 < options.poisson < 0.5), "Poisson's ratio must be in ]0, 0.5[!") assert_((0 < options.order), 'displacement approximation order must be at least 1!') filename = options.filename if filename is not None: mesh = Mesh.from_file(filename) dim = mesh.dim dims = nm.diff(mesh.get_bounding_box(), axis=0) else: dims = nm.array(eval(options.dims), dtype=nm.float64) dim = len(dims) centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim] shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim] output('dimensions:', dims) output('centre: ', centre) output('shape: ', shape) mesh = gen_block_mesh(dims, shape, centre, name='mesh') output('axis: ', options.axis) assert_((-dim <= options.axis < dim), 'invalid axis value!') eig_solver = Solver.any_from_conf(eig_conf) # Build the problem definition. domain = FEDomain('domain', mesh) bbox = domain.get_mesh_bounding_box() min_coor, max_coor = bbox[:, options.axis] eps = 1e-8 * (max_coor - min_coor) ax = 'xyz'[:dim][options.axis] omega = domain.create_region('Omega', 'all') """ bottom = domain.create_region('Bottom', 'vertices in (%s < %.10f)' % (ax, min_coor + eps), 'facet') bottom_top = domain.create_region('BottomTop', 'r.Bottom +v vertices in (%s > %.10f)' % (ax, max_coor - eps), 'facet') """ #import pdb; pdb.set_trace() left = domain.create_region('left', 'vertices in (x < -0.49)', 'facet') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=options.order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson) m = Material('m', D=mtx_d, rho=options.density) integral = Integral('i', order=2 * options.order) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u) eq1 = Equation('stiffness', t1) eq2 = Equation('mass', t2) lhs_eqs = Equations([eq1, eq2]) pb = Problem('modal', equations=lhs_eqs) """ if options.bc_kind == 'free': pb.time_update() n_rbm = dim * (dim + 1) // 2 elif options.bc_kind == 'cantilever': fixed = EssentialBC('Fixed', bottom, {'u.all' : 0.0}) pb.time_update(ebcs=Conditions([fixed])) n_rbm = 0 elif options.bc_kind == 'fixed': fixed = EssentialBC('Fixed', bottom_top, {'u.all' : 0.0}) pb.time_update(ebcs=Conditions([fixed])) n_rbm = 0 else: raise ValueError('unsupported BC kind! (%s)' % options.bc_kind) if options.ignore is not None: n_rbm = options.ignore """ fixed = EssentialBC('Fixed', left, {'u.all': 0.0}) pb.time_update(ebcs=Conditions([fixed])) n_rbm = 0 pb.update_materials() # Assemble stiffness and mass matrices. mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a) mtx_m = mtx_k.copy() mtx_m.data[:] = 0.0 mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m) try: eigs, svecs = eig_solver(mtx_k, mtx_m, options.n_eigs + n_rbm, eigenvectors=True) except sla.ArpackNoConvergence as ee: eigs = ee.eigenvalues svecs = ee.eigenvectors output('only %d eigenvalues converged!' % len(eigs)) output('%d eigenvalues converged (%d ignored as rigid body modes)' % (len(eigs), n_rbm)) eigs = eigs[n_rbm:] svecs = svecs[:, n_rbm:] omegas = nm.sqrt(eigs) freqs = omegas / (2 * nm.pi) output('number | eigenvalue | angular frequency ' '| frequency') for ii, eig in enumerate(eigs): output('%6d | %17.12e | %17.12e | %17.12e' % (ii + 1, eig, omegas[ii], freqs[ii])) # Make full eigenvectors (add DOFs fixed by boundary conditions). variables = pb.get_variables() vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]), dtype=nm.float64) for ii in range(svecs.shape[1]): vecs[:, ii] = variables.make_full_vec(svecs[:, ii]) # Save the eigenvectors. out = {} state = pb.create_state() for ii in range(eigs.shape[0]): state.set_full(vecs[:, ii]) aux = state.create_output_dict() strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)', integrals=Integrals([integral]), mode='el_avg', verbose=False) out['u%03d' % ii] = aux.popitem()[1] out['strain%03d' % ii] = Struct(mode='cell', data=strain) pb.save_state('eigenshapes.vtk', out=out) pb.save_regions_as_groups('regions') if len(eigs) and options.show: # Show the solution. If the approximation order is greater than 1, the # extra DOFs are simply thrown away. from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.domain_specific import DomainSpecificPlot scaling = 0.05 * dims.max() / nm.abs(vecs).max() ds = {} for ii in range(eigs.shape[0]): pd = DomainSpecificPlot('plot_displacements', [ 'rel_scaling=%s' % scaling, 'color_kind="tensors"', 'color_name="strain%03d"' % ii ]) ds['u%03d' % ii] = pd view = Viewer('eigenshapes.vtk') view(domain_specific=ds, only_names=sorted(ds.keys()), is_scalar_bar=False, is_wireframe=True)
def 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('-o', '--output-dir', default='.', help=helps['output_dir']) parser.add_argument('--R1', metavar='R1', action='store', dest='R1', default='0.5', help=helps['R1']) parser.add_argument('--R2', metavar='R2', action='store', dest='R2', default='1.0', help=helps['R2']) parser.add_argument('--C1', metavar='C1', action='store', dest='C1', default='0.0,0.0', help=helps['C1']) parser.add_argument('--C2', metavar='C2', action='store', dest='C2', default='0.0,0.0', help=helps['C2']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=2, help=helps['order']) parser.add_argument('-v', '--viewpatch', action='store_true', dest='viewpatch', default=False, help=helps['viewpatch']) options = parser.parse_args() # Creation of the NURBS-patch with igakit R1 = eval(options.R1) R2 = eval(options.R2) C1 = list(eval(options.C1)) C2 = list(eval(options.C2)) order = options.order viewpatch = options.viewpatch create_patch(R1, R2, C1, C2, order=order, viewpatch=viewpatch) # Setting a Domain instance filename_domain = data_dir + '/meshes/iga/concentric_circles.iga' domain = IGDomain.from_file(filename_domain) # Sub-domains omega = domain.create_region('Omega', 'all') Gamma_out = domain.create_region('Gamma_out', 'vertices of set xi01', kind='facet') Gamma_in = domain.create_region('Gamma_in', 'vertices of set xi00', kind='facet') # Field (featuring order elevation) order_increase = order - domain.nurbs.degrees[0] order_increase *= int(order_increase > 0) field = Field.from_args('fu', nm.float64, 'scalar', omega, approx_order='iga', space='H1', poly_space_base='iga') # Variables u = FieldVariable('u', 'unknown', field) # unknown function v = FieldVariable('v', 'test', field, primary_var_name='u') # test function # Integral integral = Integral('i', order=2 * field.approx_order) # Term t = Term.new('dw_laplace( v, u )', integral, omega, v=v, u=u) # Equation eq = Equation('laplace', t) eqs = Equations([eq]) # Boundary Conditions u_in = EssentialBC('u_in', Gamma_in, {'u.all': 7.0}) u_out = EssentialBC('u_out', Gamma_out, {'u.all': 3.0}) # solvers ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) # problem instance pb = Problem('potential', equations=eqs, active_only=True) # Set boundary conditions pb.set_bcs(ebcs=Conditions([u_in, u_out])) # solving pb.set_solver(nls) status = IndexedStruct() state = pb.solve(status=status, save_results=True, verbose=True) # Saving the results to a classic VTK file filename = os.path.join(options.output_dir, 'concentric_circles.vtk') ensure_path(filename) pb.save_state(filename, state)
def main(): from sfepy import data_dir parser = OptionParser(usage=usage, version='%prog') parser.add_option('--young', metavar='float', type=float, action='store', dest='young', default=2000.0, help=helps['young']) parser.add_option('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.4, help=helps['poisson']) parser.add_option('--load', metavar='float', type=float, action='store', dest='load', default=-1000.0, help=helps['load']) parser.add_option('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_option('-r', '--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_option('-s', '--show', action="store_true", dest='show', default=False, help=helps['show']) parser.add_option('-p', '--probe', action="store_true", dest='probe', default=False, help=helps['probe']) options, args = parser.parse_args() assert_((0.0 < options.poisson < 0.5), "Poisson's ratio must be in ]0, 0.5[!") assert_((0 < options.order), 'displacement approximation order must be at least 1!') output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' vertical load:', options.load) output('uniform mesh refinement level:', options.refine) # Build the problem definition. mesh = Mesh.from_file(data_dir + '/meshes/2d/its2D.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.001', 'facet') bottom = domain.create_region('Bottom', 'vertices in y < 0.001', 'facet') top = domain.create_region('Top', 'vertex 2', 'vertex') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=options.order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') D = stiffness_from_youngpoisson(2, options.young, options.poisson) asphalt = Material('Asphalt', D=D) load = Material('Load', values={'.val': [0.0, options.load]}) integral = Integral('i', order=2 * options.order) integral0 = Integral('i', order=0) t1 = Term.new('dw_lin_elastic(Asphalt.D, v, u)', integral, omega, Asphalt=asphalt, v=v, u=u) t2 = Term.new('dw_point_load(Load.val, v)', integral0, top, Load=load, v=v) eq = Equation('balance', t1 - t2) eqs = Equations([eq]) xsym = EssentialBC('XSym', bottom, {'u.1': 0.0}) ysym = EssentialBC('YSym', left, {'u.0': 0.0}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls) pb.time_update(ebcs=Conditions([xsym, ysym])) # Solve the problem. state = pb.solve() output(nls_status) # Postprocess the solution. out = state.create_output_dict() out = stress_strain(out, pb, state, extend=True) pb.save_state('its2D_interactive.vtk', out=out) gdata = geometry_data['2_3'] nc = len(gdata.coors) integral_vn = Integral('ivn', coors=gdata.coors, weights=[gdata.volume / nc] * nc) nodal_stress(out, pb, state, integrals=Integrals([integral_vn])) if options.probe: # Probe the solution. probes, labels = gen_lines(pb) sfield = Field.from_args('sym_tensor', nm.float64, 3, omega, approx_order=options.order - 1) stress = FieldVariable('stress', 'parameter', sfield, primary_var_name='(set-to-None)') strain = FieldVariable('strain', 'parameter', sfield, primary_var_name='(set-to-None)') cfield = Field.from_args('component', nm.float64, 1, omega, approx_order=options.order - 1) component = FieldVariable('component', 'parameter', cfield, primary_var_name='(set-to-None)') ev = pb.evaluate order = 2 * (options.order - 1) strain_qp = ev('ev_cauchy_strain.%d.Omega(u)' % order, mode='qp') stress_qp = ev('ev_cauchy_stress.%d.Omega(Asphalt.D, u)' % order, mode='qp', copy_materials=False) project_by_component(strain, strain_qp, component, order) project_by_component(stress, stress_qp, component, order) all_results = [] for ii, probe in enumerate(probes): fig, results = probe_results(u, strain, stress, probe, labels[ii]) fig.savefig('its2D_interactive_probe_%d.png' % ii) all_results.append(results) for ii, results in enumerate(all_results): output('probe %d:' % ii) 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 if options.show: # Show the solution. If the approximation order is greater than 1, the # extra DOFs are simply thrown away. from sfepy.postprocess.viewer import Viewer view = Viewer('its2D_interactive.vtk') view(vector_mode='warp_norm', rel_scaling=1, is_scalar_bar=True, is_wireframe=True)
def main(): parser = OptionParser(usage=usage, version='%prog') parser.add_option('-d', '--dims', metavar='dims', action='store', dest='dims', default='[1.0, 1.0]', help=helps['dims']) parser.add_option('-c', '--centre', metavar='centre', action='store', dest='centre', default='[0.0, 0.0]', help=helps['centre']) parser.add_option('-s', '--shape', metavar='shape', action='store', dest='shape', default='[11, 11]', help=helps['shape']) parser.add_option('-b', '--bc-kind', metavar='kind', action='store', dest='bc_kind', choices=['free', 'clamped'], default='free', help=helps['bc_kind']) parser.add_option('--young', metavar='float', type=float, action='store', dest='young', default=6.80e+10, help=helps['young']) parser.add_option('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.36, help=helps['poisson']) parser.add_option('--density', metavar='float', type=float, action='store', dest='density', default=2700.0, help=helps['density']) parser.add_option('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_option('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['order']) parser.add_option('', '--show', action="store_true", dest='show', default=False, help=helps['show']) options, args = parser.parse_args() assert_((0.0 < options.poisson < 0.5), "Poisson's ratio must be in ]0, 0.5[!") assert_((0 < options.order), 'displacement approximation order must be at least 1!') dims = nm.array(eval(options.dims), dtype=nm.float64) dim = len(dims) centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim] shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim] output('dimensions:', dims) output('centre: ', centre) output('shape: ', shape) output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' density:', options.density) # Build the problem definition. mesh = gen_block_mesh(dims, shape, centre, name='mesh') domain = FEDomain('domain', mesh) bbox = domain.get_mesh_bounding_box() min_y, max_y = bbox[:, 1] eps = 1e-8 * (max_y - min_y) omega = domain.create_region('Omega', 'all') bottom = domain.create_region('Bottom', 'vertices in (y < %.10f)' % (min_y + eps), 'facet') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=options.order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson) m = Material('m', D=mtx_d, rho=options.density) integral = Integral('i', order=2 * options.order) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u) eq1 = Equation('stiffness', t1) eq2 = Equation('mass', t2) lhs_eqs = Equations([eq1, eq2]) pb = Problem('modal', equations=lhs_eqs) if options.bc_kind == 'free': pb.time_update() n_rbm = dim * (dim + 1) / 2 else: fixed_b = EssentialBC('FixedB', bottom, {'u.all': 0.0}) pb.time_update(ebcs=Conditions([fixed_b])) n_rbm = 0 pb.update_materials() # Assemble stiffness and mass matrices. mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a) mtx_m = mtx_k.copy() mtx_m.data[:] = 0.0 mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m) try: eigs, svecs = sla.eigsh(mtx_k, k=options.n_eigs + n_rbm, M=mtx_m, which='SM', tol=1e-5, maxiter=10000) except sla.ArpackNoConvergence as ee: eigs = ee.eigenvalues svecs = ee.eigenvectors output('only %d eigenvalues converged!' % len(eigs)) eigs = eigs[n_rbm:] svecs = svecs[:, n_rbm:] output('eigenvalues:', eigs) output('eigen-frequencies:', nm.sqrt(eigs)) # Make full eigenvectors (add DOFs fixed by boundary conditions). variables = pb.get_variables() vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]), dtype=nm.float64) for ii in xrange(svecs.shape[1]): vecs[:, ii] = variables.make_full_vec(svecs[:, ii]) # Save the eigenvectors. out = {} state = pb.create_state() for ii in xrange(eigs.shape[0]): state.set_full(vecs[:, ii]) aux = state.create_output_dict() strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)', integrals=Integrals([integral]), mode='el_avg', verbose=False) out['u%03d' % ii] = aux.popitem()[1] out['strain%03d' % ii] = Struct(mode='cell', data=strain) pb.save_state('eigenshapes.vtk', out=out) pb.save_regions_as_groups('regions') if options.show: # Show the solution. If the approximation order is greater than 1, the # extra DOFs are simply thrown away. from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.domain_specific import DomainSpecificPlot scaling = 0.05 * dims.max() / nm.abs(vecs).max() ds = {} for ii in xrange(eigs.shape[0]): pd = DomainSpecificPlot('plot_displacements', [ 'rel_scaling=%s' % scaling, 'color_kind="tensors"', 'color_name="strain%03d"' % ii ]) ds['u%03d' % ii] = pd view = Viewer('eigenshapes.vtk') view(domain_specific=ds, only_names=sorted(ds.keys()), is_scalar_bar=False, is_wireframe=True)