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 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(Aga, pars): Nbar = Aga.N N = np.array((np.array(Nbar) + 1) / 2, dtype=np.int) dim = Nbar.__len__() Y = np.ones(dim) _, Ghat, _ = proj.scalar(N, Y) Ghat2 = Ghat.enlarge(Nbar) F2 = DFT(name='FN', inverse=False, N=Nbar) # discrete Fourier transform (DFT) iF2 = DFT(name='FiN', inverse=True, N=Nbar) # inverse DFT G1N = Operator(name='G1', mat=[[iF2, Ghat2, F2]]) # projection in original space PAfun = Operator(name='FiGFA', mat=[[G1N, Aga]]) # lin. operator for a linear system 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) x0 = Tensor(N=Nbar, shape=(dim, ), Fourier=False) # initial approximation to solvers B = PAfun(-EN) # right-hand side of linear system tic = Timer(name='CG (gradient field)') X, info = linear_solver(solver='CG', Afun=PAfun, B=B, x0=x0, par=pars.solver, callback=None) tic.measure() AH = Aga(X + EN) * (X + EN) return Struct(AH=AH, X=X, time=tic.vals[0][0], pars=pars)
epN_new2 = epN - alp * FiN(hG1(FN(A(epN)))) print(""" Then the resulting vectors are compared to show they are the same: (epN_new == epN_new2) = """) print(epN_new == epN_new2) print("""============================== Now, we show a solution of homogenization problem for material defined in problem 'pb' and particular choice of macroscopic value E =""") # macroscopic load in Mandel's notation E = np.zeros(D) E[0] = 1 EN = Tensor(name='EN', N=N, shape=(D, ), Fourier=False) EN.set_mean(E) print(EN) # definition of reference media according to Moulinec-Suquet Km = K.mean() Gm = G.mean() a = 1 / (Km + 4. / 3 * Gm) b = 1. / (2 * Gm) # linear combination of projections corresponding to Moulinec-Suquet scheme G1N_MS = Operator(name='G1', mat=[[FiN, a * hG1hN + b * hG1sN, FN]]) # linear system with scaled projection Afun_MS = Operator(name='FiGFA', mat=[[G1N_MS, A]]) # linear system with orthogonal projection Afun = Operator(name='FiGFA', mat=[[G1N, A]])
def elasticity(problem): """ Homogenization of linear elasticity. Parameters ---------- problem : object """ print(' ') pb = problem print(pb) # Fourier projections _, hG1hN, hG1sN, hG2hN, hG2sN = proj.elasticity(pb.solve['N'], pb.Y, NyqNul=True) del _ if pb.solve['kind'] is 'GaNi': Nbar = pb.solve['N'] elif pb.solve['kind'] is 'Ga': Nbar = 2*pb.solve['N'] - 1 hG1hN = hG1hN.enlarge(Nbar) hG1sN = hG1sN.enlarge(Nbar) hG2hN = hG2hN.enlarge(Nbar) hG2sN = hG2sN.enlarge(Nbar) FN = DFT(name='FN', inverse=False, N=Nbar) FiN = DFT(name='FiN', inverse=True, N=Nbar) G1N = Operator(name='G1', mat=[[FiN, hG1hN + hG1sN, FN]]) G2N = Operator(name='G2', mat=[[FiN, hG2hN + hG2sN, FN]]) for primaldual in pb.solve['primaldual']: tim = Timer(name='primal-dual') print('\nproblem: ' + primaldual) solutions = np.zeros(pb.shape).tolist() results = np.zeros(pb.shape).tolist() # material coefficients mat = Material(pb.material) if pb.solve['kind'] is 'GaNi': A = mat.get_A_GaNi(pb.solve['N'], primaldual) elif pb.solve['kind'] is 'Ga': A = mat.get_A_Ga(Nbar=Nbar, primaldual=primaldual) if primaldual is 'primal': GN = G1N else: GN = G2N Afun = Operator(name='FiGFA', mat=[[GN, A]]) D = int(pb.dim*(pb.dim+1)/2) for iL in range(D): # iteration over unitary loads E = np.zeros(D) E[iL] = 1 print('macroscopic load E = ' + str(E)) EN = Tensor(name='EN', N=Nbar, shape=(D,), Fourier=False) EN.set_mean(E) # initial approximation for solvers x0 = EN.zeros_like(name='x0') B = Afun(-EN) # RHS if not hasattr(pb.solver, 'callback'): cb = CallBack(A=Afun, B=B) elif pb.solver['callback'] == 'detailed': cb = CallBack_GA(A=Afun, B=B, EN=EN, A_Ga=A, GN=GN) else: raise NotImplementedError("The solver callback (%s) is not \ implemented" % (pb.solver['callback'])) print('solver : %s' % pb.solver['kind']) X, info = linear_solver(solver=pb.solver['kind'], Afun=Afun, B=B, x0=x0, par=pb.solver, callback=cb) solutions[iL] = add_macro2minimizer(X, E) results[iL] = {'cb': cb, 'info': info} print(cb) tim.measure() # POSTPROCESSING del Afun, B, E, EN, GN, X postprocess(pb, A, mat, solutions, results, primaldual)
def elasticity(problem): """ Homogenization of linear elasticity. Parameters ---------- problem : object """ print(' ') pb = problem print(pb) # Fourier projections _, hG1hN, hG1sN, hG2hN, hG2sN = proj.elasticity(pb.solve['N'], pb.Y, NyqNul=True) del _ if pb.solve['kind'] is 'GaNi': Nbar = pb.solve['N'] elif pb.solve['kind'] is 'Ga': Nbar = 2 * pb.solve['N'] - 1 hG1hN = hG1hN.enlarge(Nbar) hG1sN = hG1sN.enlarge(Nbar) hG2hN = hG2hN.enlarge(Nbar) hG2sN = hG2sN.enlarge(Nbar) FN = DFT(name='FN', inverse=False, N=Nbar) FiN = DFT(name='FiN', inverse=True, N=Nbar) G1N = Operator(name='G1', mat=[[FiN, hG1hN + hG1sN, FN]]) G2N = Operator(name='G2', mat=[[FiN, hG2hN + hG2sN, FN]]) for primaldual in pb.solve['primaldual']: tim = Timer(name='primal-dual') print(('\nproblem: ' + primaldual)) solutions = np.zeros(pb.shape).tolist() results = np.zeros(pb.shape).tolist() # material coefficients mat = Material(pb.material) if pb.solve['kind'] is 'GaNi': A = mat.get_A_GaNi(pb.solve['N'], primaldual) elif pb.solve['kind'] is 'Ga': A = mat.get_A_Ga(Nbar=Nbar, primaldual=primaldual) if primaldual is 'primal': GN = G1N else: GN = G2N Afun = Operator(name='FiGFA', mat=[[GN, A]]) D = int(pb.dim * (pb.dim + 1) / 2) for iL in range(D): # iteration over unitary loads E = np.zeros(D) E[iL] = 1 print(('macroscopic load E = ' + str(E))) EN = Tensor(name='EN', N=Nbar, shape=(D, ), Fourier=False) EN.set_mean(E) # initial approximation for solvers x0 = EN.zeros_like(name='x0') B = Afun(-EN) # RHS if not hasattr(pb.solver, 'callback'): cb = CallBack(A=Afun, B=B) elif pb.solver['callback'] == 'detailed': cb = CallBack_GA(A=Afun, B=B, EN=EN, A_Ga=A, GN=GN) else: raise NotImplementedError("The solver callback (%s) is not \ implemented" % (pb.solver['callback'])) print(('solver : %s' % pb.solver['kind'])) X, info = linear_solver(solver=pb.solver['kind'], Afun=Afun, B=B, x0=x0, par=pb.solver, callback=cb) solutions[iL] = add_macro2minimizer(X, E) results[iL] = {'cb': cb, 'info': info} print(cb) tim.measure() # POSTPROCESSING del Afun, B, E, EN, GN, X postprocess(pb, A, mat, solutions, results, primaldual)
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_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')
# projections in Fourier space _, hG1N, _ = proj.scalar(pb['solve']['N'], pb['material']['Y'], NyqNul=True, tensor=True) # increasing the projection with zeros to comply with a projection # on double grid, see Definition 24 in IJNME2016 hG1N = hG1N.enlarge(Nbar) FN = DFT(name='FN', inverse=False, N=Nbar) # discrete Fourier transform (DFT) FiN = DFT(name='FiN', inverse=True, N=Nbar) # inverse DFT G1N = Operator(name='G1', mat=[[FiN, hG1N, FN]]) # projection in original space Afun = Operator(name='FiGFA', mat=[[G1N, A]]) # lin. operator for a linear system 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) x0 = Tensor(N=Nbar, shape=(dim,), Fourier=False) # initial approximation to solvers B = Afun(-EN) # right-hand side of linear system X, info = linear_solver(solver='CG', Afun=Afun, B=B, x0=x0, par=pb['solver'], callback=None) print('homogenised properties (component 11) =', A(X + EN)*(X + EN)) if __name__ == "__main__": ## plotting of local fields ################## X.plot(ind=0, N=N) print('END')