def homog_GaNi_full_potential(Agani, Aga, pars): N = Agani.N # double grid number dim = N.__len__() F = DFT(name='FN', inverse=False, N=N) # discrete Fourier transform (DFT) iF = DFT(name='FiN', inverse=True, N=N) # inverse DFT P = get_preconditioner(N, pars) E = np.zeros(dim) E[0] = 1 # macroscopic load EN = Tensor(name='EN', N=N, shape=(dim, ), Fourier=False) # constant trig. pol. EN.set_mean(E) def DFAFGfun(X): assert (X.Fourier) FAX = F(Agani * iF(grad(X))) return -div(FAX) B = div(F(Agani(EN))) x0 = Tensor(N=N, shape=(), Fourier=True) # initial approximation to solvers PDFAFGPfun = lambda Fx: P * DFAFGfun(P * Fx) PB = P * B tic = Timer(name='CG (potential)') iPU, info = linear_solver(solver='CG', Afun=PDFAFGPfun, B=PB, x0=x0, par=pars.solver, callback=None) tic.measure() print(('iterations of CG={}'.format(info['kit']))) print(('norm of residuum={}'.format(info['norm_res']))) Fu = P * iPU if Aga is None: # GaNi homogenised properties print('!!!!! homogenised properties are GaNi only !!!!!') XEN = iF(grad(Fu)) + EN AH = Agani(XEN) * XEN else: Nbar = 2 * np.array(N) - 1 iF2 = DFT(name='FiN', inverse=True, N=Nbar) # inverse DFT XEN = iF2(grad(Fu).project(Nbar)) + EN.project(Nbar) AH = Aga(XEN) * XEN return Struct(AH=AH, Fu=Fu, info=info, time=tic.vals[0][0], pars=pars)
def homog_Ga_full_potential(Aga, pars): Nbar = Aga.N # double grid number N = np.array((np.array(Nbar) + 1) / 2, dtype=np.int) dim = Nbar.__len__() F2 = DFT(name='FN', inverse=False, N=Nbar) # discrete Fourier transform (DFT) iF2 = DFT(name='FiN', inverse=True, N=Nbar) # inverse DFT P = get_preconditioner(N, pars) E = np.zeros(dim) E[0] = 1 # macroscopic load EN = Tensor(name='EN', N=Nbar, shape=(dim, ), Fourier=False) # constant trig. pol. EN.set_mean(E) def DFAFGfun(X): assert (X.Fourier) FAX = F2(Aga * iF2(grad(X).enlarge(Nbar))) FAX = FAX.project(N) return -div(FAX) B = div(F2(Aga(EN)).decrease(N)) x0 = Tensor(N=N, shape=(), Fourier=True) # initial approximation to solvers PDFAFGPfun = lambda Fx: P * DFAFGfun(P * Fx) PB = P * B tic = Timer(name='CG (potential)') iPU, info = linear_solver(solver='CG', Afun=PDFAFGPfun, B=PB, x0=x0, par=pars.solver, callback=None) tic.measure() print(('iterations of CG={}'.format(info['kit']))) print(('norm of residuum={}'.format(info['norm_res']))) R = PB - PDFAFGPfun(iPU) print(('norm of residuum={} (from definition)'.format(R.norm()))) Fu = P * iPU X = iF2(grad(Fu).project(Nbar)) AH = Aga(X + EN) * (X + EN) return Struct(AH=AH, e=X, Fu=Fu, info=info, time=tic.vals[0][0])
def test_operators(self): print('\nChecking operators...') for dim, fft_form in itertools.product([2, 3], fft_forms): N = 5 * np.ones(dim, dtype=np.int) F = DFT(N=N, inverse=False, fft_form=fft_form) iF = DFT(N=N, inverse=True, fft_form=fft_form) # Fourier transform prt.disable() print(F) # checking representation prt.enable() u = Tensor(name='u', shape=(), N=N, Fourier=False, fft_form=fft_form).randomize() Fu = F(u) u2 = iF(Fu) self.assertAlmostEqual(0, (u == u2)[1], delta=1e-13, msg='Fourier transform') fft_formsC = copy(fft_forms) fft_formsC.remove(fft_form) for fft_formc in fft_formsC: FuC = Fu.set_fft_form(fft_formc, copy=True) Fu2 = FuC.set_fft_form(fft_form, copy=True) msg = 'Tensor.set_fft_form()' self.assertAlmostEqual(0, Fu.norm() - FuC.norm(), delta=1e-13, msg=msg) self.assertAlmostEqual(0, norm(Fu.mean() - FuC.mean()), delta=1e-13, msg=msg) self.assertAlmostEqual(0, (Fu == Fu2)[1], delta=1e-13, msg=msg) # scalar problem u = Tensor(name='u', shape=(1, ), N=N, Fourier=False, fft_form=fft_form).randomize() u.val -= np.mean(u.val) Fu = F(u) Fu2 = potential(grad(Fu)) self.assertAlmostEqual(0, (Fu == Fu2)[1], delta=1e-13, msg='scalar problem, Fourier=True') u2 = potential(grad(u)) self.assertAlmostEqual(0, (u == u2)[1], delta=1e-13, msg='scalar problem, Fourier=False') hG, hD = grad_div_tensor(N, fft_form=fft_form) self.assertAlmostEqual(0, (hD(hG(Fu)) == div(grad(Fu)))[1], delta=1e-13, msg='scalar problem, Fourier=True') # vectorial problem u = Tensor(name='u', shape=(dim, ), N=N, Fourier=False, fft_form=fft_form) u.randomize() u.add_mean(-u.mean()) Fu = F(u) Fu2 = potential(grad(Fu)) self.assertAlmostEqual(0, (Fu == Fu2)[1], delta=1e-13, msg='vectorial problem, Fourier=True') u2 = potential(grad(u)) self.assertAlmostEqual(0, (u == u2)[1], delta=1e-13, msg='vectorial problem, Fourier=False') # 'vectorial problem - symetric gradient Fu2 = potential(symgrad(Fu), small_strain=True) self.assertAlmostEqual(0, (Fu == Fu2)[1], delta=1e-13, msg='vectorial - sym, Fourier=True') u2 = potential(symgrad(u), small_strain=True) self.assertAlmostEqual(0, (u == u2)[1], delta=1e-13, msg='vectorial - sym, Fourier=False') # matrix version of DFT u = Tensor(name='u', shape=(1, ), N=N, Fourier=False, fft_form='c').randomize() F = DFT(N=N, inverse=False, fft_form='c') Fu = F(u) dft = F.matrix(shape=u.shape) Fu2 = dft.dot(u.val.ravel()) self.assertAlmostEqual(0, norm(Fu.val.ravel() - Fu2), delta=1e-13) print('...ok')
def test_compatibility(self): print('\nChecking compatibility...') for dim, fft_form in itertools.product([3], fft_forms): N = 5 * np.ones(dim, dtype=np.int) F = DFT(inverse=False, N=N, fft_form=fft_form) iF = DFT(inverse=True, N=N, fft_form=fft_form) # scalar problem _, G1l, G2l = scalar(N, Y=np.ones(dim), fft_form=fft_form) P1 = Operator(name='P1', mat=[[iF, G1l, F]]) P2 = Operator(name='P2', mat=[[iF, G2l, F]]) u = Tensor(name='u', shape=(1, ), N=N, Fourier=False, fft_form=fft_form) u.randomize() grad_u = grad(u) self.assertAlmostEqual(0, (P1(grad_u) - grad_u).norm(), delta=1e-13) self.assertAlmostEqual(0, P2(grad_u).norm(), delta=1e-13) e = P1( Tensor(name='u', shape=(dim, ), N=N, Fourier=False, fft_form=fft_form).randomize()) e2 = grad(potential(e)) self.assertAlmostEqual(0, (e - e2).norm(), delta=1e-13) # vectorial problem hG = elasticity_large_deformation(N=N, Y=np.ones(dim), fft_form=fft_form) P1 = Operator(name='P', mat=[[iF, hG, F]]) u = Tensor(name='u', shape=(dim, ), N=N, Fourier=False, fft_form=fft_form) u.randomize() grad_u = grad(u) val = (P1(grad_u) - grad_u).norm() self.assertAlmostEqual(0, val, delta=1e-13) e = Tensor(name='F', shape=(dim, dim), N=N, Fourier=False, fft_form=fft_form) e = P1(e.randomize()) e2 = grad(potential(e)) self.assertAlmostEqual(0, (e - e2).norm(), delta=1e-13) # transpose P1TT = P1.transpose().transpose() self.assertTrue(P1(grad_u) == P1TT(grad_u)) self.assertTrue(hG == (hG.transpose_left().transpose_left())) self.assertTrue(hG == (hG.transpose_right().transpose_right())) # vectorial problem - symetric gradient hG = elasticity_small_strain(N=N, Y=np.ones(dim), fft_form=fft_form) P1 = Operator(name='P', mat=[[iF, hG, F]]) u = Tensor(name='u', shape=(dim, ), N=N, Fourier=False, fft_form=fft_form) u.randomize() grad_u = symgrad(u) val = (P1(grad_u) - grad_u).norm() self.assertAlmostEqual(0, val, delta=1e-13) e = Tensor(name='strain', shape=(dim, dim), N=N, Fourier=False, fft_form=fft_form) e = P1(e.randomize()) e2 = symgrad(potential(e, small_strain=True)) self.assertAlmostEqual(0, (e - e2).norm(), delta=1e-13) # means Fu = F(u) E = np.random.random(u.shape) u.set_mean(E) self.assertAlmostEqual(0, norm(u.mean() - E), delta=1e-13) Fu.set_mean(E) self.assertAlmostEqual(0, norm(Fu.mean() - E), delta=1e-13) # __repr__ prt.disable() print(P1) print(u) prt.enable() self.assertAlmostEqual(0, (P1 == P1.transpose()), delta=1e-13) print('...ok')
def test_operators(self): print('\nChecking operators...') for dim, fft_form in itertools.product([2, 3], fft_forms): N=5*np.ones(dim, dtype=np.int) F=DFT(N=N, inverse=False, fft_form=fft_form) iF=DFT(N=N, inverse=True, fft_form=fft_form) # Fourier transform prt.disable() print(F) # checking representation prt.enable() u=Tensor(name='u', shape=(), N=N, Fourier=False, fft_form=fft_form).randomize() Fu=F(u) u2=iF(Fu) self.assertAlmostEqual(0, (u==u2)[1], delta=1e-13, msg='Fourier transform') fft_formsC=copy(fft_forms) fft_formsC.remove(fft_form) for fft_formc in fft_formsC: FuC=Fu.set_fft_form(fft_formc, copy=True) Fu2=FuC.set_fft_form(fft_form, copy=True) msg='Tensor.set_fft_form()' self.assertAlmostEqual(0, Fu.norm()-FuC.norm(), delta=1e-13, msg=msg) self.assertAlmostEqual(0, norm(Fu.mean()-FuC.mean()), delta=1e-13, msg=msg) self.assertAlmostEqual(0, (Fu==Fu2)[1], delta=1e-13, msg=msg) # scalar problem u=Tensor(name='u', shape=(1,), N=N, Fourier=False, fft_form=fft_form).randomize() u.val-=np.mean(u.val) Fu=F(u) Fu2=potential(grad(Fu)) self.assertAlmostEqual(0, (Fu==Fu2)[1], delta=1e-13, msg='scalar problem, Fourier=True') u2=potential(grad(u)) self.assertAlmostEqual(0, (u==u2)[1], delta=1e-13, msg='scalar problem, Fourier=False') hG, hD=grad_div_tensor(N, fft_form=fft_form) self.assertAlmostEqual(0, (hD(hG(Fu))==div(grad(Fu)))[1], delta=1e-13, msg='scalar problem, Fourier=True') # vectorial problem u=Tensor(name='u', shape=(dim,), N=N, Fourier=False, fft_form=fft_form) u.randomize() u.add_mean(-u.mean()) Fu=F(u) Fu2=potential(grad(Fu)) self.assertAlmostEqual(0, (Fu==Fu2)[1], delta=1e-13, msg='vectorial problem, Fourier=True') u2=potential(grad(u)) self.assertAlmostEqual(0, (u==u2)[1], delta=1e-13, msg='vectorial problem, Fourier=False') # 'vectorial problem - symetric gradient Fu2=potential(symgrad(Fu), small_strain=True) self.assertAlmostEqual(0, (Fu==Fu2)[1], delta=1e-13, msg='vectorial - sym, Fourier=True') u2=potential(symgrad(u), small_strain=True) self.assertAlmostEqual(0, (u==u2)[1], delta=1e-13, msg='vectorial - sym, Fourier=False') # matrix version of DFT u=Tensor(name='u', shape=(1,), N=N, Fourier=False, fft_form='c').randomize() F=DFT(N=N, inverse=False, fft_form='c') Fu=F(u) dft=F.matrix(shape=u.shape) Fu2=dft.dot(u.val.ravel()) self.assertAlmostEqual(0, norm(Fu.val.ravel()-Fu2), delta=1e-13) print('...ok')
def test_compatibility(self): print('\nChecking compatibility...') for dim, fft_form in itertools.product([3], fft_forms): N=5*np.ones(dim, dtype=np.int) F=DFT(inverse=False, N=N, fft_form=fft_form) iF=DFT(inverse=True, N=N, fft_form=fft_form) # scalar problem _, G1l, G2l=scalar(N, Y=np.ones(dim), fft_form=fft_form) P1=Operator(name='P1', mat=[[iF, G1l, F]]) P2=Operator(name='P2', mat=[[iF, G2l, F]]) u=Tensor(name='u', shape=(1,), N=N, Fourier=False, fft_form=fft_form) u.randomize() grad_u=grad(u) self.assertAlmostEqual(0, (P1(grad_u)-grad_u).norm(), delta=1e-13) self.assertAlmostEqual(0, P2(grad_u).norm(), delta=1e-13) e=P1(Tensor(name='u', shape=(dim,), N=N, Fourier=False, fft_form=fft_form).randomize()) e2=grad(potential(e)) self.assertAlmostEqual(0, (e-e2).norm(), delta=1e-13) # vectorial problem hG=elasticity_large_deformation(N=N, Y=np.ones(dim), fft_form=fft_form) P1=Operator(name='P', mat=[[iF, hG, F]]) u=Tensor(name='u', shape=(dim,), N=N, Fourier=False, fft_form=fft_form) u.randomize() grad_u=grad(u) val=(P1(grad_u)-grad_u).norm() self.assertAlmostEqual(0, val, delta=1e-13) e=Tensor(name='F', shape=(dim, dim), N=N, Fourier=False, fft_form=fft_form) e=P1(e.randomize()) e2=grad(potential(e)) self.assertAlmostEqual(0, (e-e2).norm(), delta=1e-13) # transpose P1TT=P1.transpose().transpose() self.assertTrue(P1(grad_u)==P1TT(grad_u)) self.assertTrue(hG==(hG.transpose_left().transpose_left())) self.assertTrue(hG==(hG.transpose_right().transpose_right())) # vectorial problem - symetric gradient hG=elasticity_small_strain(N=N, Y=np.ones(dim), fft_form=fft_form) P1=Operator(name='P', mat=[[iF, hG, F]]) u=Tensor(name='u', shape=(dim,), N=N, Fourier=False, fft_form=fft_form) u.randomize() grad_u=symgrad(u) val=(P1(grad_u)-grad_u).norm() self.assertAlmostEqual(0, val, delta=1e-13) e=Tensor(name='strain', shape=(dim, dim), N=N, Fourier=False, fft_form=fft_form) e=P1(e.randomize()) e2=symgrad(potential(e, small_strain=True)) self.assertAlmostEqual(0, (e-e2).norm(), delta=1e-13) # means Fu=F(u) E=np.random.random(u.shape) u.set_mean(E) self.assertAlmostEqual(0, norm(u.mean()-E), delta=1e-13) Fu.set_mean(E) self.assertAlmostEqual(0, norm(Fu.mean()-E), delta=1e-13) # __repr__ prt.disable() print(P1) print(u) prt.enable() self.assertAlmostEqual(0, (P1==P1.transpose()), delta=1e-13) print('...ok')
def DFAFGfun(X): assert (X.Fourier) FAX = F2(Aga * iF2(grad(X).enlarge(Nbar))) FAX = FAX.project(N) return -div(FAX)
def DFAFGfun(X): assert (X.Fourier) FAX = F(Agani * iF(grad(X))) return -div(FAX)