def test_vector_matrix( self ): from sfepy.fem import eval_term_op problem = self.problem state = problem.create_state_vector() problem.apply_ebc( state ) aux1 = eval_term_op( state, "dw_diffusion.i1.Omega( m.K, q, p )", problem, dw_mode = 'vector' ) aux1g = problem.variables.make_full_vec( aux1 ) problem.time_update( conf_ebc = {}, conf_epbc = {} ) mtx = eval_term_op( state, "dw_diffusion.i1.Omega( m.K, q, p )", problem, dw_mode = 'matrix' ) aux2g = mtx * state problem.time_update( conf_ebc = self.conf.ebcs, conf_epbc = self.conf.epbcs ) aux2 = problem.variables.strip_state_vector( aux2g, follow_epbc = True ) ret = self.compare_vectors( aux1, aux2, label1 = 'vector mode', label2 = 'matrix mode' ) if not ret: self.report( 'variable %s: failed' % var_name ) return ret
def test_consistency_d_dw( self ): from sfepy.base.base import select_by_names from sfepy.fem import eval_term_op ok = True pb = self.problem for aux in test_terms: term_template, (prefix, par_name, d_vars, dw_vars, mat_mode) = aux print term_template, prefix, par_name, d_vars, dw_vars, mat_mode var_names = nm.unique1d( d_vars + dw_vars ) variables = select_by_names( pb.conf.variables, var_names ) pb.set_variables( variables ) vecs = {} for var_name in d_vars: var = pb.variables[var_name] n_dof = var.field.n_nod * var.field.dim[0] vecs[var_name] = nm.arange( n_dof, dtype = nm.float64 ) var.data_from_data( vecs[var_name] ) term1 = term_template % ((prefix,) + d_vars) pb.set_equations( {'eq': term1} ) mat_args = {'m' : {'mode' : mat_mode}} pb.time_update( extra_mat_args = mat_args ) dummy = pb.create_state_vector() if prefix == 'd': val1 = eval_term_op( dummy, term1, pb ) else: val1 = eval_term_op( dummy, term1, pb, call_mode = 'd_eval' ) self.report( '%s: %s' % (term1, val1) ) term2 = term_template % (('dw',) + dw_vars[:-1]) vec = eval_term_op( dummy, term2, pb ) val2 = nm.dot( vecs[par_name], vec ) self.report( '%s: %s' % (term2, val2) ) err = nm.abs( val1 - val2 ) / nm.abs( val1 ) _ok = err < 1e-12 self.report( 'relative difference: %e -> %s' % (err, _ok) ) ok = ok and _ok return ok
def test_linear_rigid_body_bc( self ): import scipy if scipy.version.version == "0.6.0": # This test uses a functionality implemented in scipy svn, which is # missing in scipy 0.6.0 return True from sfepy.base.base import Struct from sfepy.solvers.generic import solve_stationary from sfepy.base.base import IndexedStruct from sfepy.fem import eval_term_op status = IndexedStruct() problem, vec, data = solve_stationary( self.conf, nls_status = status ) ok = status.condition == 0 self.report( 'converged: %s' % ok ) out = problem.state_to_output( vec ) strain = eval_term_op( vec, 'de_cauchy_strain.i1.Y( u )', problem ) out['strain'] = Struct( name = 'output_data', mode = 'cell', data = strain, dof_types = None ) name = op.join( self.options.out_dir, op.split( self.conf.output_name )[1] ) problem.domain.mesh.write( name, io = 'auto', out = out ) ## # Check if rigid body displacements are really rigid should go here. return ok
def __call__( self, volume, problem = None, data = None ): problem = get_default( problem, self.problem ) problem.select_variables( self.variables ) dim = problem.get_dim() coef = nm.zeros( (dim, dim), dtype = nm.float64 ) for ir in range( dim ): for name, val in self.get_variables( problem, ir, None, data, 'row' ): problem.variables[name].data_from_data( val ) for ic in range( dim ): for name, val in self.get_variables( problem, None, ic, data, 'col' ): problem.variables[name].data_from_data( val ) val = eval_term_op( None, self.expression, problem, call_mode = 'd_eval' ) coef[ir,ic] = val coef /= volume return coef
def __call__( self, volume, problem = None, data = None ): problem = get_default( problem, self.problem ) problem.select_variables( self.variables ) dim, sym = problem.get_dim( get_sym = True ) coef = nm.zeros( (sym, sym), dtype = nm.float64 ) for ir, (irr, icr) in enumerate( iter_sym( dim ) ): for name, val in self.get_variables( problem, irr, icr, data, 'row' ): problem.variables[name].data_from_data( val ) for ic, (irc, icc) in enumerate( iter_sym( dim ) ): for name, val in self.get_variables( problem, irc, icc, data, 'col' ): problem.variables[name].data_from_data( val ) val = eval_term_op( None, self.expression, problem, call_mode = 'd_eval' ) coef[ir,ic] = val coef /= volume return coef
def iterate( vec_vhxc, pb, conf, eig_solver, n_eigs, mtx_b, log, n_electron = 5 ): global itercount itercount += 1 from sfepy.physics import dft pb.update_materials( extra_mat_args = {'mat_v' : {'vhxc' : vec_vhxc}} ) 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) ) print 'computing the Ax=Blx Kohn-Sham problem...' eigs, mtx_s_phi = eig_solver( mtx_a, mtx_b, conf.options.n_eigs ) if len(eigs) < n_electron: print len(eigs) print eigs raise Exception("Not enough eigenvalues have converged. Exiting.") print "saving solutions, iter=%d" % itercount out = {} var_name = pb.variables.get_names( kind = 'state' )[0] for ii in xrange( len(eigs) ): vec_phi = pb.variables.make_full_vec( mtx_s_phi[:,ii] ) update_state_to_output( out, pb, vec_phi, var_name+'%03d' % ii ) pb.save_state( "tmp/iter%d.vtk" % itercount, out = out ) print "solutions saved" vec_phi = nm.zeros_like( vec_vhxc ) vec_n = nm.zeros_like( vec_vhxc ) for ii in xrange( n_electron ): vec_phi = pb.variables.make_full_vec( mtx_s_phi[:,ii] ) vec_n += vec_phi ** 2 vec_vxc = nm.zeros_like( vec_vhxc ) for ii, val in enumerate( vec_n ): vec_vxc[ii] = dft.getvxc( val/(4*pi), 0 ) pb.set_equations( conf.equations_vh ) pb.time_update() pb.variables['n'].data_from_data( vec_n ) print "Solving Ax=b Poisson equation" vec_vh = pb.solve() #sphere = eval_term_op( dummy, conf.equations['sphere'], pb) #print sphere norm = nla.norm( vec_vh + vec_vxc ) log( norm, norm ) return eigs, mtx_s_phi, vec_n, vec_vh, vec_vxc
def post_process( out, problem, mtx_phi ): from sfepy.fem import eval_term_op for key in out.keys(): ii = int( key[1:] ) vec = mtx_phi[:,ii].copy() strain = eval_term_op( vec, 'de_cauchy_strain.i1.Y23( u )', problem ) strain = extend_cell_data( strain, problem, 'Y23' ) out['strain%03d' % ii] = Struct( name = 'output_data', mode = 'cell', data = strain, dof_types = None ) return out
def __call__( self, volume, problem = None, data = None ): problem = get_default( problem, self.problem ) problem.select_variables( self.variables ) coef = nm.zeros( (1,), dtype = nm.float64 ) for name, val in self.get_variables( problem, data ): problem.variables[name].data_from_data( val ) val = eval_term_op( None, self.expression, problem, call_mode = 'd_eval' ) coef = val / volume return coef
def verify_incompressibility( out, problem, state, extend = False ): """This hook is normally used for post-processing (additional results can be inserted into `out` dictionary), but here we just verify the weak incompressibility condition.""" from sfepy.base.base import Struct, debug from sfepy.fem import eval_term_op vv = problem.variables one = nm.ones( (vv['pp'].field.n_nod,), dtype = nm.float64 ) vv['pp'].data_from_data( one ) zero = eval_term_op( state, 'dw_stokes.i1.Omega( u, pp )', problem, pp = one, call_mode = 'd_eval' ) print 'div( u ) = %.3e' % zero return out
def __call__( self, volume, problem = None, data = None ): problem = get_default( problem, self.problem ) problem.select_variables( self.variables ) coef = nm.zeros( (1,), dtype = nm.float64 ) ldata = data[self.requires[0]] var0 = problem.variables[0] ndata = nm.zeros( (var0.n_nod,), dtype=nm.float64 ) for ivar in ldata.di.vnames: ndata += ldata.states[ldata.di.indx[ivar]] problem.variables[0].data_from_data( ndata ) val = eval_term_op( None, self.expression, problem, call_mode = 'd_eval' ) coef = val / volume return coef
def main(): from sfepy.base.base import spause from sfepy.base.conf import ProblemConf, get_standard_keywords from sfepy.fem import eval_term_op, ProblemDefinition from sfepy.homogenization.utils import create_pis from sfepy.homogenization.coefs import CorrectorsRS, ElasticCoef nm.set_printoptions( precision = 3 ) spause( r""">>> First, this file will be read in place of an input (problem description) file. Press 'q' to quit the example, press any other key to continue...""" ) required, other = get_standard_keywords() required.remove( 'equations' ) # Use this file as the input file. conf = ProblemConf.from_file( __file__, required, other ) print conf.to_dict().keys() spause( r""">>> ...the read input as a dict (keys only for brevity). ['q'/other key to quit/continue...]""" ) spause( r""">>> Now the input will be used to create a ProblemDefinition instance. ['q'/other key to quit/continue...]""" ) problem = ProblemDefinition.from_conf( conf, init_variables = False, init_equations = False ) print problem spause( r""">>> ...the ProblemDefinition instance. ['q'/other key to quit/continue...]""" ) spause( r""">>> The homogenized elastic coefficient $E_{ijkl}$ is expressed using $\Pi$ operators, computed now. In fact, those operators are permuted coordinates of the mesh nodes. ['q'/other key to quit/continue...]""" ) req = conf.requirements['pis'] pis = create_pis( problem, req['variables'][0] ) print pis spause( r""">>> ...the $\Pi$ operators. ['q'/other key to quit/continue...]""" ) spause( r""">>> Next, $E_{ijkl}$ needs so called steady state correctors $\bar{\omega}^{rs}$, computed now. The results will be saved in: %s_*.vtk ['q'/other key to quit/continue...]""" % problem.ofn_trunk ) save_hook = make_save_hook( problem.ofn_trunk + '_rs_%d%d' ) req = conf.requirements['corrs_rs'] solve_corrs = CorrectorsRS( 'steady rs correctors', problem, req ) corrs_rs = solve_corrs( data = pis, save_hook = save_hook ) print corrs_rs spause( r""">>> ...the $\bar{\omega}^{rs}$ correctors. ['q'/other key to quit/continue...]""" ) spause( r""">>> Then the volume of the domain is needed. ['q'/other key to quit/continue...]""" ) volume = eval_term_op( None, 'd_volume.i3.Y( uc )', problem ) print volume spause( r""">>> ...the volume. ['q'/other key to quit/continue...]""" ) spause( r""">>> Finally, $E_{ijkl}$ can be computed. ['q'/other key to quit/continue...]""" ) get_coef = ElasticCoef( 'homogenized elastic tensor', problem, conf.coefs['E'] ) c_e = get_coef( volume, data = {'pis': pis, 'corrs' : corrs_rs} ) print r""">>> The homogenized elastic coefficient $E_{ijkl}$, symmetric storage with rows, columns in 11, 22, 12 ordering:""" print c_e
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 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 )