def init_solvers(self, nls_status=None, ls_conf=None, nls_conf=None, mtx=None, **kwargs): ls_conf = get_default(ls_conf, self.ls_conf, "you must set linear solver!") nls_conf = get_default(nls_conf, self.nls_conf, "you must set nonlinear solver!") ev = self.get_evaluator(**kwargs) ls = Solver.any_from_conf(ls_conf, mtx=mtx) nls = Solver.any_from_conf(nls_conf, evaluator=ev, lin_solver=ls, status=nls_status) self.solvers = Struct(name="solvers", ls=ls, nls=nls)
def is_linear(self): nls_conf = get_default(None, self.nls_conf, "you must set nonlinear solver!") aux = Solver.any_from_conf(nls_conf) if aux.conf.problem == "linear": return True else: return False
def presolve(self, mtx): """Prepare A^{-1} B^T for the Schur complement.""" mtx_a = mtx['A'] mtx_bt = mtx['BT'] output('full A size: %.3f MB' % (8.0 * nm.prod(mtx_a.shape) / 1e6)) output('full B size: %.3f MB' % (8.0 * nm.prod(mtx_bt.shape) / 1e6)) ls = Solver.any_from_conf(self.problem.ls_conf, presolve=True, mtx=mtx_a) if self.mode == 'explicit': tt = time.clock() mtx_aibt = nm.zeros(mtx_bt.shape, dtype=mtx_bt.dtype) for ic in xrange(mtx_bt.shape[1]): mtx_aibt[:,ic] = ls(mtx_bt[:,ic].toarray().squeeze()) output('mtx_aibt: %.2f s' % (time.clock() - tt)) action_aibt = MatrixAction.from_array(mtx_aibt) else: ## # c: 30.08.2007, r: 13.02.2008 def fun_aibt(vec): # Fix me for sparse mtx_bt... rhs = sc.dot(mtx_bt, vec) out = ls(rhs) return out action_aibt = MatrixAction.from_function(fun_aibt, (mtx_a.shape[0], mtx_bt.shape[1]), nm.float64) mtx['action_aibt'] = action_aibt
def solve_optimize(conf, options): opts = conf.options trunk = io.get_trunk(conf.filename_mesh) data = {} dpb = Problem.from_conf(conf, init_equations=False) equations = getattr(conf, '_'.join(('equations_direct', opts.problem))) dpb.set_equations(equations) dpb.name = 'direct' dpb.time_update(None) apb = dpb.copy('adjoint') equations = getattr( conf, '_'.join( ('equations_adjoint', opts.problem, opts.objective_function))) apb.set_equations(equations) apb.time_update(None) apb.ebcs.zero_dofs() apb.update_equations(None, ebcs=apb.ebcs) ls_conf = dpb.get_solver_conf(opts.ls) dnls_conf = dpb.get_solver_conf(opts.nls_direct) anls_conf = dpb.get_solver_conf(opts.nls_adjoint) opt_conf = dpb.get_solver_conf(opts.optimizer) dpb.init_solvers(ls_conf=ls_conf, nls_conf=dnls_conf) apb.init_solvers(ls_conf=ls_conf, nls_conf=anls_conf) shape_opt = so.ShapeOptimFlowCase.from_conf(conf, dpb, apb) design0 = shape_opt.dsg_vars.val shape_opt.cache = Struct(design=design0 + 100, state=None, i_mesh=-1) opt_status = IndexedStruct() optimizer = Solver.any_from_conf(opt_conf, obj_fun=so.obj_fun, obj_fun_grad=so.obj_fun_grad, status=opt_status, obj_args=(shape_opt, opts)) ## # State problem solution for the initial design. vec_dp0 = so.solve_problem_for_design(dpb, design0, shape_opt, opts) dpb.save_state(trunk + '_direct_initial.vtk', vec_dp0) ## # Optimize. des = optimizer(design0) print opt_status ## # Save final state (for "optimal" design). dpb.domain.mesh.write(trunk + '_opt.mesh', io='auto') dpb.save_state(trunk + '_direct_current.vtk', shape_opt.cache.state) print des
def presolve(self, mtx): """Prepare A^{-1} B^T for the Schur complement.""" mtx_a = mtx['A'] mtx_bt = mtx['BT'] output('full A size: %.3f MB' % (8.0 * nm.prod(mtx_a.shape) / 1e6)) output('full B size: %.3f MB' % (8.0 * nm.prod(mtx_bt.shape) / 1e6)) ls = Solver.any_from_conf(self.problem.ls_conf, presolve=True, mtx=mtx_a) if self.mode == 'explicit': tt = time.clock() mtx_aibt = nm.zeros(mtx_bt.shape, dtype=mtx_bt.dtype) for ic in xrange(mtx_bt.shape[1]): mtx_aibt[:, ic] = ls(mtx_bt[:, ic].toarray().squeeze()) output('mtx_aibt: %.2f s' % (time.clock() - tt)) action_aibt = MatrixAction.from_array(mtx_aibt) else: ## # c: 30.08.2007, r: 13.02.2008 def fun_aibt(vec): # Fix me for sparse mtx_bt... rhs = sc.dot(mtx_bt, vec) out = ls(rhs) return out action_aibt = MatrixAction.from_function( fun_aibt, (mtx_a.shape[0], mtx_bt.shape[1]), nm.float64) mtx['action_aibt'] = action_aibt
def test_eigenvalue_solvers(self): eig_confs = self._list_eigenvalue_solvers(self.conf.solvers) n_eigs = 5 ok = True tt = [] for eig_conf in eig_confs: self.report(eig_conf.name) eig_solver = Solver.any_from_conf(eig_conf) t0 = time.clock() eigs, vecs = eig_solver(self.mtx, n_eigs=n_eigs, eigenvectors=True) tt.append((' '.join((eig_conf.name, eig_conf.kind)), time.clock() - t0)) self.report(eigs) _ok = nm.allclose(eigs.real, eigs_expected, rtol=0.0, atol=1e-8) ok = ok and (_ok or (eig_conf.kind in self.can_fail)) tt.sort(key=lambda x: x[1]) self.report('solution times:') for row in tt: self.report('%.2f [s]' % row[1], ':', row[0]) return ok
def is_linear(self): nls_conf = get_default(None, self.nls_conf, 'you must set nonlinear solver!') aux = Solver.any_from_conf(nls_conf) if aux.conf.problem == 'linear': return True else: return False
def init_solvers(self, nls_status=None, ls_conf=None, nls_conf=None, mtx=None, presolve=False): """Create and initialize solvers.""" ls_conf = get_default(ls_conf, self.ls_conf, 'you must set linear solver!') nls_conf = get_default(nls_conf, self.nls_conf, 'you must set nonlinear solver!') if presolve: tt = time.clock() if ls_conf.get('needs_problem_instance', False): extra_args = {'problem': self} else: extra_args = {} ls = Solver.any_from_conf(ls_conf, mtx=mtx, presolve=presolve, **extra_args) if presolve: tt = time.clock() - tt output('presolve: %.2f [s]' % tt) if nls_conf.get('needs_problem_instance', False): extra_args = {'problem': self} else: extra_args = {} ev = self.get_evaluator() if self.conf.options.get('ulf', False): self.nls_iter_hook = ev.new_ulf_iteration nls = Solver.any_from_conf(nls_conf, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix, lin_solver=ls, iter_hook=self.nls_iter_hook, status=nls_status, **extra_args) self.solvers = Struct(name='solvers', ls=ls, nls=nls)
def solve_optimize(conf, options): opts = conf.options trunk = io.get_trunk(conf.filename_mesh) data = {} dpb = ProblemDefinition.from_conf(conf, init_equations=False) equations = getattr(conf, "_".join(("equations_direct", opts.problem))) dpb.set_equations(equations) dpb.name = "direct" dpb.time_update(None) apb = dpb.copy("adjoint") equations = getattr(conf, "_".join(("equations_adjoint", opts.problem, opts.objective_function))) apb.set_equations(equations) apb.time_update(None) apb.ebcs.zero_dofs() apb.update_equations(None, ebcs=apb.ebcs) ls_conf = dpb.get_solver_conf(opts.ls) dnls_conf = dpb.get_solver_conf(opts.nls_direct) anls_conf = dpb.get_solver_conf(opts.nls_adjoint) opt_conf = dpb.get_solver_conf(opts.optimizer) dpb.init_solvers(ls_conf=ls_conf, nls_conf=dnls_conf) apb.init_solvers(ls_conf=ls_conf, nls_conf=anls_conf) shape_opt = so.ShapeOptimFlowCase.from_conf(conf, dpb, apb) design0 = shape_opt.dsg_vars.val shape_opt.cache = Struct(design=design0 + 100, state=None, i_mesh=-1) opt_status = IndexedStruct() optimizer = Solver.any_from_conf( opt_conf, obj_fun=so.obj_fun, obj_fun_grad=so.obj_fun_grad, status=opt_status, obj_args=(shape_opt, opts) ) ## # State problem solution for the initial design. vec_dp0 = so.solve_problem_for_design(dpb, design0, shape_opt, opts) dpb.save_state(trunk + "_direct_initial.vtk", vec_dp0) ## # Optimize. des = optimizer(design0) print opt_status ## # Save final state (for "optimal" design). dpb.domain.mesh.write(trunk + "_opt.mesh", io="auto") dpb.save_state(trunk + "_direct_current.vtk", shape_opt.cache.state) print des
def __init__(self, problem, options): self.mtx_mass = problem.evaluate(options.mass, mode='weak', auto_init=True, dw_mode='matrix') if options.lumped: raise NotImplementedError else: # Initialize solvers (and possibly presolve the matrix). self.ls = Solver.any_from_conf(problem.ls_conf, mtx=self.mtx_mass, presolve=True)
def init_solvers(self, nls_status=None, ls_conf=None, nls_conf=None, force=False): """ Create and initialize solver instances. Parameters ---------- nls_status : dict-like, IndexedStruct, optional The user-supplied object to hold nonlinear solver convergence statistics. ls_conf : Struct, optional The linear solver options. nls_conf : Struct, optional The nonlinear solver options. force : bool If True, re-create the solver instances even if they already exist in `self.nls` attribute. """ if (self.nls is None) or force: ls_conf = get_default(ls_conf, self.ls_conf, 'you must set linear solver!') nls_conf = get_default(nls_conf, self.nls_conf, 'you must set nonlinear solver!') ls = Solver.any_from_conf(ls_conf, problem=self) ev = self.get_evaluator() if self.conf.options.get('ulf', False): self.nls_iter_hook = ev.new_ulf_iteration nls = Solver.any_from_conf(nls_conf, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix, lin_solver=ls, iter_hook=self.nls_iter_hook, status=nls_status, problem=self) self.set_solver(nls)
def get_time_solver(self, ts_conf=None, **kwargs): """ Create and return a TimeSteppingSolver instance. Notes ----- Also sets `self.ts` attribute. """ ts_conf = get_default(ts_conf, self.ts_conf, "you must set time-stepping solver!") ts_solver = Solver.any_from_conf(ts_conf, problem=self, **kwargs) self.ts = ts_solver.ts return ts_solver
def test_eigenvalue_solvers(self): from sfepy.base.base import IndexedStruct eig_confs = self._list_eigenvalue_solvers(self.conf.solvers) all_n_eigs = [5, 0] ok = True tt = [] for ii, n_eigs in enumerate(all_n_eigs): for eig_conf in eig_confs: self.report(eig_conf.name) try: eig_solver = Solver.any_from_conf(eig_conf) except (ValueError, ImportError): if eig_conf.kind in self.can_fail: continue else: raise status = IndexedStruct() eigs, vecs = eig_solver(self.mtx, n_eigs=n_eigs, eigenvectors=True, status=status) tt.append([ ' '.join((eig_conf.name, eig_conf.kind)), status.time, n_eigs ]) self.report(eigs) _ok = nm.allclose(eigs.real, eigs_expected[ii], rtol=0.0, atol=1e-8) tt[-1].append(_ok) ok = ok and (_ok or (eig_conf.kind in self.can_fail) or (eig_conf.name in self.can_miss)) tt.sort(key=lambda x: x[1]) self.report('solution times:') for row in tt: self.report('%.2f [s] : %s (%d) (ok: %s)' % (row[1], row[0], row[2], row[3])) return ok
def init_solvers(self, nls_status=None, ls_conf=None, nls_conf=None, mtx=None, presolve=False): """Create and initialize solvers.""" ls_conf = get_default(ls_conf, self.ls_conf, "you must set linear solver!") nls_conf = get_default(nls_conf, self.nls_conf, "you must set nonlinear solver!") if presolve: tt = time.clock() if ls_conf.get("needs_problem_instance", False): extra_args = {"problem": self} else: extra_args = {} ls = Solver.any_from_conf(ls_conf, mtx=mtx, presolve=presolve, **extra_args) if presolve: tt = time.clock() - tt output("presolve: %.2f [s]" % tt) if nls_conf.get("needs_problem_instance", False): extra_args = {"problem": self} else: extra_args = {} ev = self.get_evaluator() if self.conf.options.get("ulf", False): self.nls_iter_hook = ev.new_ulf_iteration nls = Solver.any_from_conf( nls_conf, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix, lin_solver=ls, iter_hook=self.nls_iter_hook, status=nls_status, **extra_args ) self.set_solvers_instances(ls=ls, nls=nls)
def eig( mtx_a, mtx_b = None, num = None, eigenvectors = True, return_time = None, method = 'eig.scipy', **ckwargs ): kwargs = {'name' : 'aux', 'kind' : method} kwargs.update( ckwargs ) conf = Struct( **kwargs ) solver = Solver.any_from_conf( conf ) status = {} out = solver( mtx_a, mtx_b, num, eigenvectors, status ) if return_time is not None: return_time[0] = status['time'] return out
def get_time_solver(self, ts_conf=None, **kwargs): """ Create and return a TimeSteppingSolver instance. Notes ----- Also sets `self.ts` attribute. """ ts_conf = get_default(ts_conf, self.ts_conf, 'you must set time-stepping solver!') ts_solver = Solver.any_from_conf(ts_conf, problem=self, **kwargs) self.ts = ts_solver.ts return ts_solver
def init_solvers(self, nls_status=None, ls_conf=None, nls_conf=None, mtx=None, presolve=False): """Create and initialize solvers.""" ls_conf = get_default( ls_conf, self.ls_conf, 'you must set linear solver!' ) nls_conf = get_default( nls_conf, self.nls_conf, 'you must set nonlinear solver!' ) if presolve: tt = time.clock() if get_default_attr(ls_conf, 'needs_problem_instance', False): extra_args = {'problem' : self} else: extra_args = {} ls = Solver.any_from_conf(ls_conf, mtx=mtx, presolve=presolve, **extra_args) if presolve: tt = time.clock() - tt output('presolve: %.2f [s]' % tt) if get_default_attr(nls_conf, 'needs_problem_instance', False): extra_args = {'problem' : self} else: extra_args = {} ev = self.get_evaluator() if get_default_attr(self.conf.options, 'ulf', False): self.nls_iter_hook = ev.new_ulf_iteration nls = Solver.any_from_conf(nls_conf, fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix, lin_solver=ls, iter_hook=self.nls_iter_hook, status=nls_status, **extra_args) self.solvers = Struct( name = 'solvers', ls = ls, nls = nls )
def prepare_matrices(self, problem): """ A = K + B^T D^{-1} B """ equations = problem.equations mtx = equations.eval_tangent_matrices(None, problem.mtx_a, by_blocks=True) ls = Solver.any_from_conf(problem.ls_conf, presolve=True, mtx=mtx['D']) mtx_b, mtx_m = mtx['B'], mtx['M'] mtx_dib = nm.empty(mtx_b.shape, dtype=mtx_b.dtype) for ic in xrange(mtx_b.shape[1]): mtx_dib[:, ic] = ls(mtx_b[:, ic].toarray().squeeze()) mtx_a = mtx['K'] + mtx_b.T * mtx_dib return mtx_a, mtx_m, mtx_dib
def prepare_matrices(self, problem): """ A = K + B^T D^{-1} B """ equations = problem.equations mtx = equations.eval_tangent_matrices(None, problem.mtx_a, by_blocks=True) ls = Solver.any_from_conf(problem.ls_conf, presolve=True, mtx=mtx['D']) mtx_b, mtx_m = mtx['B'], mtx['M'] mtx_dib = nm.empty(mtx_b.shape, dtype=mtx_b.dtype) for ic in xrange(mtx_b.shape[1]): mtx_dib[:,ic] = ls(mtx_b[:,ic].toarray().squeeze()) mtx_a = mtx['K'] + mtx_b.T * mtx_dib return mtx_a, mtx_m, mtx_dib
def solve_eigen_problem(self): opts = self.app_options pb = self.problem pb.set_equations(pb.conf.equations) pb.time_update() output('assembling lhs...') tt = time.clock() mtx_a = pb.evaluate(pb.conf.equations['lhs'], mode='weak', auto_init=True, dw_mode='matrix') output('...done in %.2f s' % (time.clock() - tt)) if 'rhs' in pb.conf.equations: output('assembling rhs...') tt = time.clock() mtx_b = pb.evaluate(pb.conf.equations['rhs'], mode='weak', dw_mode='matrix') output('...done in %.2f s' % (time.clock() - tt)) else: mtx_b = None n_eigs = get_default(opts.n_eigs, mtx_a.shape[0]) output('solving eigenvalue problem for {} values...'.format(n_eigs)) eig = Solver.any_from_conf(pb.get_solver_conf(opts.evps)) if opts.eigs_only: eigs = eig(mtx_a, mtx_b, n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig(mtx_a, mtx_b, n_eigs, eigenvectors=True) output('...done') vecs = self.make_full(svecs) self.save_results(eigs, vecs) return Struct(pb=pb, eigs=eigs, vecs=vecs)
def solve_eigen_problem(self): opts = self.app_options pb = self.problem pb.set_equations(pb.conf.equations) pb.time_update() output('assembling lhs...') tt = time.clock() mtx_a = pb.evaluate(pb.conf.equations['lhs'], mode='weak', auto_init=True, dw_mode='matrix') output('...done in %.2f s' % (time.clock() - tt)) if 'rhs' in pb.conf.equations: output('assembling rhs...') tt = time.clock() mtx_b = pb.evaluate(pb.conf.equations['rhs'], mode='weak', dw_mode='matrix') output('...done in %.2f s' % (time.clock() - tt)) else: mtx_b = None _n_eigs = get_default(opts.n_eigs, mtx_a.shape[0]) output('solving eigenvalue problem for {} values...'.format(_n_eigs)) eig = Solver.any_from_conf(pb.get_solver_conf(opts.evps)) if opts.eigs_only: eigs = eig(mtx_a, mtx_b, opts.n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig(mtx_a, mtx_b, opts.n_eigs, eigenvectors=True) output('...done') vecs = self.make_full(svecs) self.save_results(eigs, vecs) return Struct(pb=pb, eigs=eigs, vecs=vecs)
def test_eigenvalue_solvers(self): eig_confs = self._list_eigenvalue_solvers(self.conf.solvers) n_eigs = 5 ok = True tt = [] for eig_conf in eig_confs: self.report(eig_conf.name) try: eig_solver = Solver.any_from_conf(eig_conf) except (ValueError, ImportError): if eig_conf.kind in self.can_fail: continue else: raise t0 = time.clock() eigs, vecs = eig_solver(self.mtx, n_eigs=n_eigs, eigenvectors=True) tt.append( [' '.join((eig_conf.name, eig_conf.kind)), time.clock() - t0]) self.report(eigs) _ok = nm.allclose(eigs.real, eigs_expected, rtol=0.0, atol=1e-8) tt[-1].append(_ok) ok = ok and (_ok or (eig_conf.kind in self.can_fail) or (eig_conf.name in self.can_miss)) tt.sort(key=lambda x: x[1]) self.report('solution times:') for row in tt: self.report('%.2f [s] : %s (ok: %s)' % (row[1], row[0], row[2])) return ok
def test_eigenvalue_solvers(self): eig_confs = self._list_eigenvalue_solvers(self.conf.solvers) n_eigs = 5 ok = True tt = [] for eig_conf in eig_confs: self.report(eig_conf.name) try: eig_solver = Solver.any_from_conf(eig_conf) except (ValueError, ImportError): if eig_conf.kind in self.can_fail: continue else: raise t0 = time.clock() eigs, vecs = eig_solver(self.mtx, n_eigs=n_eigs, eigenvectors=True) tt.append([' '.join((eig_conf.name, eig_conf.kind)), time.clock() - t0]) self.report(eigs) _ok = nm.allclose(eigs.real, eigs_expected, rtol=0.0, atol=1e-8) tt[-1].append(_ok) ok = ok and (_ok or (eig_conf.kind in self.can_fail) or (eig_conf.name in self.can_miss)) tt.sort(key=lambda x: x[1]) self.report('solution times:') for row in tt: self.report('%.2f [s] : %s (ok: %s)' % (row[1], row[0], row[2])) return ok
def test_ls_reuse(self): import numpy as nm from sfepy.solvers import Solver from sfepy.discrete.state import State self.problem.init_solvers(ls_conf=self.problem.solver_confs['d00']) nls = self.problem.get_nls() state0 = State(self.problem.equations.variables) state0.apply_ebc() vec0 = state0.get_reduced() self.problem.update_materials() rhs = nls.fun(vec0) mtx = nls.fun_grad(vec0) ok = True for name in ['i12', 'i01']: solver_conf = self.problem.solver_confs[name] method = solver_conf.get('method', '') precond = solver_conf.get('precond', '') name = ' '.join((solver_conf.name, solver_conf.kind, method, precond)).rstrip() self.report(name) try: ls = Solver.any_from_conf(solver_conf) except: self.report('skipped!') continue conf = ls.conf.copy() conf.force_reuse = True sol00 = ls(rhs, mtx=mtx, conf=conf) digest00 = ls.mtx_digest sol0 = ls(rhs, mtx=mtx) digest0 = ls.mtx_digest sol1 = ls(rhs, mtx=2 * mtx, conf=conf) digest1 = ls.mtx_digest sol2 = ls(rhs, mtx=2 * mtx) digest2 = ls.mtx_digest ls(rhs, mtx=2 * mtx) digest3 = ls.mtx_digest _ok = digest00 != digest0 self.report(digest00, '!=', digest0, ':', _ok) ok = ok and _ok _ok = digest0 == digest1 self.report(digest0, '==', digest1, ':', _ok) ok = ok and _ok _ok = digest1 != digest2 self.report(digest1, '!=', digest2, ':', _ok) ok = ok and _ok _ok = digest2[1] == digest3[1] self.report(digest2[1], '==', digest3[1], ':', _ok) ok = ok and _ok _ok = nm.allclose(sol00, sol0, atol=1e-12, rtol=0.0) self.report('sol00 == sol0:', _ok) ok = ok and _ok _ok = nm.allclose(sol0, sol1, atol=1e-12, rtol=0.0) self.report('sol0 == sol1:', _ok) ok = ok and _ok _ok = nm.allclose(sol0, 2 * sol2, atol=1e-12, rtol=0.0) self.report('sol0 == 2 * sol2:', _ok) ok = ok and _ok return ok
def solve_eigen_problem( self, ofn_trunk = None, post_process_hook = None ): if self.cached_evp is not None: return self.cached_evp problem = self.problem ofn_trunk = get_default( ofn_trunk, problem.ofn_trunk, 'output file name trunk missing!' ) post_process_hook = get_default( post_process_hook, self.post_process_hook ) conf = self.conf eig_problem = self.app_options.eig_problem if eig_problem in ['simple', 'simple_liquid']: problem.set_equations( conf.equations ) problem.time_update() mtx_a = problem.evaluate(conf.equations['lhs'], mode='weak', auto_init=True, dw_mode='matrix') mtx_m = problem.evaluate(conf.equations['rhs'], mode='weak', dw_mode='matrix') elif eig_problem == 'schur': # A = K + B^T D^{-1} B. mtx = assemble_by_blocks( conf.equations, self.problem, ebcs = conf.ebcs, epbcs = conf.epbcs ) problem.set_equations( conf.equations ) problem.time_update() ls = Solver.any_from_conf( problem.ls_conf, presolve = True, mtx = mtx['D'] ) mtx_b, mtx_m = mtx['B'], mtx['M'] mtx_dib = nm.empty( mtx_b.shape, dtype = mtx_b.dtype ) for ic in xrange( mtx_b.shape[1] ): mtx_dib[:,ic] = ls( mtx_b[:,ic].toarray().squeeze() ) mtx_a = mtx['K'] + mtx_b.T * mtx_dib else: raise NotImplementedError ## from sfepy.base.plotutils import spy, plt ## spy( mtx_b, eps = 1e-12 ) ## plt.show() ## mtx_a.save( 'a.txt', format='%d %d %.12f\n' ) ## mtx_b.save( 'b.txt', format='%d %d %.12f\n' ) ## pause() output( 'computing resonance frequencies...' ) tt = [0] if isinstance( mtx_a, sc.sparse.spmatrix ): mtx_a = mtx_a.toarray() if isinstance( mtx_m, sc.sparse.spmatrix ): mtx_m = mtx_m.toarray() eigs, mtx_s_phi = eig(mtx_a, mtx_m, return_time=tt, method=self.app_options.eigensolver) eigs[eigs<0.0] = 0.0 output( '...done in %.2f s' % tt[0] ) output( 'original eigenfrequencies:' ) output( eigs ) opts = self.app_options epsilon2 = opts.scale_epsilon * opts.scale_epsilon eigs_rescaled = (opts.elasticity_contrast / epsilon2) * eigs output( 'rescaled eigenfrequencies:' ) output( eigs_rescaled ) output( 'number of eigenfrequencies: %d' % eigs.shape[0] ) try: assert_( nm.isfinite( eigs ).all() ) except ValueError: debug() # B-orthogonality check. ## print nm.dot( mtx_s_phi[:,5], nm.dot( mtx_m, mtx_s_phi[:,5] ) ) ## print nm.dot( mtx_s_phi[:,5], nm.dot( mtx_m, mtx_s_phi[:,0] ) ) ## debug() n_eigs = eigs.shape[0] variables = problem.get_variables() mtx_phi = nm.empty( (variables.di.ptr[-1], mtx_s_phi.shape[1]), dtype = nm.float64 ) make_full = variables.make_full_vec if eig_problem in ['simple', 'simple_liquid']: for ii in xrange( n_eigs ): mtx_phi[:,ii] = make_full( mtx_s_phi[:,ii] ) eig_vectors = mtx_phi elif eig_problem == 'schur': # Update also eliminated variables. schur = self.app_options.schur primary_var = schur['primary_var'] eliminated_var = schur['eliminated_var'] mtx_s_phi_schur = - sc.dot( mtx_dib, mtx_s_phi ) aux = nm.empty( (variables.adi.ptr[-1],), dtype = nm.float64 ) set = variables.set_state_part for ii in xrange( n_eigs ): set( aux, mtx_s_phi[:,ii], primary_var, stripped = True ) set( aux, mtx_s_phi_schur[:,ii], eliminated_var, stripped = True ) mtx_phi[:,ii] = make_full( aux ) indx = variables.get_indx( primary_var ) eig_vectors = mtx_phi[indx,:] save = self.app_options.save out = {} for ii in xrange( n_eigs ): if (ii >= save[0]) and (ii < (n_eigs - save[1])): continue aux = problem.state_to_output( mtx_phi[:,ii] ) for name, val in aux.iteritems(): out[name+'%03d' % ii] = val if post_process_hook is not None: out = post_process_hook( out, problem, mtx_phi ) problem.domain.mesh.write( ofn_trunk + '.vtk', io = 'auto', out = out ) fd = open( ofn_trunk + '_eigs.txt', 'w' ) eigs.tofile( fd, ' ' ) fd.close() evp = Struct( kind = eig_problem, eigs = eigs, eigs_rescaled = eigs_rescaled, eig_vectors = eig_vectors ) self.cached_evp = evp return evp
def solve_navier_stokes(conf, options): opts = conf.options dpb = Problem.from_conf(conf, init_equations=False) equations = getattr(conf, '_'.join(('equations_direct', opts.problem))) dpb.set_equations(equations) ls_conf = dpb.get_solver_conf(opts.ls) nls_conf = dpb.get_solver_conf(opts.nls_direct) method = opts.direct_method if method == 'stationary': data = {} dpb.time_update(None) state_dp = dpb.solve(nls_conf=nls_conf) elif method == 'transient': ls = Solver.any_from_conf(ls_conf) ts_conf = dpb.get_solver_conf(opts.ts_direct) data = {'ts': Struct(dt=ts_conf.dt)} # Plug in mass term. mequations = {} for key, eq in equations.iteritems(): if 'dw_div_grad' in eq: eq = '+'.join((ts_conf.mass_term, eq)).replace('++', '+') mequations[key] = eq if ts_conf.stokes_init: state_dp0 = solve_stokes(dpb, conf.equations_direct_stokes, nls_conf) dpb.set_equations(mequations) else: dpb.set_equations(mequations) state_dp0 = dpb.create_state() dpb.time_update(None) state_dp0.apply_ebc() from sfepy.base.log import Log log = Log.from_conf(Struct(is_plot=True), ([r'$||u||$'], [r'$||p||$'])) output('Navier-Stokes...') ev = BasicEvaluator(dpb, ts=Struct(dt=ts_conf.dt)) nls = Solver.any_from_conf(nls_conf, evaluator=ev, lin_solver=ls) n_step = ts_conf.n_step step = 0 while 1: for ii in xrange(n_step): output(step) vec_u = state_dp0('w') vec_p = state_dp0('r') log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p)) dpb.variables.set_data_from_state('w_0', state_dp0(), 'w') vec_dp = nls(state_dp0()) step += 1 state_dp = state_dp0.copy() state_dp.set_reduced(vec_dp) state_dp0 = state_dp if ts_conf.interactive: try: n_step = int(raw_input('continue: ')) if n_step <= 0: break except: break vec_u = state_dp('w') vec_p = state_dp('r') log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p), finished=True) else: raise 'unknown Navier-Stokes solution method (%s)!' % method return dpb, state_dp, data
def solve_navier_stokes(conf, options): opts = conf.options dpb = ProblemDefinition.from_conf(conf, init_equations=False) equations = getattr(conf, '_'.join(('equations_direct', opts.problem))) dpb.set_equations(equations) ls_conf = dpb.get_solver_conf( opts.ls ) nls_conf = dpb.get_solver_conf(opts.nls_direct) method = opts.direct_method if method == 'stationary': data = {} dpb.time_update(None) vec_dp = dpb.solve(nls_conf=nls_conf) elif method == 'transient': ls = Solver.any_from_conf( ls_conf ) ts_conf = dpb.get_solver_conf( opts.ts_direct ) data = {'ts' : Struct( dt = ts_conf.dt )} # Plug in mass term. mequations = {} for key, eq in equations.iteritems(): if 'dw_div_grad' in eq: eq = '+'.join( (ts_conf.mass_term, eq) ).replace( '++', '+') mequations[key] = eq if ts_conf.stokes_init: vec_dp0 = solve_stokes( dpb, conf.equations_direct_stokes, nls_conf ) dpb.set_equations( mequations ) else: dpb.set_equations( mequations ) vec_dp0 = dpb.create_state_vector() dpb.time_update( None ) dpb.apply_ebc( vec_dp0 ) from sfepy.base.log import Log log = Log.from_conf( Struct( is_plot = True ), ([r'$||u||$'], [r'$||p||$']) ) output( 'Navier-Stokes...' ) ev = BasicEvaluator( dpb, ts = Struct( dt = ts_conf.dt ) ) nls = Solver.any_from_conf( nls_conf, evaluator = ev, lin_solver = ls ) n_step = ts_conf.n_step step = 0 while 1: for ii in xrange( n_step ): output( step ) vec_u = dpb.variables.get_state_part_view( vec_dp0, 'w' ) vec_p = dpb.variables.get_state_part_view( vec_dp0, 'r' ) log( nm.linalg.norm( vec_u ), nm.linalg.norm( vec_p ) ) dpb.variables.non_state_data_from_state( 'w_0', vec_dp0, 'w' ) vec_dp = nls( vec_dp0 ) step += 1 vec_dp0 = vec_dp.copy() if ts_conf.interactive: try: n_step = int( raw_input( 'continue: ' ) ) if n_step <= 0: break except: break vec_u = dpb.variables.get_state_part_view( vec_dp, 'w' ) vec_p = dpb.variables.get_state_part_view( vec_dp, 'r' ) log( nm.linalg.norm( vec_u ), nm.linalg.norm( vec_p ), finished = True ) else: raise 'unknown Navier-Stokes solution method (%s)!' % method return dpb, vec_dp, data
def setup_precond(mtx, problem): """ Setup a preconditioner for `mtx`. """ import scipy.sparse.linalg as spla from sfepy.solvers import Solver # Get active DOF indices for u, p. adi = problem.get_variables().adi iu = adi.indx['u'] ip = adi.indx['p'] # Get the diagonal blocks of the linear system matrix. K = mtx[iu, iu] M = mtx[ip, ip] # Create solvers for K, M blocks to be used in matvec_bj(). A different # solver for each block could be used. conf = problem.solver_confs['direct'] # conf = problem.solver_confs['cg-s'] # conf = problem.solver_confs['cg-p'] # conf = problem.solver_confs['pyamg'] ls1 = Solver.any_from_conf(conf, mtx=K, context=problem) ls2 = Solver.any_from_conf(conf, mtx=M, context=problem) def matvec_bj(vec): """ The application of the Block Jacobi preconditioner. The exact version (as with the `'direct'` solver) can be obtained also by using the following PETSs command-line options, together with the `'iterative-p'` solver:: -ksp_monitor -pc_type fieldsplit -pc_fieldsplit_type additive -fieldsplit_u_ksp_type preonly -fieldsplit_u_pc_type lu -fieldsplit_p_ksp_type preonly -fieldsplit_p_pc_type lu The inexact version (20 iterations of a CG solver for each block, as with the `'cg-s'` or `'cg-p'` solvers) can be obtained also by using the following PETSs command-line options, together with the `'iterative-p'` solver:: -ksp_monitor -pc_type fieldsplit -pc_fieldsplit_type additive -fieldsplit_u_ksp_type cg -fieldsplit_u_pc_type none -fieldsplit_p_ksp_type cg -fieldsplit_p_pc_type none -fieldsplit_u_ksp_max_it 20 -fieldsplit_p_ksp_max_it 20 """ vu = ls1(vec[iu]) vp = ls2(vec[ip]) return nm.r_[vu, vp] def matvec_j(vec): """ The application of the Jacobi (diagonal) preconditioner. The same effect can be obtained also by using the following PETSs command-line options, together with the `'iterative-p'` solver:: -ksp_monitor -pc_type jacobi """ D = mtx.diagonal() return vec / D # Create the preconditioner, using one of matvec_bj() or matvec_j(). precond = Struct(name='precond', shape=mtx.shape, matvec=matvec_bj) precond = spla.aslinearoperator(precond) return precond
def solve_eigen_problem(self): options = self.options opts = self.app_options pb = self.problem dim = pb.domain.mesh.dim pb.set_equations(pb.conf.equations) pb.time_update() output('assembling lhs...') tt = time.clock() mtx_a = pb.evaluate(pb.conf.equations['lhs'], mode='weak', auto_init=True, dw_mode='matrix') output('...done in %.2f s' % (time.clock() - tt)) output('assembling rhs...') tt = time.clock() mtx_b = pb.evaluate(pb.conf.equations['rhs'], mode='weak', dw_mode='matrix') output('...done in %.2f s' % (time.clock() - tt)) n_eigs = get_default(opts.n_eigs, mtx_a.shape[0]) output('computing resonance frequencies...') eig = Solver.any_from_conf(pb.get_solver_conf(opts.eigen_solver)) eigs, mtx_s_phi = eig(mtx_a, mtx_b, n_eigs) output('...done') bounding_box = pb.domain.mesh.get_bounding_box() # this assumes a box (3D), or a square (2D): a = bounding_box[1][0] - bounding_box[0][0] E_exact = None if options.hydrogen or options.boron: if options.hydrogen: Z = 1 elif options.boron: Z = 5 if dim == 2: E_exact = [ -float(Z)**2 / 2 / (n - 0.5)**2 / 4 for n in [1] + [2] * 3 + [3] * 5 + [4] * 8 + [5] * 15 ] elif dim == 3: E_exact = [ -float(Z)**2 / 2 / n**2 for n in [1] + [2] * 2**2 + [3] * 3**2 ] if options.well: if dim == 2: E_exact = [ pi**2 / (2 * a**2) * x for x in [2, 5, 5, 8, 10, 10, 13, 13, 17, 17, 18, 20, 20] ] elif dim == 3: E_exact = [ pi**2 / (2 * a**2) * x for x in [ 3, 6, 6, 6, 9, 9, 9, 11, 11, 11, 12, 14, 14, 14, 14, 14, 14, 17, 17, 17 ] ] if options.oscillator: if dim == 2: E_exact = [1] + [2] * 2 + [3] * 3 + [4] * 4 + [5] * 5 + [6] * 6 elif dim == 3: E_exact = [ float(1) / 2 + x for x in [1] + [2] * 3 + [3] * 6 + [4] * 10 ] if E_exact is not None: output("a=%f" % a) output("Energies:") output("n exact FEM error") for i, e in enumerate(eigs): from numpy import NaN if i < len(E_exact): exact = E_exact[i] err = 100 * abs((exact - e) / exact) else: exact = NaN err = NaN output("%d: %.8f %.8f %5.2f%%" % (i, exact, e, err)) else: output(eigs) mtx_phi = self.make_full(mtx_s_phi) self.save_results(eigs, mtx_phi) return Struct(pb=pb, eigs=eigs, mtx_phi=mtx_phi)
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 solve_navier_stokes(conf, options): opts = conf.options dpb = ProblemDefinition.from_conf(conf, init_equations=False) equations = getattr(conf, "_".join(("equations_direct", opts.problem))) dpb.set_equations(equations) ls_conf = dpb.get_solver_conf(opts.ls) nls_conf = dpb.get_solver_conf(opts.nls_direct) method = opts.direct_method if method == "stationary": data = {} dpb.time_update(None) state_dp = dpb.solve(nls_conf=nls_conf) elif method == "transient": ls = Solver.any_from_conf(ls_conf) ts_conf = dpb.get_solver_conf(opts.ts_direct) data = {"ts": Struct(dt=ts_conf.dt)} # Plug in mass term. mequations = {} for key, eq in equations.iteritems(): if "dw_div_grad" in eq: eq = "+".join((ts_conf.mass_term, eq)).replace("++", "+") mequations[key] = eq if ts_conf.stokes_init: state_dp0 = solve_stokes(dpb, conf.equations_direct_stokes, nls_conf) dpb.set_equations(mequations) else: dpb.set_equations(mequations) state_dp0 = dpb.create_state() dpb.time_update(None) state_dp0.apply_ebc() from sfepy.base.log import Log log = Log.from_conf(Struct(is_plot=True), ([r"$||u||$"], [r"$||p||$"])) output("Navier-Stokes...") ev = BasicEvaluator(dpb, ts=Struct(dt=ts_conf.dt)) nls = Solver.any_from_conf(nls_conf, evaluator=ev, lin_solver=ls) n_step = ts_conf.n_step step = 0 while 1: for ii in xrange(n_step): output(step) vec_u = state_dp0("w") vec_p = state_dp0("r") log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p)) dpb.variables.set_data_from_state("w_0", state_dp0(), "w") vec_dp = nls(state_dp0()) step += 1 state_dp = state_dp0.copy() state_dp.set_reduced(vec_dp) state_dp0 = state_dp if ts_conf.interactive: try: n_step = int(raw_input("continue: ")) if n_step <= 0: break except: break vec_u = state_dp("w") vec_p = state_dp("r") log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p), finished=True) else: raise "unknown Navier-Stokes solution method (%s)!" % method return dpb, state_dp, data
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='eigsh',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='0,6.4,33', 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']) group = parser.add_mutually_exclusive_group() group.add_argument('--eigs-only', action='store_true', dest='eigs_only', default=False, help=helps['eigs_only']) group.add_argument('--post-process', action='store_true', dest='post_process', default=False, help=helps['post_process']) 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-regions', action='store_true', dest='save_regions', default=False, help=helps['save_regions']) 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('--no-legends', action='store_false', dest='show_legends', default=True, help=helps['no_legends']) parser.add_argument('--no-show', action='store_false', dest='show', default=True, help=helps['no_show']) 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) else: mod = sys.modules[__name__] apply_units = mod.apply_units define = mod.define set_wave_dir = mod.set_wave_dir setup_n_eigs = mod.setup_n_eigs build_evp_matrices = mod.build_evp_matrices save_materials = mod.save_materials get_std_wave_fun = mod.get_std_wave_fun get_stepper = mod.get_stepper process_evp_results = mod.process_evp_results 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))], quote_command_line=True) 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) pb, wdir, bzone, mtxs = assemble_matrices(define, mod, pars, set_wave_dir, options) dim = pb.domain.shape.dim if dim != 2: options.plane = 'strain' if options.save_regions: pb.save_regions_as_groups(os.path.join(output_dir, 'regions')) if options.save_materials: save_materials(output_dir, pb, options) conf = pb.solver_confs['eig'] eig_solver = Solver.any_from_conf(conf) n_eigs, options.n_eigs = setup_n_eigs(options, pb, mtxs) get_color = lambda ii: plt.cm.viridis((float(ii) / (options.n_eigs - 1))) plot_kwargs = [{'color' : get_color(ii), 'ls' : '', 'marker' : 'o'} for ii in range(options.n_eigs)] log_names = [] log_plot_kwargs = [] if options.log_std_waves: std_wave_fun, log_names, log_plot_kwargs = get_std_wave_fun( pb, options) else: std_wave_fun = None stepper = get_stepper(rng, pb, options) if options.mode == 'omega': eigenshapes_filename = os.path.join(output_dir, 'frequency-eigenshapes-%s.vtk' % stepper.suffix) log = Log([[r'$\lambda_{%d}$' % ii for ii in range(options.n_eigs)], [r'$\omega_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs, plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * options.n_eigs, ['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear', 'linear'], xlabels=[r'$\kappa$', r'$\kappa$'], ylabels=[r'eigenvalues $\lambda_i$', r'frequencies $\omega_i$'], show_legends=options.show_legends, is_plot=options.show, 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)) evp_mtxs = build_evp_matrices(mtxs, wmag, options.mode, pb) if options.eigs_only: eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=True) omegas, svecs, out = process_evp_results( eigs, svecs, wmag, options.mode, wdir, bzone, pb, mtxs, std_wave_fun=std_wave_fun ) log(*out, x=[wmag, wmag]) save_eigenvectors(eigenshapes_filename % iv, svecs, wmag, wdir, pb) gc.collect() log(save_figure=os.path.join(output_dir, 'frequencies.png')) log(finished=True) else: eigenshapes_filename = os.path.join(output_dir, 'wave-number-eigenshapes-%s.vtk' % stepper.suffix) log = Log([[r'$\kappa_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear'], xlabels=[r'$\omega$'], ylabels=[r'wave numbers $\kappa_i$'], show_legends=options.show_legends, is_plot=options.show, 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)) evp_mtxs = build_evp_matrices(mtxs, omega, options.mode, pb) if options.eigs_only: eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=True) kappas, svecs, out = process_evp_results( eigs, svecs, omega, options.mode, wdir, bzone, pb, mtxs, std_wave_fun=std_wave_fun ) log(*out, x=[omega]) save_eigenvectors(eigenshapes_filename % io, svecs, kappas, wdir, pb) gc.collect() log(save_figure=os.path.join(output_dir, 'wave-numbers.png')) log(finished=True)
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 test_semismooth_newton(self): import numpy as nm from sfepy.solvers import Solver ns = [0, 6, 2, 2] offsets = nm.cumsum(ns) nx = offsets[-1] iw = slice(offsets[0], offsets[1]) ig = slice(offsets[1], offsets[2]) il = slice(offsets[2], offsets[3]) def fun_smooth(vec_x): xw = vec_x[iw] xg = vec_x[ig] xl = vec_x[il] m = self.ms rw = m['A'] * xw - m['Bb'].T * xg - self.m['fs'] rg = m['Bb'] * xw + xl * xg rwg = nm.r_[rw, rg] return rwg def fun_smooth_grad(vec_x): xw = vec_x[iw] xl = vec_x[il] xg = vec_x[ig] m = self.m mzl = nm.zeros((6, 2), dtype=nm.float64) mw = nm.c_[m['A'], -m['Bb'].T, mzl] mg = nm.c_[m['Bb'], nm.diag(xl), nm.diag(xg)] mx = nm.r_[mw, mg] mx = sps.csr_matrix(mx) return mx def fun_a(vec_x): xw = vec_x[iw] xg = vec_x[ig] subsd = {} for ii, key in enumerate(self.w_names): subsd[key] = xw[ii] sn = eval_matrix(self.m['sn'], **subsd).squeeze() ra = nm.abs(xg) - fc * nm.abs(sn) return -ra def fun_a_grad(vec_x): xw = vec_x[iw] xg = vec_x[ig] xl = vec_x[il] subsd = {} for ii, key in enumerate(self.w_names): subsd[key] = xw[ii] md = eval_matrix(self.m['D'], **subsd) sn = eval_matrix(self.m['sn'], **subsd).squeeze() ma = nm.zeros((xl.shape[0], nx), dtype=nm.float64) ma[:, iw] = -fc * nm.sign(sn)[:, None] * md ma[:, ig] = nm.sign(xg)[:, None] * self.m['C'] return -sps.csr_matrix(ma) def fun_b(vec_x): xl = vec_x[il] return xl def fun_b_grad(vec_x): xl = vec_x[il] mb = nm.zeros((xl.shape[0], nx), dtype=nm.float64) mb[:, il] = self.m['C'] return sps.csr_matrix(mb) vec_x0 = 0.1 * nm.ones((nx, ), dtype=nm.float64) lin_solver = Solver.any_from_conf(dict_to_struct(ls_conf)) status = {} solver = Solver.any_from_conf(dict_to_struct(conf), fun_smooth=fun_smooth, fun_smooth_grad=fun_smooth_grad, fun_a=fun_a, fun_a_grad=fun_a_grad, fun_b=fun_b, fun_b_grad=fun_b_grad, lin_solver=lin_solver, status=status) vec_x = solver(vec_x0) xw = vec_x[iw] xg = vec_x[ig] xl = vec_x[il] self.report('x:', xw) self.report('g:', xg) self.report('l:', xl) subsd = {} for ii, key in enumerate(self.w_names): subsd[key] = xw[ii] sn = eval_matrix(self.m['sn'], **subsd).squeeze() self.report('sn:', sn) ok = status['condition'] == 0 return ok
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='eigsh',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('--define-kwargs', metavar='dict-like', action='store', dest='define_kwargs', default=None, help=helps['define_kwargs']) 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('--stepper', action='store', dest='stepper', choices=['linear', 'brillouin'], default='linear', help=helps['stepper']) parser.add_argument('--range', metavar='start,stop,count', action='store', dest='range', default='0,6.4,33', 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']) group = parser.add_mutually_exclusive_group() group.add_argument('--eigs-only', action='store_true', dest='eigs_only', default=False, help=helps['eigs_only']) group.add_argument('--post-process', action='store_true', dest='post_process', default=False, help=helps['post_process']) 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-regions', action='store_true', dest='save_regions', default=False, help=helps['save_regions']) 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('--no-legends', action='store_false', dest='show_legends', default=True, help=helps['no_legends']) parser.add_argument('--no-show', action='store_false', dest='show', default=True, help=helps['no_show']) 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) else: mod = sys.modules[__name__] apply_units = mod.apply_units define = mod.define set_wave_dir = mod.set_wave_dir setup_n_eigs = mod.setup_n_eigs build_evp_matrices = mod.build_evp_matrices save_materials = mod.save_materials get_std_wave_fun = mod.get_std_wave_fun get_stepper = mod.get_stepper process_evp_results = mod.process_evp_results 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) options.define_kwargs = dict_from_string(options.define_kwargs) 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))], quote_command_line=True) 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: if options.stepper == 'brillouin': raise ValueError('Cannot use "brillouin" stepper in kappa mode!') 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) pb, wdir, bzone, mtxs = assemble_matrices(define, mod, pars, set_wave_dir, options) dim = pb.domain.shape.dim if dim != 2: options.plane = 'strain' if options.save_regions: pb.save_regions_as_groups(os.path.join(output_dir, 'regions')) if options.save_materials: save_materials(output_dir, pb, options) conf = pb.solver_confs['eig'] eig_solver = Solver.any_from_conf(conf) n_eigs, options.n_eigs = setup_n_eigs(options, pb, mtxs) get_color = lambda ii: plt.cm.viridis((float(ii) / (options.n_eigs - 1))) plot_kwargs = [{'color' : get_color(ii), 'ls' : '', 'marker' : 'o'} for ii in range(options.n_eigs)] get_color_dim = lambda ii: plt.cm.viridis((float(ii) / (dim-1))) plot_kwargs_dim = [{'color' : get_color_dim(ii), 'ls' : '', 'marker' : 'o'} for ii in range(dim)] log_names = [] log_plot_kwargs = [] if options.log_std_waves: std_wave_fun, log_names, log_plot_kwargs = get_std_wave_fun( pb, options) else: std_wave_fun = None stepper = get_stepper(rng, pb, options) if options.mode == 'omega': eigenshapes_filename = os.path.join(output_dir, 'frequency-eigenshapes-%s.vtk' % stepper.suffix) if options.stepper == 'linear': log = Log([[r'$\lambda_{%d}$' % ii for ii in range(options.n_eigs)], [r'$\omega_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs, plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * options.n_eigs, ['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear', 'linear'], xlabels=[r'$\kappa$', r'$\kappa$'], ylabels=[r'eigenvalues $\lambda_i$', r'frequencies $\omega_i$'], show_legends=options.show_legends, is_plot=options.show, log_filename=os.path.join(output_dir, 'frequencies.txt'), aggregate=1000, sleep=0.1) else: log = Log([[r'$\kappa_{%d}$'% ii for ii in range(dim)], [r'$\omega_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs_dim, plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * dim, ['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear', 'linear'], xlabels=[r'', r''], ylabels=[r'wave vector $\kappa$', r'frequencies $\omega_i$'], show_legends=options.show_legends, is_plot=options.show, log_filename=os.path.join(output_dir, 'frequencies.txt'), aggregate=1000, sleep=0.1) for aux in stepper: if options.stepper == 'linear': iv, wmag = aux else: iv, wmag, wdir = aux output('step %d: wave vector %s' % (iv, wmag * wdir)) if options.stepper == 'brillouin': pb, _, bzone, mtxs = assemble_matrices( define, mod, pars, set_wave_dir, options, wdir=wdir) evp_mtxs = build_evp_matrices(mtxs, wmag, options.mode, pb) if options.eigs_only: eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=True) omegas, svecs, out = process_evp_results( eigs, svecs, wmag, wdir, bzone, pb, mtxs, options, std_wave_fun=std_wave_fun ) if options.stepper == 'linear': log(*out, x=[wmag, wmag]) else: log(*out, x=[iv, iv]) save_eigenvectors(eigenshapes_filename % iv, svecs, wmag, wdir, pb) gc.collect() log(save_figure=os.path.join(output_dir, 'frequencies.png')) log(finished=True) else: eigenshapes_filename = os.path.join(output_dir, 'wave-number-eigenshapes-%s.vtk' % stepper.suffix) log = Log([[r'$\kappa_{%d}$' % ii for ii in range(options.n_eigs)] + log_names], plot_kwargs=[plot_kwargs + log_plot_kwargs], formats=[['{:.5e}'] * (options.n_eigs + len(log_names))], yscales=['linear'], xlabels=[r'$\omega$'], ylabels=[r'wave numbers $\kappa_i$'], show_legends=options.show_legends, is_plot=options.show, 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)) evp_mtxs = build_evp_matrices(mtxs, omega, options.mode, pb) if options.eigs_only: eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=False) svecs = None else: eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs, eigenvectors=True) kappas, svecs, out = process_evp_results( eigs, svecs, omega, wdir, bzone, pb, mtxs, options, std_wave_fun=std_wave_fun ) log(*out, x=[omega]) save_eigenvectors(eigenshapes_filename % io, svecs, kappas, wdir, pb) gc.collect() log(save_figure=os.path.join(output_dir, 'wave-numbers.png')) log(finished=True)
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)
aux = "eig.scipy,method:'eigh',tol:1e-7,maxiter:10000".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) dims = nm.array([1.0, 1.5], dtype=nm.float64) dim = len(dims) centre = nm.array([0.0, 0.0], dtype=nm.float64)[:dim] shape = nm.array([11, 16], dtype=nm.int32)[:dim] mesh = gen_block_mesh(dims, shape, centre, name='mesh') 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[:, -1] eps = 1e-8 * (max_coor - min_coor) ax = 'xyz'[:dim][-1] 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=1)
def solve_eigen_problem1( conf, options ): pb = ProblemDefinition.from_conf( conf ) dim = pb.domain.mesh.dim pb.time_update() dummy = pb.create_state_vector() output( 'assembling lhs...' ) tt = time.clock() mtx_a = eval_term_op( dummy, conf.equations['lhs'], pb, dw_mode = 'matrix', tangent_matrix = pb.mtx_a ) output( '...done in %.2f s' % (time.clock() - tt) ) output( 'assembling rhs...' ) tt = time.clock() mtx_b = eval_term_op( dummy, conf.equations['rhs'], pb, dw_mode = 'matrix', tangent_matrix = pb.mtx_a.copy() ) output( '...done in %.2f s' % (time.clock() - tt) ) #mtxA.save( 'tmp/a.txt', format='%d %d %.12f\n' ) #mtxB.save( 'tmp/b.txt', format='%d %d %.12f\n' ) try: n_eigs = conf.options.n_eigs except AttributeError: n_eigs = mtx_a.shape[0] if n_eigs is None: n_eigs = mtx_a.shape[0] ## mtx_a.save( 'a.txt', format='%d %d %.12f\n' ) ## mtx_b.save( 'b.txt', format='%d %d %.12f\n' ) print 'computing resonance frequencies...' eig = Solver.any_from_conf( pb.get_solver_conf( conf.options.eigen_solver ) ) eigs, mtx_s_phi = eig( mtx_a, mtx_b, conf.options.n_eigs ) from sfepy.fem.mesh import Mesh bounding_box = Mesh.from_file("tmp/mesh.vtk").get_bounding_box() # this assumes a box (3D), or a square (2D): a = bounding_box[1][0] - bounding_box[0][0] E_exact = None if options.hydrogen or options.boron: if options.hydrogen: Z = 1 elif options.boron: Z = 5 if options.dim == 2: E_exact = [-float(Z)**2/2/(n-0.5)**2/4 for n in [1]+[2]*3+[3]*5 +\ [4]*8 + [5]*15] elif options.dim == 3: E_exact = [-float(Z)**2/2/n**2 for n in [1]+[2]*2**2+[3]*3**2 ] if options.well: if options.dim == 2: E_exact = [pi**2/(2*a**2)*x for x in [2, 5, 5, 8, 10, 10, 13, 13, 17, 17, 18, 20, 20 ] ] elif options.dim == 3: E_exact = [pi**2/(2*a**2)*x for x in [3, 6, 6, 6, 9, 9, 9, 11, 11, 11, 12, 14, 14, 14, 14, 14, 14, 17, 17, 17] ] if options.oscillator: if options.dim == 2: E_exact = [1] + [2]*2 + [3]*3 + [4]*4 + [5]*5 + [6]*6 elif options.dim == 3: E_exact = [float(1)/2+x for x in [1]+[2]*3+[3]*6+[4]*10 ] if E_exact is not None: print "a=%f" % a print "Energies:" print "n exact FEM error" for i, e in enumerate(eigs): from numpy import NaN if i < len(E_exact): exact = E_exact[i] err = 100*abs((exact - e)/exact) else: exact = NaN err = NaN print "%d: %.8f %.8f %5.2f%%" % (i, exact, e, err) else: print eigs ## import sfepy.base.plotutils as plu ## plu.spy( mtx_b, eps = 1e-12 ) ## plu.pylab.show() ## pause() n_eigs = eigs.shape[0] mtx_phi = nm.empty( (pb.variables.di.ptr[-1], mtx_s_phi.shape[1]), dtype = nm.float64 ) for ii in xrange( n_eigs ): mtx_phi[:,ii] = pb.variables.make_full_vec( mtx_s_phi[:,ii] ) save = get_default_attr( conf.options, 'save_eig_vectors', None ) out = {} for ii in xrange( n_eigs ): if save is not None: if (ii > save[0]) and (ii < (n_eigs - save[1])): continue aux = pb.state_to_output( mtx_phi[:,ii] ) key = aux.keys()[0] out[key+'%03d' % ii] = aux[key] ofn_trunk = options.output_filename_trunk pb.domain.mesh.write( ofn_trunk + '.vtk', io = 'auto', out = out ) fd = open( ofn_trunk + '_eigs.txt', 'w' ) eigs.tofile( fd, ' ' ) fd.close() return Struct( pb = pb, eigs = eigs, mtx_phi = mtx_phi )
def test_semismooth_newton(self): import numpy as nm from sfepy.solvers import Solver ns = [0, 6, 2, 2] offsets = nm.cumsum(ns) nx = offsets[-1] iw = slice(offsets[0], offsets[1]) ig = slice(offsets[1], offsets[2]) il = slice(offsets[2], offsets[3]) def fun_smooth(vec_x): xw = vec_x[iw] xg = vec_x[ig] xl = vec_x[il] m = self.ms rw = m['A'] * xw - m['Bb'].T * xg - self.m['fs'] rg = m['Bb'] * xw + xl * xg rwg = nm.r_[rw, rg] return rwg def fun_smooth_grad(vec_x): xw = vec_x[iw] xl = vec_x[il] xg = vec_x[ig] m = self.m mzl = nm.zeros((6, 2), dtype=nm.float64) mw = nm.c_[m['A'], -m['Bb'].T, mzl] mg = nm.c_[m['Bb'], nm.diag(xl), nm.diag(xg)] mx = nm.r_[mw, mg] mx = sps.csr_matrix(mx) return mx def fun_a(vec_x): xw = vec_x[iw] xg = vec_x[ig] subsd = {} for ii, key in enumerate(self.w_names): subsd[key] = xw[ii] sn = eval_matrix(self.m['sn'], **subsd).squeeze() ra = nm.abs(xg) - fc * nm.abs(sn) return -ra def fun_a_grad(vec_x): xw = vec_x[iw] xg = vec_x[ig] xl = vec_x[il] subsd = {} for ii, key in enumerate(self.w_names): subsd[key] = xw[ii] md = eval_matrix(self.m['D'], **subsd) sn = eval_matrix(self.m['sn'], **subsd).squeeze() ma = nm.zeros((xl.shape[0], nx), dtype=nm.float64) ma[:,iw] = - fc * nm.sign(sn)[:,None] * md ma[:,ig] = nm.sign(xg)[:,None] * self.m['C'] return -sps.csr_matrix(ma) def fun_b(vec_x): xl = vec_x[il] return xl def fun_b_grad(vec_x): xl = vec_x[il] mb = nm.zeros((xl.shape[0], nx), dtype=nm.float64) mb[:,il] = self.m['C'] return sps.csr_matrix(mb) vec_x0 = 0.1 * nm.ones((nx,), dtype=nm.float64) lin_solver = Solver.any_from_conf(dict_to_struct(ls_conf)) status = {} solver = Solver.any_from_conf(dict_to_struct(conf), fun_smooth=fun_smooth, fun_smooth_grad=fun_smooth_grad, fun_a=fun_a, fun_a_grad=fun_a_grad, fun_b=fun_b, fun_b_grad=fun_b_grad, lin_solver=lin_solver, status=status) vec_x = solver(vec_x0) xw = vec_x[iw] xg = vec_x[ig] xl = vec_x[il] self.report('x:', xw) self.report('g:', xg) self.report('l:', xl) subsd = {} for ii, key in enumerate(self.w_names): subsd[key] = xw[ii] sn = eval_matrix(self.m['sn'], **subsd).squeeze() self.report('sn:', sn) ok = status['condition'] == 0 return ok
def get_time_solver(self, ts_conf=None, **kwargs): ts_conf = get_default(ts_conf, self.ts_conf, "you must set time-stepping solver!") return Solver.any_from_conf(ts_conf, **kwargs)
def solve_eigen_problem_n( self ): opts = self.app_options pb = self.problem dim = pb.domain.mesh.dim pb.set_equations( pb.conf.equations ) pb.select_bcs( ebc_names = ['ZeroSurface'] ) output( 'assembling rhs...' ) tt = time.clock() mtx_b = pb.evaluate(pb.conf.equations['rhs'], mode='weak', auto_init=True, dw_mode='matrix') output( '...done in %.2f s' % (time.clock() - tt) ) assert_( nm.alltrue( nm.isfinite( mtx_b.data ) ) ) ## mtx_b.save( 'b.txt', format='%d %d %.12f\n' ) aux = pb.create_evaluable(pb.conf.equations['lhs'], mode='weak', dw_mode='matrix') mtx_a_equations, mtx_a_variables = aux if self.options.plot: log_conf = { 'is_plot' : True, 'aggregate' : 1, 'yscales' : ['linear', 'log'], } else: log_conf = { 'is_plot' : False, } log = Log.from_conf( log_conf, ([r'$|F(x)|$'], [r'$|F(x)-x|$']) ) file_output = Output('', opts.log_filename, combined = True) eig_conf = pb.get_solver_conf( opts.eigen_solver ) eig_solver = Solver.any_from_conf( eig_conf ) # Just to get the shape. Assumes one element group only!!! v_hxc_qp = pb.evaluate('dq_state_in_volume_qp.i1.Omega(Psi)') v_hxc_qp.fill(0.0) self.qp_shape = v_hxc_qp.shape vec_v_hxc = self._interp_to_nodes(v_hxc_qp) self.norm_v_hxc0 = nla.norm(vec_v_hxc) self.itercount = 0 aux = wrap_function(self.iterate, (eig_solver, mtx_a_equations, mtx_a_variables, mtx_b, log, file_output)) ncalls, times, nonlin_v, results = aux # Create and call the DFT solver. dft_conf = pb.get_solver_conf(opts.dft_solver) dft_status = {} dft_solver = Solver.any_from_conf(dft_conf, fun = nonlin_v, status = dft_status) v_hxc_qp = dft_solver(v_hxc_qp.ravel()) v_hxc_qp = nm.array(v_hxc_qp, dtype=nm.float64) v_hxc_qp.shape = self.qp_shape eigs, mtx_s_phi, vec_n, vec_v_h, v_ion_qp, v_xc_qp, v_hxc_qp = results output( 'DFT iteration time [s]:', dft_status['time_stats'] ) fun = pb.materials['mat_v'].function variable = self.problem.create_variables(['scalar'])['scalar'] vec_v_ion = fun(None, variable.field.get_coor(), mode='qp')['V_ion'].squeeze() vec_v_xc = self._interp_to_nodes(v_xc_qp) vec_v_hxc = self._interp_to_nodes(v_hxc_qp) vec_v_sum = self._interp_to_nodes(v_hxc_qp + v_ion_qp) coor = pb.domain.get_mesh_coors() r2 = norm_l2_along_axis(coor, squared=True) vec_nr2 = vec_n * r2 pb.select_bcs( ebc_names = ['ZeroSurface'] ) mtx_phi = self.make_full( mtx_s_phi ) out = {} update_state_to_output(out, pb, vec_n, 'n') update_state_to_output(out, pb, vec_nr2, 'nr2') update_state_to_output(out, pb, vec_v_h, 'V_h') update_state_to_output(out, pb, vec_v_xc, 'V_xc') update_state_to_output(out, pb, vec_v_ion, 'V_ion') update_state_to_output(out, pb, vec_v_hxc, 'V_hxc') update_state_to_output(out, pb, vec_v_sum, 'V_sum') self.save_results(eigs, mtx_phi, out=out) if self.options.plot: log( save_figure = opts.iter_fig_name ) pause() log(finished=True) return Struct( pb = pb, eigs = eigs, mtx_phi = mtx_phi, vec_n = vec_n, vec_nr2 = vec_nr2, vec_v_h = vec_v_h, vec_v_xc = vec_v_xc )
def test_ls_reuse(self): import numpy as nm from sfepy.solvers import Solver from sfepy.discrete.state import State self.problem.init_solvers(ls_conf=self.problem.solver_confs['d00']) nls = self.problem.get_nls() state0 = State(self.problem.equations.variables) state0.apply_ebc() vec0 = state0.get_reduced() self.problem.update_materials() rhs = nls.fun(vec0) mtx = nls.fun_grad(vec0) ok = True for name in ['i12', 'i01']: solver_conf = self.problem.solver_confs[name] method = solver_conf.get('method', '') precond = solver_conf.get('precond', '') name = ' '.join((solver_conf.name, solver_conf.kind, method, precond)).rstrip() self.report(name) try: ls = Solver.any_from_conf(solver_conf) except: self.report('skipped!') continue conf = ls.conf.copy() conf.force_reuse = True sol00 = ls(rhs, mtx=mtx, conf=conf) digest00 = ls.mtx_digest sol0 = ls(rhs, mtx=mtx) digest0 = ls.mtx_digest sol1 = ls(rhs, mtx=2*mtx, conf=conf) digest1 = ls.mtx_digest sol2 = ls(rhs, mtx=2*mtx) digest2 = ls.mtx_digest ls(rhs, mtx=2*mtx) digest3 = ls.mtx_digest _ok = digest00 != digest0 self.report(digest00, '!=', digest0, ':', _ok); ok = ok and _ok _ok = digest0 == digest1 self.report(digest0, '==', digest1, ':', _ok); ok = ok and _ok _ok = digest1 != digest2 self.report(digest1, '!=', digest2, ':', _ok); ok = ok and _ok _ok = digest2[1] == digest3[1] self.report(digest2[1], '==', digest3[1], ':', _ok); ok = ok and _ok _ok = nm.allclose(sol00, sol0, atol=1e-12, rtol=0.0) self.report('sol00 == sol0:', _ok); ok = ok and _ok _ok = nm.allclose(sol0, sol1, atol=1e-12, rtol=0.0) self.report('sol0 == sol1:', _ok); ok = ok and _ok _ok = nm.allclose(sol0, 2 * sol2, atol=1e-12, rtol=0.0) self.report('sol0 == 2 * sol2:', _ok); ok = ok and _ok return ok
def solve_eigen_problem(self): options = self.options opts = self.app_options pb = self.problem dim = pb.domain.mesh.dim pb.set_equations(pb.conf.equations) pb.time_update() output('assembling lhs...') tt = time.clock() mtx_a = pb.evaluate(pb.conf.equations['lhs'], mode='weak', auto_init=True, dw_mode='matrix') output('...done in %.2f s' % (time.clock() - tt)) output('assembling rhs...') tt = time.clock() mtx_b = pb.evaluate(pb.conf.equations['rhs'], mode='weak', dw_mode='matrix') output('...done in %.2f s' % (time.clock() - tt)) n_eigs = get_default(opts.n_eigs, mtx_a.shape[0]) output('computing resonance frequencies...') eig = Solver.any_from_conf(pb.get_solver_conf(opts.eigen_solver)) eigs, mtx_s_phi = eig(mtx_a, mtx_b, n_eigs, eigenvectors=True) output('...done') bounding_box = pb.domain.mesh.get_bounding_box() # this assumes a box (3D), or a square (2D): a = bounding_box[1][0] - bounding_box[0][0] E_exact = None if options.hydrogen or options.boron: if options.hydrogen: Z = 1 elif options.boron: Z = 5 if dim == 2: E_exact = [-float(Z)**2/2/(n-0.5)**2/4 for n in [1]+[2]*3+[3]*5 + [4]*8 + [5]*15] elif dim == 3: E_exact = [-float(Z)**2/2/n**2 for n in [1]+[2]*2**2+[3]*3**2 ] if options.well: if dim == 2: E_exact = [pi**2/(2*a**2)*x for x in [2, 5, 5, 8, 10, 10, 13, 13, 17, 17, 18, 20, 20 ] ] elif dim == 3: E_exact = [pi**2/(2*a**2)*x for x in [3, 6, 6, 6, 9, 9, 9, 11, 11, 11, 12, 14, 14, 14, 14, 14, 14, 17, 17, 17] ] if options.oscillator: if dim == 2: E_exact = [1] + [2]*2 + [3]*3 + [4]*4 + [5]*5 + [6]*6 elif dim == 3: E_exact = [float(1)/2+x for x in [1]+[2]*3+[3]*6+[4]*10 ] if E_exact is not None: output("a=%f" % a) output("Energies:") output("n exact FEM error") for i, e in enumerate(eigs): from numpy import NaN if i < len(E_exact): exact = E_exact[i] err = 100*abs((exact - e)/exact) else: exact = NaN err = NaN output("%d: %.8f %.8f %5.2f%%" % (i, exact, e, err)) else: output(eigs) mtx_phi = self.make_full(mtx_s_phi) self.save_results(eigs, mtx_phi) return Struct(pb=pb, eigs=eigs, mtx_phi=mtx_phi)
def solve_eigen_problem_n( conf, options ): pb = ProblemDefinition.from_conf( conf ) dim = pb.domain.mesh.dim pb.time_update() dummy = pb.create_state_vector() output( 'assembling rhs...' ) tt = time.clock() mtx_b = eval_term_op( dummy, conf.equations['rhs'], pb, dw_mode = 'matrix', tangent_matrix = pb.mtx_a.copy() ) output( '...done in %.2f s' % (time.clock() - tt) ) #mtxA.save( 'tmp/a.txt', format='%d %d %.12f\n' ) #mtxB.save( 'tmp/b.txt', format='%d %d %.12f\n' ) try: n_eigs = conf.options.n_eigs except AttributeError: n_eigs = mtx_a.shape[0] if n_eigs is None: n_eigs = mtx_a.shape[0] ## mtx_a.save( 'a.txt', format='%d %d %.12f\n' ) ## mtx_b.save( 'b.txt', format='%d %d %.12f\n' ) if options.plot: log_conf = { 'is_plot' : True, 'aggregate' : 1, 'yscales' : ['linear', 'log'], } else: log_conf = { 'is_plot' : False, } log = Log.from_conf( log_conf, ([r'$|F(x)|$'], [r'$|F(x)|$']) ) eig_conf = pb.get_solver_conf( conf.options.eigen_solver ) eig_solver = Solver.any_from_conf( eig_conf ) vec_vhxc = nm.zeros( (pb.variables.di.ptr[-1],), dtype = nm.float64 ) aux = wrap_function( iterate, (pb, conf, eig_solver, n_eigs, mtx_b, log) ) ncalls, times, nonlin_v = aux vec_vhxc = broyden3( nonlin_v, vec_vhxc, verbose = True ) out = iterate( vec_vhxc, pb, conf, eig_solver, n_eigs, mtx_b ) eigs, mtx_s_phi, vec_n, vec_vh, vec_vxc = out if options.plot: log( finished = True ) pause() coor = pb.domain.get_mesh_coors() r = coor[:,0]**2 + coor[:,1]**2 + coor[:,2]**2 vec_nr2 = vec_n * r n_eigs = eigs.shape[0] mtx_phi = nm.empty( (pb.variables.di.ptr[-1], mtx_s_phi.shape[1]), dtype = nm.float64 ) for ii in xrange( n_eigs ): mtx_phi[:,ii] = pb.variables.make_full_vec( mtx_s_phi[:,ii] ) save = get_default_attr( conf.options, 'save_eig_vectors', None ) out = {} for ii in xrange( n_eigs ): if save is not None: if (ii >= save[0]) and (ii < (n_eigs - save[1])): continue aux = pb.state_to_output( mtx_phi[:,ii] ) key = aux.keys()[0] out[key+'%03d' % ii] = aux[key] update_state_to_output( out, pb, vec_n, 'n' ) update_state_to_output( out, pb, vec_nr2, 'nr2' ) update_state_to_output( out, pb, vec_vh, 'vh' ) update_state_to_output( out, pb, vec_vxc, 'vxc' ) ofn_trunk = options.output_filename_trunk pb.domain.mesh.write( ofn_trunk + '.vtk', io = 'auto', out = out ) fd = open( ofn_trunk + '_eigs.txt', 'w' ) eigs.tofile( fd, ' ' ) fd.close() return Struct( pb = pb, eigs = eigs, mtx_phi = mtx_phi )