def __init__(self, K): # Variables x, y = sym.symbols('x[0], x[1]', real=True, positive=True) f = sym.Function('f')(x, y) grid = np.linspace(0, 1, K + 2)[1:-1] x_obs, y_obs = np.meshgrid(grid, grid) self.x_obs, self.y_obs = x_obs.reshape(K * K), y_obs.reshape(K * K) # --- THIS PART USED TO NOT BE PARALELLIZABLE --- # # Create mesh and define function space n_mesh = 80 self.mesh = fen.UnitSquareMesh(n_mesh, n_mesh) self.f_space = fen.FunctionSpace(self.mesh, 'P', 2) # Define boundary condition # u_boundary = fen.Expression('x[0] + x[1]', degree=2) u_boundary = fen.Expression('0', degree=2) self.bound_cond = fen.DirichletBC(self.f_space, u_boundary, lambda x, on_boundary: on_boundary) # Define variational problem self.trial_f = fen.TrialFunction(self.f_space) self.test_f = fen.TestFunction(self.f_space) rhs = fen.Constant(50) self.lin_func = rhs * self.test_f * fen.dx
def geneFunctionSpace(self): P2 = fe.FiniteElement('P', fe.triangle, 2) element = fe.MixedElement([P2, P2]) if self.domain.haveMesh == False: self.domain.geneMesh() self.V = fe.FunctionSpace(self.domain.mesh, element) self.haveFunctionSpace = True
def setup_fe(self): # Define the relevant function spaces V = d.FunctionSpace(self.mesh, "Lagrange", 1) self.V = V # DG0 is useful for defining piecewise constant functions DV = d.FunctionSpace(self.mesh, "Discontinuous Lagrange", 0) self.DV = DV # Define test and trial functions for FE self.z = d.TrialFunction(self.V) self.w = d.TestFunction(self.V) regions = self.per_tissue_constant(lambda l: l) region_file = d.File("../%s-regions.pvd" % input_mesh) region_file << regions
def _residual(u_n, u_nm1, u_nm2, f_n): ''' Compute the residual of the PDE at time step n. ''' # BUG: project into higher order functional space? V = u_n.function_space() mesh = V.mesh() basis_degree = V.ufl_element().degree() U = F.FunctionSpace(mesh, 'P', basis_degree + 3) f_n_v = F.project(f_n, U).vector()[:] u_nm1_v = F.project(u_nm1, U).vector()[:] u_nm2_v = F.project(u_nm2, U).vector()[:] u_n_ = F.project(u_n, U) u_n_v = u_n_.vector()[:] ddu_n_v = F.project(u_n_.dx(0).dx(0), U).vector()[:] # or use the same order? # f_n_ = F.project(f_n, V).vector()[:] # u_n_ = F.project(u_n, V).vector()[:] # u_nm1_ = F.project(u_nm1, V).vector()[:] # u_nm2_ = F.project(u_nm2, V).vector()[:] # ddu_n = F.project(u_n.dx(0).dx(0), V).vector()[:] R = np.sum(u_n_v - (dt**2) * (c**2) * ddu_n_v - (dt**2) * f_n_v - 2 * u_nm1_v + u_nm2_v) return R
def test_export_xdmf(): mesh = fenics.UnitSquareMesh(3, 3) V = fenics.FunctionSpace(mesh, 'P', 1) folder = "Solution" exports = { "xdmf": { "functions": ['solute', 'retention'], "labels": ['a', 'b'], "folder": folder } } files = [fenics.XDMFFile(folder + "/" + "a.xdmf"), fenics.XDMFFile(folder + "/" + "b.xdmf")] assert FESTIM.export_xdmf( [fenics.Function(V), fenics.Function(V)], exports, files, 20) is None exports["xdmf"]["functions"] = ['solute', 'blabla'] with pytest.raises(KeyError, match=r'blabla'): FESTIM.export_xdmf( [fenics.Function(V), fenics.Function(V)], exports, files, 20) exports["xdmf"]["functions"] = ['solute', '13'] with pytest.raises(KeyError, match=r'13'): FESTIM.export_xdmf( [fenics.Function(V), fenics.Function(V)], exports, files, 20)
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(to_numpy(test_input), expected)
def set_constant_concentration(self, value): function_space_copy = fenics.FunctionSpace(self.mesh, self.element()) new_solution = fenics.Function(function_space_copy) new_solution.vector()[:] = self.solution.vector() class WholeDomain(fenics.SubDomain): def inside(self, x, on_boundary): return True hack = fenics.DirichletBC(function_space_copy.sub(3), value, WholeDomain()) hack.apply(new_solution.vector()) for solution in self._solutions: solution.vector()[:] = new_solution.vector() for i in range(len(self._times)): self._times[i] = 0.
def vjp_assemble_impl( g: np.array, fenics_output_form: ufl.Form, fenics_inputs: List[FenicsVariable], ) -> Tuple[np.array]: """Computes the gradients of the output with respect to the inputs.""" # Compute derivative form for the output with respect to each input fenics_grads_forms = [] for fenics_input in fenics_inputs: # Need to construct direction (test function) first if isinstance(fenics_input, fenics.Function): V = fenics_input.function_space() elif isinstance(fenics_input, fenics.Constant): mesh = fenics_output_form.ufl_domain().ufl_cargo() V = fenics.FunctionSpace(mesh, "Real", 0) else: raise NotImplementedError dv = fenics.TestFunction(V) fenics_grad_form = fenics.derivative(fenics_output_form, fenics_input, dv) fenics_grads_forms.append(fenics_grad_form) # Assemble the derivative forms fenics_grads = [fenics.assemble(form) for form in fenics_grads_forms] # Convert FEniCS gradients to jax array representation jax_grads = ( None if fg is None else np.asarray(g * fenics_to_numpy(fg)) for fg in fenics_grads ) jax_grad_tuple = tuple(jax_grads) return jax_grad_tuple
def solver(f, u_D, bc_funs, ndim, length, nx, ny, nz=None, degree=2): """Fenics 求解器 Args: f (Expression): [description] u_D (Expression): [description] bc_funs (List[Callable]): [description] ndim (int): [description] length (float): [description] nx (int): [description] ny (int): [description] nz (int, optional): [description]. Defaults to None. degree (int, optional): [description]. Defaults to 1. Returns: Function: 解 u """ mesh = get_mesh(length, nx, ny, nz) # mesh = refine_mesh(mesh, length) V = fs.FunctionSpace(mesh, "P", degree) bcs = [fs.DirichletBC(V, u_D, bc) for bc in bc_funs] u = fs.TrialFunction(V) v = fs.TestFunction(V) FF = fs.dot(fs.grad(u), fs.grad(v)) * fs.dx - f * v * fs.dx a = fs.lhs(FF) L = fs.rhs(FF) u = fs.Function(V) fs.solve(a == L, u, bcs) return u, mesh
def compute_mesh_volume(self): one = fe.Constant(1) DG = fe.FunctionSpace(self.mesh, 'DG', 0) v = fe.TestFunction(DG) L = v * one * fe.dx b = fe.assemble(L) self.mesh_volume = b.get_local().sum()
def calc_system_variables(*, coords, advect_params, flags, pert_params): dx = (coords.we[1] - coords.we[0]) * 1000 dy = (coords.sn[1] - coords.sn[0]) * 1000 # dx, dy in m not km max_horizon = pd.Timedelta(advect_params['max_horizon']) ci_crop_shape = np.array([coords.sn_crop.size, coords.we_crop.size], dtype='int') U_crop_shape = np.array([coords.sn_crop.size, coords.we_stag_crop.size], dtype='int') V_crop_shape = np.array([coords.sn_stag_crop.size, coords.we_crop.size], dtype='int') U_crop_size = U_crop_shape[0] * U_crop_shape[1] V_crop_size = V_crop_shape[0] * V_crop_shape[1] wind_size = U_crop_size + V_crop_size num_of_horizons = int((max_horizon / 15).seconds / 60) sys_vars = { 'dx': dx, 'dy': dy, 'num_of_horizons': num_of_horizons, 'max_horizon': max_horizon, 'ci_crop_shape': ci_crop_shape, 'U_crop_shape': U_crop_shape, 'V_crop_shape': V_crop_shape, 'U_crop_size': U_crop_size, 'V_crop_size': V_crop_size, 'wind_size': wind_size } if flags['div']: mesh = fe.RectangleMesh( fe.Point(0, 0), fe.Point(int(V_crop_shape[1] - 1), int(U_crop_shape[0] - 1)), int(V_crop_shape[1] - 1), int(U_crop_shape[0] - 1)) FunctionSpace_wind = fe.FunctionSpace(mesh, 'P', 1) sys_vars['FunctionSpace_wind'] = FunctionSpace_wind if flags['perturbation']: rf_eig, rf_vectors = eig_2d_covariance(x=coords.we_crop, y=coords.sn_crop, Lx=pert_params['Lx'], Ly=pert_params['Ly'], tol=pert_params['tol']) rf_approx_var = (rf_vectors * rf_eig[None, :] * rf_vectors).sum(-1).mean() sys_vars['rf_eig'] = rf_eig sys_vars['rf_vectors'] = rf_vectors sys_vars['rf_approx_var'] = rf_approx_var if flags['perturb_winds']: rf_eig, rf_vectors = eig_2d_covariance(coords.we_crop, coords.sn_crop, Lx=pert_params['Lx_wind'], Ly=pert_params['Ly_wind'], tol=pert_params['tol_wind']) rf_approx_var = (rf_vectors * rf_eig[None, :] * rf_vectors).sum(-1).mean() rf_eig = rf_eig * pert_params['Lx_wind']**2 sys_vars['rf_eig_wind'] = rf_eig sys_vars['rf_vectors_wind'] = rf_vectors sys_vars['rf_approx_var_wind'] = rf_approx_var sys_vars = dict2nt(sys_vars, 'sys_vars') return sys_vars
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 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 test_empty_measure(): mesh, _, _, dx, ds, dS = cashocs.regular_mesh(5) V = fenics.FunctionSpace(mesh, 'CG', 1) dm = cashocs.utils.EmptyMeasure(dx) trial = fenics.TrialFunction(V) test = fenics.TestFunction(V) assert fenics.assemble(1 * dm) == 0.0 assert (fenics.assemble(test * dm).norm('linf')) == 0.0 assert (fenics.assemble(trial * test * dm).norm('linf')) == 0.0
def run(self): e_domain = self._create_e_domain() mesh = generate_mesh(e_domain, MESH_PTS) self._create_boundary_expression() Omega_e = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1) Omega_i = fe.FiniteElement("Lagrange", self.passive_seg.mesh.ufl_cell(), 1) Omega = fe.FunctionSpace(mesh, Omega_e * Omega_i) Theta_e, Theta_i = fe.TrialFunction(Omega) v_e, v_i = fe.TestFunctions(Omega) sigma_e, sigma_i = 0.3, 0.4 LHS = sigma_e * fe.inner(fe.grad(Theta_e), fe.grad(v_e)) * fe.dx # poisson LHS += sigma_i * fe.inner(fe.grad(Theta_i), fe.grad(v_i)) * fe.dx # poisson LHS -= sigma_e * fe.grad(Theta_e) * v_e * fe.ds # current LHS += sigma_i * fe.grad(Theta_i) * v_i * fe.ds # current RHS = self.boundary_exp * v_e * fe.ds # source term # TODO: solve Poisson in extracellular space w = fe.Function(Omega) fe.solve(LHS == RHS, w) Theta_e, Theta_i = w.split() plot(fe.interpolate(Theta, fe.FunctionSpace(mesh, Omega)), mode='color') plt.show() # Set the potential just inside the membrane to Ve (just computed) # minus V_m (from prev timestep) self.passive_seg.set_v(Theta, self.passive_seg_vm) # Solve for the potential and current inside the passive cell self.passive_seg.run() # Use Im to compute a new Vm for the next timestep, eq (8) self.passive_seg_vm = self.passive_seg_vm + self.dt / self.cm * ( self.passive_seg_im - self.passive_seg_vm / self.rm)
def mesh_gen_default(self, intervals, typ='P', order=1): """ creates a square with sides of 1, divided by intervals by default the type of the volume associated with the mesh is considered to be Lagrangian, with order 1. """ self._mesh = FEN.UnitSquareMesh(intervals, intervals) self.input['mesh'] = self._mesh self._V = FEN.FunctionSpace(self._mesh, typ, order) self.input['V'] = self._V self._u = FEN.TrialFunction(self._V) self._v = FEN.TestFunction(self._V)
def __init__(self, mesh, constitutive_model): W = fe.FunctionSpace(mesh, "DG", 1) super().__init__(mesh, constitutive_model, W) self.w = fe.Function(W) self.p, self.p0 = self.w, fe.Function(W) self.g = fe.TestFunction(W) self.functional = fe.inner(self.p, self.g) - fe.inner( self.constitutive_model)
def dynamic_solver_func(ncells=10, # количество узлов на заданном итервале init_time=0, # начальный момент времени end_time=10, # конечный момент времени dxdphi=1, # производная от потенциала по х dydphi=1, # производня от потенциала по у x0=0, # начальное положение по оси х vx0=1, # проекция начальной скорости на ось х y0=0, # начальное положение по оси у vy0=1): # проекция начальной скорости на ось у """ Функция на вход которой подается производная от потенциала гравитационного поля, возвращающая координаты смещенных материальных точек (частиц). """ # генерация сетки на заданном интервале времени mesh = fen.IntervalMesh(ncells, 0, end_time-init_time) welm = fen.MixedElement([fen.FiniteElement('Lagrange', fen.interval, 2), fen.FiniteElement('Lagrange', fen.interval, 2), fen.FiniteElement('Lagrange', fen.interval, 2), fen.FiniteElement('Lagrange', fen.interval, 2)]) # генерация функционального рростаанства W = fen.FunctionSpace(mesh, welm) # постановка начальных условий задачи bcsys = [fen.DirichletBC(W.sub(0), fen.Constant(x0), 'near(x[0], 0)'), fen.DirichletBC(W.sub(1), fen.Constant(vx0), 'near(x[0], 0)'), fen.DirichletBC(W.sub(2), fen.Constant(y0), 'near(x[0], 0)'), fen.DirichletBC(W.sub(3), fen.Constant(vy0), 'near(x[0], 0)')] # опееделение тестовых функций для решения задачи up = fen.Function(W) x_cor, v_x, y_cor, v_y = fen.split(up) v1, v2, v3, v4 = fen.split(fen.TestFunction(W)) # постановка задачи drdt = v; dvdt = - grad(phi) в проекциях на оси системы координат weak_form = (x_cor.dx(0) - v_x) * v1 * fen.dx + (v_x.dx(0) + dxdphi) * v2 * fen.dx \ + (y_cor.dx(0) - v_y) * v3 * fen.dx + (v_y.dx(0) + dydphi) * v4 * fen.dx # решние поставленной задачи fen.solve(weak_form == 0, up, bcs=bcsys) # определение момента времени time = fen.Point(end_time - init_time) # расчет координат и скоростей x_end_time = up(time.x())[0] vx_end_time = up(time.x())[1] y_end_time = up(time.x())[2] vy_end_time = up(time.x())[3] return x_end_time, y_end_time, vx_end_time, vy_end_time
def _build_function_space(self): class Exterior(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and (fa.near(x[1], 1) or fa.near(x[0], 1) or fa.near(x[0], 0) or fa.near(x[1], 0)) class Left(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[0], 0) class Right(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[0], 1) class Bottom(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[1], 0) class Top(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[1], 1) class Interior(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and (x[0] > 0.1 and x[0] < 0.9 and x[1] > 0.1 and x[1] < 0.9) self.exteriors_dic = { 'left': Left(), 'right': Right(), 'bottom': Bottom(), 'top': Top() } self.exterior = Exterior() self.interior = Interior() self.V = fa.FunctionSpace(self.mesh, 'P', 1) self.source = da.Expression(("100*sin(2*pi*x[0])"), degree=3) # self.source = da.Expression("k*100*exp( (-(x[0]-x0)*(x[0]-x0) -(x[1]-x1)*(x[1]-x1)) / (2*0.01*l) )", # k=1, l=1, x0=0.9, x1=0.1, degree=3) # self.source = da.Constant(10) self.source = da.interpolate(self.source, self.V) boundary_fn_ext = da.Constant(1.) boundary_fn_int = da.Constant(1.) boundary_bc_ext = da.DirichletBC(self.V, boundary_fn_ext, self.exterior) boundary_bc_int = da.DirichletBC(self.V, boundary_fn_int, self.interior) self.bcs = [boundary_bc_ext, boundary_bc_int]
def Vufl(soln, t): "Make a UFL object for plotting V" split = fe.split(soln.function) irho = split[0] iUs = split[1:] soln.ksdg.set_time(t) V = (soln.V(iUs, irho, params=soln.ksdg.iparams) / (soln.ksdg.iparams['sigma']**2 / 2)) fs = soln.function.function_space() cell = fs.ufl_cell() CE = fe.FiniteElement('CG', cell, soln.degree) CS = fe.FunctionSpace(fs.mesh(), CE) pV = fe.project(V, CS, solver_type='petsc') return pV
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 __init__(self, my_d, fen_dic, det_dic): self.p_electric = [] self.w_p_electric = [] self.det_model = fen_dic['name'] self.fl_x = my_d.l_x / fen_dic['xyscale'] self.fl_y = my_d.l_y / fen_dic['xyscale'] self.fl_z = my_d.l_z self.tol = 1e-14 self.det_dic = det_dic m_sensor_box = self.fenics_space(my_d) self.mesh3D = mshr.generate_mesh(m_sensor_box, fen_dic['mesh']) self.V = fenics.FunctionSpace(self.mesh3D, 'P', 1) self.fenics_p_electric(my_d) self.fenics_p_w_electric(my_d)
def __init__(self, N, K): # Variables x, y = sym.symbols('x[0], x[1]', real=True, positive=True) f = sym.Function('f')(x, y) # Precision (inverse covariance) operator, when α = 1 tau, alpha = 3, 2 precision = (-sym.diff(f, x, x) - sym.diff(f, y, y) + tau**2 * f) indices = [(m, n) for m in range(0, N) for n in range(0, N)] # indices = indices[:-1] self.indices = sorted(indices, key=max) eig_f = [ sym.cos(i[0] * sym.pi * x) * sym.cos(i[1] * sym.pi * y) for i in self.indices ] # Eigenvalues of the covariance operator self.eig_v = [ 1 / (precision.subs(f, e).doit() / e).simplify()**alpha for e in eig_f ] grid = np.linspace(0, 1, K + 2)[1:-1] x_obs, y_obs = np.meshgrid(grid, grid) self.x_obs, self.y_obs = x_obs.reshape(K * K), y_obs.reshape(K * K) # Basis_functions self.functions = [ f * np.sqrt(float(v)) for f, v in zip(eig_f, self.eig_v) ] # --- THIS PART USED TO NOT BE PARALELLIZABLE --- # # Create mesh and define function space n_mesh = 80 mesh = fen.UnitSquareMesh(n_mesh, n_mesh) self.f_space = fen.FunctionSpace(mesh, 'P', 2) # Define boundary condition # u_boundary = fen.Expression('x[0] + x[1]', degree=2) u_boundary = fen.Expression('0', degree=2) self.bound_cond = fen.DirichletBC(self.f_space, u_boundary, lambda x, on_boundary: on_boundary) # Define variational problem self.trial_f = fen.TrialFunction(self.f_space) self.test_f = fen.TestFunction(self.f_space) rhs = fen.Constant(50) # rhs = fen.Expression('sin(x[0])*sin(x[1])', degree=2) self.lin_func = rhs * self.test_f * fen.dx
def solve_poisson_problem(mesh, boundary_values_expression, forcing_function): """ Solve the Poisson problem with P2 elements. """ V = fenics.FunctionSpace(mesh, "P", 2) u, v = fenics.TrialFunction(V), fenics.TestFunction(V) solution = fenics.Function(V) fenics.solve( fenics.dot(fenics.grad(v), fenics.grad(u)) * fenics.dx == v * forcing_function * fenics.dx, solution, fenics.DirichletBC(V, boundary_values_expression, boundary)) return solution
def solve_poisson_eps(h, eps, plot=False): eps = fe.Constant(eps) n = int(1 / h) # Create mesh and define function space mesh = fe.UnitIntervalMesh(n) V = fe.FunctionSpace(mesh, 'P', 1) # Define boundary condition u_D = fe.Constant(0.0) # Find exact solution: u_exact = fe.Expression( "(1./2 - x[0]) * (2 * x[0] + eps/(2*pi) * sin(2*pi*x[0]/eps)) " "+ eps*eps/(2*pi*2*pi) * (1 - cos(2*pi*x[0]/eps)) + x[0]*x[0]", eps=eps, degree=4) def boundary(x, on_boundary): return on_boundary bc = fe.DirichletBC(V, u_D, boundary) # Define variational problem u = fe.TrialFunction(V) v = fe.TestFunction(V) f = fe.Constant(1) A = fe.Expression('1./(2+cos(2*pi*x[0]/eps))', eps=eps, degree=2) a = A * fe.dot(fe.grad(u), fe.grad(v)) * fe.dx L = f * v * fe.dx # Compute solution u = fe.Function(V) fe.solve(a == L, u, bc) if plot: # Plot solution fe.plot(u) fe.plot(u_exact, mesh=mesh) # Hold plot fe.interactive() # # Save solution to file in VTK format # vtkfile = fe.File('poisson/solution.pvd') # vtkfile << u # Compute error err_norm = fe.errornorm(u_exact, u, 'L2') return err_norm
def writeToHDF5(self): print 'self.hdfFileName', self.hdfFileName, type(self.hdfFileName) mesh = Mesh(self.xmlFileName) hfile = fc.HDF5File(mesh.mpi_comm(), self.hdfFileName, "w") V = fc.FunctionSpace(mesh, 'CG', 1) thicknessiD = interpolateDataClass(thickness.interp, degree=2) bediD = interpolateDataClass(bed.interp, degree=2) surfaceiD = interpolateDataClass(surface.interp, degree=2) smbiD = interpolateDataClass(smb.interp, degree=2) velocityiD = interpolateDataClass(velocity.interp, degree=2) t2miD = interpolateDataClass(t2m.interp, degree=2) th = project(thicknessiD, V) be = project(bediD, V) su = project(surfaceiD, V) sm = project(smbiD, V) ve = project(velocityiD, V) t2 = project(t2miD, V) hfile.write(th, 'thickness') hfile.write(be, 'bed') hfile.write(su, 'surface') hfile.write(sm, 'smb') hfile.write(ve, 'velocity') hfile.write(t2, 't2m') hfile.write(mesh, "mesh") hfile.close() parTHF = File(self.paraFileName + 'thickness' + '.pvd') parTHF << th parBEF = File(self.paraFileName + 'bed' + '.pvd') parBEF << be parSUF = File(self.paraFileName + 'surface' + '.pvd') parSUF << su parSMF = File(self.paraFileName + 'smb' + '.pvd') parSMF << sm parVEF = File(self.paraFileName + 'velocity' + '.pvd') parVEF << ve parT2F = File(self.paraFileName, 't2m' + '.pvd') parT2F << t2 print 'Done with mesh'
def solve_initial_problem_v2(self): V = fn.FunctionSpace(self.mesh, 'Lagrange', 2) # Define test and trial functions. v = fn.TestFunction(V) u = fn.TrialFunction(V) # Define radial coordinates. r = fn.SpatialCoordinate(self.mesh)[0] # Define the relative permittivity. class relative_perm(fn.UserExpression): def __init__(self, markers, subdomain_ids, **kwargs): super().__init__(**kwargs) self.markers = markers self.subdomain_ids = subdomain_ids def eval_cell(self, values, x, cell): if self.markers[cell.index] == self.subdomain_ids['Vacuum']: values[0] = 1. else: values[0] = 10. rel_perm = relative_perm(self.subdomains, self.subdomains_ids, degree=0) # Define the variational form. a = r * rel_perm * fn.inner(fn.grad(u), fn.grad(v)) * self.dx L = fn.Constant(0.) * v * self.dx # Define the boundary conditions. bc1 = fn.DirichletBC(V, fn.Constant(0.), self.boundaries, self.boundaries_ids['Bottom_Wall']) bc4 = fn.DirichletBC(V, fn.Constant(-10.), self.boundaries, self.boundaries_ids['Top_Wall']) bcs = [bc1, bc4] # Solve the problem. init_phi = fn.Function(V) fn.solve(a == L, init_phi, bcs) return Poisson.block_project(init_phi, self.mesh, self.restrictions_dict['vacuum_rtc'], self.subdomains, self.subdomains_ids['Vacuum'], space_type='scalar')
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