def convolve_field_sym_tensor( fvars, pvars, var_name, dim, iel, ts ): r""" .. math:: \int_0^t f^{ij}(t-s) p_{ij}(s) ds Notes ----- - t is given by step - f: fvars field variables, defined in a micro domain, have shape [step][fmf dims] - p: pvars sym. tensor point variables, a scalar in a point of macro-domain, FMField style, have shape [dim, dim][var_name][n_step][var dims] """ step0 = max( 0, ts.step - fvars[0,0][var_name].steps[-1] ) val = nm.zeros_like( fvars[0,0][var_name][0] ) for ik in xrange( step0, ts.step + 1 ): ## print ' ', ik, ts.step-ik for ir in range( dim ): for ic in range( dim ): ii = coor_to_sym( ir, ic, dim ) vf = fvars[ir,ic][var_name][ts.step-ik] vp = pvars[ik][iel,0,ii,0] val += vf * vp * ts.dt return val
def compute_cat_sym_sym(coef, iw_dir): """ Christoffel acoustic tensor (part) of elasticity tensor dimension. """ dim = iw_dir.shape[0] cat = nm.zeros((dim, dim), dtype=nm.float64) for ii in range(dim): for ij in range(dim): ir = coor_to_sym(ii, ij, dim) for ik in range(dim): for il in range(dim): ic = coor_to_sym(ik, il, dim) cat[ii,ik] += coef[ir,ic] * iw_dir[ij] * iw_dir[il] return cat
def convolve_field_sym_tensor(fvars, pvars, var_name, dim, iel, ts): r""" .. math:: \int_0^t f^{ij}(t-s) p_{ij}(s) ds Notes ----- - t is given by step - f: fvars field variables, defined in a micro domain, have shape [step][fmf dims] - p: pvars sym. tensor point variables, a scalar in a point of macro-domain, FMField style, have shape [dim, dim][var_name][n_step][var dims] """ step0 = max(0, ts.step - fvars[0, 0][var_name].steps[-1]) val = nm.zeros_like(fvars[0, 0][var_name][0]) for ik in xrange(step0, ts.step + 1): ## print ' ', ik, ts.step-ik for ir in range(dim): for ic in range(dim): ii = coor_to_sym(ir, ic, dim) vf = fvars[ir, ic][var_name][ts.step - ik] vp = pvars[ik][iel, 0, ii, 0] val += vf * vp * ts.dt return val
def compute_cat_sym_sym(coef, iw_dir): """ Christoffel acoustic tensor (part) of elasticity tensor dimension. """ dim = iw_dir.shape[0] cat = nm.zeros((dim, dim), dtype=nm.float64) for ii in range(dim): for ij in range(dim): ir = coor_to_sym(ii, ij, dim) for ik in range(dim): for il in range(dim): ic = coor_to_sym(ik, il, dim) cat[ii, ik] += coef[ir, ic] * iw_dir[ij] * iw_dir[il] return cat
def add_strain_rs(corrs_rs, strain, vu, dim, iel, out=None): if out is None: out = nm.zeros_like(corrs_rs[0, 0][vu][0]) for ir in range(dim): for ic in range(dim): ii = coor_to_sym(ir, ic, dim) out += corrs_rs[ir, ic][vu].data * strain[iel, 0, ii, 0] return out
def add_strain_rs( corrs_rs, strain, vu, dim, iel, out = None ): if out is None: out = nm.zeros_like( corrs_rs[0,0][vu][0] ) for ir in range( dim ): for ic in range( dim ): ii = coor_to_sym( ir, ic, dim ) out += corrs_rs[ir,ic][vu].data * strain[iel,0,ii,0] return out
def compute_cat( coefs, iw_dir, mode = 'simple' ): r"""Compute Christoffel acoustic tensor (cat) given the incident wave direction (unit vector). - if mode == 'simple', coefs.elastic is the elasticity tensor C and cat := \Gamma_{ik} = C_{ijkl} n_j n_l - if mode == 'piezo', coefs.elastic, .coupling, .dielectric are the elasticity, piezo-coupling and dielectric tensors C, G, D and cat := H_{ik} = \Gamma_{ik} + \frac{1}{\xi} \gamma_i \gamma_j, where \gamma_i = G_{kij} n_j n_k, \xi = D_{kl} n_k n_l """ dim = iw_dir.shape[0] cat = nm.zeros( (dim, dim), dtype = nm.float64 ) mtx_c = coefs.elastic for ii in range( dim ): for ij in range( dim ): ir = coor_to_sym( ii, ij, dim ) for ik in range( dim ): for il in range( dim ): ic = coor_to_sym( ik, il, dim ) cat[ii,ik] += mtx_c[ir,ic] * iw_dir[ij] * iw_dir[il] # print cat if mode =='piezo': xi = nm.dot( nm.dot( coefs.dielectric, iw_dir ), iw_dir ) # print xi gamma = nm.zeros( (dim,), dtype = nm.float64 ) mtx_g = coefs.coupling for ii in range( dim ): for ij in range( dim ): ir = coor_to_sym( ii, ij, dim ) for ik in range( dim ): gamma[ii] += mtx_g[ik,ir] * iw_dir[ij] * iw_dir[ik] # print gamma cat += nm.outer( gamma, gamma ) / xi return cat
def compute_cat_dim_sym(coef, iw_dir): """ Christoffel acoustic tensor part of piezo-coupling tensor dimension. """ dim = iw_dir.shape[0] cat = nm.zeros((dim,), dtype=nm.float64) for ii in range(dim): for ij in range(dim): ir = coor_to_sym(ii, ij, dim) for ik in range(dim): cat[ii] += coef[ik,ir] * iw_dir[ij] * iw_dir[ik] return cat
def compute_cat_dim_sym(coef, iw_dir): """ Christoffel acoustic tensor part of piezo-coupling tensor dimension. """ dim = iw_dir.shape[0] cat = nm.zeros((dim, ), dtype=nm.float64) for ii in range(dim): for ij in range(dim): ir = coor_to_sym(ii, ij, dim) for ik in range(dim): cat[ii] += coef[ik, ir] * iw_dir[ij] * iw_dir[ik] return cat
def compute_micro_u(corrs, strain, vu, dim, out=None): r""" Micro displacements. .. math:: \bm{u}^1 = \bm{\chi}^{ij}\, e_{ij}^x(\bm{u}^0) """ if out is None: out = nm.zeros_like(corrs[vu + '_00']) for ir in range(dim): for ic in range(dim): ii = coor_to_sym(ir, ic, dim) out += corrs[vu + '_%d%d' % (ir, ic)] * strain[ii] return out
def compute_micro_u( corrs, strain, vu, dim, out = None ): r""" Micro displacements. .. math:: \bm{u}^1 = \bm{\chi}^{ij}\, e_{ij}^x(\bm{u}^0) """ if out is None: out = nm.zeros_like( corrs[vu+'_00'] ) for ir in range( dim ): for ic in range( dim ): ii = coor_to_sym( ir, ic, dim ) out += corrs[vu+'_%d%d' % (ir, ic)] * strain[ii] return out
def compute_u_from_macro(strain, coor, iel, centre=None): r""" Macro-induced displacements. .. math:: e_{ij}^x(\bm{u})\,(y_j - y_j^c) """ n_nod, dim = coor.shape if centre is None: centre = nm.zeros((dim, ), dtype=nm.float64) n_nod, dim = coor.shape um = nm.zeros((n_nod * dim, ), dtype=nm.float64) for ir in range(dim): for ic in range(dim): ii = coor_to_sym(ir, ic, dim) um[ir::dim] += strain[iel, 0, ii, 0] * (coor[:, ic] - centre[ic]) return um
def compute_u_from_macro(strain, coor, iel, centre=None): r""" Macro-induced displacements. .. math:: e_{ij}^x(\bm{u})\,(y_j - y_j^c) """ n_nod, dim = coor.shape if centre is None: centre = nm.zeros((dim,), dtype=nm.float64) n_nod, dim = coor.shape um = nm.zeros((n_nod * dim,), dtype=nm.float64) for ir in range(dim): for ic in range(dim): ii = coor_to_sym(ir, ic, dim) um[ir::dim] += strain[iel,0,ii,0] * (coor[:,ic] - centre[ic]) return um
def recovery_micro_dfc(pb, corrs, macro): eps0 = macro['eps0'] mesh = pb.domain.mesh regions = pb.domain.regions dim = mesh.dim Yms_map = regions['Yms'].get_entities(0) Ym_map = regions['Ym'].get_entities(0) gl = '_' + list(corrs.keys())[0].split('_')[-1] u1 = -corrs['corrs_p' + gl]['u'] * macro['press'][Yms_map, :] phi = -corrs['corrs_p' + gl]['r'] * macro['press'][Ym_map, :] for ii in range(2): u1 += corrs['corrs_k%d' % ii + gl]['u'] * macro['phi'][ii] phi += corrs['corrs_k%d' % ii + gl]['r'] * macro['phi'][ii] for ii in range(dim): for jj in range(dim): kk = coor_to_sym(ii, jj, dim) phi += corrs['corrs_rs' + gl]['r_%d%d' % (ii, jj)]\ * nm.expand_dims(macro['strain'][Ym_map, kk], axis=1) u1 += corrs['corrs_rs' + gl]['u_%d%d' % (ii, jj)]\ * nm.expand_dims(macro['strain'][Yms_map, kk], axis=1) u = macro['u'][Yms_map, :] + eps0 * u1 mvar = pb.create_variables(['u', 'r', 'svar']) e_mac_Yms = [None] * macro['strain'].shape[1] for ii in range(dim): for jj in range(dim): kk = coor_to_sym(ii, jj, dim) mvar['svar'].set_data(macro['strain'][:, kk]) mac_e_Yms = pb.evaluate('ev_volume_integrate.i2.Yms(svar)', mode='el_avg', var_dict={'svar': mvar['svar']}) e_mac_Yms[kk] = mac_e_Yms.squeeze() e_mac_Yms = nm.vstack(e_mac_Yms).T[:, nm.newaxis, :, nm.newaxis] mvar['r'].set_data(phi) E_mic = pb.evaluate( 'ev_grad.i2.Ym(r)', mode='el_avg', var_dict={'r': mvar['r']}) / eps0 mvar['u'].set_data(u1) e_mic = pb.evaluate('ev_cauchy_strain.i2.Yms(u)', mode='el_avg', var_dict={'u': mvar['u']}) e_mic += e_mac_Yms out = { 'u0': (macro['u'][Yms_map, :], 'u', 'p'), # macro displacement 'u1': (u1, 'u', 'p'), # local displacement corrections, see eq. (58) 'u': (u, 'u', 'p'), # total displacement 'e_mic': (e_mic, 'u', 'c'), # micro strain field, see eq. (58) 'phi': (phi, 'r', 'p'), # electric potential, see eq. (57) 'E_mic': (E_mic, 'r', 'c'), # electric field, see eq. (58) } return data_to_struct(out)
def recovery_micro(pb, corrs, macro): eps0 = macro['eps0'] mesh = pb.domain.mesh regions = pb.domain.regions dim = mesh.dim Ymc_map = regions['Ymc'].get_entities(0) Ym_map = regions['Ym'].get_entities(0) # deformation u1, phi = 0, 0 for ii in range(2): u1 += corrs['corrs_k%d' % ii]['u'] * macro['phi'][ii] phi += corrs['corrs_k%d' % ii]['r'] * macro['phi'][ii] for ii in range(dim): for jj in range(dim): kk = coor_to_sym(ii, jj, dim) phi += corrs['corrs_rs']['r_%d%d' % (ii, jj)]\ * nm.expand_dims(macro['strain'][Ym_map, kk], axis=1) u1 += corrs['corrs_rs']['u_%d%d' % (ii, jj)]\ * nm.expand_dims(macro['strain'][Ymc_map, kk], axis=1) u = macro['u'][Ymc_map, :] + eps0 * u1 mvar = pb.create_variables(['u', 'r', 'svar']) e_mac_Ymc = [None] * macro['strain'].shape[1] for ii in range(dim): for jj in range(dim): kk = coor_to_sym(ii, jj, dim) mvar['svar'].set_data(macro['strain'][:, kk]) mac_e_Ymc = pb.evaluate('ev_integrate.i2.Ymc(svar)', mode='el_avg', var_dict={'svar': mvar['svar']}) e_mac_Ymc[kk] = mac_e_Ymc.squeeze() e_mac_Ymc = nm.vstack(e_mac_Ymc).T[:, nm.newaxis, :, nm.newaxis] mvar['r'].set_data(phi) E_mic = pb.evaluate( 'ev_grad.i2.Ym(r)', mode='el_avg', var_dict={'r': mvar['r']}) / eps0 mvar['u'].set_data(u1) e_mic = pb.evaluate('ev_cauchy_strain.i2.Ymc(u)', mode='el_avg', var_dict={'u': mvar['u']}) e_mic += e_mac_Ymc out = { 'u0': (macro['u'][Ymc_map, :], 'u', 'p'), 'u': (u, 'u', 'p'), 'u1': (u1, 'u', 'p'), 'e_mic': (e_mic, 'u', 'c'), 'phi': (phi, 'r', 'p'), 'E_mic': (E_mic, 'r', 'c'), } out_struct = {} for k, v in out.items(): out_struct[k] = Struct(name='output_data', mode='cell' if v[2] == 'c' else 'vertex', data=v[0], var_name=v[1], dofs=None) return out_struct
def recovery_micro(pb, corrs, macro): eps0 = macro['eps0'] mesh = pb.domain.mesh regions = pb.domain.regions dim = mesh.dim Ymc_map = regions['Ymc'].get_entities(0) Ym_map = regions['Ym'].get_entities(0) # deformation u1, phi = 0, 0 for ii in range(2): u1 += corrs['corrs_k%d' % ii]['u'] * macro['phi'][ii] phi += corrs['corrs_k%d' % ii]['r'] * macro['phi'][ii] for ii in range(dim): for jj in range(dim): kk = coor_to_sym(ii, jj, dim) phi += corrs['corrs_rs']['r_%d%d' % (ii, jj)]\ * nm.expand_dims(macro['strain'][Ym_map, kk], axis=1) u1 += corrs['corrs_rs']['u_%d%d' % (ii, jj)]\ * nm.expand_dims(macro['strain'][Ymc_map, kk], axis=1) u = macro['u'][Ymc_map, :] + eps0 * u1 mvar = pb.create_variables(['u', 'r', 'svar']) e_mac_Ymc = [None] * macro['strain'].shape[1] for ii in range(dim): for jj in range(dim): kk = coor_to_sym(ii, jj, dim) mvar['svar'].set_data(macro['strain'][:, kk]) mac_e_Ymc = pb.evaluate('ev_volume_integrate.i2.Ymc(svar)', mode='el_avg', var_dict={'svar': mvar['svar']}) e_mac_Ymc[kk] = mac_e_Ymc.squeeze() e_mac_Ymc = nm.vstack(e_mac_Ymc).T[:, nm.newaxis, :, nm.newaxis] mvar['r'].set_data(phi) E_mic = pb.evaluate('ev_grad.i2.Ym(r)', mode='el_avg', var_dict={'r': mvar['r']}) / eps0 mvar['u'].set_data(u1) e_mic = pb.evaluate('ev_cauchy_strain.i2.Ymc(u)', mode='el_avg', var_dict={'u': mvar['u']}) e_mic += e_mac_Ymc out = { 'u0': (macro['u'][Ymc_map, :], 'u', 'p'), 'u': (u, 'u', 'p'), 'u1': (u1, 'u', 'p'), 'e_mic': (e_mic, 'u', 'c'), 'phi': (phi, 'r', 'p'), 'E_mic': (E_mic, 'r', 'c'), } out_struct = {} for k, v in out.items(): out_struct[k] = Struct(name='output_data', mode='cell' if v[2] == 'c' else 'vertex', data=v[0], var_name=v[1], dofs=None) return out_struct