def grad(X): if X.shape==(1,): shape=(X.dim,) else: shape=X.shape+(X.dim,) name='grad({0})'.format(X.name[:10]) gX=Tensor(name=name, shape=shape, N=X.N, Fourier=True, fft_form=X.fft_form) if X.Fourier: FX=X else: F=DFT(N=X.N, fft_form=X.fft_form) # TODO:change to X.fourier() FX=F(X) dim=len(X.N) freq=Grid.get_freq(X.N, X.Y, fft_form=X.fft_form) strfreq='xyz' coef=2*np.pi*1j val=np.empty((X.dim,)+X.shape+X.N_fft, dtype=np.complex) for ii in range(X.dim): mul_str='{0},...{1}->...{1}'.format(strfreq[ii], strfreq[:dim]) val[ii]=np.einsum(mul_str, coef*freq[ii], FX.val, dtype=np.complex) if X.shape==(1,): gX.val=np.squeeze(val) else: gX.val=np.moveaxis(val, 0, X.order) if not X.Fourier: iF=DFT(N=X.N, inverse=True, fft_form=gX.fft_form) gX=iF(gX) gX.name='grad({0})'.format(X.name[:10]) return gX
def scalar(N, Y, fft_form=fft_form_default): dim = np.size(N) N = np.array(N, dtype=np.int) xi = Grid.get_freq(N, Y, fft_form=fft_form) N_fft=tuple(xi[i].size for i in range(dim)) hGrad = np.zeros((dim,)+N_fft) # zero initialize for ind in itertools.product(*[range(n) for n in N_fft]): for i in range(dim): hGrad[i][ind] = xi[i][ind[i]] kok= np.einsum('i...,j...->ij...', hGrad, hGrad).real k2 = np.einsum('i...,i...', hGrad, hGrad).real ind_center=mean_index(N, fft_form=fft_form) k2[ind_center]=1. G0lval=np.zeros_like(kok) Ival=np.zeros_like(kok) for ii in range(dim): # diagonal components G0lval[ii, ii][ind_center] = 1 Ival[ii, ii] = 1 G1l=Tensor(name='G1', val=kok/k2, order=2, N=N, Y=Y, multype=21, Fourier=True, fft_form=fft_form) G0l=Tensor(name='G1', val=G0lval, order=2, N=N, Y=Y, multype=21, Fourier=True, fft_form=fft_form) I = Tensor(name='I', val=Ival, order=2, N=N, Y=Y, multype=21, Fourier=True, fft_form=fft_form) G2l=I-G1l-G0l return G0l, G1l, G2l
def div(X): if X.shape==(1,): shape=() else: shape=X.shape[:-1] assert(X.shape[-1]==X.dim) assert(X.order==1) dX=Tensor(shape=shape, N=X.N, Fourier=True, fft_form=X.fft_form) if X.Fourier: FX=X else: F=DFT(N=X.N, fft_form=X.fft_form) FX=F(X) dim=len(X.N) freq=Grid.get_freq(X.N, X.Y, fft_form=FX.fft_form) strfreq='xyz' coef=2*np.pi*1j for ii in range(X.dim): mul_str='{0},...{1}->...{1}'.format(strfreq[ii], strfreq[:dim]) dX.val+=np.einsum(mul_str, coef*freq[ii], FX.val[ii], dtype=np.complex) if not X.Fourier: iF=DFT(N=X.N, inverse=True, fft_form=dX.fft_form) dX=iF(dX) dX.name='div({0})'.format(X.name[:10]) return dX
def div(X): if X.shape == (1, ): shape = () else: shape = X.shape[:-1] assert (X.shape[-1] == X.dim) assert (X.order == 1) dX = Tensor(shape=shape, N=X.N, Fourier=True, fft_form=X.fft_form) if X.Fourier: FX = X else: F = DFT(N=X.N, fft_form=X.fft_form) FX = F(X) dim = len(X.N) freq = Grid.get_freq(X.N, X.Y, fft_form=FX.fft_form) strfreq = 'xyz' coef = 2 * np.pi * 1j for ii in range(X.dim): mul_str = '{0},...{1}->...{1}'.format(strfreq[ii], strfreq[:dim]) dX.val += np.einsum(mul_str, coef * freq[ii], FX.val[ii], dtype=np.complex) if not X.Fourier: iF = DFT(N=X.N, inverse=True, fft_form=dX.fft_form) dX = iF(dX) dX.name = 'div({0})'.format(X.name[:10]) return dX
def scalar(N, Y, fft_form=fft_form_default): dim = np.size(N) N = np.array(N, dtype=np.int) xi = Grid.get_freq(N, Y, fft_form=fft_form) N_fft=tuple(xi[i].size for i in range(dim)) hGrad = np.zeros((dim,)+N_fft) # zero initialize for ind in itertools.product(*[list(range(n)) for n in N_fft]): for i in range(dim): hGrad[i][ind] = xi[i][ind[i]] kok= np.einsum('i...,j...->ij...', hGrad, hGrad).real k2 = np.einsum('i...,i...', hGrad, hGrad).real ind_center=mean_index(N, fft_form=fft_form) k2[ind_center]=1. G0lval=np.zeros_like(kok) Ival=np.zeros_like(kok) for ii in range(dim): # diagonal components G0lval[ii, ii][ind_center] = 1 Ival[ii, ii] = 1 G1l=Tensor(name='G1', val=kok/k2, order=2, N=N, Y=Y, multype=21, Fourier=True, fft_form=fft_form) G0l=Tensor(name='G1', val=G0lval, order=2, N=N, Y=Y, multype=21, Fourier=True, fft_form=fft_form) I = Tensor(name='I', val=Ival, order=2, N=N, Y=Y, multype=21, Fourier=True, fft_form=fft_form) G2l=I-G1l-G0l return G0l, G1l, G2l
def grad(X): if X.shape==(1,): shape=(X.dim,) else: shape=X.shape+(X.dim,) name='grad({0})'.format(X.name[:10]) gX=Tensor(name=name, shape=shape, N=X.N, Fourier=True, fft_form=X.fft_form) if X.Fourier: FX=X else: F=DFT(N=X.N, fft_form=X.fft_form) # TODO:change to X.fourier() FX=F(X) dim=len(X.N) freq=Grid.get_freq(X.N, X.Y, fft_form=X.fft_form) strfreq='xyz' coef=2*np.pi*1j val=np.empty((X.dim,)+X.shape+X.N_fft, dtype=np.complex) for ii in range(X.dim): mul_str='{0},...{1}->...{1}'.format(strfreq[ii], strfreq[:dim]) val[ii]=np.einsum(mul_str, coef*freq[ii], FX.val, dtype=np.complex) if X.shape==(1,): gX.val=np.squeeze(val) else: gX.val=np.moveaxis(val, 0, X.order) if not X.Fourier: iF=DFT(N=X.N, inverse=True, fft_form=gX.fft_form) gX=iF(gX) gX.name='grad({0})'.format(X.name[:10]) return gX
def potential(X, small_strain=False): if X.Fourier: FX = X else: F = DFT(N=X.N, fft_form=X.fft_form) FX = F(X) freq = Grid.get_freq(X.N, X.Y, fft_form=FX.fft_form) if X.order == 1: assert (X.dim == X.shape[0]) iX = Tensor(name='potential({0})'.format(X.name[:10]), shape=(1, ), N=X.N, Fourier=True, fft_form=FX.fft_form) iX.val[0] = potential_scalar(FX.val, freq=freq, mean_index=FX.mean_index()) elif X.order == 2: assert (X.dim == X.shape[0]) assert (X.dim == X.shape[1]) iX = Tensor(name='potential({0})'.format(X.name[:10]), shape=(X.dim, ), N=X.N, Fourier=True, fft_form=FX.fft_form) if not small_strain: for ii in range(X.dim): iX.val[ii] = potential_scalar(FX.val[ii], freq=freq, mean_index=FX.mean_index()) else: assert ((X - X.transpose()).norm() < 1e-14) # symmetricity omeg = FX.zeros_like() # non-symmetric part of the gradient gomeg = Tensor(name='potential({0})'.format(X.name[:10]), shape=FX.shape + (X.dim, ), N=X.N, Fourier=True) grad_ep = grad(FX) # gradient of strain gomeg.val = np.einsum('ikj...->ijk...', grad_ep.val) - np.einsum( 'jki...->ijk...', grad_ep.val) for ij in itertools.product(list(range(X.dim)), repeat=2): omeg.val[ij] = potential_scalar(gomeg.val[ij], freq=freq, mean_index=FX.mean_index()) gradu = FX + omeg iX = potential(gradu, small_strain=False) if X.Fourier: return iX else: iF = DFT(N=X.N, inverse=True, fft_form=FX.fft_form) return iF(iX)
def elasticity_large_deformation(N, Y, fft_form=fft_form_default): N = np.array(N, dtype=np.int) dim = N.size assert(dim==3) freq = Grid.get_freq(N, Y, fft_form=fft_form) N_fft=tuple(freq[i].size for i in range(dim)) Ghat = np.zeros(np.hstack([dim*np.ones(4, dtype=np.int), N_fft])) delta = lambda i,j: np.float(i==j) for i, j, k, l in itertools.product(range(dim), repeat=4): for x, y, z in np.ndindex(*N_fft): q = np.array([freq[0][x], freq[1][y], freq[2][z]]) if not q.dot(q) == 0: Ghat[i,j,k,l,x,y,z] = delta(i,k)*q[j]*q[l] / (q.dot(q)) Ghat_tensor = Tensor(name='Ghat', val=Ghat, order=4, N=N, multype=42, Fourier=True, fft_form=fft_form) return Ghat_tensor
def elasticity_large_deformation(N, Y, fft_form=fft_form_default): N = np.array(N, dtype=np.int) dim = N.size assert(dim==3) freq = Grid.get_freq(N, Y, fft_form=fft_form) N_fft=tuple(freq[i].size for i in range(dim)) Ghat = np.zeros(np.hstack([dim*np.ones(4, dtype=np.int), N_fft])) delta = lambda i,j: np.float(i==j) for i, j, k, l in itertools.product(list(range(dim)), repeat=4): for x, y, z in np.ndindex(*N_fft): q = np.array([freq[0][x], freq[1][y], freq[2][z]]) if not q.dot(q) == 0: Ghat[i,j,k,l,x,y,z] = delta(i,k)*q[j]*q[l] / (q.dot(q)) Ghat_tensor = Tensor(name='Ghat', val=Ghat, order=4, N=N, multype=42, Fourier=True, fft_form=fft_form) return Ghat_tensor
def potential(X, small_strain=False): if X.Fourier: FX=X else: F=DFT(N=X.N, fft_form=X.fft_form) FX=F(X) freq=Grid.get_freq(X.N, X.Y, fft_form=FX.fft_form) if X.order==1: assert(X.dim==X.shape[0]) iX=Tensor(name='potential({0})'.format(X.name[:10]), shape=(1,), N=X.N, Fourier=True, fft_form=FX.fft_form) iX.val[0]=potential_scalar(FX.val, freq=freq, mean_index=FX.mean_index()) elif X.order==2: assert(X.dim==X.shape[0]) assert(X.dim==X.shape[1]) iX=Tensor(name='potential({0})'.format(X.name[:10]), shape=(X.dim,), N=X.N, Fourier=True, fft_form=FX.fft_form) if not small_strain: for ii in range(X.dim): iX.val[ii]=potential_scalar(FX.val[ii], freq=freq, mean_index=FX.mean_index()) else: assert((X-X.transpose()).norm()<1e-14) # symmetricity omeg=FX.zeros_like() # non-symmetric part of the gradient gomeg=Tensor(name='potential({0})'.format(X.name[:10]), shape=FX.shape+(X.dim,), N=X.N, Fourier=True) grad_ep=grad(FX) # gradient of strain gomeg.val=np.einsum('ikj...->ijk...', grad_ep.val)-np.einsum('jki...->ijk...', grad_ep.val) for ij in itertools.product(range(X.dim), repeat=2): omeg.val[ij]=potential_scalar(gomeg.val[ij], freq=freq, mean_index=FX.mean_index()) gradu=FX+omeg iX=potential(gradu, small_strain=False) if X.Fourier: return iX else: iF=DFT(N=X.N, inverse=True, fft_form=FX.fft_form) return iF(iX)