def set_initial_conditions(self): self.current_time = self.initial_time #Initial condition #self.u_n = fe.project(self.boundary_fun, self.function_space) if self.mode == 'test': print('Setting initial conditions') self.boundary_fun.t = self.current_time self.u_n = fe.interpolate(self.boundary_fun, self.function_space) else: if self.dimension == 2: self.u_n = fe.project(self.ic_fun, self.function_space) if self.dimension == 1: #self.u_n = fe.interpolate(fe.Constant(0), self.function_space) #self.u_n.vector()[self.dof_map[0]] = 1 self.boundary_fun.t = self.current_time self.u_n = fe.interpolate(self.boundary_fun, self.function_space) self.u = fe.Function(self.function_space) self.compute_error() self.save_snapshot()
def __init__(self, para): self.nx, self.ny = para['mesh_N'][0], para['mesh_N'][1] self.mesh = fe.UnitSquareMesh(self.nx, self.ny) self.Vu = fe.FunctionSpace(self.mesh, 'P', para['P']) self.Vc = fe.FunctionSpace(self.mesh, 'P', para['P']) self.al = fe.Expression(para['alpha'], degree=5) self.q1 = fe.interpolate(fe.Expression(para['q1'], degree=5), self.Vc) self.q2 = fe.interpolate(fe.Expression(para['q2'], degree=5), self.Vc) self.q3 = fe.interpolate(fe.Expression(para['q3'], degree=5), self.Vc) self.f = fe.Expression(para['f'], degree=5) self.theta = fe.Constant(0.0) self.u = fe.Function(self.Vu)
def calTrueSol(para): nx, ny = para['mesh_N'][0], para['mesh_N'][1] mesh = fe.UnitSquareMesh(nx, ny) Vu = fe.FunctionSpace(mesh, 'P', para['P']) Vc = fe.FunctionSpace(mesh, 'P', para['P']) al = fe.Constant(para['alpha']) f = fe.Expression(para['f'], degree=5) q1 = fe.interpolate(fe.Expression(para['q1'], degree=5), Vc) q2 = fe.interpolate(fe.Expression(para['q2'], degree=5), Vc) q3 = fe.interpolate(fe.Expression(para['q3'], degree=5), Vc) theta = fe.interpolate(fe.Expression(para['q4'], degree=5), Vc) class BoundaryX0(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[0], 0.0) class BoundaryX1(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[0], 1.0) class BoundaryY0(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[1], 0.0) class BoundaryY1(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[1], 1.0) boundaries = fe.MeshFunction('size_t', mesh, mesh.topology().dim() - 1) boundaries.set_all(0) bc0, bc1, bc2, bc3 = BoundaryX0(), BoundaryX1(), BoundaryY0(), BoundaryY1() bc0.mark(boundaries, 1) bc1.mark(boundaries, 2) bc2.mark(boundaries, 3) bc3.mark(boundaries, 4) domains = fe.MeshFunction("size_t", mesh, mesh.topology().dim()) domains.set_all(0) bcD = fe.DirichletBC(Vu, theta, boundaries, 4) dx = fe.Measure('dx', domain=mesh, subdomain_data=domains) ds = fe.Measure('ds', domain=mesh, subdomain_data=boundaries) u_trial, u_test = fe.TrialFunction(Vu), fe.TestFunction(Vu) u = fe.Function(Vu) left = fe.inner(al * fe.nabla_grad(u_trial), fe.nabla_grad(u_test)) * dx right = f * u_test * dx + (q1 * u_test * ds(1) + q2 * u_test * ds(2) + q3 * u_test * ds(3)) left_m, right_m = fe.assemble_system(left, right, bcD) fe.solve(left_m, u.vector(), right_m) return u
def evenodd_functions_old( omesh, degree, func, width=None, evenodd=None ): """Break a function into even and odd components Required parameters: omesh: the mesh on which the function is defined degree: the degree of the FunctionSpace func: the Function. This has to be something that fe.interpolate can interpolate onto a FunctionSpace or that fe.project can project onto a FunctionSpace. width: the width of the domain on which func is defined. (If not provided, this will be determined from omesh. evenodd: the symmetries of the functions to be constructed evenodd_symmetries(dim) is used if this is not provided """ SS = FunctionSpace(omesh, 'CG', degree) dim = omesh.geometry().dim() if width is None: stats = mesh_stats(omesh) width = stats['xmax'] if evenodd is None: evenodd = evenodd_symmetries(dim) try: f0 = fe.interpolate(func, SS) except TypeError: f0 = fe.project(func, SS) ffuncs = [] flips = evenodd_symmetries(dim) for flip in (flips): fmesh = Mesh(omesh) SSf = FunctionSpace(fmesh, 'CG', degree) ffunc = fe.interpolate(f0, SSf) fmesh.coordinates()[:, :] = (width*flip + (1 - 2*flip)*fmesh.coordinates()) fmesh.bounding_box_tree().build(fmesh) ffuncs.append(ffunc) E = evenodd_matrix(evenodd) components = matmul(2**(-dim)*E, ffuncs) cs = [] for c in components: try: cs.append(fe.interpolate(c, SS)) except TypeError: cs.append(fe.project(c, SS, solver_type='lu')) return(cs)
def shooting_gmres(direction): # Define empty functions on interface increment = Function(interface.function_space) (increment_displacement, increment_velocity) = increment.split(increment) # Split entrance vectors direction_split = np.split(direction, 2) # Set values of functions on interface increment_displacement.vector().set_local(displacement_interface + param.EPSILON * direction_split[0]) increment_velocity.vector().set_local(velocity_interface + param.EPSILON * direction_split[1]) # Interpolate functions on solid subdomain increment_displacement_solid = interpolate( increment_displacement, solid.function_space_split[0]) increment_velocity_solid = interpolate(increment_velocity, solid.function_space_split[1]) displacement_solid.new.assign(increment_displacement_solid) velocity_solid.new.assign(increment_velocity_solid) # Compute shooting function shooting_function_increment = shooting_function( displacement_fluid, velocity_fluid, displacement_solid, velocity_solid, functional_fluid_initial, functional_solid_initial, bilinear_form_fluid, functional_fluid, bilinear_form_solid, functional_solid, first_time_step, fluid, solid, interface, param, fluid_macrotimestep, solid_macrotimestep, adjoint, ) return (shooting_function_increment - shooting_function_value) / param.EPSILON
def function_interpolate(fin, fsout, coords=None, method='nearest'): """Copy a fenics Function Required arguments: fin: the input Function to copy fsout: the output FunctionSpace onto which to copy it Optional arguments: coords: the global coordinates of the DOFs of the FunctionSpace on which fin is defined. If not provided, gather_dof_coords will be called to get them. If you intend to do several interpolations from functions defined on the same FunctionSpace, you can avoid multiple calls to gather_dof_coords by supplying this argument. method='nearest': the method argument of scipy.interpolate.griddata. Returns: The values from fin are interpolated into fout, a Function defined on fsout. fout is returned. """ comm = fsout.mesh().mpi_comm() logGATHER('comm.size', comm.size) try: fsin = fin.function_space() except AttributeError: # fallback for Constant fout = fe.interpolate(fin, fsout) return (fout) vlen = fsin.dim() # # dofs logGATHER('vlen', vlen) if coords is None: coords = gather_dof_coords(fsin) logGATHER('fsin.mesh().mpi_comm().size', fsin.mesh().mpi_comm().size) try: vec0 = fin.vector().gather_on_zero() except AttributeError: # fallback for Constant fout = fe.interpolate(fin, fsout) return (fout) if comm.rank == 0: vec = vec0.copy() else: vec = np.empty(vlen) comm.Bcast(vec, root=0) logGATHER('vec', vec) fout = Function(fsout) fout.vector()[:] = griddata(coords, vec, fsout.tabulate_dof_coordinates(), method=method).flatten() fout.vector().apply('insert') return (fout)
def compute_error(u1, u2): """ L1 error between two functions u1 and u2 :param u1: FEniCS function :param u2: FEniCS function :return: Approximate L1 error between u1 and u2 """ mesh_resolution_ref = 400 mesh_ref = UnitSquareMesh(mesh_resolution_ref, mesh_resolution_ref) V_ref = FunctionSpace(mesh_ref, "CG", degree=1) Iu1 = interpolate(u1, V_ref) Iu2 = interpolate(u2, V_ref) error = assemble(abs(Iu1 - Iu2) * dx) return error
def test_fenics_to_numpy_function(): # Functions in DG0 have nodes at centers of finite element cells mesh = fenics.UnitIntervalMesh(10) V = fenics.FunctionSpace(mesh, "DG", 0) test_input = fenics.interpolate(fenics.Expression("x[0]", degree=1), V) expected = numpy.linspace(0.05, 0.95, num=10) assert numpy.allclose(fenics_to_numpy(test_input), expected)
def compute_mesh_error(do_local_refine, mesh_resolution, num_refinements): mesh = generate_rectangle_mesh(mesh_resolution) # Define heat kernel t0 = 0.01 u = Expression("exp(-(x[0]*x[0]+x[1]*x[1])/(4*t))/(4*pi*t)", t=t0, domain=mesh, degree=3) # Define finite element function space degree = 1 V = FunctionSpace(mesh, "CG", degree) # Refine mesh r = 0.4 xc, yc = 0.0, 0.0 for i in range(0, num_refinements): if do_local_refine: mesh = local_refine(mesh, [xc, yc], r) else: mesh = refine(mesh) # Interpolate the heat kernel into the function space Iu = interpolate(u, V) # Compute L1 error between u and its interpolant error = compute_error(u, Iu) return error
def eva(self, num): # construct basis functions, Set num points corresponding to num basis functions basPoints = np.linspace(0, 1, num) dx = basPoints[1] - basPoints[0] aa, bb, cc = -dx, 0.0, dx for x_p in basPoints: self.theta.append( fe.interpolate( fe.Expression( 'x[0] < a || x[0] > c ? 0 : (x[0] >=a && x[0] <= b ? (x[0]-a)/(b-a) : 1-(x[0]-b)/(c-b))', degree=2, a=aa, b=bb, c=cc), self.Vc)) aa, bb, cc = aa + dx, bb + dx, cc + dx u_trial, u_test = fe.TrialFunction(self.Vu), fe.TestFunction(self.Vu) left = fe.inner(self.al * fe.nabla_grad(u_trial), fe.nabla_grad(u_test)) * fe.dx right = self.f * u_test * fe.dx def boundaryD(x, on_boundary): return on_boundary and fe.near(x[1], 1.0) for i in range(num): uH = fe.Function(self.Vu) bcD = fe.DirichletBC(self.Vu, self.theta[i], boundaryD) left_m, right_m = fe.assemble_system(left, right, bcD) fe.solve(left_m, uH.vector(), right_m) self.sol.append(uH)
def run(self): domain = self._create_domain() mesh = generate_mesh(domain, MESH_PTS) # fe.plot(mesh) # plt.show() self._create_boundary_expression() Omega = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1) R = fe.FiniteElement("Real", mesh.ufl_cell(), 0) W = fe.FunctionSpace(mesh, Omega*R) Theta, c = fe.TrialFunction(W) v, d = fe.TestFunctions(W) sigma = self.conductivity LHS = (sigma * fe.inner(fe.grad(Theta), fe.grad(v)) + c*v + Theta*d) * fe.dx RHS = self.boundary_exp * v * fe.ds w = fe.Function(W) fe.solve(LHS == RHS, w) Theta, c = w.split() print(c(0, 0)) # fe.plot(Theta, "solution", mode='color', vmin=-3, vmax=3) # plt.show() plot(fe.interpolate(Theta, fe.FunctionSpace(mesh, Omega)), mode='color') plt.show()
def error_function(u_e, u, norm="L2"): """ Compute the error between estimated solution u and exact solution u_e in the specified norm. """ # Get function space V = u.function_space() if norm == "L2": # L2 norm # Explicit computation of L2 norm # E = ((u_e - u) ** 2) * F.dx # error = np.sqrt(np.abs(F.assemble(E))) # Implicit interpolation of u_e to higher-order elements. # u will also be interpolated to the space Ve before integration error = F.errornorm(u_e, u, norm_type="L2", degree_rise=3) elif norm == "H10": # H^1_0 seminorm error = F.errornorm(u_e, u, norm_type="H10", degree_rise=3) elif norm == "max": # max/infinity norm u_e_ = F.interpolate(u_e, V) error = np.abs(np.array(u_e_.vector()) - np.array(u.vector())).max() return error
def run_fokker_planck(nx, num_steps, t_0 = 0, t_final=10): # define mesh mesh = IntervalMesh(nx, -200, 200) # define function space. V = FunctionSpace(mesh, "Lagrange", 1) # Homogenous Neumann BCs don't have to be defined as they are the default in dolfin # define parameters. dt = (t_final-t_0) / num_steps # set mu and sigma mu = Constant(-1) D = Constant(1) # define initial conditions u_0 u_0 = Expression('x[0]', degree=1) # set U_n to be the interpolant of u_0 over the function space V. Note that # u_n is the value of u at the previous timestep, while u is the current value. u_n = interpolate(u_0, V) # Define variational problem u = TrialFunction(V) v = TestFunction(V) F = u*v*dx + dt*inner(D*grad(u), grad(v))*dx + dt*mu*grad(u)[0]*v*dx - inner(u_n, v)*dx # isolate the bilinear and linear forms. a, L = lhs(F), rhs(F) # initialize function to capture solution. t = 0 u_h = Function(V) plt.figure(figsize=(15, 15)) # time-stepping section for n in range(num_steps): t += dt # compute solution solve(a == L, u_h) u_n.assign(u_h) # Plot solutions intermittently if n % (num_steps // 10) == 0 and num_steps > 0: plot(u_h, label='t = %s' % t) plt.legend() plt.grid() plt.title("Finite Element Solutions to Fokker-Planck Equation with $\mu(x, t) = -(x+1)$ , $D(x, t) = e^t x^2$, $t_n$ = %s" % t_final) plt.ylabel("$u(x, t)$") plt.xlabel("x") plt.savefig("fpe/fokker-planck-solutions-mu.png") plt.clf() # return the approximate solution evaluated on the coordinates, and the actual coordinates. return u_n.compute_vertex_values(), mesh.coordinates()
def initialise(dem, bounds, res): """ Function to initialise the model space :param dem: 0 = no input DEM; 1 = input DEM :param bounds: west, south, east, north - if no DEM [0, 0, lx, ly]; if DEM [west, south, east, north] :param res: model resolution along the y-axis. :return model_space, u_n, mesh, V, bc: """ if dem == 0: lx = bounds[1] ly = bounds[3] # Create mesh and define function space domain = Rectangle(Point(0, 0), Point(lx / ly, ly / ly)) mesh = generate_mesh(domain, res) V = FunctionSpace(mesh, 'P', 1) # Define initial value u_D = Constant(0) eps = 10 / ly u_n = interpolate(u_D, V) u_n.vector().set_local(u_n.vector().get_local() + eps * np.random.random(u_n.vector().size())) if dem == 1: u_n, lx, ly, mesh, V = read_dem(bounds, res) # boundary conditions class East(SubDomain): def inside(self, x, on_boundary): return near(x[0], lx / ly) class West(SubDomain): def inside(self, x, on_boundary): return near(x[0], 0.0) class North(SubDomain): def inside(self, x, on_boundary): return near(x[1], ly / ly) class South(SubDomain): def inside(self, x, on_boundary): return near(x[1], 0.0) # Should make this into an option! bc = [DirichletBC(V, u_n, West()), DirichletBC(V, u_n, East())] # def boundary(x, on_boundary): # return on_boundary # bc = DirichletBC(V, u_n, boundary) model_space = [lx, ly, res] return model_space, u_n, mesh, V, bc
def test_jax_to_fenics_function(test_input, expected_expr): mesh = fenics.UnitIntervalMesh(10) V = fenics.FunctionSpace(mesh, "DG", 0) template = fenics.Function(V) fenics_test_input = numpy_to_fenics(test_input, template) expected = fenics.interpolate(fenics.Expression(expected_expr, degree=1), V) assert numpy.allclose( fenics_test_input.vector().get_local(), expected.vector().get_local() )
def test_numpy_to_fenics_function(): test_input = numpy.linspace(0.05, 0.95, num=10) mesh = fenics.UnitIntervalMesh(10) V = fenics.FunctionSpace(mesh, "DG", 0) template = fenics.Function(V) fenics_test_input = numpy_to_fenics(test_input, template) expected = fenics.interpolate(fenics.Expression("x[0]", degree=1), V) assert numpy.allclose(fenics_test_input.vector().get_local(), expected.vector().get_local())
def test_interpolator(): W = fenics.FunctionSpace(mesh, 'CG', 2) X = fenics.FunctionSpace(mesh, 'DG', 0) interp_W = cashocs.utils.Interpolator(V, W) interp_X = cashocs.utils.Interpolator(V, X) func_V = fenics.Function(V) func_V.vector()[:] = np.random.rand(V.dim()) fen_W = fenics.interpolate(func_V, W) fen_X = fenics.interpolate(func_V, X) cas_W = interp_W.interpolate(func_V) cas_X = interp_X.interpolate(func_V) assert np.allclose(fen_W.vector()[:], cas_W.vector()[:]) assert np.allclose(fen_X.vector()[:], cas_X.vector()[:])
def evenodd_functions( omesh, degree, func, width=None, evenodd=None ): """Break a function into even and odd components Required parameters: omesh: the mesh on which the function is defined degree: the degree of the FunctionSpace func: the Function. This has to be something that fe.interpolate can interpolate onto a FunctionSpace or that fe.project can project onto a FunctionSpace. width: the width of the domain on which func is defined. (If not provided, this will be determined from omesh. evenodd: the symmetries of the functions to be constructed evenodd_symmetries(dim) is used if this is not provided """ SS = FunctionSpace(omesh, 'CG', degree) dim = omesh.geometry().dim() comm = omesh.mpi_comm() rank = comm.rank if width is None: stats = mesh_stats(omesh) width = stats['xmax'] if evenodd is None: evenodd = evenodd_symmetries(dim) try: f0 = fe.interpolate(func, SS) except TypeError: f0 = fe.project(func, SS) vec0 = f0.vector().gather_on_zero() dofcoords = gather_dof_coords(SS) ndofs = len(dofcoords) fvecs = np.empty((2**dim, len(vec0)), float) flips = evenodd_symmetries(dim) for row,flip in enumerate(flips): newcoords = (width*flip + (1 - 2*flip)*dofcoords) remap = coord_remap(SS, newcoords) E = evenodd_matrix(evenodd) if rank == 0: fvecs[row, :] = vec0[remap] components = np.matmul(2**(-dim)*E, fvecs) else: components = np.zeros((2**dim, ndofs), float) logPERIODIC('components.shape', components.shape) fs = [] logPERIODIC('broadcasting function DOFs') for c in components: f = Function(SS) f = bcast_function(SS, c, f) # f.set_allow_extrapolation(True) fs.append(f) return(fs)
def test_formulation_1_extrap_1_material(): ''' Test function formulation() with 1 extrinsic trap and 1 material ''' dt = 1 traps = [{ "energy": 1, "materials": [1], "type": "extrinsic" }] materials = [{ "alpha": 1, "beta": 2, "density": 3, "borders": [0, 1], "E_diff": 4, "D_0": 5, "id": 1 }] mesh = fenics.UnitIntervalMesh(10) V = fenics.VectorFunctionSpace(mesh, 'P', 1, 2) W = fenics.FunctionSpace(mesh, 'P', 1) u = fenics.Function(V) u_n = fenics.Function(V) v = fenics.TestFunction(V) n = fenics.interpolate(fenics.Expression('1', degree=0), W) solutions = list(fenics.split(u)) previous_solutions = list(fenics.split(u_n)) testfunctions = list(fenics.split(v)) extrinsic_traps = [n] mf = fenics.MeshFunction('size_t', mesh, 1, 1) dx = fenics.dx(subdomain_data=mf) temp = fenics.Expression("300", degree=0) flux_ = fenics.Expression("10000", degree=0) F, expressions = FESTIM.formulation( traps, extrinsic_traps, solutions, testfunctions, previous_solutions, dt, dx, materials, temp, flux_) expected_form = ((solutions[0] - previous_solutions[0]) / dt) * \ testfunctions[0]*dx expected_form += 5 * fenics.exp(-4/8.6e-5/temp) * \ fenics.dot( fenics.grad(solutions[0]), fenics.grad(testfunctions[0]))*dx(1) expected_form += -flux_*testfunctions[0]*dx + \ ((solutions[1] - previous_solutions[1]) / dt) * \ testfunctions[1]*dx expected_form += - 5 * fenics.exp(-4/8.6e-5/temp)/1/1/2 * \ solutions[0] * (extrinsic_traps[0] - solutions[1]) * \ testfunctions[1]*dx(1) expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[1] * \ testfunctions[1]*dx(1) expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \ testfunctions[0]*dx assert expected_form.equals(F) is True
def initial_values(self): p0, u0_0, u0_1, T0, C0 = "0.", "1.", "0.", "0.", "0." w0 = fenics.interpolate( fenics.Expression((p0, u0_0, u0_1, T0, C0), element=self.element()), self.function_space) return w0
def test_fenics_to_numpy_mixed_function(): # Functions in DG0 have nodes at centers of finite element cells mesh = fenics.UnitIntervalMesh(10) vec_dim = 4 V = fenics.VectorFunctionSpace(mesh, "DG", 0, dim=vec_dim) test_input = fenics.interpolate( fenics.Expression(vec_dim * ("x[0]", ), element=V.ufl_element()), V) expected = numpy.linspace(0.05, 0.95, num=10) expected = numpy.reshape(numpy.tile(expected, (4, 1)).T, V.dim()) assert numpy.allclose(fenics_to_numpy(test_input), expected)
def initial_values(self): initial_values = fenics.interpolate( fenics.Expression( ("0.", "0.", "0.", "(T_c - T_h)*x[0] + T_h", "0."), T_h=self.T(self.hot_wall_temperature_degC), T_c=self.T(self.cold_wall_temperature_degC), element=self.element()), self.function_space) return initial_values
def interpolate_function(self, v): """ Interpolate v on the job's element, V. Args: v (?): The function to interpolate. Returns: (?): Interpolated function. """ return FEN.interpolate(v, V=self.V)
def solve(self, **arguments): t_start = time.clock() # definig Function space on this mesh using Lagrange #polynoimals of degree 1. H = FunctionSpace(self.mesh, "CG", 1) # Setting up the variational problem v = TrialFunction(H) w = TestFunction(H) coeff_dx2 = Constant(1) coeff_v = Constant(1) f = Expression("(4*pow(pi,2))*exp(-(1/coeff_v)*t)*sin(2*pi*x[0])", {'coeff_v': coeff_v}, degree=2) v0 = Expression("sin(2*pi*x[0])", degree=2) f.t = 0 def boundary(x, on_boundary): return on_boundary bc = DirichletBC(H, v0, boundary) v1 = interpolate(v0, H) dt = self.steps.time a = (dt * inner(grad(v), grad(w)) + dt * coeff_v * inner(v, w)) * dx L = (f * dt - coeff_v * v1) * w * dx A = assemble(a) v = Function(H) T = self.domain.time[-1] t = dt # solving the variational problem. while t <= T: b = assemble(L, tensor=b) vo.t = t bc.apply(A, b) solve(A, v.vector(), b) t += dt v1.assign(v) self.solution.extend(v.vector().array()) return [self.solution, time.clock() - t_start]
def initial_values(self): initial_values = fenics.interpolate( fenics.Expression( ("0.", "0.", "0.", "(T_h - T_c)*(x[0] < x_m0) + T_c", "0."), T_h=self.hot_wall_temperature, T_c=self.cold_wall_temperature, x_m0=1. / 2.**(self.initial_hot_wall_refinement_cycles - 1), element=self.element()), self.function_space) return initial_values
def xest_second_tutorial(self): T = 2.0 # final time num_steps = 50 # number of time steps dt = T / num_steps # time step size # Create mesh and define function space nx = ny = 30 mesh = fenics.RectangleMesh(fenics.Point(-2, -2), fenics.Point(2, 2), nx, ny) V = fenics.FunctionSpace(mesh, 'P', 1) # Define boundary condition def boundary(x, on_boundary): return on_boundary bc = fenics.DirichletBC(V, fenics.Constant(0), boundary) # Define initial value u_0 = fenics.Expression('exp(-a*pow(x[0], 2) - a*pow(x[1], 2))', degree=2, a=5) u_n = fenics.interpolate(u_0, V) # Define variational problem u = fenics.TrialFunction(V) v = fenics.TestFunction(V) f = fenics.Constant(0) F = u * v * fenics.dx + dt * fenics.dot(fenics.grad(u), fenics.grad( v)) * fenics.dx - (u_n + dt * f) * v * fenics.dx a, L = fenics.lhs(F), fenics.rhs(F) # Create VTK file for saving solution vtkfile = fenics.File( os.path.join(os.path.dirname(__file__), 'output', 'heat_gaussian', 'solution.pvd')) # Time-stepping u = fenics.Function(V) t = 0 not_initialised = True for n in range(num_steps): # Update current time t += dt # Compute solution fenics.solve(a == L, u, bc) # Save to file and plot solution vtkfile << (u, t) # Here we'll need to call tripcolor ourselves to get access to the color range fenics.plot(u) animation_camera.snap() u_n.assign(u) animation = animation_camera.animate() animation.save( os.path.join(os.path.dirname(__file__), 'output', 'heat_gaussian.mp4'))
def interpolate_H(self): print("Interpolating H_old...") control_points_new_map = self.control_points impact_radii_new_map = self.impact_radii map_type = self.map_type inside_domain = self.inside_domain H_old = self.H_old boundary_info = self.boundary_info if boundary_info is None: control_points_old_map = self.control_points[:-1] impact_radii_old_map = self.impact_radii_old else: control_points_old_map = self.control_points impact_radii_old_map = self.impact_radii # print("boundary_info {}".format(boundary_info)) # print("control_points_new_map {}".format(control_points_new_map)) # print("control_points_old_map {}".format(control_points_old_map)) # print("impact_radii_new_map {}".format(impact_radii_new_map)) # print("impact_radii_old_map {}".format(impact_radii_old_map)) class InterpolateExpression(fe.UserExpression): def eval(self, values, x_hat_new): x = map_function_normal(x_hat_new, control_points_new_map, impact_radii_new_map, map_type, boundary_info) x_hat_old = inverse_map_function_normal( x, control_points_old_map, impact_radii_old_map, map_type) point = fe.Point(x_hat_old) if not inside_domain(point): print("x_hat_new is ({}, {})".format( float(x_hat_new[0]), float(x_hat_new[1]))) print("x is ({}, {})".format(float(x[0]), float(x[1]))) print("x_hat_old is ({}, {})".format( float(x_hat_old[0]), float(x_hat_old[1]))) values[0] = H_old(point) def value_shape(self): return () H_exp = InterpolateExpression() # self.H_old.assign(fe.project(H_exp, self.WW)) # two slow self.H_old.assign(fe.interpolate(H_exp, self.WW)) print("Finish interploating H_old")
def solve_poisson_with_fem(lightweight=False): # Create mesh and define function space mesh = fs.UnitSquareMesh(8, 8) V = fs.FunctionSpace(mesh, 'P', 1) # Define boundary condition u_code = 'x[0] + 2*x[1] + 1' u_D = fs.Expression(u_code, degree=2) def boundary(x, on_boundary): return on_boundary bc = fs.DirichletBC(V, u_D, boundary) # Define variational problem u = fs.Function(V) # Note: not TrialFunction! v = fs.TestFunction(V) # f = fs.Expression(f_code, degree=2) f_code = '-10*x[0] - 20*x[1] - 10' f = fs.Expression(f_code, degree=2) F = q(u) * fs.dot(fs.grad(u), fs.grad(v)) * fs.dx - f * v * fs.dx # Compute solution fs.solve(F == 0, u, bc) # Plot solution fs.plot(u) # Compute maximum error at vertices. This computation illustrates # an alternative to using compute_vertex_values as in poisson.py. u_e = fs.interpolate(u_D, V) # Restore numpy object image1d = np.empty((81, ), dtype=np.float) for v in fs.vertices(mesh): image1d[v.index()] = u(*mesh.coordinates()[v.index()]) if not lightweight: error_max = np.abs(u_e.vector().get_local() - u.vector().get_local()).max() print('error_max = ', error_max) fs.plot(u) plt.show() save_contour(image1d, 1.0, 1.0, 'poisson') return image1d
def initial_values(self): p0, u0_0, u0_1 = "0.", "0.", "0." T0 = "T_h + (T_c - T_h)*x[0]" C0 = "0." w0 = fenics.interpolate( fenics.Expression((p0, u0_0, u0_1, T0, C0), T_h=self.hot_wall_temperature, T_c=self.cold_wall_temperature, element=self.element()), self.function_space) return w0
def interpolate(self, expression_strings): """Interpolate the solution from mathematical expressions. Parameters ---------- expression_strings : tuple of strings Each string will be an argument to a `fenics.Expression`. """ interpolated_solution = fenics.interpolate( fenics.Expression(expression_strings, element=self.element), self.function_space.leaf_node()) self.solution.leaf_node().vector( )[:] = interpolated_solution.leaf_node().vector()