def __init__( self, time_order=1, integration_measure=fenics.dx(metadata={"quadrature_degree": 8}), uniform_gridsize=20, setup_solver=True): self.uniform_gridsize = uniform_gridsize self.cold_wall_temperature_before_freezing = fenics.Constant(0.1) self.cold_wall_temperature_during_freezing = fenics.Constant(-1.1) super().__init__(time_order=time_order, integration_measure=integration_measure, setup_solver=setup_solver, initial_uniform_gridsize=uniform_gridsize) self.hot_wall_temperature.assign(1.25) self.cold_wall_temperature.assign(0.25) if setup_solver: self.solver.parameters["newton_solver"]["maximum_iterations"] = 12
def __init__( self, time_order=1, integration_measure=fenics.dx(metadata={"quadrature_degree": 8}), setup_solver=True): super().__init__(time_order=time_order, integration_measure=integration_measure, setup_solver=setup_solver) self.hot_wall_temperature.assign(1.) self.cold_wall_temperature.assign(-0.01) self.initial_concentration.assign(0.) self.concentration_rayleigh_number.assign(0.) self.schmidt_number.assign(1.e32) self.liquidus_slope.assign(0.) self.timestep_size.assign(10.) self.temperature_rayleigh_number.assign(3.27e5) self.prandtl_number.assign(56.2) self.stefan_number.assign(0.045) self.regularization_central_temperature_offset.assign(0.01) self.regularization_smoothing_parameter.assign(0.025)
def __init__( self, time_order=1, integration_measure=fenics.dx(metadata={"quadrature_degree": 8}), setup_solver=True): self.hot_wall_temperature_degC = 10. self.cold_wall_temperature_degC = 0. self.pure_liquidus_temperature_degC = 0. super().__init__(time_order=time_order, integration_measure=integration_measure, setup_solver=setup_solver) self.temperature_rayleigh_number.assign(2.518084e6) self.prandtl_number.assign(6.99) """ Disable freezing. """ self.pure_liquidus_temperature.assign( self.T(self.pure_liquidus_temperature_degC)) self.regularization_central_temperature_offset.assign(0.) self.solid_viscosity.assign(self.liquid_viscosity) self.stefan_number.assign(1.e32) """ Disable concentration equation """ self.concentration_rayleigh_number.assign(0.) self.schmidt_number.assign(1.e32) self.liquidus_slope.assign(0.)
def compute_error_estimates(self, eigenvalue: float, eigenfunction: fenics.Function) \ -> Tuple[np.float, np.float]: """Compute error estimates. This method computes a posteriori error estimates of two kinds. The first type assumes that the computed eigenvalue is correct and verifies that the $L^2$ distance between the right and the left hand sides of the variational formulation. The second type of check assumes that the eigenfunctions are correct and validates the computed eigenvalue against the Rayleigh quotient of the eigenfunction. Parameters ---------- eigenvalue : float An eigenvalue. eigenfunction : fenics.Function Eigenfunction corresponding to `eigenvalue`. Returns ------- l2_dist : float $L^2$ distance between the left hand side of the variational formulation and the result of multiplying the right hand side by `eigenvalue`. lambda_dist : float Absolute value of the difference between `eigenvalue` and the Rayleigh quotient corresponding to `eigenfunction`. """ l, u = eigenvalue, eigenfunction a, b = self._construct_eigenproblem(u, u) # Compute L2 distance. E = fenics.assemble((a - l * b)**2 * fenics.dx(degree=self.degree)) l2_dist = np.sqrt(np.abs(E)) # Check Rayleigh quotient. deg = self.degree rayleigh_quotient = (fenics.assemble(a * fenics.dx(degree=deg)) / fenics.assemble(b * fenics.dx(degree=deg))) lambda_dist = np.abs(l - rayleigh_quotient) return l2_dist, lambda_dist
def __init__( self, time_order=1, integration_measure=fenics.dx(metadata={"quadrature_degree": 8}), setup_solver=True): class Lid(fenics.SubDomain): def inside(self, x, on_boundary): return on_boundary and fenics.near(x[1], 1.) self.lid = Lid() class FixedWalls(fenics.SubDomain): def inside(self, x, on_boundary): return on_boundary and (not fenics.near(x[1], 1.)) self.fixed_walls = FixedWalls() class BottomWall(fenics.SubDomain): def inside(self, x, on_boundary): return on_boundary and fenics.near(x[1], 0.) self.bottom_wall = BottomWall() super().__init__(time_order=time_order, integration_measure=integration_measure, setup_solver=setup_solver) self.timestep_size.assign(1.e12) self.temperature_rayleigh_number.assign(0.) self.concentration_rayleigh_number.assign(0.) self.schmidt_number.assign(1.e32) self.prandtl_number.assign(1.) """ Disable effects of phase-change. Oddly enough, simply specifying an arbitrarily low melting temperature results in the Newton solver returning NaN's, e.g. the following did not work: self.regularization_central_temperature.assign(1.e-32) As a reminder of this for future development, let's assign something that works here. """ self.pure_liquidus_temperature.assign(0.) self.liquidus_slope.assign(0.) self.regularization_central_temperature_offset.assign(0.) self.liquid_viscosity.assign(0.01) self.solid_viscosity.assign(self.liquid_viscosity) self.stefan_number.assign(1.e32)
def defineWeakSystemDomain(): """Define system of equations of the weak formulation of the second-orderformulation of the PN equations on the domain . """ sMD = importlib.import_module( "systemMatricesDomain_d_%d_k_%s_N_%d" % (par['spatialDimension'], par['kernelName'], N_PN)) systemMatricesDomain = sMD.getSystemMatricesDomain(par) lhs = 0.0 * v[0] * fe.dx(V) for i in range(nEvenMoments): for j in range(nEvenMoments): if (par['spatialDimension'] == 1): lhs += systemMatricesDomain['Kzz'][i][j] * fe.dot( fe.grad(u[j])[0], fe.grad(v[i])[0]) * fe.dx(V) elif (par['spatialDimension'] == 2): lhs += systemMatricesDomain['Kxx'][i][j] * fe.dot( fe.grad(u[j])[0], fe.grad(v[i])[0]) * fe.dx(V) lhs += systemMatricesDomain['Kxy'][i][j] * fe.dot( fe.grad(u[j])[1], fe.grad(v[i])[0]) * fe.dx(V) lhs += systemMatricesDomain['Kyx'][i][j] * fe.dot( fe.grad(u[j])[0], fe.grad(v[i])[1]) * fe.dx(V) lhs += systemMatricesDomain['Kyy'][i][j] * fe.dot( fe.grad(u[j])[1], fe.grad(v[i])[1]) * fe.dx(V) else: raise ValueError( 'Only spatial dimensions <= 2 implemented!') lhs += systemMatricesDomain['S'][i][j] * u[j] * v[i] * fe.dx(V) return lhs
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 setup_derived_attributes(self): """ Set attributes which shouldn't be touched by the user. """ self.fenics_timestep_size = fenics.Constant(self.timestep_size) if self.second_order_time_discretization: self.old_fenics_timestep_size = fenics.Constant(self.timestep_size) if self.quadrature_degree is None: self.integration_metric = fenics.dx else: self.integration_metric = fenics.dx(metadata={'quadrature_degree': self.quadrature_degree})
def __init__( self, initial_uniform_gridsize=1, time_order=1, integration_measure=fenics.dx(metadata={"quadrature_degree": 8}), setup_solver=True): self.initial_hot_wall_refinement_cycles = 6 super().__init__(time_order=time_order, integration_measure=integration_measure, setup_solver=setup_solver, initial_uniform_gridsize=initial_uniform_gridsize) self.hot_wall_temperature.assign(1.) self.cold_wall_temperature.assign(-0.11) self.initial_concentration.assign(1.) self.temperature_rayleigh_number.assign(3.27e5) self.prandtl_number.assign(56.2) Ra_T = self.temperature_rayleigh_number.__float__() Pr = self.prandtl_number.__float__() self.concentration_rayleigh_number.assign(-0.3 * Ra_T / Pr) self.stefan_number.assign(0.045) Le = 100. self.schmidt_number.assign(Pr * Le) self.pure_liquidus_temperature.assign(0.) self.liquidus_slope.assign(-0.1) self.regularization_central_temperature_offset.assign(0.01) self.regularization_smoothing_parameter.assign(0.025)
def __init__( self, time_order=1, integration_measure=fenics.dx(metadata={"quadrature_degree": 8}), initial_uniform_gridsize=8, setup_solver=True): self.initial_uniform_gridsize = initial_uniform_gridsize super().__init__(time_order=time_order, integration_measure=integration_measure, setup_solver=setup_solver) self.hot_wall_temperature.assign(0.5) self.cold_wall_temperature.assign(-0.5) self.timestep_size.assign(1.e-3) self.temperature_rayleigh_number.assign(1.e6) self.prandtl_number.assign(0.71) """ Disable phase-change. Oddly enough, simply specifying an arbitrarily low melting temperature results in the Newton solver returning NaN's, e.g. the following did not work: self.regularization_central_temperature.assign(1.e-32) As a reminder of this for future development, let's assign something that works here. """ self.pure_liquidus_temperature.assign(0.) self.regularization_central_temperature_offset.assign(-1.) self.solid_viscosity.assign(self.liquid_viscosity) self.stefan_number.assign(1.e32) """ Disable concentration equation """ self.concentration_rayleigh_number.assign(0.) self.schmidt_number.assign(1.e32) self.liquidus_slope.assign(0.)
def solve_flem(model_space, physical_space, flow, u_n, mesh, V, bc, dt, num_steps, out_time, plot, statistics, name): """ Solve for landscape evolution This function does hte hard work. First the model domain is created. Then we loop through time and solve the diffusion equation to solve for landscape evolution. Output can be saved as vtk files at every "out_time" specified. Plots using fenics inbuilt library can be visualised at every "plot_time" This function returns a 1d numpy array of time, sediment flux and if statistics is turned on a 2d numpy array of the final wavelength of the landscape. :param model_space: list of domain variables, [lx,ly,res] :param physical_space: list of physical parameters, [kappa, c, nexp, alpha, U] :param flow: 0 = MFD node-to-node; 1 = MFD cell-to-cell; 2 = SD node-to-node; 3 = SD cell-to-cell :param u_n: elevation function :param mesh: dolphyn mesh :param V: fenics functionspace :param bc: boundary conditions :param dt: time step size in years :param num_steps: number of time steps :param out_time: time steps to output vtk files (0=none) :param plot: plot sediment flux (0=off,1=on) :param statistics: output statistics of landscape (0=off,1=on) :param name: directory name for output vtk files :return: sed_flux, time, wavelength """ # Domain dimensions lx = model_space[0] ly = model_space[1] # Physical parameters kappa = physical_space[0] # diffusion coefficient c = physical_space[1] # discharge transport coefficient nexp = physical_space[2] # discharge exponent alpha = physical_space[3] # precipitation rate De = c * pow(alpha * ly, nexp) / kappa uamp = physical_space[4] * ly / kappa # uplift dt = dt * kappa / (ly * ly) # time step size sed_flux = np.zeros(num_steps) # array to store sediment flux time = np.zeros(num_steps) # Define variational problem u = TrialFunction(V) v = TestFunction(V) f = Constant(uamp) # 0 = MFD node-to-node; 1 = MFD cell-to-cell; 2 = SD node-to-node; 3 = SD cell-to-cell if flow == 0: q_n = mfd_nodenode(mesh, V, u_n, De, nexp) if flow == 1: q_n = mfd_cellcell(mesh, V, u_n, De, nexp) if flow == 2: q_n = sd_nodenode(mesh, V, u_n, De, nexp) if flow == 3: q_n = sd_cellcell(mesh, V, u_n, De, nexp) F = u * v * dx + dt * q_n * dot(grad(u), grad(v)) * dx - (u_n + dt * f) * v * dx a, L = lhs(F), rhs(F) # Solution and sediment flux u = Function(V) q_s = Expression('u0 + displ - u1', u0=u_n, displ=Constant(uamp * dt), u1=u, degree=2) # Iterate t = 0 i = 0 for n in range(num_steps): # This needs to become an option! # Double rain fall # if n == 501: # alpha = 2 # De = c*pow(alpha*ly,nexp)/kappa # Update current time t += dt # Compute solution solve(a == L, u, bc) # Calculate sediment flux sed_flux[i] = assemble(q_s * dx(mesh)) time[i] = t i += 1 # Update previous solution u_n.assign(u) # Update flux # 0 = MFD node-to-node; 1 = MFD cell-to-cell; 2 = SD node-to-node; 3 = SD cell-to-cell if flow == 0: q = mfd_nodenode(mesh, V, u_n, De, nexp) if flow == 1: q = mfd_cellcell(mesh, V, u_n, De, nexp) if flow == 2: q = sd_nodenode(mesh, V, u_n, De, nexp) if flow == 3: q = sd_cellcell(mesh, V, u_n, De, nexp) q_n.assign(q) # Output solutions if out_time != 0: if np.mod(n, out_time) == 0: filename = '%s/u_solution_%d.pvd' % (name, n) vtkfile = File(filename) vtkfile << u filename = '%s/q_solution_%d.pvd' % (name, n) vtkfile = File(filename) vtkfile << q # Post processing if plot != 0: plt.plot(time * 1e-6 * ly * ly / kappa, sed_flux / dt * kappa, 'k', linewidth=2) plt.xlabel('Time (Myr)') plt.ylabel('Sediment Flux (m^2/yr)') sedname = '%s/sed_flux_%d.svg' % (name, model_space[2]) plt.savefig(sedname, format='svg') plt.clf() if out_time != 0: # Output last elevation filename = '%s/u_solution_%d_%d.pvd' % (name, model_space[2], n) vtkfile = File(filename) u.rename("elv", "elevation") vtkfile << u # Output last water flux filename = '%s/q_solution_%d_%d.pvd' % (name, model_space[2], n) vtkfile = File(filename) q.rename("flx", "flux") vtkfile << q # Calculate valley spacing from peak to peak in water flux tol = 0.001 # avoid hitting points outside the domain y = np.linspace(0 + tol, 1 - tol, 100) x = np.linspace(0.01, lx / ly - 0.01, 20) wavelength = np.zeros(len(x)) if statistics != 0: i = 0 for ix in x: points = [(ix, y_) for y_ in y] # 2D points q_line = np.array([q(point) for point in points]) indexes = peakutils.indexes(q_line, thres=0.05, min_dist=5) if len(indexes) > 1: wavelength[i] = sum(np.diff(y[indexes])) / (len(indexes) - 1) else: wavelength[i] = 0 i += 1 if plot != 0: plt.plot(y * 1e-3 * ly, q_line * kappa / ly, 'k', linewidth=2) plt.plot(y[indexes] * 1e-3 * ly, q_line[indexes] * kappa / ly, '+r') plt.xlabel('Distance (km)') plt.ylabel('Water Flux (m/yr)') watername = '%s/water_flux_spacing_%d.svg' % (name, model_space[2]) plt.savefig(watername, format='svg') plt.clf() return sed_flux, time, wavelength
else: sij = 0.5 * (fe.grad(u) + fe.grad(u).T) nu_tv = lmx**(2 * fe.inner(sij, sij))**(0.5) ns_tv = fe.inner((nu_tv) * fe.grad(v), fe.grad(u)) * fe.dx ns_visc = nu * fe.inner(fe.grad(v), fe.grad(u)) * fe.dx ns_conti = q * fe.div(u) * fe.dx ns_forcing = fe.dot(v, b) * fe.dx NS = ns_conv + ns_press + ns_tv + ns_visc + ns_conti + ns_forcing N = 5 fe.parameters["form_compiler"]["quadrature_degree"] = N if MODEL: #dx(metadata={'quadrature_degree':N}) # maybe 10. <10? tv_adv = fe.inner(nu_test, fe.inner( u, fe.grad(nu_trial))) * fe.dx(metadata={'quadrature_degree': N}) tv1 = fe.inner(nu_test, Cb1 * (1 - ft2) * 1 * nu_trial) * fe.dx( metadata={'quadrature_degree': N }) # TODO Missing stilde term #tv1 = fe.inner(nu_test, Cb1 * (1 - ft2) * Stilde * nu_trial) * fe.dx(metadata={'quadrature_degree':N}) tv2 = fe.inner( (1 / sigma) * fe.grad(nu_test), (nu + nu_trial) * fe.grad(nu_trial)) * fe.dx(metadata={'quadrature_degree': N}) tv3 = fe.inner(nu_test / sigma * Cb2, fe.dot(fe.grad(nu_trial), fe.grad(nu_trial))) * fe.dx( metadata={'quadrature_degree': N}) #tv4 = fe.inner(nu_test * (Cw1 * fw - Cb1 / kappa / kappa * ft2), (nu_trial / d) * (nu_trial / d)) * fe.dx tv4 = fe.inner( nu_test, (Cw1 - Cb1 / kappa / kappa * ft2) * (nu_trial / d)**2) * fe.dx(
def test_formulation_1_trap_2_materials(): ''' Test function formulation() with 1 intrinsic trap and 2 materials ''' def create_subdomains(x1, x2): class domain(FESTIM.SubDomain): def inside(self, x, on_boundary): return x[0] >= x1 and x[0] <= x2 domain = domain() return domain dt = 1 traps = [{ "energy": 1, "density": 2, "materials": [1, 2] }] materials = [{ "alpha": 1, "beta": 2, "density": 3, "borders": [0, 0.5], "E_diff": 4, "D_0": 5, "id": 1 }, { "alpha": 2, "beta": 3, "density": 4, "borders": [0.5, 1], "E_diff": 5, "D_0": 6, "id": 2 }] extrinsic_traps = [] mesh = fenics.UnitIntervalMesh(10) mf = fenics.MeshFunction("size_t", mesh, 1, 1) mat1 = create_subdomains(0, 0.5) mat2 = create_subdomains(0.5, 1) mat1.mark(mf, 1) mat2.mark(mf, 2) V = fenics.VectorFunctionSpace(mesh, 'P', 1, 2) u = fenics.Function(V) u_n = fenics.Function(V) v = fenics.TestFunction(V) solutions = list(fenics.split(u)) previous_solutions = list(fenics.split(u_n)) testfunctions = list(fenics.split(v)) mf = fenics.MeshFunction('size_t', mesh, 1, 1) dx = fenics.dx(subdomain_data=mf) temp = fenics.Expression("300", degree=0) flux_ = fenics.Expression("1", degree=0) F, expressions = FESTIM.formulation( traps, extrinsic_traps, solutions, testfunctions, previous_solutions, dt, dx, materials, temp, flux_) # Transient sol expected_form = ((solutions[0] - previous_solutions[0]) / dt) * \ testfunctions[0]*dx # Diffusion sol mat 1 expected_form += 5 * fenics.exp(-4/8.6e-5/temp) * \ fenics.dot( fenics.grad(solutions[0]), fenics.grad(testfunctions[0]))*dx(1) # Diffusion sol mat 2 expected_form += 6 * fenics.exp(-5/8.6e-5/temp) * \ fenics.dot( fenics.grad(solutions[0]), fenics.grad(testfunctions[0]))*dx(2) # Source sol expected_form += -flux_*testfunctions[0]*dx # Transient trap 1 expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \ testfunctions[1]*dx # Trapping trap 1 mat 1 expected_form += - 5 * fenics.exp(-4/8.6e-5/temp)/1/1/2 * \ solutions[0] * (2 - solutions[1]) * \ testfunctions[1]*dx(1) # Trapping trap 1 mat 2 expected_form += - 6 * fenics.exp(-5/8.6e-5/temp)/2/2/3 * \ solutions[0] * (2 - solutions[1]) * \ testfunctions[1]*dx(2) # Detrapping trap 1 mat 1 expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[1] * \ testfunctions[1]*dx(1) # Detrapping trap 1 mat 2 expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[1] * \ testfunctions[1]*dx(2) # Source detrapping sol expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \ testfunctions[0]*dx assert expected_form.equals(F) is True
def test_formulation_2_traps_1_material(): ''' Test function formulation() with 2 intrinsic traps and 1 material ''' # Set parameters dt = 1 traps = [{ "energy": 1, "density": 2, "materials": [1] }, { "energy": 1, "density": 2, "materials": [1] }] materials = [{ "alpha": 1, "beta": 2, "density": 3, "borders": [0, 1], "E_diff": 4, "D_0": 5, "id": 1 }] extrinsic_traps = [] # Prepare mesh = fenics.UnitIntervalMesh(10) V = fenics.VectorFunctionSpace(mesh, 'P', 1, len(traps)+1) u = fenics.Function(V) u_n = fenics.Function(V) v = fenics.TestFunction(V) solutions = list(fenics.split(u)) previous_solutions = list(fenics.split(u_n)) testfunctions = list(fenics.split(v)) mf = fenics.MeshFunction('size_t', mesh, 1, 1) dx = fenics.dx(subdomain_data=mf) temp = fenics.Expression("300", degree=0) flux_ = fenics.Expression("1", degree=0) F, expressions = FESTIM.formulation( traps, extrinsic_traps, solutions, testfunctions, previous_solutions, dt, dx, materials, temp, flux_) # Transient sol expected_form = ((solutions[0] - previous_solutions[0]) / dt) * \ testfunctions[0]*dx # Diffusion sol expected_form += 5 * fenics.exp(-4/8.6e-5/temp) * \ fenics.dot( fenics.grad(solutions[0]), fenics.grad(testfunctions[0]))*dx(1) # Source sol expected_form += -flux_*testfunctions[0]*dx # Transient trap 1 expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \ testfunctions[1]*dx # Trapping trap 1 expected_form += - 5 * fenics.exp(-4/8.6e-5/temp)/1/1/2 * \ solutions[0] * (2 - solutions[1]) * \ testfunctions[1]*dx(1) # Detrapping trap 1 expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[1] * \ testfunctions[1]*dx(1) # Source detrapping sol expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \ testfunctions[0]*dx # Transient trap 2 expected_form += ((solutions[2] - previous_solutions[2]) / dt) * \ testfunctions[2]*dx # Trapping trap 2 expected_form += - 5 * fenics.exp(-4/8.6e-5/temp)/1/1/2 * \ solutions[0] * (2 - solutions[2]) * \ testfunctions[2]*dx(1) # Detrapping trap 2 expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[2] * \ testfunctions[2]*dx(1) # Source detrapping 2 sol expected_form += ((solutions[2] - previous_solutions[2]) / dt) * \ testfunctions[0]*dx assert expected_form.equals(F) is True
Vsig = fnc.TensorFunctionSpace(mesh, "DG", 0) # Funciones Test y trial du = fnc.TrialFunction(V) w = fnc.TestFunction(V) # Desplazamiento actual Desconocido! u = fnc.Function(V, name="Desplazamiento") #Campos del paso anterior (Desplazamiento, velocidad, aceleración) u_old = fnc.Function(V) v_old = fnc.Function(V) a_old = fnc.Function(V) #Define la medida de la integral de borde (contorno) dss = fnc.ds(subdomain_data=bordes) fnc.dx = fnc.dx(metadata={'quadrature_degree': 3}) #Condición de borde del costado izquierdo zero = fnc.Constant((0.0, 0.0, 0.0)) bc = fnc.DirichletBC(V, zero, bordes, 1) #bc2 = fnc.DirichletBC(V, zero, bordes, 2) #bc3 = fnc.DirichletBC(V, zero, bordes, 10) #bc = [bc1, bc2] def eps(v): return fnc.sym(fnc.grad(v)) # Tensor de tensiones def sigma(r):
x_m0=initial_melt_thickness, element=mixed_element), W) p_n, u_n, T_n = fenics.split(w_n) timestep_size = 10. Delta_t = fenics.Constant(timestep_size) u_t = (u - u_n) / Delta_t T_t = (T - T_n) / Delta_t phi_t = (phi(T) - phi(T_n)) / Delta_t dx = fenics.dx(metadata={'quadrature_degree': 8}) inner, dot, grad, div, sym = \ fenics.inner, fenics.dot, fenics.grad, fenics.div, fenics.sym mass = -psi_p * div(u) momentum = dot(psi_u, u_t + dot(grad(u), u) + f_B) - div(psi_u)*p \ + 2.*mu(phi(T))*inner(sym(grad(psi_u)), sym(grad(u))) enthalpy = psi_T * (T_t - 1. / Ste * phi_t) + dot(grad(psi_T), 1. / Pr * grad(T) - T * u) F = (mass + momentum + enthalpy) * dx