def u_exact(self,t): """ Routine to compute the exact solution at time t Args: t: current time Returns: exact solution """ w = df.Expression('r*(1-pow(tanh(r*((0.75-4) - x[1])),2)) + r*(1-pow(tanh(r*(x[1] - (0.25-4))),2)) - \ r*(1-pow(tanh(r*((0.75-3) - x[1])),2)) + r*(1-pow(tanh(r*(x[1] - (0.25-3))),2)) - \ r*(1-pow(tanh(r*((0.75-2) - x[1])),2)) + r*(1-pow(tanh(r*(x[1] - (0.25-2))),2)) - \ r*(1-pow(tanh(r*((0.75-1) - x[1])),2)) + r*(1-pow(tanh(r*(x[1] - (0.25-1))),2)) - \ r*(1-pow(tanh(r*((0.75-0) - x[1])),2)) + r*(1-pow(tanh(r*(x[1] - (0.25-0))),2)) - \ r*(1-pow(tanh(r*((0.75+1) - x[1])),2)) + r*(1-pow(tanh(r*(x[1] - (0.25+1))),2)) - \ r*(1-pow(tanh(r*((0.75+2) - x[1])),2)) + r*(1-pow(tanh(r*(x[1] - (0.25+2))),2)) - \ r*(1-pow(tanh(r*((0.75+3) - x[1])),2)) + r*(1-pow(tanh(r*(x[1] - (0.25+3))),2)) - \ r*(1-pow(tanh(r*((0.75+4) - x[1])),2)) + r*(1-pow(tanh(r*(x[1] - (0.25+4))),2)) - \ d*2*a*cos(2*a*(x[0]+0.25))',d=self.delta,r=self.rho,a=np.pi,degree=self.order) me = fenics_mesh(self.V) me.values = df.interpolate(w,self.V) # df.plot(me.values) # df.interactive() # exit() return me
def __invert_mass_matrix(self,u): """ Helper routine to invert mass matrix Args: u: current values Returns: inv(M)*u """ me = fenics_mesh(self.V) A = 1.0*self.M b = fenics_mesh(u) df.solve(A,me.values.vector(),b.values.vector()) return me
def solve_system(self,rhs,factor,u0,t): """ Dolfin's linear solver for (M-dtA)u = rhs Args: rhs: right-hand side for the nonlinear system factor: abbrev. for the node-to-node stepsize (or any other factor required) u0: initial guess for the iterative solver (not used here so far) Returns: solution as mesh """ A = self.M - factor*self.K b = fenics_mesh(rhs) u = fenics_mesh(u0) df.solve(A,u.values.vector(),b.values.vector()) return u
def __eval_fexpl(self,u,t): """ Helper routine to evaluate the explicit part of the RHS Args: u: current values (not used here) t: current time Returns: explicit part of RHS """ A = 1.0*self.K b = self.apply_mass_matrix(u) psi = fenics_mesh(self.V) df.solve(A,psi.values.vector(),b.values.vector()) fexpl = fenics_mesh(self.V) fexpl.values = df.project(df.Dx(psi.values,1)*df.Dx(u.values,0) - df.Dx(psi.values,0)*df.Dx(u.values,1),self.V) return fexpl
def apply_mass_matrix(self,u): """ Routine to apply mass matrix Args: u: current values Returns: M*u """ me = fenics_mesh(self.V) me.values = df.Function(self.V,self.M*u.values.vector()) return me
def prolong_space(self,G): """ Prolongation implementation Args: G: the coarse level data (easier to access than via the coarse attribute) """ if isinstance(G,fenics_mesh): u_fine = fenics_mesh(self.init_f) u_fine.values = df.interpolate(G.values,u_fine.V) elif isinstance(G,rhs_fenics_mesh): u_fine = rhs_fenics_mesh(self.init_f) u_fine.impl.values = df.interpolate(G.impl.values,u_fine.impl.V) u_fine.expl.values = df.interpolate(G.expl.values,u_fine.expl.V) return u_fine
def restrict_space(self,F): """ Restriction implementation Args: F: the fine level data (easier to access than via the fine attribute) """ if isinstance(F,fenics_mesh): u_coarse = fenics_mesh(self.init_c) u_coarse.values = df.interpolate(F.values,u_coarse.V) elif isinstance(F,rhs_fenics_mesh): u_coarse = rhs_fenics_mesh(self.init_c) u_coarse.impl.values = df.interpolate(F.impl.values,u_coarse.impl.V) u_coarse.expl.values = df.interpolate(F.expl.values,u_coarse.expl.V) return u_coarse
def __eval_fimpl(self,u,t): """ Helper routine to evaluate the implicit part of the RHS Args: u: current values t: current time (not used here) Returns: implicit part of RHS """ tmp = fenics_mesh(self.V) tmp.values = df.Function(self.V,self.K*u.values.vector()) fimpl = self.__invert_mass_matrix(tmp) return fimpl
def __eval_fexpl(self,u,t): """ Helper routine to evaluate the explicit part of the RHS Args: u: current values (not used here) t: current time Returns: explicit part of RHS """ self.g.t = t fexpl = fenics_mesh(self.V) fexpl.values = df.Function(self.V,df.interpolate(self.g,self.V).vector()) return fexpl
def u_exact(self,t): """ Routine to compute the exact solution at time t Args: t: current time Returns: exact solution """ # u0 = df.Expression('sin(a*x[0]) * sin(a*x[1]) * cos(t)',a=np.pi,t=t,degree=self.order) u0 = df.Expression('sin(a*x[0]) * cos(t)',a=np.pi,t=t,degree=self.order) me = fenics_mesh(self.V) me.values = df.interpolate(u0,self.V) return me
def u_exact(self,t): """ Routine to compute the exact solution at time t Args: t: current time Returns: exact solution """ # u0 = df.Expression('sin(a*x[0]) * sin(a*x[1]) * cos(t)',a=np.pi,t=t,degree=self.order) u0 = df.Expression('exp(-nu*pow(2*a*k,2)*t) * sin(2*a*k*(x[0]+mu*t))',a=np.pi,nu=self.nu,mu=self.mu,k=self.k,t=t) me = fenics_mesh(self.V) me.values = df.interpolate(u0,self.V) return me
def solve_system(self,rhs,factor,u0,t): """ Dolfin's linear solver for (M-dtA)u = rhs Args: rhs: right-hand side for the nonlinear system factor: abbrev. for the node-to-node stepsize (or any other factor required) u0: initial guess for the iterative solver (not used here so far) Returns: solution as mesh """ sol = fenics_mesh(self.V) # self.g.t = t self.w.assign(sol.values) q1,q2 = df.TestFunctions(self.V) w1,w2 = df.split(self.w) r1,r2 = df.split(rhs.values) F1 = w1*q1*df.dx - factor*self.F1 - r1*q1*df.dx F2 = w2*q2*df.dx - factor*self.F2 - r2*q2*df.dx F = F1+F2 du = df.TrialFunction(self.V) J = df.derivative(F, self.w, du) problem = df.NonlinearVariationalProblem(F, self.w, [], J) solver = df.NonlinearVariationalSolver(problem) prm = solver.parameters prm['newton_solver']['absolute_tolerance'] = 1E-09 prm['newton_solver']['relative_tolerance'] = 1E-08 prm['newton_solver']['maximum_iterations'] = 100 prm['newton_solver']['relaxation_parameter'] = 1.0 # df.set_log_level(df.PROGRESS) solver.solve() sol.values.assign(self.w) return sol
def eval_f(self,u,t): """ Routine to evaluate both parts of the RHS Args: u: current values t: current time Returns: the RHS divided into two parts """ f = fenics_mesh(self.V) self.w.assign(u.values) f.values = df.Function(self.V,df.assemble(self.F)) f = self.__invert_mass_matrix(f) return f
def solve_system(self,rhs,factor,u0,t): """ Dolfin's linear solver for (M-dtA)u = rhs Args: rhs: right-hand side for the nonlinear system factor: abbrev. for the node-to-node stepsize (or any other factor required) u0: initial guess for the iterative solver (not used here so far) Returns: solution as mesh """ sol = fenics_mesh(self.V) self.g.t = t self.w.assign(sol.values) v = df.TestFunction(self.V) F = self.w*v*df.dx - factor*self.a_K - rhs.values*v*df.dx du = df.TrialFunction(self.V) J = df.derivative(F, self.w, du) problem = df.NonlinearVariationalProblem(F, self.w, self.bc, J) solver = df.NonlinearVariationalSolver(problem) prm = solver.parameters prm['newton_solver']['absolute_tolerance'] = 1E-8 prm['newton_solver']['relative_tolerance'] = 1E-7 prm['newton_solver']['maximum_iterations'] = 25 prm['newton_solver']['relaxation_parameter'] = 1.0 # df.set_log_level(df.PROGRESS) solver.solve() sol.values.assign(self.w) return sol
def u_exact(self,t): """ Routine to compute the exact solution at time t Args: t: current time Returns: exact solution """ class InitialConditions(df.Expression): def __init__(self): random.seed(2) pass def eval(self, values, x): # if df.between(x[0],(0.375,0.625)): # # values[1] = 0.25*np.power(np.sin(8*np.pi*x[0]),2) # # values[0] = 1 - 2*values[1] # values[0] = 0.5 + random.random() # values[1] = 0.25 # else: # values[1] = 0 # values[0] = 1 values[0] = 1 - 0.5*np.power(np.sin(np.pi*x[0]/100),100) values[1] = 0.25*np.power(np.sin(np.pi*x[0]/100),100) def value_shape(self): return (2,) # class InitialConditions(df.Expression): # def eval(self, values, x): # if df.between(x[0],(0.75,1.25)) and df.between(x[1],(0.75,1.25)): # values[1] = 0.25*np.power(np.sin(4*np.pi*x[0]),2)*np.power(np.sin(4*np.pi*x[1]),2) # values[0] = 1 - 2*values[1] # else: # values[1] = 0 # values[0] = 1 # def value_shape(self): # return (2,) # class InitialConditions(df.Expression): # def __init(self): # random.seed(2) # # def eval(self, values, x): # if df.between(x[0],(0.475,0.525)) and df.between(x[1],(0.475,0.525)): # # values[1] = 0.25 + random.uniform(-0.01,0.01) # # values[0] = 0.5 + random.uniform(-0.01,0.01) # values[1] = 1 # values[0] = 0 # else: # values[1] = 0 # values[0] = 1 # def value_shape(self): # return (2,) uinit = InitialConditions() me = fenics_mesh(self.V) me.values = df.interpolate(uinit,self.V) # u1,u2 = df.split(me.values) # df.plot(u1,interactive = True) # exit() return me