def get_mat(coors, mode, pb): if mode == 'qp': cnf = pb.conf # get material coefficients if hasattr(cnf, 'opt_data'): # from optim. E_f, nu_f, E_m, nu_m = cnf.opt_data['mat_params'] else: # given values E_f, nu_f, E_m, nu_m = 160.e9, 0.28, 5.e9, 0.45 nqp = coors.shape[0] nel = pb.domain.mesh.n_el nqpe = nqp // nel out = nm.zeros((nqp, 6, 6), dtype=nm.float64) # set values - matrix D_m = stiffness_from_youngpoisson(3, E_m, nu_m) Ym = pb.domain.regions['Ym'].get_cells() idx0 = (nm.arange(nqpe)[:,nm.newaxis] * nm.ones((1, Ym.shape[0]), dtype=nm.int32)).T.flatten() idxs = (Ym[:,nm.newaxis] * nm.ones((1, nqpe), dtype=nm.int32)).flatten() * nqpe out[idxs + idx0,...] = D_m # set values - fiber D_f = stiffness_from_youngpoisson(3, E_f, nu_f) Yf = pb.domain.regions['Yf'].get_cells() idx0 = (nm.arange(nqpe)[:,nm.newaxis] * nm.ones((1, Yf.shape[0]), dtype=nm.int32)).T.flatten() idxs = (Yf[:,nm.newaxis] * nm.ones((1, nqpe), dtype=nm.int32)).flatten() * nqpe out[idxs + idx0,...] = D_f return {'D': out}
def get_mat(coors, mode, pb): if mode == 'qp': cnf = pb.conf # get material coefficients if hasattr(cnf, 'opt_data'): # from optim. E_f, nu_f, E_m, nu_m = cnf.opt_data['mat_params'] else: # given values E_f, nu_f, E_m, nu_m = 160.e9, 0.28, 5.e9, 0.45 nqp = coors.shape[0] nel = pb.domain.mesh.n_el nqpe = nqp // nel out = nm.zeros((nqp, 6, 6), dtype=nm.float64) # set values - matrix D_m = stiffness_from_youngpoisson(3, E_m, nu_m) Ym = pb.domain.regions['Ym'].get_cells() idx0 = (nm.arange(nqpe)[:, nm.newaxis] * nm.ones( (1, Ym.shape[0]), dtype=nm.int32)).T.flatten() idxs = (Ym[:, nm.newaxis] * nm.ones( (1, nqpe), dtype=nm.int32)).flatten() * nqpe out[idxs + idx0, ...] = D_m # set values - fiber D_f = stiffness_from_youngpoisson(3, E_f, nu_f) Yf = pb.domain.regions['Yf'].get_cells() idx0 = (nm.arange(nqpe)[:, nm.newaxis] * nm.ones( (1, Yf.shape[0]), dtype=nm.int32)).T.flatten() idxs = (Yf[:, nm.newaxis] * nm.ones( (1, nqpe), dtype=nm.int32)).flatten() * nqpe out[idxs + idx0, ...] = D_f return {'D': out}
def get_mat2(ts,coors, mode=None,**kwargs): #if mode == 'qp': #cnf = pb.conf # get material coefficients # given values E_f, nu_f, E_m, nu_m = 160.e9, 0.28, 5.e9, 0.45 #nqp = coors.shape[0] #nel = pb.domain.mesh.n_el #nqpe = nqp / nel out = nm.zeros((6, 6), dtype=nm.float64) # set values - matrix D_m = stiffness_from_youngpoisson(3, E_m, nu_m) # set values - fiber D_f = stiffness_from_youngpoisson(3, E_f, nu_f) out[...] = D_m out[0:nqp/2,...] = D_f #out[nqp/2:nqp,...] = D_m return {'D': out}
def get_mat1(ts,coors, mode=None,**kwargs): if mode == 'qp': nqp = coors.shape[0] out = nm.zeros((nqp, 6, 6), dtype=nm.float64) D_m = stiffness_from_youngpoisson(3, E_m, nu_m) D_f = stiffness_from_youngpoisson(3, E_f, nu_f) out[0:nqp, ...] = D_f top = centre[2] - dims[2]/2 bottom = centre[2] + dims[2]/2 thicknes = 0.2*(bottom - top) for i in nm.arange(nqp): if coors[i,2]>thicknes + top and coors[i,2]<bottom-thicknes: out[i,...] = D_m return {'D': out}
def get_D(ts, coors, mode=None, **kwargs): if mode == 'qp': val = stiffness_from_youngpoisson(2, 1, 0.27) #val = stiffness_from_lame(dim=3, # lam=1e1*np.ones(coors.shape[0]), # mu=1e0*np.ones(coors.shape[0])) return {'D': val}
def get_mat1(ts,coors, mode=None,**kwargs): if mode == 'qp': #cnf = pb.conf # get material coefficients # given values #E_f, nu_f, E_m, nu_m = 160.e9, 0.2, 5.e9, 0.4 nqp = coors.shape[0] #nel = pb.domain.mesh.n_el #nqpe = nqp / nel out = nm.zeros((nqp, 6, 6), dtype=nm.float64) D_m = stiffness_from_youngpoisson(3, E_m, nu_m) D_f = stiffness_from_youngpoisson(3, E_f, nu_f) out[0:nqp, ...] = D_f for i in nm.arange(nqp): if coors[i,2]>-0.1 and coors[i,2]<0.1: out[i,...] = D_m return {'D': out}
def get_mat(coors, mode, pb): if mode == 'qp': # get material data if hasattr(pb.conf, 'opt_data'): # from homogenization D = pb.conf.opt_data['D_homog'] else: # given values D = stiffness_from_youngpoisson(3, 150.0e9, 0.3) nqp = coors.shape[0] return {'D': nm.tile(D, (nqp, 1, 1))}
def get_mat(coors, mode, pb): if mode == 'qp': # get material data if hasattr(pb.conf, 'opt_data'): # from homogenization D = pb.conf.opt_data['D_homog'] else: # given values D = stiffness_from_youngpoisson(3, 150.0e9, 0.3) nqp = coors.shape[0] return {'D': nm.tile(D, (nqp, 1, 1))}
def create_elastic_tensor(young, poisson, shear_correction=True): """ Create the elastic tensor with the applied shear correction (the default) for the shell10x element. """ from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson # Static condensation so that \sigma_{33} = 0. mtx = stiffness_from_youngpoisson(3, young, poisson, plane='stress') mtx[2, :3] = mtx[:2, 2] = 0.0 if shear_correction: mtx[4, 4] *= 5.0 / 6.0 mtx[5, 5] *= 5.0 / 6.0 return mtx
def create_elastic_tensor(young, poisson, shear_correction=True): """ Create the elastic tensor with the applied shear correction (the default) for the shell10x element. """ from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson # Static condensation so that \sigma_{33} = 0. mtx = stiffness_from_youngpoisson(3, young, poisson, plane='stress') mtx[2, :3] = mtx[:2, 2] = 0.0 if shear_correction: mtx[4, 4] *= 5.0 / 6.0 mtx[5, 5] *= 5.0 / 6.0 return mtx
data=strain, dofs=None) return out filename_mesh = 'meshes/strut_test.vtk' z_displacement = -0.10 regions = { 'Omega' : 'all', 'Top' : ('vertices in (z > 1.0)', 'facet'), 'Bot' : ('vertices in (z < 0.0)', 'facet'), } materials = { 'solid' : ({'D': stiffness_from_youngpoisson(dim=3, young=1e9, poisson=0.24)},), } fields = { 'displacement': ('real', 'vector', 'Omega', 1), } integrals = { 'i' : 1, } variables = { 'u' : ('unknown field', 'displacement', 0), 'v' : ('test field', 'displacement', 'u'), }
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) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name = 'u') mtx_d = stiffness_from_youngpoisson(dim, 6.80, 0.36) young = 6.8 poisson = 0.36 mu0 = young / (2.0 * (1.0 + poisson)) mu1 = mu0 * 1.00001 lambda0 = young * poisson / ((1.0 + poisson) * (1.0 - 2.0 * poisson)) lambda1 = young * poisson / ((1.0 + poisson) * (1.0 - 2.0 * poisson)) * 1.00001 D0 = numpy.array([[lambda0 + 2 * mu0, lambda0, 0.0], [lambda0, lambda0 + 2 * mu0, 0.0], [0.0, 0.0, mu0]]) D1 = numpy.array([[lambda0 + 2 * mu1, lambda0, 0.0], [lambda0, lambda0 + 2 * mu1, 0.0], [0.0, 0.0, mu1]])
def main(): parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('--version', action='version', version='%(prog)s') parser.add_argument('-d', '--dims', metavar='dims', action='store', dest='dims', default='[1.0, 1.0]', help=helps['dims']) parser.add_argument('-c', '--centre', metavar='centre', action='store', dest='centre', default='[0.0, 0.0]', help=helps['centre']) parser.add_argument('-s', '--shape', metavar='shape', action='store', dest='shape', default='[11, 11]', help=helps['shape']) parser.add_argument('-b', '--bc-kind', metavar='kind', action='store', dest='bc_kind', choices=['free', 'cantilever', 'fixed'], default='free', help=helps['bc_kind']) parser.add_argument('-a', '--axis', metavar='0, ..., dim, or -1', type=int, action='store', dest='axis', default=-1, help=helps['axis']) parser.add_argument('--young', metavar='float', type=float, action='store', dest='young', default=200e+9, help=helps['young']) parser.add_argument('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.3, help=helps['poisson']) parser.add_argument('--density', metavar='float', type=float, action='store', dest='density', default=7800.0, help=helps['density']) parser.add_argument('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_argument('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['n_eigs']) parser.add_argument('-i', '--ignore', metavar='int', type=int, action='store', dest='ignore', default=None, help=helps['ignore']) parser.add_argument('--solver', metavar='solver', action='store', dest='solver', default= \ "eig.scipy,method:'eigh',tol:1e-5,maxiter:1000", help=helps['solver']) parser.add_argument('--show', action="store_true", dest='show', default=False, help=helps['show']) #parser.add_argument('filename', nargs='?', default=None) #read block.mesh #parser.add_argument('filename', nargs='?', default="platehexat200mm.mesh") parser.add_argument('filename', nargs='?', default="block_1m.mesh") options = parser.parse_args() aux = options.solver.split(',') kwargs = {} for option in aux[1:]: key, val = option.split(':') kwargs[key.strip()] = eval(val) eig_conf = Struct(name='evp', kind=aux[0], **kwargs) output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' density:', options.density) output('displacement field approximation order:', options.order) output('requested %d eigenvalues' % options.n_eigs) output('using eigenvalue problem solver:', eig_conf.kind) output.level += 1 for key, val in six.iteritems(kwargs): output('%s: %r' % (key, val)) output.level -= 1 assert_((0.0 < options.poisson < 0.5), "Poisson's ratio must be in ]0, 0.5[!") assert_((0 < options.order), 'displacement approximation order must be at least 1!') filename = options.filename if filename is not None: mesh = Mesh.from_file(filename) dim = mesh.dim dims = nm.diff(mesh.get_bounding_box(), axis=0) else: dims = nm.array(eval(options.dims), dtype=nm.float64) dim = len(dims) centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim] shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim] output('dimensions:', dims) output('centre: ', centre) output('shape: ', shape) mesh = gen_block_mesh(dims, shape, centre, name='mesh') output('axis: ', options.axis) assert_((-dim <= options.axis < dim), 'invalid axis value!') eig_solver = Solver.any_from_conf(eig_conf) # Build the problem definition. domain = FEDomain('domain', mesh) bbox = domain.get_mesh_bounding_box() min_coor, max_coor = bbox[:, options.axis] eps = 1e-8 * (max_coor - min_coor) ax = 'xyz'[:dim][options.axis] omega = domain.create_region('Omega', 'all') """ bottom = domain.create_region('Bottom', 'vertices in (%s < %.10f)' % (ax, min_coor + eps), 'facet') bottom_top = domain.create_region('BottomTop', 'r.Bottom +v vertices in (%s > %.10f)' % (ax, max_coor - eps), 'facet') """ #import pdb; pdb.set_trace() left = domain.create_region('left', 'vertices in (x < -0.49)', 'facet') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=options.order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson) m = Material('m', D=mtx_d, rho=options.density) integral = Integral('i', order=2 * options.order) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u) eq1 = Equation('stiffness', t1) eq2 = Equation('mass', t2) lhs_eqs = Equations([eq1, eq2]) pb = Problem('modal', equations=lhs_eqs) """ if options.bc_kind == 'free': pb.time_update() n_rbm = dim * (dim + 1) // 2 elif options.bc_kind == 'cantilever': fixed = EssentialBC('Fixed', bottom, {'u.all' : 0.0}) pb.time_update(ebcs=Conditions([fixed])) n_rbm = 0 elif options.bc_kind == 'fixed': fixed = EssentialBC('Fixed', bottom_top, {'u.all' : 0.0}) pb.time_update(ebcs=Conditions([fixed])) n_rbm = 0 else: raise ValueError('unsupported BC kind! (%s)' % options.bc_kind) if options.ignore is not None: n_rbm = options.ignore """ fixed = EssentialBC('Fixed', left, {'u.all': 0.0}) pb.time_update(ebcs=Conditions([fixed])) n_rbm = 0 pb.update_materials() # Assemble stiffness and mass matrices. mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a) mtx_m = mtx_k.copy() mtx_m.data[:] = 0.0 mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m) try: eigs, svecs = eig_solver(mtx_k, mtx_m, options.n_eigs + n_rbm, eigenvectors=True) except sla.ArpackNoConvergence as ee: eigs = ee.eigenvalues svecs = ee.eigenvectors output('only %d eigenvalues converged!' % len(eigs)) output('%d eigenvalues converged (%d ignored as rigid body modes)' % (len(eigs), n_rbm)) eigs = eigs[n_rbm:] svecs = svecs[:, n_rbm:] omegas = nm.sqrt(eigs) freqs = omegas / (2 * nm.pi) output('number | eigenvalue | angular frequency ' '| frequency') for ii, eig in enumerate(eigs): output('%6d | %17.12e | %17.12e | %17.12e' % (ii + 1, eig, omegas[ii], freqs[ii])) # Make full eigenvectors (add DOFs fixed by boundary conditions). variables = pb.get_variables() vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]), dtype=nm.float64) for ii in range(svecs.shape[1]): vecs[:, ii] = variables.make_full_vec(svecs[:, ii]) # Save the eigenvectors. out = {} state = pb.create_state() for ii in range(eigs.shape[0]): state.set_full(vecs[:, ii]) aux = state.create_output_dict() strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)', integrals=Integrals([integral]), mode='el_avg', verbose=False) out['u%03d' % ii] = aux.popitem()[1] out['strain%03d' % ii] = Struct(mode='cell', data=strain) pb.save_state('eigenshapes.vtk', out=out) pb.save_regions_as_groups('regions') if len(eigs) and options.show: # Show the solution. If the approximation order is greater than 1, the # extra DOFs are simply thrown away. from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.domain_specific import DomainSpecificPlot scaling = 0.05 * dims.max() / nm.abs(vecs).max() ds = {} for ii in range(eigs.shape[0]): pd = DomainSpecificPlot('plot_displacements', [ 'rel_scaling=%s' % scaling, 'color_kind="tensors"', 'color_name="strain%03d"' % ii ]) ds['u%03d' % ii] = pd view = Viewer('eigenshapes.vtk') view(domain_specific=ds, only_names=sorted(ds.keys()), is_scalar_bar=False, is_wireframe=True)
def main(): parser = OptionParser(usage=usage, version='%prog') parser.add_option('-d', '--dims', metavar='dims', action='store', dest='dims', default='[1.0, 1.0]', help=helps['dims']) parser.add_option('-c', '--centre', metavar='centre', action='store', dest='centre', default='[0.0, 0.0]', help=helps['centre']) parser.add_option('-s', '--shape', metavar='shape', action='store', dest='shape', default='[11, 11]', help=helps['shape']) parser.add_option('-b', '--bc-kind', metavar='kind', action='store', dest='bc_kind', choices=['free', 'clamped'], default='free', help=helps['bc_kind']) parser.add_option('--young', metavar='float', type=float, action='store', dest='young', default=6.80e+10, help=helps['young']) parser.add_option('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.36, help=helps['poisson']) parser.add_option('--density', metavar='float', type=float, action='store', dest='density', default=2700.0, help=helps['density']) parser.add_option('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_option('-n', '--n-eigs', metavar='int', type=int, action='store', dest='n_eigs', default=6, help=helps['order']) parser.add_option('', '--show', action="store_true", dest='show', default=False, help=helps['show']) options, args = parser.parse_args() assert_((0.0 < options.poisson < 0.5), "Poisson's ratio must be in ]0, 0.5[!") assert_((0 < options.order), 'displacement approximation order must be at least 1!') dims = nm.array(eval(options.dims), dtype=nm.float64) dim = len(dims) centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim] shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim] output('dimensions:', dims) output('centre: ', centre) output('shape: ', shape) output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' density:', options.density) # Build the problem definition. mesh = gen_block_mesh(dims, shape, centre, name='mesh') domain = FEDomain('domain', mesh) bbox = domain.get_mesh_bounding_box() min_y, max_y = bbox[:, 1] eps = 1e-8 * (max_y - min_y) omega = domain.create_region('Omega', 'all') bottom = domain.create_region('Bottom', 'vertices in (y < %.10f)' % (min_y + eps), 'facet') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=options.order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson) m = Material('m', D=mtx_d, rho=options.density) integral = Integral('i', order=2 * options.order) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u) eq1 = Equation('stiffness', t1) eq2 = Equation('mass', t2) lhs_eqs = Equations([eq1, eq2]) pb = Problem('modal', equations=lhs_eqs) if options.bc_kind == 'free': pb.time_update() n_rbm = dim * (dim + 1) / 2 else: fixed_b = EssentialBC('FixedB', bottom, {'u.all': 0.0}) pb.time_update(ebcs=Conditions([fixed_b])) n_rbm = 0 pb.update_materials() # Assemble stiffness and mass matrices. mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a) mtx_m = mtx_k.copy() mtx_m.data[:] = 0.0 mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m) try: eigs, svecs = sla.eigsh(mtx_k, k=options.n_eigs + n_rbm, M=mtx_m, which='SM', tol=1e-5, maxiter=10000) except sla.ArpackNoConvergence as ee: eigs = ee.eigenvalues svecs = ee.eigenvectors output('only %d eigenvalues converged!' % len(eigs)) eigs = eigs[n_rbm:] svecs = svecs[:, n_rbm:] output('eigenvalues:', eigs) output('eigen-frequencies:', nm.sqrt(eigs)) # Make full eigenvectors (add DOFs fixed by boundary conditions). variables = pb.get_variables() vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]), dtype=nm.float64) for ii in xrange(svecs.shape[1]): vecs[:, ii] = variables.make_full_vec(svecs[:, ii]) # Save the eigenvectors. out = {} state = pb.create_state() for ii in xrange(eigs.shape[0]): state.set_full(vecs[:, ii]) aux = state.create_output_dict() strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)', integrals=Integrals([integral]), mode='el_avg', verbose=False) out['u%03d' % ii] = aux.popitem()[1] out['strain%03d' % ii] = Struct(mode='cell', data=strain) pb.save_state('eigenshapes.vtk', out=out) pb.save_regions_as_groups('regions') if options.show: # Show the solution. If the approximation order is greater than 1, the # extra DOFs are simply thrown away. from sfepy.postprocess.viewer import Viewer from sfepy.postprocess.domain_specific import DomainSpecificPlot scaling = 0.05 * dims.max() / nm.abs(vecs).max() ds = {} for ii in xrange(eigs.shape[0]): pd = DomainSpecificPlot('plot_displacements', [ 'rel_scaling=%s' % scaling, 'color_kind="tensors"', 'color_name="strain%03d"' % ii ]) ds['u%03d' % ii] = pd view = Viewer('eigenshapes.vtk') view(domain_specific=ds, only_names=sorted(ds.keys()), is_scalar_bar=False, is_wireframe=True)
return out filename_mesh = UserMeshIO(mesh_hook) options = { 'nls' : 'newton', 'ls' : 'ls', 'post_process_hook' : 'post_process', } fields = { 'displacement': ('real', dim, 'Omega', 1), } materials = { 'solid' : ({'D': stiffness_from_youngpoisson(dim, young=1.0, poisson=0.3)},), 'contact' : ({'.epss' : 1e1},), } variables = { 'u' : ('unknown field', 'displacement', 0), 'v' : ('test field', 'displacement', 'u'), } bbox0 = get_bbox(dims0, centre0, eps=1e-5) bbox1 = get_bbox(dims1, nm.asarray(centre1) + nm.asarray(shift1), eps=1e-5) if dim == 2: regions = { 'Omega' : 'all', 'Omega0' : 'cells of group 0',
def define(grid0=100, filename_mesh=None): eps0 = 0.01 / grid0 if filename_mesh is None: filename_mesh = osp.join(data_dir, 'piezo_mesh_micro_dfc.vtk') mesh = Mesh.from_file(filename_mesh) n_conduct = len(nm.unique(mesh.cmesh.cell_groups)) - 2 sym_eye = 'nm.array([1,1,0])' if mesh.dim == 2 else\ 'nm.array([1,1,1,0,0,0])' bbox = mesh.get_bounding_box() regions = define_box_regions(mesh.dim, bbox[0], bbox[1], eps=1e-3) regions.update({ 'Y': 'all', # matrix 'Ym': 'cells of group 1', 'Ym_left': ('r.Ym *v r.Left', 'vertex'), 'Ym_right': ('r.Ym *v r.Right', 'vertex'), 'Ym_bottom': ('r.Ym *v r.Bottom', 'vertex'), 'Ym_top': ('r.Ym *v r.Top', 'vertex'), 'Ym_far': ('r.Ym *v r.Far', 'vertex'), 'Ym_near': ('r.Ym *v r.Near', 'vertex'), 'Gamma_mc': ('r.Ym *v r.Yc', 'facet', 'Ym'), # channel / inclusion 'Yc': 'cells of group 2', 'Yc0': ('r.Yc -v r.Gamma_cm', 'vertex'), 'Gamma_cm': ('r.Ym *v r.Yc', 'facet', 'Yc'), }) print('number of cnonductors: %d' % n_conduct) regions.update({ 'Yms': ('r.Ym +v r.Ys', 'cell'), 'Yms_left': ('r.Yms *v r.Left', 'vertex'), 'Yms_right': ('r.Yms *v r.Right', 'vertex'), 'Yms_bottom': ('r.Yms *v r.Bottom', 'vertex'), 'Yms_top': ('r.Yms *v r.Top', 'vertex'), 'Yms_far': ('r.Yms *v r.Far', 'vertex'), 'Yms_near': ('r.Yms *v r.Near', 'vertex'), 'Gamma_ms': ('r.Ym *v r.Ys', 'facet', 'Ym'), 'Gamma_msc': ('r.Yms *v r.Yc', 'facet', 'Yms'), 'Ys': (' +v '.join(['r.Ys%d' % k for k in range(n_conduct)]), 'cell'), }) options = { 'coefs_filename': 'coefs_poropiezo_%d' % (grid0), 'volume': { 'variables': ['svar'], 'expression': 'd_volume.i2.Y(svar)', }, 'coefs': 'coefs', 'requirements': 'requirements', 'output_dir': osp.join(data_dir, 'results'), 'ls': 'ls', 'file_per_var': True, 'absolute_mesh_path': True, 'multiprocessing': False, 'recovery_hook': recovery_micro_dfc, } fields = { 'displacement': ('real', 'vector', 'Yms', 1), 'potential': ('real', 'scalar', 'Ym', 1), 'sfield': ('real', 'scalar', 'Y', 1), } variables = { # displacement 'u': ('unknown field', 'displacement'), 'v': ('test field', 'displacement', 'u'), 'Pi_u': ('parameter field', 'displacement', 'u'), 'U1': ('parameter field', 'displacement', '(set-to-None)'), 'U2': ('parameter field', 'displacement', '(set-to-None)'), # potential 'r': ('unknown field', 'potential'), 's': ('test field', 'potential', 'r'), 'Pi_r': ('parameter field', 'potential', 'r'), 'R1': ('parameter field', 'potential', '(set-to-None)'), 'R2': ('parameter field', 'potential', '(set-to-None)'), # aux variable 'svar': ('parameter field', 'sfield', '(set-to-None)'), } epbcs, periodic = get_periodic_bc([('u', 'Yms'), ('r', 'Ym')]) mat_g_sc, mat_d_sc = eps0, eps0**2 # BaTiO3 - Miara, Rohan, ... doi: 10.1016/j.jmps.2005.05.006 materials = { 'matrix': ({ 'D': { 'Ym': nm.array([[1.504, 0.656, 0.659, 0, 0, 0], [0.656, 1.504, 0.659, 0, 0, 0], [0.659, 0.659, 1.455, 0, 0, 0], [0, 0, 0, 0.424, 0, 0], [0, 0, 0, 0, 0.439, 0], [0, 0, 0, 0, 0, 0.439]]) * 1e11, } }, ), 'piezo': ({ 'g': nm.array([[0, 0, 0, 0, 11.404, 0], [0, 0, 0, 0, 0, 11.404], [-4.322, -4.322, 17.360, 0, 0, 0]]) / mat_g_sc, 'd': nm.array([[1.284, 0, 0], [0, 1.284, 0], [0, 0, 1.505]]) * 1e-8 / mat_d_sc, }, ), 'fluid': ({ 'gamma': 1.0 / 2.15e9 }, ), } functions = { 'match_x_plane': (per.match_x_plane, ), 'match_y_plane': (per.match_y_plane, ), 'match_z_plane': (per.match_z_plane, ), } ebcs = { 'fixed_u': ('Corners', { 'u.all': 0.0 }), 'fixed_r': ('Gamma_ms', { 'r.all': 0.0 }), } integrals = { 'i2': 2, 'i5': 5, } solvers = { 'ls': ('ls.scipy_direct', {}), 'ns_em6': ('nls.newton', { 'i_max': 1, 'eps_a': 1e-6, 'eps_r': 1e-6, 'problem': 'nonlinear' }), 'ns_em3': ('nls.newton', { 'i_max': 1, 'eps_a': 1e-3, 'eps_r': 1e-6, 'problem': 'nonlinear' }), } coefs = { # homogenized elasticity, see eq. (46)_1 'A': { 'requires': ['c.A1', 'c.A2'], 'expression': 'c.A1 + c.A2', 'class': cb.CoefEval, }, 'A1': { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_rs'], 'expression': 'dw_lin_elastic.i2.Yms(matrix.D, U1, U2)', 'set_variables': [('U1', ('corrs_rs', 'pis_u'), 'u'), ('U2', ('corrs_rs', 'pis_u'), 'u')], 'class': cb.CoefSymSym, }, 'A2': { 'status': 'auxiliary', 'requires': ['corrs_rs'], 'expression': 'dw_diffusion.i2.Ym(piezo.d, R1, R2)', 'set_variables': [('R1', 'corrs_rs', 'r'), ('R2', 'corrs_rs', 'r')], 'class': cb.CoefSymSym, }, # homogenized Biot coefficient, see eq. (46)_2 'B': { 'requires': ['c.Phi', 'c.B1', 'c.B2'], 'expression': 'c.B1 - c.B2 + c.Phi * %s' % sym_eye, 'class': cb.CoefEval, }, 'B1': { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_p'], 'expression': 'dw_lin_elastic.i2.Yms(matrix.D, U1, U2)', 'set_variables': [('U1', 'corrs_p', 'u'), ('U2', 'pis_u', 'u')], 'class': cb.CoefSym, }, 'B2': { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_p'], 'expression': 'dw_piezo_coupling.i2.Ym(piezo.g, U1, R1)', 'set_variables': [('R1', 'corrs_p', 'r'), ('U1', 'pis_u', 'u')], 'class': cb.CoefSym, }, # homogenized compressibility coefficient, see eq. (46)_6 'M': { 'requires': ['c.Phi', 'c.N'], 'expression': 'c.N + c.Phi * %e' % materials['fluid'][0]['gamma'], 'class': cb.CoefEval, }, 'N': { 'status': 'auxiliary', 'requires': ['corrs_p'], 'expression': 'dw_surface_ltr.i2.Gamma_msc(U1)', 'set_variables': [('U1', 'corrs_p', 'u')], 'class': cb.CoefOne, }, 'Phi': { 'requires': ['c.vol'], 'expression': 'c.vol["fraction_Yc"]', 'class': cb.CoefEval, }, # volume fractions of Ym, Yc, Ys1, Ys2, ... 'vol': { 'regions': ['Ym', 'Yc'] + ['Ys%d' % k for k in range(n_conduct)], 'expression': 'd_volume.i2.%s(svar)', 'class': cb.VolumeFractions, }, 'eps0': { 'requires': [], 'expression': '%e' % eps0, 'class': cb.CoefEval, }, 'filenames': {}, } requirements = { 'pis_u': { 'variables': ['u'], 'class': cb.ShapeDimDim, }, 'pis_r': { 'variables': ['r'], 'class': cb.ShapeDim, }, # local subproblem defined by eq. (41) 'corrs_rs': { 'requires': ['pis_u'], 'ebcs': ['fixed_u', 'fixed_r'], 'epbcs': periodic['per_u'] + periodic['per_r'], 'is_linear': True, 'equations': { 'eq1': """dw_lin_elastic.i2.Yms(matrix.D, v, u) - dw_piezo_coupling.i2.Ym(piezo.g, v, r) = - dw_lin_elastic.i2.Yms(matrix.D, v, Pi_u)""", 'eq2': """ - dw_piezo_coupling.i2.Ym(piezo.g, u, s) - dw_diffusion.i2.Ym(piezo.d, s, r) = dw_piezo_coupling.i2.Ym(piezo.g, Pi_u, s)""", }, 'set_variables': [('Pi_u', 'pis_u', 'u')], 'class': cb.CorrDimDim, 'save_name': 'corrs_rs_%d' % grid0, 'dump_variables': ['u', 'r'], 'solvers': { 'ls': 'ls', 'nls': 'ns_em3' }, }, # local subproblem defined by eq. (42) 'corrs_p': { 'requires': [], 'ebcs': ['fixed_u', 'fixed_r'], 'epbcs': periodic['per_u'] + periodic['per_r'], 'is_linear': True, 'equations': { 'eq1': """dw_lin_elastic.i2.Yms(matrix.D, v, u) - dw_piezo_coupling.i2.Ym(piezo.g, v, r) = dw_surface_ltr.i2.Gamma_msc(v)""", 'eq2': """ - dw_piezo_coupling.i2.Ym(piezo.g, u, s) - dw_diffusion.i2.Ym(piezo.d, s, r) = 0""" }, 'class': cb.CorrOne, 'save_name': 'corrs_p_%d' % grid0, 'dump_variables': ['u', 'r'], 'solvers': { 'ls': 'ls', 'nls': 'ns_em6' }, }, # local subproblem defined by eq. (43) 'corrs_rho': { 'requires': [], 'ebcs': ['fixed_u', 'fixed_r'], 'epbcs': periodic['per_u'] + periodic['per_r'], 'is_linear': True, 'equations': { 'eq1': """dw_lin_elastic.i2.Yms(matrix.D, v, u) - dw_piezo_coupling.i2.Ym(piezo.g, v, r) = 0""", 'eq2': """ - dw_piezo_coupling.i2.Ym(piezo.g, u, s) - dw_diffusion.i2.Ym(piezo.d, s, r) = - dw_surface_integrate.i2.Gamma_mc(s)""" }, 'class': cb.CorrOne, 'save_name': 'corrs_p_%d' % grid0, 'dump_variables': ['u', 'r'], 'solvers': { 'ls': 'ls', 'nls': 'ns_em6' }, }, } for k in range(n_conduct): sk = '%d' % k regions.update({ 'Ys' + sk: 'cells of group %d' % (3 + k), 'Gamma_s' + sk: ('r.Ym *v r.Ys' + sk, 'facet', 'Ym'), }) materials['matrix'][0]['D'].update({ 'Ys' + sk: stiffness_from_youngpoisson(3, 200e9, 0.25), }) ebcs.update({ 'fixed_r1_k_' + sk: ('Gamma_s' + sk, { 'r.0': 1.0 }), 'fixed_r0_k_' + sk: ('Gamma_s' + sk, { 'r.0': 0.0 }), }) fixed_r0_k = [ 'fixed_r0_k_%d' % ii for ii in range(n_conduct) if not ii == k ] # local subproblems defined for conductors, see eq. (44) requirements.update({ 'corrs_k' + sk: { 'requires': ['pis_r'], 'ebcs': ['fixed_u', 'fixed_r1_k_' + sk] + fixed_r0_k, 'epbcs': periodic['per_u'] + periodic['per_r'], 'is_linear': True, 'equations': { 'eq1': """dw_lin_elastic.i2.Yms(matrix.D, v, u) - dw_piezo_coupling.i2.Ym(piezo.g, v, r) = 0""", 'eq2': """ - dw_piezo_coupling.i2.Ym(piezo.g, u, s) - dw_diffusion.i2.Ym(piezo.d, s, r) = 0""" }, 'class': cb.CorrOne, 'save_name': 'corrs_k' + sk + '_%d' % grid0, 'dump_variables': ['u', 'r'], 'solvers': { 'ls': 'ls', 'nls': 'ns_em6' }, }, }) coefs.update({ # homogenized coefficient (46)_3 'H' + sk: { 'requires': ['c.H1_' + sk, 'c.H2_' + sk], 'expression': 'c.H1_%s - c.H2_%s' % (sk, sk), 'class': cb.CoefEval, }, 'H1_' + sk: { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_k' + sk], 'expression': 'dw_lin_elastic.i2.Yms(matrix.D, U1, U2)', 'set_variables': [('U1', 'corrs_k' + sk, 'u'), ('U2', 'pis_u', 'u')], 'class': cb.CoefSym, }, 'H2_' + sk: { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_k' + sk], 'expression': 'dw_piezo_coupling.i2.Ym(piezo.g, U1, R1)', 'set_variables': [('R1', 'corrs_k' + sk, 'r'), ('U1', 'pis_u', 'u')], 'class': cb.CoefSym, }, # homogenized coefficient (46)_7 'Z' + sk: { 'requires': ['corrs_k' + sk], 'expression': 'dw_surface_ltr.i2.Gamma_msc(U1)', 'set_variables': [('U1', 'corrs_k' + sk, 'u')], 'class': cb.CoefOne, }, }) return locals()
filename_mesh = data_dir + "/meshes/3d/matrix_fiber.mesh" dim = 3 region_lbn = (0, 0, 0) region_rtf = (1, 1, 1) #! Regions #! ------- #! Regions, edges, ... regions = {"Y": "all", "Ym": "cells of group 1", "Yc": "cells of group 2"} regions.update(define_box_regions(dim, region_lbn, region_rtf)) #! Materials #! --------- materials = { "mat": ( { "D": { "Ym": stiffness_from_youngpoisson(dim, 7.0e9, 0.4), "Yc": stiffness_from_youngpoisson(dim, 70.0e9, 0.2), } }, ) } #! Fields #! ------ #! Scalar field for corrector basis functions. fields = {"corrector": ("real", dim, "Y", 1)} #! Variables #! --------- #! Unknown and corresponding test variables. Parameter fields #! used for evaluation of homogenized coefficients. variables = { "u": ("unknown field", "corrector", 0),
dim = 3 region_lbn = (0, 0, 0) region_rtf = (1, 1, 1) #! Regions #! ------- #! Regions, edges, ... regions = { 'Y' : 'all', 'Ym' : 'cells of group 1', 'Yc' : 'cells of group 2', } regions.update( define_box_regions( dim, region_lbn, region_rtf ) ) #! Materials #! --------- materials = { 'mat' : ({'D' : {'Ym': stiffness_from_youngpoisson(dim, 7.0e9, 0.4), 'Yc': stiffness_from_youngpoisson(dim, 70.0e9, 0.2)}},), } #! Fields #! ------ #! Scalar field for corrector basis functions. fields = { 'corrector' : ('real', dim, 'Y', 1), } #! Variables #! --------- #! Unknown and corresponding test variables. Parameter fields #! used for evaluation of homogenized coefficients. variables = { 'u' : ('unknown field', 'corrector', 0), 'v' : ('test field', 'corrector', 'u'),
'Omega2': 'cells of group 2', 'Interface': ('r.Omega1 *v r.Omega2', 'facet', 'Omega1'), } integrals = { 'i': 2, } piezo_g = nm.array([[0, 0, 0, 0, 10, 0], [0, 0, 0, 0, 0, 10], [-5, -5, 15, 0, 0, 0]]) materials = { 'mat': ({ 'D': { 'Omega1': stiffness_from_youngpoisson(3, 100, 0.3), 'Omega2': stiffness_from_youngpoisson(3, 1, 0.49), }, 'K': {'Omega1': nm.eye(3), 'Omega2': nm.eye(3) * 1e-3}, 'c': {'Omega1': 1, 'Omega2': 1000}, 'g': {'Omega1': piezo_g * 1e2, 'Omega2': piezo_g}, 's': { 'Omega1': nm.array([[1, 2, 3, 0, 0, 0]]).T, 'Omega2': nm.array([[8, 4, 2, 0, 0, 0]]).T, } },), } equations = {} test_terms = [
def define(eps0=1e-3, filename_mesh='meshes/3d/piezo_mesh_micro.vtk'): mesh = Mesh.from_file(filename_mesh) bbox = mesh.get_bounding_box() regions = define_box_regions(mesh.dim, bbox[0], bbox[1], eps=1e-3) regions.update({ 'Ymc': 'all', # matrix 'Ym': 'cells of group 1', 'Ym_left': ('r.Ym *v r.Left', 'vertex'), 'Ym_right': ('r.Ym *v r.Right', 'vertex'), 'Ym_bottom': ('r.Ym *v r.Bottom', 'vertex'), 'Ym_top': ('r.Ym *v r.Top', 'vertex'), 'Ym_far': ('r.Ym *v r.Far', 'vertex'), 'Ym_near': ('r.Ym *v r.Near', 'vertex'), 'Gamma_ms': ('r.Ym *v r.Yc', 'facet', 'Ym'), # conductors 'Yc': ('r.Yc1 +c r.Yc2', 'cell'), 'Yc1': 'cells of group 2', 'Yc2': 'cells of group 3', 'Gamma_s1': ('r.Ym *v r.Yc1', 'facet', 'Ym'), 'Gamma_s2': ('r.Ym *v r.Yc2', 'facet', 'Ym'), }) options = { 'coefs_filename': 'coefs_piezo', 'volume': {'value': nm.prod(bbox[1] - bbox[0])}, 'coefs': 'coefs', 'requirements': 'requirements', 'output_dir': 'output', 'file_per_var': True, 'absolute_mesh_path': True, 'multiprocessing': False, 'recovery_hook': recovery_micro, } fields = { 'displacement': ('real', 'vector', 'Ymc', 1), 'potential': ('real', 'scalar', 'Ym', 1), 'sfield': ('real', 'scalar', 'Ymc', 1), } variables = { # displacement 'u': ('unknown field', 'displacement'), 'v': ('test field', 'displacement', 'u'), 'Pi_u': ('parameter field', 'displacement', 'u'), 'U1': ('parameter field', 'displacement', '(set-to-None)'), 'U2': ('parameter field', 'displacement', '(set-to-None)'), # potential 'r': ('unknown field', 'potential'), 's': ('test field', 'potential', 'r'), 'Pi_r': ('parameter field', 'potential', 'r'), 'R1': ('parameter field', 'potential', '(set-to-None)'), 'R2': ('parameter field', 'potential', '(set-to-None)'), # auxiliary 'svar': ('parameter field', 'sfield', '(set-to-None)'), } epbcs = { 'p_ux': (['Left', 'Right'], {'u.all': 'u.all'}, 'match_x_plane'), 'p_uy': (['Near', 'Far'], {'u.all': 'u.all'}, 'match_y_plane'), 'p_uz': (['Bottom', 'Top'], {'u.all': 'u.all'}, 'match_z_plane'), 'p_rx': (['Ym_left', 'Ym_right'], {'r.0': 'r.0'}, 'match_x_plane'), 'p_ry': (['Ym_near', 'Ym_far'], {'r.0': 'r.0'}, 'match_y_plane'), 'p_rz': (['Ym_bottom', 'Ym_top'], {'r.0': 'r.0'}, 'match_z_plane'), } periodic = { 'per_u': ['per_u_x', 'per_u_y', 'per_u_z'], 'per_r': ['per_r_x', 'per_r_y', 'per_r_z'], } # rescale piezoelectric material parameters mat_g_sc, mat_d_sc = (eps0, eps0**2) materials = { 'elastic': ({ 'D': { 'Ym': nm.array([[1.504, 0.656, 0.659, 0, 0, 0], [0.656, 1.504, 0.659, 0, 0, 0], [0.659, 0.659, 1.455, 0, 0, 0], [0, 0, 0, 0.424, 0, 0], [0, 0, 0, 0, 0.439, 0], [0, 0, 0, 0, 0, 0.439]]) * 1e11, 'Yc': stiffness_from_youngpoisson(3, 200e9, 0.25)}},), 'piezo': ({ 'g': nm.array([[0, 0, 0, 0, 11.404, 0], [0, 0, 0, 0, 0, 11.404], [-4.322, -4.322, 17.360, 0, 0, 0]]) / mat_g_sc, 'd': nm.array([[1.284, 0, 0], [0, 1.284, 0], [0, 0, 1.505]]) * 1e-8 / mat_d_sc},), } functions = { 'match_x_plane': (per.match_x_plane,), 'match_y_plane': (per.match_y_plane,), 'match_z_plane': (per.match_z_plane,), } ebcs = { 'fixed_u': ('Corners', {'u.all': 0.0}), 'fixed_r': ('Gamma_ms', {'r.all': 0.0}), 'fixed_r1_s1': ('Gamma_s1', {'r.0': 1.0}), 'fixed_r0_s1': ('Gamma_s1', {'r.0': 0.0}), 'fixed_r1_s2': ('Gamma_s2', {'r.0': 1.0}), 'fixed_r0_s2': ('Gamma_s2', {'r.0': 0.0}), } integrals = { 'i2': 2, } solvers = { 'ls_d': ('ls.scipy_direct', {}), 'ls_i': ('ls.scipy_iterative', {}), 'ns_ea6': ('nls.newton', {'eps_a': 1e6, 'eps_r': 1e-3,}), 'ns_ea0': ('nls.newton', {'eps_a': 1e0, 'eps_r': 1e-3,}), } coefs = { 'A1': { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_rs'], 'expression': 'dw_lin_elastic.i2.Ymc(elastic.D, U1, U2)', 'set_variables': [('U1', ('corrs_rs', 'pis_u'), 'u'), ('U2', ('corrs_rs', 'pis_u'), 'u')], 'class': cb.CoefSymSym, }, 'A2': { 'status': 'auxiliary', 'requires': ['corrs_rs'], 'expression': 'dw_diffusion.i2.Ym(piezo.d, R1, R2)', 'set_variables': [('R1', 'corrs_rs', 'r'), ('R2', 'corrs_rs', 'r')], 'class': cb.CoefSymSym, }, 'A': { 'requires': ['c.A1', 'c.A2'], 'expression': 'c.A1 + c.A2', 'class': cb.CoefEval, }, 'vol': { 'regions': ['Ym', 'Yc1', 'Yc2'], 'expression': 'd_volume.i2.%s(svar)', 'class': cb.VolumeFractions, }, 'eps0': { 'requires': [], 'expression': '%e' % eps0, 'class': cb.CoefEval, }, 'filenames': {}, } requirements = { 'pis_u': { 'variables': ['u'], 'class': cb.ShapeDimDim, }, 'pis_r': { 'variables': ['r'], 'class': cb.ShapeDim, }, 'corrs_rs': { 'requires': ['pis_u'], 'ebcs': ['fixed_u', 'fixed_r'], 'epbcs': ['p_ux', 'p_uy', 'p_uz', 'p_rx', 'p_ry', 'p_rz'], 'equations': { 'eq1': """dw_lin_elastic.i2.Ymc(elastic.D, v, u) - dw_piezo_coupling.i2.Ym(piezo.g, v, r) = - dw_lin_elastic.i2.Ymc(elastic.D, v, Pi_u)""", 'eq2': """ - dw_piezo_coupling.i2.Ym(piezo.g, u, s) - dw_diffusion.i2.Ym(piezo.d, s, r) = dw_piezo_coupling.i2.Ym(piezo.g, Pi_u, s)""", }, 'set_variables': [('Pi_u', 'pis_u', 'u')], 'class': cb.CorrDimDim, 'save_name': 'corrs_rs', 'solvers': {'ls': 'ls_i', 'nls': 'ns_ea6'}, }, } # define requirements and coefficients related to conductors bc_conductors = [ ['fixed_r1_s1', 'fixed_r0_s2'], # phi = 1 on S1, phi = 0 on S2 ['fixed_r1_s2', 'fixed_r0_s1'], # phi = 0 on S1, phi = 1 on S2 ] for k in range(2): sk = '%d' % k requirements.update({ 'corrs_k' + sk: { 'requires': ['pis_r'], 'ebcs': ['fixed_u'] + bc_conductors[k], 'epbcs': ['p_ux', 'p_uy', 'p_uz', 'p_rx', 'p_ry', 'p_rz'], 'equations': { 'eq1': """dw_lin_elastic.i2.Ymc(elastic.D, v, u) - dw_piezo_coupling.i2.Ym(piezo.g, v, r) = 0""", 'eq2': """ - dw_piezo_coupling.i2.Ym(piezo.g, u, s) - dw_diffusion.i2.Ym(piezo.d, s, r) = 0""" }, 'class': cb.CorrOne, 'save_name': 'corrs_k' + sk, 'solvers': {'ls': 'ls_d', 'nls': 'ns_ea0'}, }, }) coefs.update({ 'V1_' + sk: { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_k' + sk], 'expression': 'dw_lin_elastic.i2.Ymc(elastic.D, U1, U2)', 'set_variables': [('U1', 'corrs_k' + sk, 'u'), ('U2', 'pis_u', 'u')], 'class': cb.CoefSym, }, 'V2_' + sk: { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_k' + sk], 'expression': 'dw_piezo_coupling.i2.Ym(piezo.g, U1, R1)', 'set_variables': [('R1', 'corrs_k' + sk, 'r'), ('U1', 'pis_u', 'u')], 'class': cb.CoefSym, }, 'V' + sk: { 'requires': ['c.V1_' + sk, 'c.V2_' + sk], 'expression': 'c.V1_%s - c.V2_%s' % (sk, sk), 'class': cb.CoefEval, }, }) return locals()
min_z, max_z = domain.get_mesh_bounding_box()[:, 2] eps = 5 omega = domain.create_region('Omega', 'all') bot = domain.create_region('Bot', 'vertices in z < %.10f' % (min_z + eps), 'vertex') top = domain.create_region('Top', 'vertices in z > %.10f' % (max_z - eps), 'vertex') field = Field.from_args('fu', np.float64, 'vector', omega, approx_order=1) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') # these are for stainless steel 316L m = Material('m', D=stiffness_from_youngpoisson(dim=3, young=1.93e9, poisson=0.275), rho=8000.0) integral = Integral('i', order=1) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) eq1 = Equation('balance_of_forces', t1) eqs = Equations([eq1]) # materials = { # 'solid': ({'K': 1e3, # bulk modulus # 'mu': 20e0, # shear modulus of neoHookean term # 'kappa': 10e0, # shear modulus of Mooney-Rivlin term # },), # } # equations = {
plt.ylabel("Cauchy strain") plt.xlabel("probe %s" % label, fontsize=8) plt.legend(loc="best", prop=fm.FontProperties(size=8)) plt.subplot(313) pars, vals = results["cauchy_stress"] for ic in range(vals.shape[1]): plt.plot(pars, vals[:, ic], label=r"$\sigma_{%s}$" % sym_indices[ic], lw=1, ls="-", marker="+", ms=3) plt.ylabel("Cauchy stress") plt.xlabel("probe %s" % label, fontsize=8) plt.legend(loc="best", prop=fm.FontProperties(size=8)) return plt.gcf(), results materials["Asphalt"][0].update({"D": stiffness_from_youngpoisson(2, young, poisson)}) # Update fields and variables to be able to use probes for tensors. fields.update({"sym_tensor": ("real", 3, "Omega", 0)}) variables.update({"s": ("parameter field", "sym_tensor", None)}) options.update( { "output_format": "h5", # VTK reader cannot read cell data yet for probing "post_process_hook": "stress_strain", "gen_probes": "gen_lines", "probe_hook": "probe_hook", } )
def define(eps0=1e-3, filename_mesh='meshes/3d/piezo_mesh_micro.vtk'): mesh = Mesh.from_file(filename_mesh) bbox = mesh.get_bounding_box() regions = define_box_regions(mesh.dim, bbox[0], bbox[1], eps=1e-3) regions.update({ 'Ymc': 'all', # matrix 'Ym': 'cells of group 1', 'Ym_left': ('r.Ym *v r.Left', 'vertex'), 'Ym_right': ('r.Ym *v r.Right', 'vertex'), 'Ym_bottom': ('r.Ym *v r.Bottom', 'vertex'), 'Ym_top': ('r.Ym *v r.Top', 'vertex'), 'Ym_far': ('r.Ym *v r.Far', 'vertex'), 'Ym_near': ('r.Ym *v r.Near', 'vertex'), 'Gamma_ms': ('r.Ym *v r.Yc', 'facet', 'Ym'), # conductors 'Yc': ('r.Yc1 +c r.Yc2', 'cell'), 'Yc1': 'cells of group 2', 'Yc2': 'cells of group 3', 'Gamma_s1': ('r.Ym *v r.Yc1', 'facet', 'Ym'), 'Gamma_s2': ('r.Ym *v r.Yc2', 'facet', 'Ym'), }) options = { 'coefs_filename': 'coefs_piezo', 'volume': { 'value': nm.prod(bbox[1] - bbox[0]) }, 'coefs': 'coefs', 'requirements': 'requirements', 'output_dir': 'output', 'file_per_var': True, 'absolute_mesh_path': True, 'multiprocessing': False, 'recovery_hook': recovery_micro, } fields = { 'displacement': ('real', 'vector', 'Ymc', 1), 'potential': ('real', 'scalar', 'Ym', 1), 'sfield': ('real', 'scalar', 'Ymc', 1), } variables = { # displacement 'u': ('unknown field', 'displacement'), 'v': ('test field', 'displacement', 'u'), 'Pi_u': ('parameter field', 'displacement', 'u'), 'U1': ('parameter field', 'displacement', '(set-to-None)'), 'U2': ('parameter field', 'displacement', '(set-to-None)'), # potential 'r': ('unknown field', 'potential'), 's': ('test field', 'potential', 'r'), 'Pi_r': ('parameter field', 'potential', 'r'), 'R1': ('parameter field', 'potential', '(set-to-None)'), 'R2': ('parameter field', 'potential', '(set-to-None)'), # auxiliary 'svar': ('parameter field', 'sfield', '(set-to-None)'), } epbcs = { 'p_ux': (['Left', 'Right'], { 'u.all': 'u.all' }, 'match_x_plane'), 'p_uy': (['Near', 'Far'], { 'u.all': 'u.all' }, 'match_y_plane'), 'p_uz': (['Bottom', 'Top'], { 'u.all': 'u.all' }, 'match_z_plane'), 'p_rx': (['Ym_left', 'Ym_right'], { 'r.0': 'r.0' }, 'match_x_plane'), 'p_ry': (['Ym_near', 'Ym_far'], { 'r.0': 'r.0' }, 'match_y_plane'), 'p_rz': (['Ym_bottom', 'Ym_top'], { 'r.0': 'r.0' }, 'match_z_plane'), } periodic = { 'per_u': ['per_u_x', 'per_u_y', 'per_u_z'], 'per_r': ['per_r_x', 'per_r_y', 'per_r_z'], } # rescale piezoelectric material parameters mat_g_sc, mat_d_sc = (eps0, eps0**2) materials = { 'elastic': ({ 'D': { 'Ym': nm.array([[1.504, 0.656, 0.659, 0, 0, 0], [0.656, 1.504, 0.659, 0, 0, 0], [0.659, 0.659, 1.455, 0, 0, 0], [0, 0, 0, 0.424, 0, 0], [0, 0, 0, 0, 0.439, 0], [0, 0, 0, 0, 0, 0.439]]) * 1e11, 'Yc': stiffness_from_youngpoisson(3, 200e9, 0.25) } }, ), 'piezo': ({ 'g': nm.array([[0, 0, 0, 0, 11.404, 0], [0, 0, 0, 0, 0, 11.404], [-4.322, -4.322, 17.360, 0, 0, 0]]) / mat_g_sc, 'd': nm.array([[1.284, 0, 0], [0, 1.284, 0], [0, 0, 1.505]]) * 1e-8 / mat_d_sc }, ), } functions = { 'match_x_plane': (per.match_x_plane, ), 'match_y_plane': (per.match_y_plane, ), 'match_z_plane': (per.match_z_plane, ), } ebcs = { 'fixed_u': ('Corners', { 'u.all': 0.0 }), 'fixed_r': ('Gamma_ms', { 'r.all': 0.0 }), 'fixed_r1_s1': ('Gamma_s1', { 'r.0': 1.0 }), 'fixed_r0_s1': ('Gamma_s1', { 'r.0': 0.0 }), 'fixed_r1_s2': ('Gamma_s2', { 'r.0': 1.0 }), 'fixed_r0_s2': ('Gamma_s2', { 'r.0': 0.0 }), } integrals = { 'i2': 2, } solvers = { 'ls_d': ('ls.scipy_direct', {}), 'ls_i': ('ls.scipy_iterative', {}), 'ns_ea6': ('nls.newton', { 'eps_a': 1e6, 'eps_r': 1e-3, }), 'ns_ea0': ('nls.newton', { 'eps_a': 1e0, 'eps_r': 1e-3, }), } coefs = { 'A1': { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_rs'], 'expression': 'dw_lin_elastic.i2.Ymc(elastic.D, U1, U2)', 'set_variables': [('U1', ('corrs_rs', 'pis_u'), 'u'), ('U2', ('corrs_rs', 'pis_u'), 'u')], 'class': cb.CoefSymSym, }, 'A2': { 'status': 'auxiliary', 'requires': ['corrs_rs'], 'expression': 'dw_diffusion.i2.Ym(piezo.d, R1, R2)', 'set_variables': [('R1', 'corrs_rs', 'r'), ('R2', 'corrs_rs', 'r')], 'class': cb.CoefSymSym, }, 'A': { 'requires': ['c.A1', 'c.A2'], 'expression': 'c.A1 + c.A2', 'class': cb.CoefEval, }, 'vol': { 'regions': ['Ym', 'Yc1', 'Yc2'], 'expression': 'ev_volume.i2.%s(svar)', 'class': cb.VolumeFractions, }, 'eps0': { 'requires': [], 'expression': '%e' % eps0, 'class': cb.CoefEval, }, 'filenames': {}, } requirements = { 'pis_u': { 'variables': ['u'], 'class': cb.ShapeDimDim, }, 'pis_r': { 'variables': ['r'], 'class': cb.ShapeDim, }, 'corrs_rs': { 'requires': ['pis_u'], 'ebcs': ['fixed_u', 'fixed_r'], 'epbcs': ['p_ux', 'p_uy', 'p_uz', 'p_rx', 'p_ry', 'p_rz'], 'equations': { 'eq1': """dw_lin_elastic.i2.Ymc(elastic.D, v, u) - dw_piezo_coupling.i2.Ym(piezo.g, v, r) = - dw_lin_elastic.i2.Ymc(elastic.D, v, Pi_u)""", 'eq2': """ - dw_piezo_coupling.i2.Ym(piezo.g, u, s) - dw_diffusion.i2.Ym(piezo.d, s, r) = dw_piezo_coupling.i2.Ym(piezo.g, Pi_u, s)""", }, 'set_variables': [('Pi_u', 'pis_u', 'u')], 'class': cb.CorrDimDim, 'save_name': 'corrs_rs', 'solvers': { 'ls': 'ls_i', 'nls': 'ns_ea6' }, }, } # define requirements and coefficients related to conductors bc_conductors = [ ['fixed_r1_s1', 'fixed_r0_s2'], # phi = 1 on S1, phi = 0 on S2 ['fixed_r1_s2', 'fixed_r0_s1'], # phi = 0 on S1, phi = 1 on S2 ] for k in range(2): sk = '%d' % k requirements.update({ 'corrs_k' + sk: { 'requires': ['pis_r'], 'ebcs': ['fixed_u'] + bc_conductors[k], 'epbcs': ['p_ux', 'p_uy', 'p_uz', 'p_rx', 'p_ry', 'p_rz'], 'equations': { 'eq1': """dw_lin_elastic.i2.Ymc(elastic.D, v, u) - dw_piezo_coupling.i2.Ym(piezo.g, v, r) = 0""", 'eq2': """ - dw_piezo_coupling.i2.Ym(piezo.g, u, s) - dw_diffusion.i2.Ym(piezo.d, s, r) = 0""" }, 'class': cb.CorrOne, 'save_name': 'corrs_k' + sk, 'solvers': { 'ls': 'ls_d', 'nls': 'ns_ea0' }, }, }) coefs.update({ 'V1_' + sk: { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_k' + sk], 'expression': 'dw_lin_elastic.i2.Ymc(elastic.D, U1, U2)', 'set_variables': [('U1', 'corrs_k' + sk, 'u'), ('U2', 'pis_u', 'u')], 'class': cb.CoefSym, }, 'V2_' + sk: { 'status': 'auxiliary', 'requires': ['pis_u', 'corrs_k' + sk], 'expression': 'dw_piezo_coupling.i2.Ym(piezo.g, U1, R1)', 'set_variables': [('R1', 'corrs_k' + sk, 'r'), ('U1', 'pis_u', 'u')], 'class': cb.CoefSym, }, 'V' + sk: { 'requires': ['c.V1_' + sk, 'c.V2_' + sk], 'expression': 'c.V1_%s - c.V2_%s' % (sk, sk), 'class': cb.CoefEval, }, }) return locals()
plt.ylabel('Cauchy strain') plt.xlabel('probe %s' % label, fontsize=8) plt.legend(loc='best', prop=fm.FontProperties(size=8)) plt.subplot(313) pars, vals = results['cauchy_stress'] for ic in range(vals.shape[1]): plt.plot(pars, vals[:,ic], label=r'$\sigma_{%s}$' % sym_indices[ic], lw=1, ls='-', marker='+', ms=3) plt.ylabel('Cauchy stress') plt.xlabel('probe %s' % label, fontsize=8) plt.legend(loc='best', prop=fm.FontProperties(size=8)) return plt.gcf(), results materials['Asphalt'][0].update({'D' : stiffness_from_youngpoisson(2, young, poisson)}) # Update fields and variables to be able to use probes for tensors. fields.update({ 'sym_tensor': ('real', 3, 'Omega', 0), }) variables.update({ 's' : ('parameter field', 'sym_tensor', None), }) options.update({ 'output_format' : 'h5', # VTK reader cannot read cell data yet for probing 'post_process_hook' : 'stress_strain', 'gen_probes' : 'gen_lines', 'probe_hook' : 'probe_hook',
filename_mesh = UserMeshIO(mesh_hook) options = { 'nls': 'newton', 'ls': 'ls', } fields = { 'displacement': ('real', dim, 'Omega', 1), } materials = { 'solid': ({ 'D': stiffness_from_youngpoisson(dim, young=1.0, poisson=0.3) }, ), 'contact': ({ '.epss': 1e1 }, ), } variables = { 'u': ('unknown field', 'displacement', 0), 'v': ('test field', 'displacement', 'u'), } bbox0 = get_bbox(dims0, centre0, eps=1e-5) bbox1 = get_bbox(dims1, nm.asarray(centre1) + nm.asarray(shift1), eps=1e-5) if dim == 2:
regions = { 'Omega': 'all', 'Impact': ('vertices in (x < 1e-12)', 'facet'), } if dim == 3: regions.update({ 'Symmetry-y': ('vertices in (y < 1e-12)', 'facet'), 'Symmetry-z': ('vertices in (z < 1e-12)', 'facet'), }) # Iron. materials = { 'solid': ({ 'D': mc.stiffness_from_youngpoisson(dim=dim, young=E, poisson=nu, plane=plane), 'rho': rho, }, ), } fields = { 'displacement': ('real', 'vector', 'Omega', 1), } integrals = { 'i': 2, } variables = {
def main(): from sfepy import data_dir parser = OptionParser(usage=usage, version='%prog') parser.add_option('--young', metavar='float', type=float, action='store', dest='young', default=2000.0, help=helps['young']) parser.add_option('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.4, help=helps['poisson']) parser.add_option('--load', metavar='float', type=float, action='store', dest='load', default=-1000.0, help=helps['load']) parser.add_option('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_option('-r', '--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_option('-s', '--show', action="store_true", dest='show', default=False, help=helps['show']) parser.add_option('-p', '--probe', action="store_true", dest='probe', default=False, help=helps['probe']) options, args = parser.parse_args() assert_((0.0 < options.poisson < 0.5), "Poisson's ratio must be in ]0, 0.5[!") assert_((0 < options.order), 'displacement approximation order must be at least 1!') output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' vertical load:', options.load) output('uniform mesh refinement level:', options.refine) # Build the problem definition. mesh = Mesh.from_file(data_dir + '/meshes/2d/its2D.mesh') domain = FEDomain('domain', mesh) if options.refine > 0: for ii in range(options.refine): output('refine %d...' % ii) domain = domain.refine() output('... %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) omega = domain.create_region('Omega', 'all') left = domain.create_region('Left', 'vertices in x < 0.001', 'facet') bottom = domain.create_region('Bottom', 'vertices in y < 0.001', 'facet') top = domain.create_region('Top', 'vertex 2', 'vertex') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=options.order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') D = stiffness_from_youngpoisson(2, options.young, options.poisson) asphalt = Material('Asphalt', D=D) load = Material('Load', values={'.val' : [0.0, options.load]}) integral = Integral('i', order=2*options.order) integral0 = Integral('i', order=0) t1 = Term.new('dw_lin_elastic(Asphalt.D, v, u)', integral, omega, Asphalt=asphalt, v=v, u=u) t2 = Term.new('dw_point_load(Load.val, v)', integral0, top, Load=load, v=v) eq = Equation('balance', t1 - t2) eqs = Equations([eq]) xsym = EssentialBC('XSym', bottom, {'u.1' : 0.0}) ysym = EssentialBC('YSym', left, {'u.0' : 0.0}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls) pb.time_update(ebcs=Conditions([xsym, ysym])) # Solve the problem. state = pb.solve() output(nls_status) # Postprocess the solution. out = state.create_output_dict() out = stress_strain(out, pb, state, extend=True) pb.save_state('its2D_interactive.vtk', out=out) gdata = geometry_data['2_3'] nc = len(gdata.coors) integral_vn = Integral('ivn', coors=gdata.coors, weights=[gdata.volume / nc] * nc) nodal_stress(out, pb, state, integrals=Integrals([integral_vn])) if options.probe: # Probe the solution. probes, labels = gen_lines(pb) sfield = Field.from_args('sym_tensor', nm.float64, 3, omega, approx_order=options.order - 1) stress = FieldVariable('stress', 'parameter', sfield, primary_var_name='(set-to-None)') strain = FieldVariable('strain', 'parameter', sfield, primary_var_name='(set-to-None)') cfield = Field.from_args('component', nm.float64, 1, omega, approx_order=options.order - 1) component = FieldVariable('component', 'parameter', cfield, primary_var_name='(set-to-None)') ev = pb.evaluate order = 2 * (options.order - 1) strain_qp = ev('ev_cauchy_strain.%d.Omega(u)' % order, mode='qp') stress_qp = ev('ev_cauchy_stress.%d.Omega(Asphalt.D, u)' % order, mode='qp', copy_materials=False) project_by_component(strain, strain_qp, component, order) project_by_component(stress, stress_qp, component, order) all_results = [] for ii, probe in enumerate(probes): fig, results = probe_results(u, strain, stress, probe, labels[ii]) fig.savefig('its2D_interactive_probe_%d.png' % ii) all_results.append(results) for ii, results in enumerate(all_results): output('probe %d:' % ii) output.level += 2 for key, res in ordered_iteritems(results): output(key + ':') val = res[1] output(' min: %+.2e, mean: %+.2e, max: %+.2e' % (val.min(), val.mean(), val.max())) output.level -= 2 if options.show: # Show the solution. If the approximation order is greater than 1, the # extra DOFs are simply thrown away. from sfepy.postprocess.viewer import Viewer view = Viewer('its2D_interactive.vtk') view(vector_mode='warp_norm', rel_scaling=1, is_scalar_bar=True, is_wireframe=True)
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson def stress_strain(out, pb, state, extend=False): """ Calculate and output strain and stress for given displacements. """ from sfepy.base.base import Struct ev = pb.evaluate strain = ev('ev_cauchy_strain.2.Omega(u)', mode='el_avg') stress = ev('ev_cauchy_stress.2.Omega(Asphalt.D, u)', mode='el_avg') out['cauchy_strain'] = Struct(name='output_data', mode='cell', data=strain, dofs=None) out['cauchy_stress'] = Struct(name='output_data', mode='cell', data=stress, dofs=None) return out asphalt = materials['Asphalt'][0] asphalt.update({'D': stiffness_from_youngpoisson(2, young, poisson)}) options.update({ 'post_process_hook': 'stress_strain', })
min_z, max_z = domain.get_mesh_bounding_box()[:, 2] eps = 1e-4 * (max_z - min_z) omega = domain.create_region('Omega', 'all') bot = domain.create_region('Bot', 'vertices in z < %.10f' % (min_z + eps), 'vertex') top = domain.create_region('Top', 'vertices in z > %.10f' % (max_z - eps), 'vertex') field = Field.from_args('fu', np.float64, 'vector', omega, approx_order=1) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') m = Material('m', D=stiffness_from_youngpoisson(dim=3, young=6.8e10, poisson=0.36), rho=2700.0) integral = Integral('i', order=1) t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u) eq1 = Equation('balance_of_forces', t1) eqs = Equations([eq1]) z_displacements = np.linspace(0, 0.05, 6) vm_stresses = np.zeros([len(z_displacements), 2]) for i, z_displacement in enumerate(z_displacements): fix_bot = EssentialBC('fix_bot', bot, {'u.all': 0.0}) fix_top = EssentialBC('fix_top', top, { 'u.[0,1]': 0.0,
filename_mesh = UserMeshIO(mesh_hook) regions = { 'Omega' : 'all', 'Impact' : ('vertices in (x < 1e-12)', 'facet'), } if dim == 3: regions.update({ 'Symmetry-y' : ('vertices in (y < 1e-12)', 'facet'), 'Symmetry-z' : ('vertices in (z < 1e-12)', 'facet'), }) # Iron. materials = { 'solid' : ({ 'D': mc.stiffness_from_youngpoisson(dim=dim, young=E, poisson=nu, plane=plane), 'rho': rho, },), } fields = { 'displacement': ('real', 'vector', 'Omega', 1), } integrals = { 'i' : 2, } variables = { 'u' : ('unknown field', 'displacement', 0), 'du' : ('unknown field', 'displacement', 1),
young = 2000.0 # Young's modulus [MPa] poisson = 0.4 # Poisson's ratio options = { 'output_dir' : output_dir, } regions = { 'Omega' : 'all', 'Left' : ('vertices in (x < 0.001)', 'facet'), 'Bottom' : ('vertices in (y < 0.001)', 'facet'), 'Top' : ('vertex 2', 'vertex'), } materials = { 'Asphalt' : ({'D': stiffness_from_youngpoisson(2, young, poisson)},), 'Load' : ({'.val' : [0.0, -1000.0]},), } fields = { 'displacement': ('real', 'vector', 'Omega', 1), } equations = { 'balance_of_forces' : """dw_lin_elastic.2.Omega(Asphalt.D, v, u) = dw_point_load.0.Top(Load.val, v)""", } variables = { 'u' : ('unknown field', 'displacement', 0),
def define(filename_mesh=None): eps0 = 0.01 # given scale parameter if filename_mesh is None: filename_mesh = osp.join(data_dir, 'micro_perf_puc.vtk') mesh = Mesh.from_file(filename_mesh) dim = 3 sym = (dim + 1) * dim // 2 sym_eye = 'nm.array([1,1,0])' if dim == 2 else 'nm.array([1,1,1,0,0,0])' bbox = mesh.get_bounding_box() regions = define_box_regions(mesh.dim, bbox[0], bbox[1], eps=1e-3) regions.update({ 'Y': 'all', 'Gamma_Y': ('vertices of surface', 'facet'), # solid matrix 'Ys': 'cells of group 1', 'Ys_left': ('r.Ys *v r.Left', 'vertex'), 'Ys_right': ('r.Ys *v r.Right', 'vertex'), 'Ys_bottom': ('r.Ys *v r.Bottom', 'vertex'), 'Ys_top': ('r.Ys *v r.Top', 'vertex'), 'Gamma_Ysf': ('r.Ys *v r.Yf', 'facet', 'Ys'), # channel 'Yf': 'cells of group 2', 'Yf0': ('r.Yf -v r.Gamma_Yfs', 'vertex'), 'Yf_left': ('r.Yf0 *v r.Left', 'vertex'), 'Yf_right': ('r.Yf0 *v r.Right', 'vertex'), 'Yf_bottom': ('r.Yf0 *v r.Bottom', 'vertex'), 'Yf_top': ('r.Yf0 *v r.Top', 'vertex'), 'Gamma_Yfs': ('r.Ys *v r.Yf', 'facet', 'Yf'), }) if dim == 3: regions.update({ 'Ys_far': ('r.Ys *v r.Far', 'vertex'), 'Ys_near': ('r.Ys *v r.Near', 'vertex'), 'Yf_far': ('r.Yf0 *v r.Far', 'vertex'), 'Yf_near': ('r.Yf0 *v r.Near', 'vertex'), }) fields = { 'volume': ('real', 'scalar', 'Y', 1), 'displacement': ('real', 'vector', 'Ys', 1), 'pressure': ('real', 'scalar', 'Yf', 1), 'velocity': ('real', 'vector', 'Yf', 2), } variables = { # displacement 'u': ('unknown field', 'displacement'), 'v': ('test field', 'displacement', 'u'), 'Pi_u': ('parameter field', 'displacement', 'u'), 'U1': ('parameter field', 'displacement', '(set-to-None)'), 'U2': ('parameter field', 'displacement', '(set-to-None)'), # velocity 'w': ('unknown field', 'velocity'), 'z': ('test field', 'velocity', 'w'), 'Pi_w': ('parameter field', 'velocity', 'w'), 'W1': ('parameter field', 'velocity', '(set-to-None)'), 'W2': ('parameter field', 'velocity', '(set-to-None)'), # pressure 'p': ('unknown field', 'pressure'), 'q': ('test field', 'pressure', 'p'), # volume 'volume': ('parameter field', 'volume', '(set-to-None)'), } functions = { 'match_x_plane': (per.match_x_plane, ), 'match_y_plane': (per.match_y_plane, ), 'match_z_plane': (per.match_z_plane, ), } materials = { 'matrix': ({ 'D': stiffness_from_youngpoisson(dim, 1e3, 0.49) }, ), #Soft tissue 'fluid': ( { 'eta_p': 3.6e-3 / eps0**2, #Rescaled blood viscosity 'aux_compress': 1e-18 }, ), #Auxillary compressibility } ebcs = { 'fixed_u': ('Corners', { 'u.all': 0.0 }), 'fixed_w': ('Gamma_Yfs', { 'w.all': 0.0 }), } epbcs, periodic = get_periodic_bc([('u', 'Ys'), ('p', 'Yf'), ('w', 'Yf')]) integrals = { 'i': 4, } options = { 'coefs': 'coefs', 'coefs_filename': 'coefs_micro', 'requirements': 'requirements', 'volume': { 'variables': ['u', 'p'], 'expression': 'd_volume.i.Ys(u) + d_volume.i.Yf(p)', }, 'output_dir': data_dir + '/results/micro', 'ls': 'ls', 'file_per_var': True, 'absolute_mesh_path': True, 'multiprocessing': True, 'output_prefix': 'micro:', } #Definition of used solvers solvers = { 'ls': ('ls.mumps', {}), 'ns_em9': ('nls.newton', { 'i_max': 1, 'eps_a': 1e-9, 'eps_r': 1e-3, 'problem': 'nonlinear' }), 'ns_em12': ('nls.newton', { 'i_max': 1, 'eps_a': 1e-12, 'eps_r': 1e-3, 'problem': 'nonlinear' }), } #Definition of homogenized coefficients, see (22) and (23) coefs = { #Elasticity coefficient 'A': { 'requires': ['pis_u', 'corrs_omega_ij'], 'expression': 'dw_lin_elastic.i.Ys(matrix.D, U1, U2)', 'set_variables': [('U1', ('corrs_omega_ij', 'pis_u'), 'u'), ('U2', ('corrs_omega_ij', 'pis_u'), 'u')], 'class': cb.CoefSymSym, }, #Biot coefficient 'hat_B': { 'status': 'auxiliary', 'requires': ['corrs_omega_ij'], 'expression': '- ev_div.i.Ys(U1)', 'set_variables': [('U1', 'corrs_omega_ij', 'u')], 'class': cb.CoefSym, }, 'B': { 'requires': ['c.phi_f', 'c.hat_B'], 'expression': 'c.hat_B + c.phi_f * %s' % sym_eye, 'class': cb.CoefEval, }, 'M': { 'requires': ['corrs_omega_p'], 'expression': 'dw_lin_elastic.i.Ys(matrix.D, U1, U2)', 'set_variables': [('U1', 'corrs_omega_p', 'u'), ('U2', 'corrs_omega_p', 'u')], 'class': cb.CoefOne, }, #Permeability 'K': { 'requires': ['corrs_psi_i'], 'expression': 'dw_div_grad.i.Yf(W1, W2)', # !!! 'set_variables': [('W1', 'corrs_psi_i', 'w'), ('W2', 'corrs_psi_i', 'w')], 'class': cb.CoefDimDim, }, #Volume fraction of fluid part 'phi_f': { 'requires': ['c.vol'], 'expression': 'c.vol["fraction_Yf"]', 'class': cb.CoefEval, }, #Coefficient for storing viscosity 'eta_p': { 'expression': '%e' % materials['fluid'][0]['eta_p'], 'class': cb.CoefEval, }, #Volume fractions 'vol': { 'regions': ['Ys', 'Yf'], 'expression': 'd_volume.i.%s(volume)', 'class': cb.VolumeFractions, }, #Surface volume fractions 'surf_vol': { 'regions': ['Ys', 'Yf'], 'expression': 'd_surface.i.%s(volume)', 'class': cb.VolumeFractions, }, 'filenames': {}, } #Definition of microscopic corrector problems requirements = { #Definition of \Pi^{ij}_k 'pis_u': { 'variables': ['u'], 'class': cb.ShapeDimDim, }, #Correcotr like class returning ones 'pis_w': { 'variables': ['w'], 'class': cb.OnesDim, }, #Corrector problem related to elasticity, see (17) 'corrs_omega_ij': { 'requires': ['pis_u'], 'ebcs': ['fixed_u'], 'epbcs': periodic['per_u'], 'is_linear': True, 'equations': { 'balance_of_forces': """dw_lin_elastic.i.Ys(matrix.D, v, u) = - dw_lin_elastic.i.Ys(matrix.D, v, Pi_u)""" }, 'set_variables': [('Pi_u', 'pis_u', 'u')], 'class': cb.CorrDimDim, 'save_name': 'corrs_omega_ij', 'dump_variables': ['u'], 'solvers': {'ls': 'ls', 'nls': 'ns_em9'}, }, # Corrector problem related to elasticity, see (18) 'corrs_omega_p': { 'requires': [], 'ebcs': ['fixed_u'], 'epbcs': periodic['per_u'], 'equations': { 'balance_of_forces': """dw_lin_elastic.i.Ys(matrix.D, v, u) = -dw_surface_ltr.i.Gamma_Ysf(v)""" }, 'class': cb.CorrOne, 'save_name': 'corrs_omega_p', 'dump_variables': ['u'], 'solvers': {'ls': 'ls', 'nls': 'ns_em3'}, }, #Corrector problem related to velocity, see (19) 'corrs_psi_i': { 'requires': ['pis_w'], 'ebcs': ['fixed_w'], 'epbcs': periodic['per_w'] + periodic['per_p'], 'is_linear': True, 'equations': { 'balance_of_forces': # !!! """dw_div_grad.i.Yf(fluid.eta_p,z, w) - dw_stokes.i.Yf(z, p) = dw_volume_dot.i.Yf(z, Pi_w)""", 'incompressibility': """dw_stokes.i.Yf(w, q) + dw_volume_dot.i.Yf(fluid.aux_compress, q, p) = 0""",# }, 'set_variables': [('Pi_w', 'pis_w', 'w')], 'class': cb.CorrDim, 'save_name': 'corrs_psi_i', 'dump_variables': ['w', 'p'], 'solvers': {'ls': 'ls', 'nls': 'ns_em12'}, }, } return locals()
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)
pars, vals = probe(ip, 'cauchy_strain') for ii, ic in enumerate(sym_indices): plt.plot(pars, vals[:,ic], label=r'$e_{%s}$' % sym_labels[ii], lw=1, ls='-', marker='+', ms=3) plt.ylabel('Cauchy strain') plt.xlabel('probe %s' % label, fontsize=8) plt.legend(loc='best', prop=fm.FontProperties(size=8)) plt.subplot(313) pars, vals = probe(ip, 'cauchy_stress') for ii, ic in enumerate(sym_indices): plt.plot(pars, vals[:,ic], label=r'$\sigma_{%s}$' % sym_labels[ii], lw=1, ls='-', marker='+', ms=3) plt.ylabel('Cauchy stress') plt.xlabel('probe %s' % label, fontsize=8) plt.legend(loc='best', prop=fm.FontProperties(size=8)) opts = pb.conf.options filename_results = os.path.join(opts.get('output_dir'), 'its2D_probe_%s.png' % ip) fig.savefig(filename_results) return out materials['Asphalt'][0].update({'D' : stiffness_from_youngpoisson(2, young, poisson)}) options.update({ 'post_process_hook' : 'stress_strain', })
dim = 3 region_lbn = (0, 0, 0) region_rtf = (1, 1, 1) #! Regions #! ------- #! Regions, edges, ... regions = { 'Y' : 'all', 'Ym' : 'cells of group 1', 'Yc' : 'cells of group 2', } regions.update( define_box_regions( dim, region_lbn, region_rtf ) ) #! Materials #! --------- materials = { 'mat' : ({'D' : {'Ym': stiffness_from_youngpoisson(dim, 7.0e9, 0.4), 'Yc': stiffness_from_youngpoisson(dim, 70.0e9, 0.2)}},), } #! Fields #! ------ #! Scalar field for corrector basis functions. fields = { 'corrector' : ('real', dim, 'Y', 1), } #! Variables #! --------- #! Unknown and corresponding test variables. Parameter fields #! used for evaluation of homogenized coefficients. variables = { 'u' : ('unknown field', 'corrector', 0), 'v' : ('test field', 'corrector', 'u'),
region_rtf = (1, 1, 1) #! Regions #! ------- #! Regions, edges, ... regions = { 'Y': ('all', {}), 'Ym': ('elements of group 1', {}), 'Yc': ('elements of group 2', {}), } regions.update(define_box_regions(dim, region_lbn, region_rtf)) #! Materials #! --------- materials = { 'mat': ({ 'D': { 'Ym': stiffness_from_youngpoisson(dim, 7.0e9, 0.4), 'Yc': stiffness_from_youngpoisson(dim, 70.0e9, 0.2) } }, ), } #! Fields #! ------ #! Scalar field for corrector basis functions. fields = { 'corrector': ('real', dim, 'Y', 1), } #! Variables #! --------- #! Unknown and corresponding test variables. Parameter fields #! used for evaluation of homogenized coefficients. variables = {
poisson = 0.4 # Poisson's ratio options = { 'output_dir': output_dir, } regions = { 'Omega': 'all', 'Left': ('vertices in (x < 0.001)', 'facet'), 'Bottom': ('vertices in (y < 0.001)', 'facet'), 'Top': ('vertex 2', 'vertex'), } materials = { 'Asphalt': ({ 'D': stiffness_from_youngpoisson(2, young, poisson) }, ), 'Load': ({ '.val': [0.0, -1000.0] }, ), } fields = { 'displacement': ('real', 'vector', 'Omega', 1), } equations = { 'balance_of_forces': """dw_lin_elastic.2.Omega(Asphalt.D, v, u) = dw_point_load.0.Top(Load.val, v)""", }
def main(): from sfepy import data_dir parser = OptionParser(usage=usage, version='%prog') parser.add_option('--young', metavar='float', type=float, action='store', dest='young', default=2000.0, help=helps['young']) parser.add_option('--poisson', metavar='float', type=float, action='store', dest='poisson', default=0.4, help=helps['poisson']) parser.add_option('--load', metavar='float', type=float, action='store', dest='load', default=-1000.0, help=helps['load']) parser.add_option('--order', metavar='int', type=int, action='store', dest='order', default=1, help=helps['order']) parser.add_option('-r', '--refine', metavar='int', type=int, action='store', dest='refine', default=0, help=helps['refine']) parser.add_option('-s', '--show', action="store_true", dest='show', default=False, help=helps['show']) parser.add_option('-p', '--probe', action="store_true", dest='probe', default=False, help=helps['probe']) options, args = parser.parse_args() assert_((0.0 < options.poisson < 0.5), "Poisson's ratio must be in ]0, 0.5[!") assert_((0 < options.order), 'displacement approximation order must be at least 1!') output('using values:') output(" Young's modulus:", options.young) output(" Poisson's ratio:", options.poisson) output(' vertical load:', options.load) output('uniform mesh refinement level:', options.refine) # Build the problem definition. mesh = Mesh.from_file(data_dir + '/meshes/2d/its2D.mesh') domain = FEDomain('domain', mesh) if options.refine > 0: for ii in xrange(options.refine): output('refine %d...' % ii) domain = domain.refine() output('... %d nodes %d elements' % (domain.shape.n_nod, domain.shape.n_el)) omega = domain.create_region('Omega', 'all') left = domain.create_region('Left', 'vertices in x < 0.001', 'facet') bottom = domain.create_region('Bottom', 'vertices in y < 0.001', 'facet') top = domain.create_region('Top', 'vertex 2', 'vertex') field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=options.order) u = FieldVariable('u', 'unknown', field) v = FieldVariable('v', 'test', field, primary_var_name='u') D = stiffness_from_youngpoisson(2, options.young, options.poisson) asphalt = Material('Asphalt', D=D) load = Material('Load', values={'.val': [0.0, options.load]}) integral = Integral('i', order=2 * options.order) integral0 = Integral('i', order=0) t1 = Term.new('dw_lin_elastic(Asphalt.D, v, u)', integral, omega, Asphalt=asphalt, v=v, u=u) t2 = Term.new('dw_point_load(Load.val, v)', integral0, top, Load=load, v=v) eq = Equation('balance', t1 - t2) eqs = Equations([eq]) xsym = EssentialBC('XSym', bottom, {'u.1': 0.0}) ysym = EssentialBC('YSym', left, {'u.0': 0.0}) ls = ScipyDirect({}) nls_status = IndexedStruct() nls = Newton({}, lin_solver=ls, status=nls_status) pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls) pb.time_update(ebcs=Conditions([xsym, ysym])) # Solve the problem. state = pb.solve() output(nls_status) # Postprocess the solution. out = state.create_output_dict() out = stress_strain(out, pb, state, extend=True) pb.save_state('its2D_interactive.vtk', out=out) gdata = geometry_data['2_3'] nc = len(gdata.coors) integral_vn = Integral('ivn', coors=gdata.coors, weights=[gdata.volume / nc] * nc) nodal_stress(out, pb, state, integrals=Integrals([integral_vn])) if options.probe: # Probe the solution. probes, labels = gen_lines(pb) sfield = Field.from_args('sym_tensor', nm.float64, 3, omega, approx_order=options.order - 1) stress = FieldVariable('stress', 'parameter', sfield, primary_var_name='(set-to-None)') strain = FieldVariable('strain', 'parameter', sfield, primary_var_name='(set-to-None)') cfield = Field.from_args('component', nm.float64, 1, omega, approx_order=options.order - 1) component = FieldVariable('component', 'parameter', cfield, primary_var_name='(set-to-None)') ev = pb.evaluate order = 2 * (options.order - 1) strain_qp = ev('ev_cauchy_strain.%d.Omega(u)' % order, mode='qp') stress_qp = ev('ev_cauchy_stress.%d.Omega(Asphalt.D, u)' % order, mode='qp', copy_materials=False) project_by_component(strain, strain_qp, component, order) project_by_component(stress, stress_qp, component, order) all_results = [] for ii, probe in enumerate(probes): fig, results = probe_results(u, strain, stress, probe, labels[ii]) fig.savefig('its2D_interactive_probe_%d.png' % ii) all_results.append(results) for ii, results in enumerate(all_results): output('probe %d:' % ii) output.level += 2 for key, res in ordered_iteritems(results): output(key + ':') val = res[1] output(' min: %+.2e, mean: %+.2e, max: %+.2e' % (val.min(), val.mean(), val.max())) output.level -= 2 if options.show: # Show the solution. If the approximation order is greater than 1, the # extra DOFs are simply thrown away. from sfepy.postprocess.viewer import Viewer view = Viewer('its2D_interactive.vtk') view(vector_mode='warp_norm', rel_scaling=1, is_scalar_bar=True, is_wireframe=True)
if integrals is None: integrals = pb.get_integrals() stress = pb.evaluate('ev_cauchy_stress.ivn.Omega(Asphalt.D, u)', mode='qp', integrals=integrals, copy_materials=False) sfield = Field.from_args('stress', nm.float64, (3,), pb.domain.regions['Omega']) svar = FieldVariable('sigma', 'parameter', sfield, primary_var_name='(set-to-None)') svar.set_from_qp(stress, integrals['ivn']) print('\n==================================================================') print('Given load = %.2f N' % -P) print('\nAnalytical solution') print('===================') print('Horizontal tensile stress = %.5e MPa/mm' % (-2.*P/(nm.pi*150.))) print('Vertical compressive stress = %.5e MPa/mm' % (-6.*P/(nm.pi*150.))) print('\nFEM solution') print('============') print('Horizontal tensile stress = %.5e MPa/mm' % (svar()[0])) print('Vertical compressive stress = %.5e MPa/mm' % (-svar()[1])) print('==================================================================') return out asphalt = materials['Asphalt'][0] asphalt.update({'D' : stiffness_from_youngpoisson(2, young, poisson)}) options.update({'post_process_hook' : 'nodal_stress',}) integrals = { 'ivn' : ('custom', gdata.coors, [gdata.volume / nc] * nc), }
def test_stiffness_tensors(self): import numpy as nm from sfepy.base.base import assert_ import sfepy.mechanics.matcoefs as mc ok = True lam = 1.0 mu = 4.0 lam = nm.array([lam] * 3) mu = nm.array([mu] * 3) d = nm.array([[ 9., 1., 1., 0., 0., 0.], [ 1., 9., 1., 0., 0., 0.], [ 1., 1., 9., 0., 0., 0.], [ 0., 0., 0., 4., 0., 0.], [ 0., 0., 0., 0., 4., 0.], [ 0., 0., 0., 0., 0., 4.]]) _ds = mc.stiffness_from_lame(3, lam, mu) assert_(_ds.shape == (3, 6, 6)) _ok = True for _d in _ds: __ok = nm.allclose(_d, d, rtol=0.0, atol=1e-14) _ok = _ok and __ok self.report('stiffness_from_lame():', _ok) ok = ok and _ok _lam, _mu = mc.lame_from_stiffness(d) _ok = (_lam == 1) and (_mu == 4) self.report('lame_from_stiffness():', _ok) ok = ok and _ok young = 1.0 poisson = 0.25 d = mc.stiffness_from_youngpoisson(3, young, poisson, plane='strain') _young, _poisson = mc.youngpoisson_from_stiffness(d, plane='strain') _ok = nm.allclose([young, poisson], [_young, _poisson], rtol=0.0, atol=1e-14) self.report('youngpoisson_from_stiffness(plane="strain"):', _ok) ok = ok and _ok d = mc.stiffness_from_youngpoisson(2, young, poisson, plane='stress') _young, _poisson = mc.youngpoisson_from_stiffness(d, plane='stress') _ok = nm.allclose([young, poisson], [_young, _poisson], rtol=0.0, atol=1e-14) self.report('youngpoisson_from_stiffness(plane="stress"):', _ok) ok = ok and _ok d = 4.0 / 3.0 * nm.array([[ 4., -2., -2., 0., 0., 0.], [-2., 4., -2., 0., 0., 0.], [-2., -2., 4., 0., 0., 0.], [ 0., 0., 0., 3., 0., 0.], [ 0., 0., 0., 0., 3., 0.], [ 0., 0., 0., 0., 0., 3.]]) _ds = mc.stiffness_from_lame_mixed(3, lam, mu) assert_(_ds.shape == (3, 6, 6)) _ok = True for _d in _ds: __ok = nm.allclose(_d, d, rtol=0.0, atol=1e-14) _ok = _ok and __ok self.report('stiffness_from_lame_mixed():', _ok) ok = ok and _ok blam = - mu * 2.0 / 3.0 _ds = mc.stiffness_from_lame(3, blam, mu) assert_(_ds.shape == (3, 6, 6)) _ok = True for _d in _ds: __ok = nm.allclose(_d, d, rtol=0.0, atol=1e-14) _ok = _ok and __ok self.report('stiffness_from_lame() with modified lambda:', _ok) ok = ok and _ok return ok