def assemble(mtx_d): m = Material('m', D=mtx_d, rho=density) integral = Integral('i', order=2 * 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) pb.time_update() n_rbm = dim * (dim + 1) / 2 pb.update_materials() tmp = time.time() # 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) return mtx_k, mtx_m
def evalValAndDeriv(D): m = Material('m', D = D, rho = 2700.0) integral = Integral('i', order=2) 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) pb.time_update() n_rbm = dim * (dim + 1) / 2 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) eigs0, evecs0 = scipy.sparse.linalg.eigsh(mtx_k, k = 10, M = mtx_m, which = 'SM') eigs = eigs0[3:] evecs = evecs0[:, 3:] dydmu = numpy.array([evecs[:, i].T.dot(dKdmu.dot(evecs[:, i])) for i in range(evecs.shape[1])]) dydlambda = numpy.array([evecs[:, i].T.dot(dKdlambda.dot(evecs[:, i])) for i in range(evecs.shape[1])]) return eigs, dydmu, dydlambda
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_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) ## pb.save_regions_as_groups('regions') pb.set_bcs(ebcs=Conditions([fix_u, shift_u])) pb.set_solver(nls) 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 from_conf(conf, options): from sfepy.discrete import Problem problem = Problem.from_conf(conf, init_equations=False) test = Test(problem=problem, conf=conf, options=options) return test
def main(): from sfepy.base.base import output from sfepy.base.conf import ProblemConf, get_standard_keywords from sfepy.discrete import Problem output.prefix = 'therel:' required, other = get_standard_keywords() conf = ProblemConf.from_file(__file__, required, other) problem = Problem.from_conf(conf, init_equations=False) # Setup output directory according to options above. problem.setup_default_output() # First solve the stationary electric conduction problem. problem.set_equations({'eq' : conf.equations['1']}) state_el = problem.solve() problem.save_state(problem.get_output_name(suffix = 'el'), state_el) # Then solve the evolutionary heat conduction problem, using state_el. problem.set_equations({'eq' : conf.equations['2']}) phi_var = problem.get_variables()['phi_known'] phi_var.set_data(state_el()) problem.solve() output('results saved in %s' % problem.get_output_name(suffix = '*'))
def main(): from sfepy.base.base import output from sfepy.base.conf import ProblemConf, get_standard_keywords from sfepy.discrete import Problem output.prefix = "therel:" required, other = get_standard_keywords() conf = ProblemConf.from_file(__file__, required, other) problem = Problem.from_conf(conf, init_equations=False) # Setup output directory according to options above. problem.setup_default_output() # First solve the stationary electric conduction problem. problem.set_equations({"eq": conf.equations["1"]}) problem.time_update() state_el = problem.solve() problem.save_state(problem.get_output_name(suffix="el"), state_el) # Then solve the evolutionary heat conduction problem, using state_el. problem.set_equations({"eq": conf.equations["2"]}) phi_var = problem.get_variables()["phi_known"] phi_var.set_data(state_el()) time_solver = problem.get_time_solver() time_solver() output("results saved in %s" % problem.get_output_name(suffix="*"))
def vary_omega1_size( problem ): """Vary size of \Omega1. Saves also the regions into options['output_dir']. Input: problem: Problem instance Return: a generator object: 1. creates new (modified) problem 2. yields the new (modified) problem and output container 3. use the output container for some logging 4. yields None (to signal next iteration to Application) """ from sfepy.discrete import Problem from sfepy.solvers.ts import get_print_info output.prefix = 'vary_omega1_size:' diameters = nm.linspace( 0.1, 0.6, 7 ) + 0.001 ofn_trunk, output_format = problem.ofn_trunk, problem.output_format output_dir = problem.output_dir join = os.path.join conf = problem.conf cf = conf.get_raw( 'functions' ) n_digit, aux, d_format = get_print_info( len( diameters ) + 1 ) for ii, diameter in enumerate( diameters ): output( 'iteration %d: diameter %3.2f' % (ii, diameter) ) cf['select_circ'] = (lambda coors, domain=None: select_circ(coors[:,0], coors[:,1], 0, diameter),) conf.edit('functions', cf) problem = Problem.from_conf(conf) problem.save_regions( join( output_dir, ('regions_' + d_format) % ii ), ['Omega_1'] ) region = problem.domain.regions['Omega_1'] if not region.has_cells(): raise ValueError('region %s has no cells!' % region.name) ofn_trunk = ofn_trunk + '_' + (d_format % ii) problem.setup_output(output_filename_trunk=ofn_trunk, output_dir=output_dir, output_format=output_format) out = [] yield problem, out out_problem, state = out[-1] filename = join( output_dir, ('log_%s.txt' % d_format) % ii ) fd = open( filename, 'w' ) log_item = '$r(\Omega_1)$: %f\n' % diameter fd.write( log_item ) fd.write( 'solution:\n' ) nm.savetxt(fd, state()) fd.close() yield None
def main(): from sfepy.base.base import output from sfepy.base.conf import ProblemConf, get_standard_keywords from sfepy.discrete import Problem from sfepy.base.plotutils import plt parser = OptionParser(usage=usage, version='%prog') parser.add_option('-n', '--no-plot', action="store_true", dest='no_plot', default=False, help=helps['no_plot']) options, args = parser.parse_args() required, other = get_standard_keywords() # Use this file as the input file. conf = ProblemConf.from_file(__file__, required, other) # Create problem instance, but do not set equations. problem = Problem.from_conf(conf, init_equations=False) # Solve the problem. Output is ignored, results stored by using the # step_hook. u_t = solve_branch(problem, linear_tension) u_c = solve_branch(problem, linear_compression) # Get pressure load by calling linear_*() for each time step. ts = problem.get_timestepper() load_t = nm.array([linear_tension(ts, nm.array([[0.0]]), 'qp')['val'] for aux in ts.iter_from(0)], dtype=nm.float64).squeeze() load_c = nm.array([linear_compression(ts, nm.array([[0.0]]), 'qp')['val'] for aux in ts.iter_from(0)], dtype=nm.float64).squeeze() # Join the branches. displacements = {} for key in u_t.keys(): displacements[key] = nm.r_[u_c[key][::-1], u_t[key]] load = nm.r_[load_c[::-1], load_t] if plt is None: output('matplotlib cannot be imported, printing raw data!') output(displacements) output(load) else: legend = [] for key, val in six.iteritems(displacements): plt.plot(load, val) legend.append(key) plt.legend(legend, loc = 2) plt.xlabel('tension [kPa]') plt.ylabel('displacement [mm]') plt.grid(True) plt.gcf().savefig('pressure_displacement.png') if not options.no_plot: plt.show()
def from_conf(conf, options): from sfepy.discrete import Problem problem = Problem.from_conf(conf) problem.time_update() test = Test(problem=problem, conf=conf, options=options) return test
def assemble_matrices(define, mod, pars, set_wave_dir, options): """ Assemble the blocks of dispersion eigenvalue problem matrices. """ define_problem = functools.partial(define, filename_mesh=options.mesh_filename, pars=pars, approx_order=options.order, refinement_level=options.refine, solver_conf=options.solver_conf, plane=options.plane, post_process=options.post_process) conf = ProblemConf.from_dict(define_problem(), mod) pb = Problem.from_conf(conf) pb.dispersion_options = options pb.set_output_dir(options.output_dir) dim = pb.domain.shape.dim # Set the normalized wave vector direction to the material(s). wdir = nm.asarray(options.wave_dir[:dim], dtype=nm.float64) wdir = wdir / nm.linalg.norm(wdir) set_wave_dir(pb, wdir) bbox = pb.domain.mesh.get_bounding_box() size = (bbox[1] - bbox[0]).max() scaling0 = apply_unit_multipliers([1.0], ['length'], options.unit_multipliers)[0] scaling = scaling0 if options.mesh_size is not None: scaling *= options.mesh_size / size output('scaling factor of periodic cell mesh coordinates:', scaling) output('new mesh size with applied unit multipliers:', scaling * size) pb.domain.mesh.coors[:] *= scaling pb.set_mesh_coors(pb.domain.mesh.coors, update_fields=True) bzone = 2.0 * nm.pi / (scaling * size) output('1. Brillouin zone size:', bzone * scaling0) output('1. Brillouin zone size with applied unit multipliers:', bzone) pb.time_update() pb.update_materials() # Assemble the matrices. mtxs = {} for key, eq in pb.equations.iteritems(): mtxs[key] = mtx = pb.mtx_a.copy() mtx = eq.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx) mtx.eliminate_zeros() output_array_stats(mtx.data, 'nonzeros in %s' % key) output('symmetry checks:') output('%s - %s^T:' % (key, key), max_diff_csr(mtx, mtx.T)) output('%s - %s^H:' % (key, key), max_diff_csr(mtx, mtx.H)) return pb, wdir, bzone, mtxs
def test_stokes_slip_bc(self): import scipy.sparse as sp from sfepy.base.conf import ProblemConf from sfepy.discrete import Problem import examples.navier_stokes.stokes_slip_bc as ssb conf = ProblemConf.from_module(ssb) pb = Problem.from_conf(conf, init_solvers=False) pb.time_update() variables = pb.get_variables() adi = variables.adi lcdi = variables.lcdi mtx = variables.mtx_lcbc ok = adi.var_names == lcdi.var_names self.report('same adi-lcdi ordering:', ok) ublock = mtx[adi.indx['u']] ir, ic = ublock.nonzero() ir += adi.indx['u'].start i0, i1 = adi.indx['u'].start, adi.indx['u'].stop _ok0 = (i0 <= ir).all() and (ir < i1).all() self.report('u block rows in [%d %d[: %s' % (i0, i1, _ok0)) i0, i1 = lcdi.indx['u'].start, lcdi.indx['u'].stop _ok1 = (i0 <= ic).all() and (ic < i1).all() self.report('u block cols in [%d %d[: %s' % (i0, i1, _ok1)) ok = ok and _ok0 and _ok1 pblock = mtx[adi.indx['p']] ir, ic, iv = sp.find(pblock) ir += adi.indx['p'].start i0, i1 = adi.indx['p'].start, adi.indx['p'].stop _ok0 = (i0 <= ir).all() and (ir < i1).all() self.report('p block rows in [%d %d[: %s' % (i0, i1, _ok0)) i0, i1 = lcdi.indx['p'].start, lcdi.indx['p'].stop _ok1 = (i0 <= ic).all() and (ic < i1).all() self.report('p block cols in [%d %d[: %s' % (i0, i1, _ok1)) ok = ok and _ok0 and _ok1 _ok0 = (len(ir) == adi.n_dof['p']) self.report('p block size correct:', _ok0) _ok1 = ((ir - adi.indx['p'].start) == (ic - lcdi.indx['p'].start)).all() self.report('p block diagonal:', _ok1) _ok2 = (iv == 1.0).all() self.report('p block identity:', _ok2) ok = ok and _ok0 and _ok1 and _ok2 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 main(): from sfepy import data_dir parser = OptionParser(usage=usage, version="%prog") parser.add_option("-s", "--show", action="store_true", dest="show", default=False, help=help["show"]) options, args = parser.parse_args() mesh = Mesh.from_file(data_dir + "/meshes/2d/rectangle_tri.mesh") domain = Domain("domain", mesh) min_x, max_x = domain.get_mesh_bounding_box()[:, 0] eps = 1e-8 * (max_x - min_x) omega = domain.create_region("Omega", "all") gamma1 = domain.create_region("Gamma1", "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", lam=1.0, mu=1.0) f = Material("f", val=[[0.02], [0.01]]) integral = Integral("i", order=3) t1 = Term.new("dw_lin_elastic_iso(m.lam, m.mu, v, u)", integral, omega, m=m, v=v, u=u) t2 = Term.new("dw_volume_lvf(f.val, v)", integral, omega, f=f, v=v) eq = Equation("balance", t1 + t2) eqs = Equations([eq]) fix_u = EssentialBC("fix_u", gamma1, {"u.all": 0.0}) bc_fun = Function("shift_u_fun", shift_u_fun, extra_args={"shift": 0.01}) shift_u = EssentialBC("shift_u", gamma2, {"u.0": bc_fun}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = 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 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({}) pb = Problem('laplace', equations=eqs, auto_solvers=None) pb.time_update(ebcs=Conditions([fix1, fix2]), lcbcs=Conditions([sper])) ev = pb.get_evaluator() nls = Newton({}, lin_solver=ls, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix) pb.set_solver(nls) state = pb.solve() return pb, state
def from_conf(conf, options): from sfepy.discrete import Problem pb = Problem.from_conf(conf, init_solvers=False) pb.time_update() mtx = pb.equations.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a) test = Test(mtx=mtx, conf=conf, options=options) return test
def __init__(self, conf, options, output_prefix, init_equations=True, **kwargs): """`kwargs` are passed to Problem.from_conf() Command-line options have precedence over conf.options.""" Application.__init__(self, conf, options, output_prefix) self.setup_options() is_eqs = init_equations if hasattr(options, "solve_not") and options.solve_not: is_eqs = False self.problem = Problem.from_conf(conf, init_equations=is_eqs, **kwargs) self.setup_output_info(self.problem, self.options)
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({}) pb = Problem("laplace", equations=eqs, auto_solvers=None) pb.time_update(ebcs=Conditions([fix1, fix2]), lcbcs=Conditions([sper])) ev = pb.get_evaluator() nls = Newton({}, lin_solver=ls, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix) pb.set_solver(nls) state = pb.solve() return pb, state
def recover_micro_hook( micro_filename, region, macro, naming_scheme = 'step_iel', recovery_file_tag='' ): # Create a micro-problem instance. required, other = get_standard_keywords() required.remove( 'equations' ) pb = Problem.from_conf_file(micro_filename, required=required, other=other, init_equations=False, init_solvers=False) coefs_filename = pb.conf.options.get('coefs_filename', 'coefs') output_dir = pb.conf.options.get('output_dir', '.') coefs_filename = op.join(output_dir, coefs_filename) + '.h5' # Coefficients and correctors coefs = Coefficients.from_file_hdf5( coefs_filename ) corrs = get_correctors_from_file( dump_names = coefs.dump_names ) recovery_hook = pb.conf.options.get('recovery_hook', None) if recovery_hook is not None: recovery_hook = pb.conf.get_function(recovery_hook) aux = max(pb.domain.shape.n_gr, 2) format = get_print_info( aux, fill = '0' )[1] \ + '_' + get_print_info( pb.domain.mesh.n_el, fill = '0' )[1] for ig, ii, iel in region.iter_cells(): print 'ig: %d, ii: %d, iel: %d' % (ig, ii, iel) local_macro = {} for k, v in macro.iteritems(): local_macro[k] = v[ii,0] out = recovery_hook( pb, corrs, local_macro ) # save data suffix = format % (ig, iel) micro_name = pb.get_output_name(extra='recovered_'\ + recovery_file_tag + suffix) filename = op.join(output_dir, op.basename(micro_name)) fpv = pb.conf.options.get('file_per_var', False) pb.save_state(filename, out=out, file_per_var=fpv)
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 save_only(conf, save_names, problem=None): """ Save information available prior to setting equations and solving them. """ if problem is None: problem = Problem.from_conf(conf, init_equations=False) if save_names.regions is not None: problem.save_regions(save_names.regions) if save_names.regions_as_groups is not None: problem.save_regions_as_groups(save_names.regions_as_groups) if save_names.field_meshes is not None: problem.save_field_meshes(save_names.field_meshes) if save_names.ebc is not None: problem.save_ebc(save_names.ebc, force=False) if save_names.ebc_nodes is not None: problem.save_ebc(save_names.ebc_nodes, force=True)
def test_ebc( self ): import numpy as nm from sfepy.discrete import Problem pb = Problem.from_conf(self.test_conf) pb.time_update() vvs = pb.get_variables() setv = vvs.set_state_part make_full = vvs.make_full_vec svec_u = nm.ones( (vvs.adi.n_dof['u'],), dtype = nm.float64 ) svec_phi = nm.empty( (vvs.adi.n_dof['phi'],), dtype = nm.float64 ) svec_phi.fill( 2.0 ) svec = vvs.create_stripped_state_vector() setv( svec, svec_u, 'u', stripped = True ) setv( svec, svec_phi, 'phi', stripped = True ) vec = make_full( svec ) ii_u = vvs.di.indx['u'].start + vvs['u'].eq_map.eqi ii_phi = vvs.di.indx['phi'].start + vvs['phi'].eq_map.eqi ok_ebc = vvs.has_ebc( vec ) ok_u = nm.all( vec[ii_u] == svec_u ) ok_phi = nm.all( vec[ii_phi] == svec_phi ) msg = '%s: %s' self.report( msg % ('ebc', ok_ebc) ) self.report( msg % ('u', ok_u) ) self.report( msg % ('phi', ok_phi) ) ok = ok_ebc and ok_u and ok_phi return ok
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__.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) pb.set_bcs(ebcs=Conditions([fix1, fix2])) pb.set_solver(nls) 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(): import os from sfepy.base.base import spause, output from sfepy.base.conf import ProblemConf, get_standard_keywords from sfepy.discrete import Problem import sfepy.homogenization.coefs_base as cb parser = OptionParser(usage=usage, version='%prog') parser.add_option('-n', '--no-pauses', action="store_true", dest='no_pauses', default=False, help=help['no_pauses']) options, args = parser.parse_args() if options.no_pauses: def spause(*args): output(*args) nm.set_printoptions(precision=3) spause(r""">>> First, this file will be read in place of an input (problem description) file. Press 'q' to quit the example, press any other key to continue...""") required, other = get_standard_keywords() required.remove('equations') # Use this file as the input file. conf = ProblemConf.from_file(__file__, required, other) print(list(conf.to_dict().keys())) spause(r""">>> ...the read input as a dict (keys only for brevity). ['q'/other key to quit/continue...]""") spause(r""">>> Now the input will be used to create a Problem instance. ['q'/other key to quit/continue...]""") problem = Problem.from_conf(conf, init_equations=False) # The homogenization mini-apps need the output_dir. output_dir = '' problem.output_dir = output_dir print(problem) spause(r""">>> ...the Problem instance. ['q'/other key to quit/continue...]""") spause(r""">>> The homogenized elastic coefficient $E_{ijkl}$ is expressed using $\Pi$ operators, computed now. In fact, those operators are permuted coordinates of the mesh nodes. ['q'/other key to quit/continue...]""") req = conf.requirements['pis'] mini_app = cb.ShapeDimDim('pis', problem, req) pis = mini_app() print(pis) spause(r""">>> ...the $\Pi$ operators. ['q'/other key to quit/continue...]""") spause(r""">>> Next, $E_{ijkl}$ needs so called steady state correctors $\bar{\omega}^{rs}$, computed now. ['q'/other key to quit/continue...]""") req = conf.requirements['corrs_rs'] save_name = req.get('save_name', '') name = os.path.join(output_dir, save_name) mini_app = cb.CorrDimDim('steady rs correctors', problem, req) mini_app.setup_output(save_format='vtk', file_per_var=False) corrs_rs = mini_app(data={'pis': pis}) print(corrs_rs) spause(r""">>> ...the $\bar{\omega}^{rs}$ correctors. The results are saved in: %s.%s Try to display them with: python postproc.py %s.%s ['q'/other key to quit/continue...]""" % (2 * (name, problem.output_format))) spause(r""">>> Then the volume of the domain is needed. ['q'/other key to quit/continue...]""") volume = problem.evaluate('d_volume.i3.Y(uc)') print(volume) spause(r""">>> ...the volume. ['q'/other key to quit/continue...]""") spause(r""">>> Finally, $E_{ijkl}$ can be computed. ['q'/other key to quit/continue...]""") mini_app = cb.CoefSymSym('homogenized elastic tensor', problem, conf.coefs['E']) c_e = mini_app(volume, data={'pis': pis, 'corrs_rs' : corrs_rs}) print(r""">>> The homogenized elastic coefficient $E_{ijkl}$, symmetric storage with rows, columns in 11, 22, 12 ordering:""") print(c_e)
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 _solve(self, property_array): """ Solve the Sfepy problem for one sample. Args: property_array: array of shape (n_x, n_y, 2) where the last index is for Lame's parameter and shear modulus, respectively. Returns: the strain field of shape (n_x, n_y, 2) where the last index represents the x and y displacements """ shape = property_array.shape[:-1] mesh = self._get_mesh(shape) domain = Domain('domain', mesh) region_all = domain.create_region('region_all', 'all') field = Field.from_args('fu', np.float64, 'vector', region_all, # pylint: disable=no-member approx_order=2) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') m = self._get_material(property_array, domain) integral = Integral('i', order=4) t1 = Term.new('dw_lin_elastic_iso(m.lam, m.mu, v, u)', integral, region_all, m=m, v=v, u=u) eq = Equation('balance_of_forces', t1) eqs = Equations([eq]) epbcs, functions = self._get_periodicBCs(domain) ebcs = self._get_displacementBCs(domain) lcbcs = self._get_linear_combinationBCs(domain) ls = ScipyDirect({}) pb = Problem('elasticity', equations=eqs, auto_solvers=None) pb.time_update( ebcs=ebcs, epbcs=epbcs, lcbcs=lcbcs, functions=functions) ev = pb.get_evaluator() nls = Newton({}, lin_solver=ls, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix) try: pb.set_solvers_instances(ls, nls) except AttributeError: pb.set_solver(nls) vec = pb.solve() u = vec.create_output_dict()['u'].data u_reshape = np.reshape(u, (tuple(x + 1 for x in shape) + u.shape[-1:])) dims = domain.get_mesh_bounding_box().shape[1] strain = np.squeeze( pb.evaluate( 'ev_cauchy_strain.{dim}.region_all(u)'.format( dim=dims), mode='el_avg', copy_materials=False)) strain_reshape = np.reshape(strain, (shape + strain.shape[-1:])) stress = np.squeeze( pb.evaluate( 'ev_cauchy_stress.{dim}.region_all(m.D, u)'.format( dim=dims), mode='el_avg', copy_materials=False)) stress_reshape = np.reshape(stress, (shape + stress.shape[-1:])) return strain_reshape, u_reshape, stress_reshape
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('--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 range(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(): from sfepy.base.conf import ProblemConf, get_standard_keywords from sfepy.discrete import Problem from sfepy.base.plotutils import plt parser = OptionParser(usage=usage, version='%prog') parser.add_option('-n', '--no-plot', action="store_true", dest='no_plot', default=False, help=helps['no_plot']) options, args = parser.parse_args() required, other = get_standard_keywords() # Use this file as the input file. conf = ProblemConf.from_file(__file__, required, other) # Create problem instance, but do not set equations. problem = Problem.from_conf(conf, init_equations=False) # Solve the problem. Output is ignored, results stored by using the # step_hook. u_t = solve_branch(problem, linear_tension) u_c = solve_branch(problem, linear_compression) # Get pressure load by calling linear_*() for each time step. ts = problem.get_timestepper() load_t = nm.array([ linear_tension(ts, nm.array([[0.0]]), 'qp')['val'] for aux in ts.iter_from(0) ], dtype=nm.float64).squeeze() load_c = nm.array([ linear_compression(ts, nm.array([[0.0]]), 'qp')['val'] for aux in ts.iter_from(0) ], dtype=nm.float64).squeeze() # Join the branches. displacements = {} for key in u_t.keys(): displacements[key] = nm.r_[u_c[key][::-1], u_t[key]] load = nm.r_[load_c[::-1], load_t] if plt is None: print 'matplotlib cannot be imported, printing raw data!' print displacements print load else: legend = [] for key, val in displacements.iteritems(): plt.plot(load, val) legend.append(key) plt.legend(legend, loc=2) plt.xlabel('tension [kPa]') plt.ylabel('displacement [mm]') plt.grid(True) plt.gcf().savefig('pressure_displacement.png') if not options.no_plot: plt.show()
def generate_probes(filename_input, filename_results, options, conf=None, problem=None, probes=None, labels=None, probe_hooks=None): """ Generate probe figures and data files. """ if conf is None: required, other = get_standard_keywords() conf = ProblemConf.from_file(filename_input, required, other) opts = conf.options if options.auto_dir: output_dir = opts.get_('output_dir', '.') filename_results = os.path.join(output_dir, filename_results) output('results in: %s' % filename_results) io = MeshIO.any_from_filename(filename_results) step = options.step if options.step >= 0 else io.read_last_step() all_data = io.read_data(step) output('loaded:', all_data.keys()) output('from step:', step) if options.only_names is None: data = all_data else: data = {} for key, val in all_data.iteritems(): if key in options.only_names: data[key] = val if problem is None: problem = Problem.from_conf(conf, init_equations=False, init_solvers=False) if probes is None: gen_probes = conf.get_function(conf.options.gen_probes) probes, labels = gen_probes(problem) if probe_hooks is None: probe_hooks = {None: conf.get_function(conf.options.probe_hook)} if options.output_filename_trunk is None: options.output_filename_trunk = problem.ofn_trunk filename_template = options.output_filename_trunk \ + ('_%%d.%s' % options.output_format) if options.same_dir: filename_template = os.path.join(os.path.dirname(filename_results), filename_template) output_dir = os.path.dirname(filename_results) for ip, probe in enumerate(probes): output(ip, probe.name) probe.set_options(close_limit=options.close_limit) for key, probe_hook in probe_hooks.iteritems(): out = probe_hook(data, probe, labels[ip], problem) if out is None: continue if isinstance(out, tuple): fig, results = out else: fig = out if key is not None: filename = filename_template % (key, ip) else: filename = filename_template % ip if fig is not None: if isinstance(fig, dict): for fig_name, fig_fig in fig.iteritems(): fig_filename = edit_filename(filename, suffix='_' + fig_name) fig_fig.savefig(fig_filename) output('figure ->', os.path.normpath(fig_filename)) else: fig.savefig(filename) output('figure ->', os.path.normpath(filename)) if results is not None: txt_filename = edit_filename(filename, new_ext='.txt') write_results(txt_filename, probe, results) output('data ->', os.path.normpath(txt_filename))
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(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 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)
# 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])) pb.time_update(ebcs=Conditions([bc1, bc2, bc3, bc4])) vec = pb.solve() print nls_status pb.save_state('customCylinder.vtk', vec) # if options.show: # view = Viewer('customCylinder.vtk') # view(vector_mode='warp_norm', rel_scaling=2, # is_scalar_bar=True, is_wireframe=True)
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) ## pb.save_regions_as_groups('regions') pb.set_bcs(ebcs=Conditions([fix_u, shift_u])) pb.set_solver(nls) 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 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 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(): 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(): # Aluminium and epoxy. default_pars = '70e9,0.35,2.799e3, 3.8e9,0.27,1.142e3' default_solver_conf = ("kind='eig.scipy',method='eigh',tol=1.0e-5," "maxiter=1000,which='LM',sigma=0.0") parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--pars', metavar='young1,poisson1,density1' ',young2,poisson2,density2', action='store', dest='pars', default=default_pars, help=helps['pars']) parser.add_argument('--conf', metavar='filename', action='store', dest='conf', default=None, help=helps['conf']) parser.add_argument('--mesh-size', type=float, metavar='float', action='store', dest='mesh_size', default=None, help=helps['mesh_size']) parser.add_argument('--unit-multipliers', metavar='c_time,c_length,c_mass', action='store', dest='unit_multipliers', default='1.0,1.0,1.0', help=helps['unit_multipliers']) parser.add_argument('--plane', action='store', dest='plane', choices=['strain', 'stress'], default='strain', help=helps['plane']) parser.add_argument('--wave-dir', metavar='float,float[,float]', action='store', dest='wave_dir', default='1.0,0.0,0.0', help=helps['wave_dir']) parser.add_argument('--mode', action='store', dest='mode', choices=['omega', 'kappa'], default='omega', help=helps['mode']) parser.add_argument('--range', metavar='start,stop,count', action='store', dest='range', default='10,100,10', help=helps['range']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_argument('--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_argument('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['n_eigs']) parser.add_argument('--eigs-only', action='store_true', dest='eigs_only', default=False, help=helps['eigs_only']) parser.add_argument('--solver-conf', metavar='dict-like', action='store', dest='solver_conf', default=default_solver_conf, help=helps['solver_conf']) parser.add_argument('--save-materials', action='store_true', dest='save_materials', default=False, help=helps['save_materials']) parser.add_argument('--log-std-waves', action='store_true', dest='log_std_waves', default=False, help=helps['log_std_waves']) parser.add_argument('--silent', action='store_true', dest='silent', default=False, help=helps['silent']) parser.add_argument('-c', '--clear', action='store_true', dest='clear', default=False, help=helps['clear']) parser.add_argument('-o', '--output-dir', metavar='path', action='store', dest='output_dir', default='output', help=helps['output_dir']) parser.add_argument('mesh_filename', default='', help=helps['mesh_filename']) options = parser.parse_args() output_dir = options.output_dir output.set_output(filename=os.path.join(output_dir, 'output_log.txt'), combined=options.silent == False) if options.conf is not None: mod = import_file(options.conf) apply_units = mod.apply_units define = mod.define set_wave_dir = mod.set_wave_dir else: apply_units = apply_units_le define = define_le set_wave_dir = set_wave_dir_le options.pars = [float(ii) for ii in options.pars.split(',')] options.unit_multipliers = [ float(ii) for ii in options.unit_multipliers.split(',') ] options.wave_dir = [float(ii) for ii in options.wave_dir.split(',')] aux = options.range.split(',') options.range = [float(aux[0]), float(aux[1]), int(aux[2])] options.solver_conf = dict_from_string(options.solver_conf) if options.clear: remove_files_patterns(output_dir, ['*.h5', '*.vtk', '*.txt'], ignores=['output_log.txt'], verbose=True) filename = os.path.join(output_dir, 'options.txt') ensure_path(filename) save_options(filename, [('options', vars(options))]) pars = apply_units(options.pars, options.unit_multipliers) output('material parameters with applied unit multipliers:') output(pars) if options.mode == 'omega': rng = copy(options.range) rng[:2] = apply_unit_multipliers(options.range[:2], ['wave_number', 'wave_number'], options.unit_multipliers) output('wave number range with applied unit multipliers:', rng) else: rng = copy(options.range) rng[:2] = apply_unit_multipliers(options.range[:2], ['frequency', 'frequency'], options.unit_multipliers) output('frequency range with applied unit multipliers:', rng) define_problem = functools.partial(define, filename_mesh=options.mesh_filename, pars=pars, approx_order=options.order, refinement_level=options.refine, solver_conf=options.solver_conf, plane=options.plane) conf = ProblemConf.from_dict(define_problem(), sys.modules[__name__]) pb = Problem.from_conf(conf) dim = pb.domain.shape.dim if dim != 2: options.plane = 'strain' wdir = nm.asarray(options.wave_dir[:dim], dtype=nm.float64) wdir = wdir / nm.linalg.norm(wdir) stepper = TimeStepper(rng[0], rng[1], dt=None, n_step=rng[2]) bbox = pb.domain.mesh.get_bounding_box() size = (bbox[1] - bbox[0]).max() scaling0 = apply_unit_multipliers([1.0], ['length'], options.unit_multipliers)[0] scaling = scaling0 if options.mesh_size is not None: scaling *= options.mesh_size / size output('scaling factor of periodic cell mesh coordinates:', scaling) output('new mesh size with applied unit multipliers:', scaling * size) pb.domain.mesh.coors[:] *= scaling pb.set_mesh_coors(pb.domain.mesh.coors, update_fields=True) bzone = 2.0 * nm.pi / (scaling * size) output('1. Brillouin zone size:', bzone * scaling0) output('1. Brillouin zone size with applied unit multipliers:', bzone) pb.time_update() pb.update_materials() if options.save_materials or options.log_std_waves: stiffness = pb.evaluate('ev_integrate_mat.2.Omega(m.D, u)', mode='el_avg', copy_materials=False, verbose=False) young, poisson = mc.youngpoisson_from_stiffness(stiffness, plane=options.plane) density = pb.evaluate('ev_integrate_mat.2.Omega(m.density, u)', mode='el_avg', copy_materials=False, verbose=False) if options.save_materials: out = {} out['young'] = Struct(name='young', mode='cell', data=young[..., None, None]) out['poisson'] = Struct(name='poisson', mode='cell', data=poisson[..., None, None]) out['density'] = Struct(name='density', mode='cell', data=density) materials_filename = os.path.join(output_dir, 'materials.vtk') pb.save_state(materials_filename, out=out) # Set the normalized wave vector direction to the material(s). set_wave_dir(pb.get_materials(), wdir) conf = pb.solver_confs['eig'] eig_solver = Solver.any_from_conf(conf) # Assemble the matrices. mtx_m = pb.mtx_a.copy() eq_m = pb.equations['M'] mtx_m = eq_m.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m) mtx_m.eliminate_zeros() mtx_k = pb.mtx_a.copy() eq_k = pb.equations['K'] mtx_k = eq_k.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_k) mtx_k.eliminate_zeros() mtx_s = pb.mtx_a.copy() eq_s = pb.equations['S'] mtx_s = eq_s.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_s) mtx_s.eliminate_zeros() mtx_r = pb.mtx_a.copy() eq_r = pb.equations['R'] mtx_r = eq_r.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_r) mtx_r.eliminate_zeros() output('symmetry checks of real blocks:') output('M - M^T:', _max_diff_csr(mtx_m, mtx_m.T)) output('K - K^T:', _max_diff_csr(mtx_k, mtx_k.T)) output('S - S^T:', _max_diff_csr(mtx_s, mtx_s.T)) output('R + R^T:', _max_diff_csr(mtx_r, -mtx_r.T)) n_eigs = options.n_eigs if options.n_eigs > mtx_k.shape[0]: options.n_eigs = mtx_k.shape[0] n_eigs = None if options.mode == 'omega': eigenshapes_filename = os.path.join( output_dir, 'frequency-eigenshapes-%s.vtk' % stepper.suffix) extra = [] extra_plot_kwargs = [] if options.log_std_waves: lam, mu = mc.lame_from_youngpoisson(young, poisson, plane=options.plane) alam = nm.average(lam) amu = nm.average(mu) adensity = nm.average(density) cp = nm.sqrt((alam + 2.0 * amu) / adensity) cs = nm.sqrt(amu / adensity) output('average p-wave speed:', cp) output('average shear wave speed:', cs) extra = [r'$\omega_p$', r'$\omega_s$'] extra_plot_kwargs = [{ 'ls': '--', 'color': 'k' }, { 'ls': '--', 'color': 'gray' }] log = Log( [[r'$\lambda_{%d}$' % ii for ii in range(options.n_eigs)], [r'$\omega_{%d}$' % ii for ii in range(options.n_eigs)] + extra], plot_kwargs=[{}, [{}] * options.n_eigs + extra_plot_kwargs], yscales=['linear', 'linear'], xlabels=[r'$\kappa$', r'$\kappa$'], ylabels=[r'eigenvalues $\lambda_i$', r'frequencies $\omega_i$'], log_filename=os.path.join(output_dir, 'frequencies.txt'), aggregate=1000, sleep=0.1) for iv, wmag in stepper: output('step %d: wave vector %s' % (iv, wmag * wdir)) mtx_a = mtx_k + wmag**2 * mtx_s + (1j * wmag) * mtx_r mtx_b = mtx_m output('A - A^H:', _max_diff_csr(mtx_a, mtx_a.H)) if options.eigs_only: eigs = eig_solver(mtx_a, mtx_b, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(mtx_a, mtx_b, n_eigs=options.n_eigs, eigenvectors=True) omegas = nm.sqrt(eigs) output('eigs, omegas:\n', nm.c_[eigs, omegas]) out = tuple(eigs) + tuple(omegas) if options.log_std_waves: out = out + (cp * wmag, cs * wmag) log(*out, x=[wmag, wmag]) save_eigenvectors(eigenshapes_filename % iv, svecs, pb) log(save_figure=os.path.join(output_dir, 'frequencies.png')) log(finished=True) else: import scipy.sparse as sps from sksparse.cholmod import cholesky eigenshapes_filename = os.path.join( output_dir, 'wave-number-eigenshapes-%s.vtk' % stepper.suffix) factor = cholesky(mtx_s) perm = factor.P() ir = nm.arange(len(perm)) mtx_p = sps.coo_matrix((nm.ones_like(perm), (ir, perm))) mtx_l = mtx_p.T * factor.L() mtx_eye = sps.eye(mtx_l.shape[0], dtype=nm.float64) output('S - LL^T:', _max_diff_csr(mtx_s, mtx_l * mtx_l.T)) log = Log([[r'$\kappa_{%d}$' % ii for ii in range(options.n_eigs)]], plot_kwargs=[{ 'ls': 'None', 'marker': 'o' }], yscales=['linear'], xlabels=[r'$\omega$'], ylabels=[r'wave numbers $\kappa_i$'], log_filename=os.path.join(output_dir, 'wave-numbers.txt'), aggregate=1000, sleep=0.1) for io, omega in stepper: output('step %d: frequency %s' % (io, omega)) mtx_a = sps.bmat([[mtx_k - omega**2 * mtx_m, None], [None, mtx_eye]]) mtx_b = sps.bmat([[1j * mtx_r, mtx_l], [mtx_l.T, None]]) output('A - A^T:', _max_diff_csr(mtx_a, mtx_a.T)) output('A - A^H:', _max_diff_csr(mtx_a, mtx_a.T)) output('B - B^H:', _max_diff_csr(mtx_b, mtx_b.H)) if options.eigs_only: eigs = eig_solver(mtx_a, mtx_b, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(mtx_a, mtx_b, n_eigs=options.n_eigs, eigenvectors=True) kappas = eigs output('kappas:\n', kappas[:, None]) out = tuple(kappas) log(*out, x=[omega]) save_eigenvectors(eigenshapes_filename % io, svecs, pb) log(save_figure=os.path.join(output_dir, 'wave-numbers.png')) log(finished=True)
def create_local_problem(omega_gi, orders): """ Local problem definition using a domain corresponding to the global region `omega_gi`. """ order_u, order_p = orders mesh = omega_gi.domain.mesh # All tasks have the whole mesh. bbox = mesh.get_bounding_box() min_x, max_x = bbox[:, 0] eps_x = 1e-8 * (max_x - min_x) min_y, max_y = bbox[:, 1] eps_y = 1e-8 * (max_y - min_y) mesh_i = Mesh.from_region(omega_gi, mesh, localize=True) domain_i = FEDomain('domain_i', mesh_i) omega_i = domain_i.create_region('Omega', 'all') gamma1_i = domain_i.create_region('Gamma1', 'vertices in (x < %.10f)' % (min_x + eps_x), 'facet', allow_empty=True) gamma2_i = domain_i.create_region('Gamma2', 'vertices in (x > %.10f)' % (max_x - eps_x), 'facet', allow_empty=True) gamma3_i = domain_i.create_region('Gamma3', 'vertices in (y < %.10f)' % (min_y + eps_y), 'facet', allow_empty=True) field1_i = Field.from_args('fu', nm.float64, mesh.dim, omega_i, approx_order=order_u) field2_i = Field.from_args('fp', nm.float64, 1, omega_i, approx_order=order_p) output('field 1: number of local DOFs:', field1_i.n_nod) output('field 2: number of local DOFs:', field2_i.n_nod) u_i = FieldVariable('u_i', 'unknown', field1_i, order=0) v_i = FieldVariable('v_i', 'test', field1_i, primary_var_name='u_i') p_i = FieldVariable('p_i', 'unknown', field2_i, order=1) q_i = FieldVariable('q_i', 'test', field2_i, primary_var_name='p_i') if mesh.dim == 2: alpha = 1e2 * nm.array([[0.132], [0.132], [0.092]]) else: alpha = 1e2 * nm.array([[0.132], [0.132], [0.132], [0.092], [0.092], [0.092]]) mat = Material('m', D=stiffness_from_lame(mesh.dim, lam=10, mu=5), k=1, alpha=alpha) integral = Integral('i', order=2*(max(order_u, order_p))) t11 = Term.new('dw_lin_elastic(m.D, v_i, u_i)', integral, omega_i, m=mat, v_i=v_i, u_i=u_i) t12 = Term.new('dw_biot(m.alpha, v_i, p_i)', integral, omega_i, m=mat, v_i=v_i, p_i=p_i) t21 = Term.new('dw_biot(m.alpha, u_i, q_i)', integral, omega_i, m=mat, u_i=u_i, q_i=q_i) t22 = Term.new('dw_laplace(m.k, q_i, p_i)', integral, omega_i, m=mat, q_i=q_i, p_i=p_i) eq1 = Equation('eq1', t11 - t12) eq2 = Equation('eq1', t21 + t22) eqs = Equations([eq1, eq2]) ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all' : 0.0}) ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.0' : 0.05}) def bc_fun(ts, coors, **kwargs): val = 0.3 * nm.sin(4 * nm.pi * (coors[:, 0] - min_x) / (max_x - min_x)) return val fun = Function('bc_fun', bc_fun) ebc3 = EssentialBC('ebc3', gamma3_i, {'p_i.all' : fun}) pb = Problem('problem_i', equations=eqs, active_only=False) pb.time_update(ebcs=Conditions([ebc1, ebc2, ebc3])) pb.update_materials() return pb
def main(): 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 range(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 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({}) pb = Problem('laplace', equations=eqs, auto_solvers=None) pb.time_update(ebcs=Conditions([fix1, fix2]), lcbcs=Conditions([sper])) ev = pb.get_evaluator() nls = Newton({}, lin_solver=ls, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix) pb.set_solver(nls) state = pb.solve() return pb, state
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
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])) pb.set_solver(nls) status = IndexedStruct() state = pb.solve(status=status) strain = pb.evaluate('ev_cauchy_strain.2.Omega(u)', u=u, mode='el_avg') stress = pb.evaluate('ev_cauchy_stress.2.Omega(m.D, u)', m=m, u=u, mode='el_avg') vms = get_von_mises_stress(stress.squeeze())
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=6.80e+10, help=helps['young']) parser.add_argument('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.36, help=helps['poisson']) parser.add_argument('--density', metavar='float', type=float, action='store', dest='density', default=2700.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) 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') 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 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 make_l2_projection_data(target, eval_data, order=None, ls=None, nls_options=None): """ Project scalar data to a scalar `target` field variable using the :math:`L^2` dot product. Parameters ---------- target : FieldVariable instance The target variable. eval_data : callable or array Either a material-like function `eval_data()`, or an array of values in quadrature points that has to be reshapable to the shape required by `order`. order : int, optional The quadrature order. If not given, it is set to `2 * target.field.approx_order`. """ if order is None: order = 2 * target.field.approx_order integral = Integral('i', order=order) un = FieldVariable('u', 'unknown', target.field) v = FieldVariable('v', 'test', un.field, primary_var_name=un.name) lhs = Term.new('dw_volume_dot(v, %s)' % un.name, integral, un.field.region, v=v, **{un.name: un}) def _eval_data(ts, coors, mode, **kwargs): if mode == 'qp': if callable(eval_data): val = eval_data(ts, coors, mode, **kwargs) else: val = eval_data.reshape((coors.shape[0], 1, 1)) return {'val': val} m = Material('m', function=_eval_data) rhs = Term.new('dw_volume_lvf(m.val, v)', integral, un.field.region, m=m, v=v) eq = Equation('projection', lhs - rhs) eqs = Equations([eq]) if ls is None: ls = ScipyDirect({}) if nls_options is None: nls_options = {} nls_status = IndexedStruct() nls = Newton(nls_options, lin_solver=ls, status=nls_status) pb = Problem('aux', equations=eqs, nls=nls, ls=ls) pb.time_update() # This sets the un variable with the projection solution. pb.solve() # Copy the projection solution to target. target.set_data(un()) if nls_status.condition != 0: output('L2 projection: solver did not converge!')
# vol = mesh.cmesh.get_volumes(3) # np.savetxt('tmp_vol.dat', vol) # vol = np.loadtxt('tmp_vol.dat') # # vm_stresses[i, 0] = np.sum(vms * vol) / np.sum(vol) # vm_stresses[i, 1] = np.max(vms) # # pb.save_state('voronoi_foam_%f.vtk' % z_displacement, state) # ### Solvers ### ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({'i_max': 20}, 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)
def recover_micro_hook(micro_filename, region, macro, naming_scheme='step_iel', recovery_file_tag='', define_args=None, verbose=False): # Create a micro-problem instance. required, other = get_standard_keywords() required.remove('equations') conf = ProblemConf.from_file(micro_filename, required, other, verbose=False, define_args=define_args) coefs_filename = conf.options.get('coefs_filename', 'coefs') output_dir = conf.options.get('output_dir', '.') coefs_filename = op.join(output_dir, coefs_filename) + '.h5' # Coefficients and correctors coefs = Coefficients.from_file_hdf5(coefs_filename) corrs = get_correctors_from_file(dump_names=coefs.dump_names) recovery_hook = conf.options.get('recovery_hook', None) if recovery_hook is not None: recovery_hook = conf.get_function(recovery_hook) pb = Problem.from_conf(conf, init_equations=False, init_solvers=False) format = get_print_info(pb.domain.mesh.n_el, fill='0')[1] output('recovering microsctructures...') tt = time.clock() output_fun = output.output_function output_level = output.level for ii, iel in enumerate(region.cells): output.level = output_level output('micro: %d (el=%d)' % (ii, iel)) local_macro = {} for k, v in six.iteritems(macro): local_macro[k] = v[ii, 0] output.set_output(quiet=not(verbose)) out = recovery_hook(pb, corrs, local_macro) output.output_function = output_fun if ii == 0: new_keys = [] new_data = {} new_idxs = [] for k in six.iterkeys(local_macro): if k not in macro: new_keys.append(k) new_data[k] = [] new_idxs.append(ii) for jj in new_keys: new_data[jj].append(local_macro[jj]) # save data if out is not None: suffix = format % iel micro_name = pb.get_output_name(extra='recovered_' + recovery_file_tag + suffix) filename = op.join(output_dir, op.basename(micro_name)) fpv = pb.conf.options.get('file_per_var', False) pb.save_state(filename, out=out, file_per_var=fpv) output('...done in %.2f s' % (time.clock() - tt)) for jj in new_keys: lout = new_data[jj] macro[jj] = nm.zeros((nm.max(new_idxs) + 1, 1) + lout[0].shape, dtype=lout[0].dtype) out = macro[jj] for kk, ii in enumerate(new_idxs): out[ii, 0] = lout[kk]
def recover_micro_hook( micro_filename, region, macro, naming_scheme = 'step_iel', recovery_file_tag='' ): # Create a micro-problem instance. required, other = get_standard_keywords() required.remove( 'equations' ) pb = Problem.from_conf_file(micro_filename, required=required, other=other, init_equations=False, init_solvers=False) coefs_filename = pb.conf.options.get('coefs_filename', 'coefs') output_dir = pb.conf.options.get('output_dir', '.') coefs_filename = op.join(output_dir, coefs_filename) + '.h5' # Coefficients and correctors coefs = Coefficients.from_file_hdf5( coefs_filename ) corrs = get_correctors_from_file( dump_names = coefs.dump_names ) recovery_hook = pb.conf.options.get('recovery_hook', None) if recovery_hook is not None: recovery_hook = pb.conf.get_function(recovery_hook) aux = max(pb.domain.shape.n_gr, 2) format = get_print_info( aux, fill = '0' )[1] \ + '_' + get_print_info( pb.domain.mesh.n_el, fill = '0' )[1] for ig, ii, iel in region.iter_cells(): print 'ig: %d, ii: %d, iel: %d' % (ig, ii, iel) local_macro = {} for k, v in macro.iteritems(): local_macro[k] = v[ii,0] out = recovery_hook( pb, corrs, local_macro ) if ii == 0: new_keys = [] new_data = {} new_idxs = [] for k in local_macro.iterkeys(): if k not in macro: new_keys.append(k) new_data[k] = [] new_idxs.append(ii) for jj in new_keys: new_data[jj].append(local_macro[jj]) # save data if out is not None: suffix = format % (ig, iel) micro_name = pb.get_output_name(extra='recovered_'\ + recovery_file_tag + suffix) filename = op.join(output_dir, op.basename(micro_name)) fpv = pb.conf.options.get('file_per_var', False) pb.save_state(filename, out=out, file_per_var=fpv) for jj in new_keys: lout = new_data[jj] macro[jj] = nm.zeros((nm.max(new_idxs) + 1,1) + lout[0].shape, dtype=lout[0].dtype) out = macro[jj] for kk, ii in enumerate(new_idxs): out[ii,0] = lout[kk]
def recover_micro_hook_eps(micro_filename, region, eval_var, nodal_values, const_values, eps0, recovery_file_tag='', define_args=None, verbose=False): # Create a micro-problem instance. required, other = get_standard_keywords() required.remove('equations') conf = ProblemConf.from_file(micro_filename, required, other, verbose=False, define_args=define_args) coefs_filename = conf.options.get('coefs_filename', 'coefs') output_dir = conf.options.get('output_dir', '.') coefs_filename = op.join(output_dir, coefs_filename) + '.h5' # Coefficients and correctors coefs = Coefficients.from_file_hdf5(coefs_filename) corrs = get_correctors_from_file(dump_names=coefs.dump_names) recovery_hook = conf.options.get('recovery_hook', None) if recovery_hook is not None: recovery_hook = conf.get_function(recovery_hook) pb = Problem.from_conf(conf, init_equations=False, init_solvers=False) # Get tiling of a given region rcoors = region.domain.mesh.coors[region.get_entities(0), :] rcmin = nm.min(rcoors, axis=0) rcmax = nm.max(rcoors, axis=0) nn = nm.round((rcmax - rcmin) / eps0) if nm.prod(nn) == 0: output('inconsistency in recovery region and microstructure size!') return cs = [] for ii, n in enumerate(nn): cs.append(nm.arange(n) * eps0 + rcmin[ii]) x0 = nm.empty((int(nm.prod(nn)), nn.shape[0]), dtype=nm.float64) for ii, icoor in enumerate(nm.meshgrid(*cs, indexing='ij')): x0[:, ii] = icoor.flatten() mesh = pb.domain.mesh coors, conn, outs, ndoffset = [], [], [], 0 # Recover region mic_coors = (mesh.coors - mesh.get_bounding_box()[0, :]) * eps0 evfield = eval_var.field output('recovering microsctructures...') tt = time.clock() output_fun = output.output_function output_level = output.level for ii, c0 in enumerate(x0): local_macro = {'eps0': eps0} local_coors = mic_coors + c0 # Inside recovery region? v = nm.ones((evfield.region.entities[0].shape[0], 1)) v[evfield.vertex_remap[region.entities[0]]] = 0 no = nm.sum(v) aux = evfield.evaluate_at(local_coors, v) if (nm.sum(aux) / no) > 1e-3: continue output.level = output_level output('micro: %d' % ii) for k, v in six.iteritems(nodal_values): local_macro[k] = evfield.evaluate_at(local_coors, v) for k, v in six.iteritems(const_values): local_macro[k] = v output.set_output(quiet=not(verbose)) outs.append(recovery_hook(pb, corrs, local_macro)) output.output_function = output_fun coors.append(local_coors) conn.append(mesh.get_conn(mesh.descs[0]) + ndoffset) ndoffset += mesh.n_nod output('...done in %.2f s' % (time.clock() - tt)) # Collect output variables outvars = {} for k, v in six.iteritems(outs[0]): if v.var_name in outvars: outvars[v.var_name].append(k) else: outvars[v.var_name] = [k] # Split output by variables/regions pvs = pb.create_variables(outvars.keys()) outregs = {k: pvs[k].field.region.get_entities(-1) for k in outvars.keys()} nrve = len(coors) coors = nm.vstack(coors) ngroups = nm.tile(mesh.cmesh.vertex_groups.squeeze(), (nrve,)) conn = nm.vstack(conn) cgroups = nm.tile(mesh.cmesh.cell_groups.squeeze(), (nrve,)) # Get region mesh and data for k, cidxs in six.iteritems(outregs): gcidxs = nm.hstack([cidxs + mesh.n_el * ii for ii in range(nrve)]) rconn = conn[gcidxs] remap = -nm.ones((coors.shape[0],), dtype=nm.int32) remap[rconn] = 1 vidxs = nm.where(remap > 0)[0] remap[vidxs] = nm.arange(len(vidxs)) rconn = remap[rconn] rcoors = coors[vidxs, :] out = {} for ifield in outvars[k]: data = [outs[ii][ifield].data for ii in range(nrve)] out[ifield] = Struct(name='output_data', mode=outs[0][ifield].mode, dofs=None, var_name=k, data=nm.vstack(data)) micro_name = pb.get_output_name(extra='recovered%s_%s' % (recovery_file_tag, k)) filename = op.join(output_dir, op.basename(micro_name)) mesh_out = Mesh.from_data('recovery_%s' % k, rcoors, ngroups[vidxs], [rconn], [cgroups[gcidxs]], [mesh.descs[0]]) mesh_out.write(filename, io='auto', out=out)
def init_subproblems(self, conf, **kwargs): from sfepy.discrete.state import State from sfepy.discrete import Problem from sfepy.base.conf import ProblemConf, get_standard_keywords from scipy.spatial import cKDTree as KDTree # init subproblems problem = self.context pb_vars = problem.get_variables() # get "master" DofInfo and last index pb_adi_indx = problem.equations.variables.adi.indx self.adi_indx = pb_adi_indx.copy() last_indx = -1 for ii in six.itervalues(self.adi_indx): last_indx = nm.max([last_indx, ii.stop]) # coupling variables self.cvars_to_pb = {} for jj in conf.coupling_variables: self.cvars_to_pb[jj] = [None, None] if jj in pb_vars.names: if pb_vars[jj].dual_var_name is not None: self.cvars_to_pb[jj][0] = -1 else: self.cvars_to_pb[jj][1] = -1 # init subproblems self.subpb = [] required, other = get_standard_keywords() master_prefix = output.get_output_prefix() for ii, ifname in enumerate(conf.others): sub_prefix = master_prefix[:-1] + '-sub%d:' % (ii + 1) output.set_output_prefix(sub_prefix) kwargs['master_problem'] = problem confi = ProblemConf.from_file(ifname, required, other, define_args=kwargs) pbi = Problem.from_conf(confi, init_equations=True) sti = State(pbi.equations.variables) pbi.equations.set_data(None, ignore_unknown=True) pbi.time_update() pbi.update_materials() sti.apply_ebc() pbi_vars = pbi.get_variables() output.set_output_prefix(master_prefix) self.subpb.append([pbi, sti, None]) # append "slave" DofInfo for jj in pbi_vars.names: if not (pbi_vars[jj].is_state()): continue didx = pbi.equations.variables.adi.indx[jj] ndof = didx.stop - didx.start if jj in self.adi_indx: if ndof != \ (self.adi_indx[jj].stop - self.adi_indx[jj].start): raise ValueError('DOFs do not match!') else: self.adi_indx.update( {jj: slice(last_indx, last_indx + ndof, None)}) last_indx += ndof for jj in conf.coupling_variables: if jj in pbi_vars.names: if pbi_vars[jj].dual_var_name is not None: self.cvars_to_pb[jj][0] = ii else: self.cvars_to_pb[jj][1] = ii self.subpb.append([problem, None, None]) self.cvars_to_pb_map = {} for varname, pbs in six.iteritems(self.cvars_to_pb): # match field nodes coors = [] for ii in pbs: pbi = self.subpb[ii][0] pbi_vars = pbi.get_variables() fcoors = pbi_vars[varname].field.coors dc = nm.abs(nm.max(fcoors, axis=0)\ - nm.min(fcoors, axis=0)) ax = nm.where(dc > 1e-9)[0] coors.append(fcoors[:, ax]) if len(coors[0]) != len(coors[1]): raise ValueError('number of nodes does not match!') kdtree = KDTree(coors[0]) map_12 = kdtree.query(coors[1])[1] pbi1 = self.subpb[pbs[0]][0] pbi1_vars = pbi1.get_variables() eq_map_1 = pbi1_vars[varname].eq_map pbi2 = self.subpb[pbs[1]][0] pbi2_vars = pbi2.get_variables() eq_map_2 = pbi2_vars[varname].eq_map dpn = eq_map_2.dpn nnd = map_12.shape[0] map_12_nd = nm.zeros((nnd * dpn, ), dtype=nm.int32) if dpn > 1: for ii in range(dpn): map_12_nd[ii::dpn] = map_12 * dpn + ii else: map_12_nd = map_12 idx = nm.where(eq_map_2.eq >= 0)[0] self.cvars_to_pb_map[varname] = eq_map_1.eq[map_12[idx]]
# ---------------------------- 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 | # ---------------------------
def main(): import os from sfepy.base.base import spause, output from sfepy.base.conf import ProblemConf, get_standard_keywords from sfepy.discrete import Problem import sfepy.homogenization.coefs_base as cb parser = ArgumentParser(description=__doc__) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('-n', '--no-pauses', action="store_true", dest='no_pauses', default=False, help=helps['no_pauses']) options = parser.parse_args() if options.no_pauses: def spause(*args): output(*args) nm.set_printoptions(precision=3) spause(r""">>> First, this file will be read in place of an input (problem description) file. Press 'q' to quit the example, press any other key to continue...""") required, other = get_standard_keywords() required.remove('equations') # Use this file as the input file. conf = ProblemConf.from_file(__file__, required, other) print(list(conf.to_dict().keys())) spause(r""">>> ...the read input as a dict (keys only for brevity). ['q'/other key to quit/continue...]""") spause(r""">>> Now the input will be used to create a Problem instance. ['q'/other key to quit/continue...]""") problem = Problem.from_conf(conf, init_equations=False) # The homogenization mini-apps need the output_dir. output_dir = '' problem.output_dir = output_dir print(problem) spause(r""">>> ...the Problem instance. ['q'/other key to quit/continue...]""") spause(r""">>> The homogenized elastic coefficient $E_{ijkl}$ is expressed using $\Pi$ operators, computed now. In fact, those operators are permuted coordinates of the mesh nodes. ['q'/other key to quit/continue...]""") req = conf.requirements['pis'] mini_app = cb.ShapeDimDim('pis', problem, req) pis = mini_app() print(pis) spause(r""">>> ...the $\Pi$ operators. ['q'/other key to quit/continue...]""") spause(r""">>> Next, $E_{ijkl}$ needs so called steady state correctors $\bar{\omega}^{rs}$, computed now. ['q'/other key to quit/continue...]""") req = conf.requirements['corrs_rs'] save_name = req.get('save_name', '') name = os.path.join(output_dir, save_name) mini_app = cb.CorrDimDim('steady rs correctors', problem, req) mini_app.setup_output(save_format='vtk', file_per_var=False) corrs_rs = mini_app(data={'pis': pis}) print(corrs_rs) spause(r""">>> ...the $\bar{\omega}^{rs}$ correctors. The results are saved in: %s.%s Try to display them with: python postproc.py %s.%s ['q'/other key to quit/continue...]""" % (2 * (name, problem.output_format))) spause(r""">>> Then the volume of the domain is needed. ['q'/other key to quit/continue...]""") volume = problem.evaluate('d_volume.i3.Y(uc)') print(volume) spause(r""">>> ...the volume. ['q'/other key to quit/continue...]""") spause(r""">>> Finally, $E_{ijkl}$ can be computed. ['q'/other key to quit/continue...]""") mini_app = cb.CoefSymSym('homogenized elastic tensor', problem, conf.coefs['E']) c_e = mini_app(volume, data={'pis': pis, 'corrs_rs' : corrs_rs}) print(r""">>> The homogenized elastic coefficient $E_{ijkl}$, symmetric storage with rows, columns in 11, 22, 12 ordering:""") print(c_e)
def from_conf(conf, options): from sfepy.discrete import Problem problem = Problem.from_conf(conf) test = Test(problem=problem, conf=conf, options=options) return test
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)
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)