Ejemplo n.º 1
0
	def compute_objective(self):
		"""Computes the part of the objective value that comes from the regularization

		Returns
		-------
		float
			Part of the objective value coming from the regularization

		"""

		if self.has_regularization:

			value = 0.0

			if self.mu_volume > 0.0:
				if not self.measure_hole:
					volume = fenics.assemble(Constant(1.0)*self.dx)
				else:
					volume = self.delta_x*self.delta_y*self.delta_z - fenics.assemble(Constant(1)*self.dx)

				value += 0.5*self.mu_volume*pow(volume - self.target_volume, 2)

			if self.mu_surface > 0.0:
				surface = fenics.assemble(Constant(1.0)*self.ds)
				# self.current_surface.val = surface
				value += 0.5*self.mu_surface*pow(surface - self.target_surface, 2)
			
			if self.mu_curvature > 0.0:
				self.compute_curvature()
				curvature_val = fenics.assemble(fenics.inner(self.kappa_curvature, self.kappa_curvature)*self.ds)
				value += 0.5*self.mu_curvature*curvature_val
			
			if self.mu_barycenter > 0.0:
				if not self.measure_hole:
					volume = fenics.assemble(Constant(1)*self.dx)

					barycenter_x = fenics.assemble(self.spatial_coordinate[0]*self.dx) / volume
					barycenter_y = fenics.assemble(self.spatial_coordinate[1]*self.dx) / volume
					if self.form_handler.mesh.geometric_dimension() == 3:
						barycenter_z = fenics.assemble(self.spatial_coordinate[2]*self.dx) / volume
					else:
						barycenter_z = 0.0

				else:
					volume = self.delta_x*self.delta_y*self.delta_z - fenics.assemble(Constant(1)*self.dx)

					barycenter_x = (0.5*(pow(self.x_end, 2) - pow(self.x_start, 2))*self.delta_y*self.delta_z - fenics.assemble(self.spatial_coordinate[0]*self.dx)) / volume
					barycenter_y = (0.5*(pow(self.y_end, 2) - pow(self.y_start, 2))*self.delta_x*self.delta_z - fenics.assemble(self.spatial_coordinate[1]*self.dx)) / volume
					if self.form_handler.mesh.geometric_dimension() == 3:
						barycenter_z = (0.5*(pow(self.z_end, 2) - pow(self.z_start, 2))*self.delta_x*self.delta_y - fenics.assemble(self.spatial_coordinate[2]*self.dx)) / volume
					else:
						barycenter_z = 0.0

				value += 0.5*self.mu_barycenter*(pow(barycenter_x - self.target_barycenter_list[0], 2) + pow(barycenter_y - self.target_barycenter_list[1], 2)
												 + pow(barycenter_z - self.target_barycenter_list[2], 2))

			return value

		else:
			return 0.0
Ejemplo n.º 2
0
    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)

        epsilon = Constant(arguments[Components().Diffusion])
        f = Constant(0)

        a = (epsilon * inner(grad(v), grad(w)) + inner(v, w)) * dx
        #Still have to figure it how to use a Neumann Condition here
        L = f * w * dx

        # solving the variational problem.
        v = Function(H)
        solve(a == L, v)

        self.solution.extend(v.vector().array())

        return [self.solution, time.clock() - t_start]
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() 
Ejemplo n.º 4
0
    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]
Ejemplo n.º 5
0
    def init_params(self, parameters, param_funcs):
        """Initialize parameter attributes from __init__ arguments

        The attributes initialized are:
        self.params0: a dict giving initial values of all parameters
        (not just floats). This is basically a copy of the parameters
        argument to __init__, with the insertion of 't' as a new
        parameter (always param_names[-1]).
        self.param_names: a list of the names of the time-varying
        parameters. This is the keys of params0 whose corrsponding
        values are of type float. The order is the order of the
        parameters in self.PSf.
        self.nparams: len(self.param_names)
        self.param_numbers: a dict mapping param names to numbers
        (ints) in the list param_names and the parameters subspace of
        the solution FunctionSpace.
        self.param_funcs: a dict whose keys are the param_names and
        whose values are functions to determine their values as a
        function of time, as explained above. These are copied from
        the param_funcs argument of __init__, except that the default
        initial value function is filled in for parameters not present
        in the argument. Also, the function defined for 't' always
        returns t.
        self.PSf: a Constant object of dimension self.nparams, holding
        the initial values of the parameters.
        """
        self.param_names = [
            n for n, v in parameters.items() if (type(v) is float and n != 't')
        ]
        self.param_names.append('t')
        self.nparams = len(self.param_names)
        logVARIABLE('self.param_names', self.param_names)
        logVARIABLE('self.nparams', self.nparams)
        self.param_numbers = collections.OrderedDict(
            zip(self.param_names, itertools.count()))
        self.params0 = collections.OrderedDict(parameters)
        self.params0['t'] = 0.0
        self.param_funcs = param_funcs.copy()

        def identity(t, params={}):
            return t

        self.param_funcs['t'] = identity
        for n in self.param_names:
            if n not in self.param_funcs:

                def value0(t, params={}, v0=self.params0[n]):
                    return v0

                self.param_funcs[n] = value0
        self.PSf = Constant([self.params0[n] for n in self.param_names])
        return
    def _solve(self, z, x=None):
        # problem variables
        du = TrialFunction(self.V)                          # incremental displacement
        v = TestFunction(self.V)                            # test function
        u = Function(self.V)                                # displacement from previous iteration

        # kinematics
        ii = Identity(3)                                    # identity tensor dimension 3
        f = ii + grad(u)                                    # deformation gradient
        c = f.T * f                                         # right Cauchy-Green tensor

        # invariants of deformation tensors
        ic = tr(c)
        j = det(f)

        # elasticity parameters
        if type(z) in [list, np.ndarray]:
            param = self.param_remapper(z[0]) if self.param_remapper is not None else z[0]
        else:
            param = self.param_remapper(z) if self.param_remapper is not None else z

        e_var = variable(Constant(param))                   # Young's modulus
        nu = Constant(.3)                                   # Shear modulus (Lamè's second parameter)
        mu, lmbda = e_var / (2 * (1 + nu)), e_var * nu / ((1 + nu) * (1 - 2 * nu))

        # strain energy density, total potential energy
        psi = (mu / 2) * (ic - 3) - mu * ln(j) + (lmbda / 2) * (ln(j)) ** 2
        pi = psi * dx - self.time * dot(self.f, u) * self.ds(3)

        ff = derivative(pi, u, v)                           # compute first variation of pi
        jj = derivative(ff, u, du)                          # compute jacobian of f

        # solving
        if x is not None:
            numeric_evals = np.zeros(shape=(x.shape[1], len(self.times)))
            evals = np.zeros(shape=(x.shape[1], len(self.eval_times)))
        else:
            numeric_evals = None
            evals = None
        for it, t in enumerate(self.times):
            self.time.t = t
            self.solver(ff == 0, u, self.bcs, J=jj, bcs=self.bcs, solver_parameters=self.solver_parameters)
            if x is not None:
                numeric_evals[:, it] = np.log(np.array([-u(x_)[2] for x_ in x.T]).T)

        # time-interpolation
        if x is not None:
            for i in range(evals.shape[0]):
                evals[i, :] = np.interp(self.eval_times, self.times, numeric_evals[i, :])
        return (evals, u) if x is not None else u
Ejemplo n.º 7
0
    def update_geometric_quantities(self):
        """Updates the geometric quantities

		Updates the volume, surface area, and barycenters (after the
		mesh is updated)

		Returns
		-------
		None
		"""

        if not self.measure_hole:
            volume = fenics.assemble(Constant(1) * self.dx)
            barycenter_x = fenics.assemble(
                self.spatial_coordinate[0] * self.dx) / volume
            barycenter_y = fenics.assemble(
                self.spatial_coordinate[1] * self.dx) / volume
            if self.form_handler.mesh.geometric_dimension() == 3:
                barycenter_z = fenics.assemble(
                    self.spatial_coordinate[2] * self.dx) / volume
            else:
                barycenter_z = 0.0

        else:
            volume = self.delta_x * self.delta_y * self.delta_z - fenics.assemble(
                Constant(1) * self.dx)
            barycenter_x = (0.5 * (pow(self.x_end, 2) - pow(self.x_start, 2)) *
                            self.delta_y * self.delta_z - fenics.assemble(
                                self.spatial_coordinate[0] * self.dx)) / volume
            barycenter_y = (0.5 * (pow(self.y_end, 2) - pow(self.y_start, 2)) *
                            self.delta_x * self.delta_z - fenics.assemble(
                                self.spatial_coordinate[1] * self.dx)) / volume
            if self.form_handler.mesh.geometric_dimension() == 3:
                barycenter_z = (0.5 *
                                (pow(self.z_end, 2) - pow(self.z_start, 2)) *
                                self.delta_x * self.delta_y -
                                fenics.assemble(self.spatial_coordinate[2] *
                                                self.dx)) / volume
            else:
                barycenter_z = 0.0

        surface = fenics.assemble(Constant(1) * self.ds)

        self.current_volume.val = volume
        self.current_surface.val = surface
        self.current_barycenter_x.val = barycenter_x
        self.current_barycenter_y.val = barycenter_y
        self.current_barycenter_z.val = barycenter_z
Ejemplo n.º 8
0
    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)

        epsilon = Constant(arguments[Components().Diffusion])
        f = Expression("(1 - epsilon*4*pow(pi,2))*cos(2*pi*x[0])",\
                       epsilon=epsilon, degree=1)

        a = (epsilon * inner(grad(v), grad(w)) + inner(v, w)) * dx
        L = f * w * dx

        # solving the variational problem.
        v = Function(H)
        solve(a == L, v)

        self.solution.extend(v.vector().array())

        return [self.solution, time.clock() - t_start]
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
def dual_error_estimates(resolution):
    mesh = UnitSquareMesh(resolution, resolution)

    def all_boundary(_, on_boundary):
        return on_boundary

    zero = Constant(0.0)

    def a(u, v):
        return inner(grad(u), grad(v)) * dx

    def L(f, v):
        return f * v * dx

    # Primal problem
    f = Expression("32.*x[0]*(1. - x[0])+32.*x[1]*(1. - x[1])",
                   domain=mesh,
                   degree=5)
    ue = Expression("16.*x[0]*(1. - x[0])*x[1]*(1. - x[1])",
                    domain=mesh,
                    degree=5)

    Qp = FunctionSpace(mesh, 'CG', 1)
    bcp = DirichletBC(Qp, zero, all_boundary)

    u = TrialFunction(Qp)
    v = TestFunction(Qp)

    U = Function(Qp)
    solve(a(u, v) == L(f, v), U, bcp)

    # Dual problem
    Qd = FunctionSpace(mesh, 'CG', 2)
    psi = Constant(1.0)
    bcd = DirichletBC(Qd, zero, all_boundary)

    w = TestFunction(Qd)
    phi = TrialFunction(Qd)
    Phi = Function(Qd)
    solve(a(w, phi) == L(psi, w), Phi, bcd)

    # Compute errors
    e1 = compute_error(ue, U)
    e2 = assemble((inner(grad(U), grad(Phi)) - f * Phi) * dx)
    print("e1 = {}".format(e1))
    print("e2 = {}".format(e2))
Ejemplo n.º 11
0
 def __init__(self, *, V: Optional[FunctionSpace], mesh: Mesh, dt: float):
     V = V or FunctionSpace(mesh, "Lagrange", 1)
     self.V = V
     self.u = TrialFunction(V)
     self.v = TestFunction(V)
     self.P_prev = Function(V)
     self.theta_a = Constant(1.0)
     self.D_e = Constant(1.0)
     self.P_d = Constant(1.0)
     self.my_v = Constant(1.0)
     self.my_d = Constant(1.0)
     self.alpha_th = Constant(1.0)
     self.M_mm = Constant(1.0)
     self.q_h = Constant(1.0)
     self.T_s = project(Constant(-5.0), V)
     self.dt = Constant(dt)
     self.mesh = mesh
Ejemplo n.º 12
0
def problem_mix(T, dt, E, coupling, VV, boundaries, rho_s, lambda_, mu_s, f,
                bcs, **Solid_namespace):
    # Temporal parameters
    t = 0
    k = Constant(dt)

    # Split problem to two 1.order differential equations
    psi, phi = TestFunctions(VV)

    # Functions, wd is for holding the solution
    d_ = {}
    w_ = {}
    wd_ = {}
    for time in ["n", "n-1", "n-2", "n-3"]:
        if time == "n" and E not in [None, reference]:
            tmp_wd = Function(VV)
            wd_[time] = tmp_wd
            wd = TrialFunction(VV)
            w, d = split(wd)
        else:
            wd = Function(VV)
            wd_[time] = wd
            w, d = split(wd)

        d_[time] = d
        w_[time] = w

    # Time derivative
    if coupling == "center":
        G = rho_s / (2 * k) * inner(w_["n"] - w_["n-2"], psi) * dx
    else:
        G = rho_s / k * inner(w_["n"] - w_["n-1"], psi) * dx

    # Stress tensor
    G += inner(Piola2(d_, w_, k, lambda_, mu_s, E_func=E), grad(psi)) * dx

    # External forces, like gravity
    G -= rho_s * inner(f, psi) * dx

    # d-w coupling
    if coupling == "CN":
        G += inner(d_["n"] - d_["n-1"] - k * 0.5 *
                   (w_["n"] + w_["n-1"]), phi) * dx
    elif coupling == "imp":
        G += inner(d_["n"] - d_["n-1"] - k * w_["n"], phi) * dx
    elif coupling == "exp":
        G += inner(d_["n"] - d_["n-1"] - k * w_["n-1"], phi) * dx
    elif coupling == "center":
        G += innter(d_["n"] - d_["n-2"] - 2 * k * w["n-1"], phi) * dx
    else:
        print "The coupling %s is not implemented, 'CN', 'imp', and 'exp' are the only valid choices."
        sys.exit(0)

    # Solve
    if E in [None, reference]:
        solver_nonlinear(G, d_, w_, wd_, bcs, T, dt, **Solid_namespace)
    else:
        solver_linear(G, d_, w_, wd_, bcs, T, dt, **Solid_namespace)
Ejemplo n.º 13
0
 def set_time(self, t):
     self.t = t
     params = collections.OrderedDict(
         zip(self.param_names, self.PSf.values()))
     self.PSf.assign(
         Constant([
             self.param_funcs[n](t, params=params) for n in self.param_names
         ]))
     logVARIABLE('self.t', self.t)
     logVARIABLE(
         'collections.OrderedDict(zip(self.param_names, self.PSf.values()))',
         collections.OrderedDict(zip(self.param_names, self.PSf.values())))
Ejemplo n.º 14
0
 def __init__(self, *, V: Optional[FunctionSpace], mesh: Mesh,
              dt: float) -> None:
     V = V or FunctionSpace(mesh, "Lagrange", 1)
     self.V = V
     self.T = TrialFunction(V)
     self.v = TestFunction(V)
     self.T_prev = Function(V)
     self.P_s = Constant(1.0)
     self.c_s = Constant(1.0)
     self.k_e = Constant(1.0)
     self.Q_pc = Constant(1.0)
     self.Q_sw = Constant(1.0)
     self.Q_mm = Constant(1.0)
     self.dt = Constant(dt)
Ejemplo n.º 15
0
def solve_wave_equation(u0, u1, u_boundary, f, domain, mesh, degree):
    """Solving the wave equation using CG-CG method.

    Args:
        u0: Initial data.
        u1: Initial velocity.
        u_boundary: Dirichlet boundary condition.
        f: Right-hand side.
        domain: Space-time domain.
        mesh: Computational mesh.
        degree: CG(degree) will be used as the finite element.
    Outputs:
        uh: Numerical solution.
    """
    # Element
    V = FunctionSpace(mesh, "CG", degree)
    # Measures on the initial and terminal slice
    mask = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
    domain.get_initial_slice().mark(mask, 1)
    ends = ds(subdomain_data=mask)
    # Form
    g = Constant(((-1.0, 0.0), (0.0, 1.0)))
    u = TrialFunction(V)
    v = TestFunction(V)
    a = dot(grad(v), dot(g, grad(u))) * dx
    L = f * v * dx + u1 * v * ends(1)
    # Assembled matrices
    A = assemble(a, keep_diagonal=True)
    b = assemble(L, keep_diagonal=True)
    # Spatial boundary condition
    bc = DirichletBC(V, u_boundary, domain.get_spatial_boundary())
    bc.apply(A, b)
    # Temporal boundary conditions (by hand)
    (A, b) = apply_time_boundary_conditions(domain, V, u0, A, b)
    # Solve
    solver = LUSolver()
    solver.set_operator(A)
    uh = Function(V)
    solver.solve(uh.vector(), b)
    return uh
Ejemplo n.º 16
0
def _incell_geodesic_step_maker(g):
    """ Symplectic integrator of the Hamiltonian geodesic equation in a cell.
    """
    # initialize
    mesh = g.function_space().mesh()
    deg = g.ufl_element().degree()
    dim = g.ufl_shape[0]

    # choose solver and compute metric derivatives
    if deg == 0:
        # lowest degree Regge
        solver = _explicit_euler
        dg = [Constant(((0, ) * dim, ) * dim) for i in range(dim)]
    else:
        # for degree >= 1
        solver = _gauss6
        # compute the first derivatives of the metric globally
        # note: this is in fact more efficient than computing the derivative
        # cell by cell on the go. memeory is not a issue here.
        W = TensorFunctionSpace(mesh, 'DG', deg - 1)
        dg = [project(g.dx(i), W, solver_type='mumps') for i in range(dim)]

    def F(y, c):
        """ Hamiltonian geodesic equation as a system."""
        q = y[0:dim]
        p = y[dim:]
        ginv = inv(_eval_metric(g, c, q))
        nq = ginv.dot(p)
        np = array([
            0.5 * _eval_metric(dg[i], c, q).dot(ginv.dot(p)).dot(ginv.dot(p))
            for i in range(dim)
        ])
        return concatenate([nq, np])

    def step(c, t, y0, h):
        """ Geodesic solver wrapper."""
        return solver(lambda y: F(y, c), t, y0, h)

    return step
Ejemplo n.º 17
0
        def set_local_from_global(m, m_global_array):
            """
      Sets the local values of the distrbuted object m to the values contained 
      in the global array m_global_array.
      """
            # This had to be changed, because the dolfin-adjoint constant.Constant is
            # different from the constant of dolfin.
            if type(m) == Constant:
                if m.rank() == 0:
                    m.assign(m_global_array[0])

                else:
                    m.assign(Constant(tuple(m_global_array)))

            elif type(m) in (function.Function, functions.function.Function):
                begin, end = m.vector().local_range()
                m_a_local = m_global_array[begin:end]
                m.vector().set_local(m_a_local)
                m.vector().apply('insert')

            else:
                raise TypeError, 'Unknown parameter type'
Ejemplo n.º 18
0
u_n = interpolate(u_D, V)
u_n.rename("Temperature", "")

precice, precice_dt, initial_data = None, 0.0, None

# Initialize the adapter according to the specific participant
if problem is ProblemType.DIRICHLET:
    precice = Adapter(adapter_config_filename="precice-adapter-config-D.json")
    precice_dt = precice.initialize(coupling_boundary, read_function_space=V, write_object=f_N_function)
elif problem is ProblemType.NEUMANN:
    precice = Adapter(adapter_config_filename="precice-adapter-config-N.json")
    precice_dt = precice.initialize(coupling_boundary, read_function_space=V_g, write_object=u_D_function)

boundary_marker = False

dt = Constant(0)
dt.assign(np.min([fenics_dt, precice_dt]))

# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Expression('beta + gamma*x[0]*x[0] - 2*gamma*t - 2*(1-gamma) - 2*alpha', degree=2, alpha=alpha,
               beta=beta, gamma=gamma, t=0)
F = u * v / dt * dx + dot(grad(u), grad(v)) * dx - (u_n / dt + f) * v * dx

bcs = [DirichletBC(V, u_D, remaining_boundary)]

# Set boundary conditions at coupling interface once wrt to the coupling expression
coupling_expression = precice.create_coupling_expression()
if problem is ProblemType.DIRICHLET:
    # modify Dirichlet boundary condition on coupling interface
Ejemplo n.º 19
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
    u_ini = Expression("1", degree=1)
    bc = DirichletBC(V, u_ini, AllBoundary())
elif args.drain:
    u_ini = Expression("0", degree=1)
    bc = DirichletBC(V, u_ini, RightBoundary())


u_n = interpolate(u_ini, V)


dt = precice.initialize(AllDomain(), read_function_space=V, write_object=u_n)
volume_term = precice.create_coupling_expression()
f = Function(V)


dt_inv = Constant(1 / dt)

diffusion_source = 1
diffusion_drain = 1
if args.source:
    F = dt_inv * (u - u_n) * v * dx - (f - u_ini) * v * dx + diffusion_source * inner(grad(u), grad(v)) * dx
elif args.drain:
    F = dt_inv * (u - u_n) * v * dx - (f - u) * v * dx + diffusion_drain * inner(grad(u), grad(v)) * dx

# Time-stepping
u_np1 = Function(V)
if args.source:
    u_n.rename("Source-Data", "")
    u_np1.rename("Source-Data", "")
elif args.drain:
    u_n.rename("Drain-Data", "")
Ejemplo n.º 21
0
def solve_linear_pde(
    u_D_array,
    T,
    D=1,
    C1=0,
    num_r=100,
    min_r=0.001,
    tol=1e-14,
    degree=1,
):
    # disable logging
    set_log_active(False)

    num_t = len(u_D_array)
    dt = T / num_t  # time step size

    mesh = IntervalMesh(num_r, min_r, 1)
    r = mesh.coordinates().flatten()
    r_args = np.argsort(r)
    V = FunctionSpace(mesh, "P", 1)

    # Define boundary conditions
    # Dirichlet condition at R
    def boundary_at_R(x, on_boundary):
        return on_boundary and near(x[0], 1, tol)

    D = Constant(D)
    u_D = Constant(u_D_array[0])
    bc_at_R = DirichletBC(V, u_D, boundary_at_R)

    # Define initial values for free c
    c_0 = Expression("C1", C1=C1, degree=degree)
    c_n = interpolate(c_0, V)

    # Define variational problem
    c = TrialFunction(V)
    v = TestFunction(V)

    # define Constants
    r_squ = Expression("4*pi*pow(x[0],2)", degree=degree)

    F_tmp = (D * dt * inner(grad(c), grad(v)) * r_squ * dx +
             c * v * r_squ * dx - c_n * v * r_squ * dx)
    a, L = lhs(F_tmp), rhs(F_tmp)
    u = Function(V)

    data_c = np.zeros((num_t, len(r)), dtype=np.double)

    for n in range(num_t):
        u_D.assign(u_D_array[n])

        # Compute solution
        solve(a == L, u, bc_at_R)
        data_c[n, :] = u.vector().vec().array

        c_n.assign(u)

    data_c = data_c[:, r_args[::-1]]
    r = r[r_args]

    return data_c, r
Ejemplo n.º 22
0
y_top = 0
y_bottom = y_top - .25
x_left = 0
x_right = x_left + 1

p0 = Point(x_left, y_bottom, 0)
p1 = Point(x_right, y_top, 1)

mesh = RectangleMesh(p0, p1, nx, ny)
V = FunctionSpace(mesh, 'P', 1)

alpha = 1  # m^2/s, https://en.wikipedia.org/wiki/Thermal_diffusivity
k = 100  # kg * m / s^3 / K, https://en.wikipedia.org/wiki/Thermal_conductivity

# Define boundary condition
u_D = Constant('310')
u_D_function = interpolate(u_D, V)
# Define flux in x direction on coupling interface (grad(u_D) in normal direction)
f_N = Constant('0')
f_N_function = interpolate(f_N, V)

coupling_boundary = TopBoundary()
bottom_boundary = BottomBoundary()

# Define initial value
u_n = interpolate(u_D, V)
u_n.rename("T", "")

# Adapter definition and initialization
precice = Adapter(adapter_config_filename="precice-adapter-config.json")
Ejemplo n.º 23
0
    determines whether a node is on the coupling boundary

    """
    return on_boundary and ((abs(x[1] - 1) < tol)
                            or abs(abs(x[0]) - W / 2) < tol)


# Geometry and material properties
dim = 2  # number of dimensions
H = 1
W = 0.1
rho = 3000
E = 4000000
nu = 0.3

mu = Constant(E / (2.0 * (1.0 + nu)))

lambda_ = Constant(E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)))

# create Mesh
n_x_Direction = 4
n_y_Direction = 26
mesh = RectangleMesh(Point(-W / 2, 0), Point(W / 2, H), n_x_Direction,
                     n_y_Direction)

h = Constant(H / n_y_Direction)

# create Function Space
V = VectorFunctionSpace(mesh, 'P', 2)

# BCs
Ejemplo n.º 24
0
    def __init__(self, form_handler):
        """Initializes the regularization

		Parameters
		----------
		form_handler : cashocs._forms.ShapeFormHandler
			the corresponding shape form handler object
		"""

        self.form_handler = form_handler
        self.config = self.form_handler.config

        self.dx = fenics.Measure('dx', self.form_handler.mesh)
        self.ds = fenics.Measure('ds', self.form_handler.mesh)

        self.spatial_coordinate = fenics.SpatialCoordinate(
            self.form_handler.mesh)

        self.measure_hole = self.config.getboolean('Regularization',
                                                   'measure_hole',
                                                   fallback=False)
        if self.measure_hole:
            self.x_start = self.config.getfloat('Regularization',
                                                'x_start',
                                                fallback=0.0)
            self.x_end = self.config.getfloat('Regularization',
                                              'x_end',
                                              fallback=1.0)
            if not self.x_end >= self.x_start:
                raise ConfigError('Regularization', 'x_end',
                                  'x_end must not be smaller than x_start.')
            self.delta_x = self.x_end - self.x_start

            self.y_start = self.config.getfloat('Regularization',
                                                'y_start',
                                                fallback=0.0)
            self.y_end = self.config.getfloat('Regularization',
                                              'y_end',
                                              fallback=1.0)
            if not self.y_end >= self.y_start:
                raise ConfigError('Regularization', 'y_end',
                                  'y_end must not be smaller than y_start.')
            self.delta_y = self.y_end - self.y_start

            self.z_start = self.config.getfloat('Regularization',
                                                'z_start',
                                                fallback=0.0)
            self.z_end = self.config.getfloat('Regularization',
                                              'z_end',
                                              fallback=1.0)
            if not self.z_end >= self.z_start:
                raise ConfigError('Regularization', 'z_end',
                                  'z_end must not be smaller than z_start.')
            self.delta_z = self.z_end - self.z_start
            if self.form_handler.mesh.geometric_dimension() == 2:
                self.delta_z = 1.0

        self.mu_volume = self.config.getfloat('Regularization',
                                              'factor_volume',
                                              fallback=0.0)
        self.target_volume = self.config.getfloat('Regularization',
                                                  'target_volume',
                                                  fallback=0.0)
        if self.config.getboolean('Regularization',
                                  'use_initial_volume',
                                  fallback=False):
            if not self.measure_hole:
                self.target_volume = fenics.assemble(Constant(1) * self.dx)
            else:
                self.target_volume = self.delta_x * self.delta_y * self.delta_z - fenics.assemble(
                    Constant(1.0) * self.dx)

        self.mu_surface = self.config.getfloat('Regularization',
                                               'factor_surface',
                                               fallback=0.0)
        self.target_surface = self.config.getfloat('Regularization',
                                                   'target_surface',
                                                   fallback=0.0)
        if self.config.getboolean('Regularization',
                                  'use_initial_surface',
                                  fallback=False):
            self.target_surface = fenics.assemble(Constant(1) * self.ds)

        self.mu_barycenter = self.config.getfloat('Regularization',
                                                  'factor_barycenter',
                                                  fallback=0.0)
        self.target_barycenter_list = json.loads(
            self.config.get('Regularization',
                            'target_barycenter',
                            fallback='[0,0,0]'))

        if not type(self.target_barycenter_list) == list:
            raise ConfigError('Regularization', 'target_barycenter',
                              'This has to be a list.')

        if self.form_handler.mesh.geometric_dimension() == 2 and len(
                self.target_barycenter_list) == 2:
            self.target_barycenter_list.append(0.0)

        if self.config.getboolean('Regularization',
                                  'use_initial_barycenter',
                                  fallback=False):
            self.target_barycenter_list = [0.0, 0.0, 0.0]
            if not self.measure_hole:
                volume = fenics.assemble(Constant(1) * self.dx)
                self.target_barycenter_list[0] = fenics.assemble(
                    self.spatial_coordinate[0] * self.dx) / volume
                self.target_barycenter_list[1] = fenics.assemble(
                    self.spatial_coordinate[1] * self.dx) / volume
                if self.form_handler.mesh.geometric_dimension() == 3:
                    self.target_barycenter_list[2] = fenics.assemble(
                        self.spatial_coordinate[2] * self.dx) / volume
                else:
                    self.target_barycenter_list[2] = 0.0

            else:
                volume = self.delta_x * self.delta_y * self.delta_z - fenics.assemble(
                    Constant(1) * self.dx)
                self.target_barycenter_list[0] = (
                    0.5 * (pow(self.x_end, 2) - pow(self.x_start, 2)) *
                    self.delta_y * self.delta_z - fenics.assemble(
                        self.spatial_coordinate[0] * self.dx)) / volume
                self.target_barycenter_list[1] = (
                    0.5 * (pow(self.y_end, 2) - pow(self.y_start, 2)) *
                    self.delta_x * self.delta_z - fenics.assemble(
                        self.spatial_coordinate[1] * self.dx)) / volume
                if self.form_handler.mesh.geometric_dimension() == 3:
                    self.target_barycenter_list[2] = (
                        0.5 * (pow(self.z_end, 2) - pow(self.z_start, 2)) *
                        self.delta_x * self.delta_y - fenics.assemble(
                            self.spatial_coordinate[2] * self.dx)) / volume
                else:
                    self.target_barycenter_list[2] = 0.0

        if not (self.mu_volume >= 0.0 and self.mu_surface >= 0.0
                and self.mu_barycenter >= 0.0):
            raise ConfigError(
                'Regularization', 'mu_volume, mu_surface, or mu_barycenter',
                'All regularization constants have to be nonnegative.')

        if self.mu_volume > 0.0 or self.mu_surface > 0.0 or self.mu_barycenter > 0.0:
            self.has_regularization = True
        else:
            self.has_regularization = False

        # self.relative_scaling = self.config.getboolean('Regularization', 'relative_scaling')
        # if self.relative_scaling and self.has_regularization:
        # 	self.scale_weights()

        self.current_volume = fenics.Expression('val', degree=0, val=1.0)
        self.current_surface = fenics.Expression('val', degree=0, val=1.0)
        self.current_barycenter_x = fenics.Expression('val', degree=0, val=0.0)
        self.current_barycenter_y = fenics.Expression('val', degree=0, val=0.0)
        self.current_barycenter_z = fenics.Expression('val', degree=0, val=0.0)
Ejemplo n.º 25
0
    def compute_shape_derivative(self):
        """Computes the part of the shape derivative that comes from the regularization

		Returns
		-------
		ufl.form.Form
			The weak form of the shape derivative coming from the regularization

		"""

        V = self.form_handler.test_vector_field
        if self.has_regularization:

            n = fenics.FacetNormal(self.form_handler.mesh)
            I = fenics.Identity(self.form_handler.mesh.geometric_dimension())

            self.shape_form = Constant(self.mu_surface) * (
                self.current_surface - Constant(self.target_surface)) * t_div(
                    V, n) * self.ds

            if not self.measure_hole:
                self.shape_form += Constant(self.mu_volume) * (
                    self.current_volume -
                    Constant(self.target_volume)) * div(V) * self.dx
                self.shape_form += Constant(self.mu_barycenter)*(self.current_barycenter_x - Constant(self.target_barycenter_list[0]))\
                         *(self.current_barycenter_x/self.current_volume*div(V) + 1/self.current_volume*(V[0] + self.spatial_coordinate[0]*div(V)))*self.dx \
                       + Constant(self.mu_barycenter)*(self.current_barycenter_y - Constant(self.target_barycenter_list[1]))\
                         *(self.current_barycenter_y/self.current_volume*div(V) + 1/self.current_volume*(V[1] + self.spatial_coordinate[1]*div(V)))*self.dx

                if self.form_handler.mesh.geometric_dimension() == 3:
                    self.shape_form += Constant(self.mu_barycenter)*(self.current_barycenter_z - Constant(self.target_barycenter_list[2]))\
                           *(self.current_barycenter_z/self.current_volume*div(V) + 1/self.current_volume*(V[2] + self.spatial_coordinate[2]*div(V)))*self.dx

            else:
                self.shape_form -= Constant(self.mu_volume) * (
                    self.current_volume -
                    Constant(self.target_volume)) * div(V) * self.dx
                self.shape_form += Constant(self.mu_barycenter)*(self.current_barycenter_x - Constant(self.target_barycenter_list[0]))\
                         *(self.current_barycenter_x/self.current_volume*div(V) - 1/self.current_volume*(V[0] + self.spatial_coordinate[0]*div(V)))*self.dx \
                       + Constant(self.mu_barycenter)*(self.current_barycenter_y - Constant(self.target_barycenter_list[1]))\
                         *(self.current_barycenter_y/self.current_volume*div(V) - 1/self.current_volume*(V[1] + self.spatial_coordinate[1]*div(V)))*self.dx

                if self.form_handler.mesh.geometric_dimension() == 3:
                    self.shape_form += Constant(self.mu_barycenter)*(self.current_barycenter_z - Constant(self.target_barycenter_list[2]))\
                             *(self.current_barycenter_z/self.current_volume*div(V) - 1/self.current_volume*(V[2] + self.spatial_coordinate[2]*div(V)))*self.dx

            return self.shape_form

        else:
            dim = self.form_handler.mesh.geometric_dimension()
            return inner(fenics.Constant([0] * dim), V) * self.dx
Ejemplo n.º 26
0
    def __init__(
        self,
        nu=Constant(0.001),
        beta=Constant((5.0, 0.0)),
        zeta=Constant(1000.0),
        delta=Constant(0.01),
        gamma=Constant(1000.0),
        time_step=0.00125,
        global_mesh_size=800,
        local_mesh_size_fluid=1,
        local_mesh_size_solid=1,
        number_elements_horizontal=80,
        number_elements_vertical=20,
        tau=Constant(0.7),
        absolute_tolerance_relaxation=1.0e-12,
        relative_tolerance_relaxation=1.0e-6,
        max_iterations_relaxation=50,
        epsilon=1.0e-6,
        absolute_tolerance_newton=1.0e-12,
        relative_tolerance_newton=1.0e-6,
        max_iterations_newton=15,
        tolerance_gmres=1.0e-12,
        max_iterations_gmres=10,
        relaxation=False,
        shooting=True,
        goal_functional_fluid=True,
        goal_functional_solid=False,
    ):

        # Define problem parameters
        self.NU = nu
        self.BETA = beta
        self.ZETA = zeta
        self.DELTA = delta
        self.GAMMA = gamma

        # Define time step on the coarsest level
        self.TIME_STEP = time_step

        # Define number of macro time steps on the coarsest level
        self.GLOBAL_MESH_SIZE = global_mesh_size

        # Define number of micro time-steps for fluid
        self.LOCAL_MESH_SIZE_FLUID = local_mesh_size_fluid

        # Define number of micro time-steps for solid
        self.LOCAL_MESH_SIZE_SOLID = local_mesh_size_solid

        # Define number of mesh cells
        self.NUMBER_ELEMENTS_HORIZONTAL = number_elements_horizontal
        self.NUMBER_ELEMENTS_VERTICAL = number_elements_vertical

        # Define relaxation parameters
        self.TAU = tau
        self.ABSOLUTE_TOLERANCE_RELAXATION = absolute_tolerance_relaxation
        self.RELATIVE_TOLERANCE_RELAXATION = relative_tolerance_relaxation
        self.MAX_ITERATIONS_RELAXATION = max_iterations_relaxation

        # Define parameters for Newton's method
        self.EPSILON = epsilon
        self.ABSOLUTE_TOLERANCE_NEWTON = absolute_tolerance_newton
        self.RELATIVE_TOLERANCE_NEWTON = relative_tolerance_newton
        self.MAX_ITERATIONS_NEWTON = max_iterations_newton

        # Define parameters for GMRES method
        self.TOLERANCE_GMRES = tolerance_gmres
        self.MAX_ITERATIONS_GMRES = max_iterations_gmres

        # Choose decoupling method
        self.RELAXATION = relaxation
        self.SHOOTING = shooting

        # Choose goal functional
        self.GOAL_FUNCTIONAL_FLUID = goal_functional_fluid
        self.GOAL_FUNCTIONAL_SOLID = goal_functional_solid
Ejemplo n.º 27
0
boundaries = FacetFunction("size_t", mesh)
boundaries.set_all(0)
BarLeftSide.mark(boundaries, 1)

# BCs
bc1 = DirichletBC(VV.sub(0), ((0, 0)), boundaries, 1)
bc2 = DirichletBC(VV.sub(1), ((0, 0)), boundaries, 1)
bcs = [bc1, bc2]

# Parameters:
rho_s = 1.0e3
mu_s = 0.5e6
nu_s = 0.4
E_1 = 1.4e6
lambda_ = nu_s * 2. * mu_s / (1. - 2. * nu_s)
f = Constant((0, -2.))
beta = Constant(0.25)

probe = Probes(coord, V)


def action(wd_, t):
    time.append(t)
    probe(wd_["n"].sub(1))


# Set up different numerical schemes
# TODO: Add options to chose solver and change solver parameters
common = {
    "space": "mixedspace",
    "E": None,  # Full implicte, not energy conservative
Ejemplo n.º 28
0
y_bottom = y_top - .25
x_left = 0
x_right = x_left + 1

p0 = Point(x_left, y_bottom, 0)
p1 = Point(x_right, y_top, 1)

mesh = RectangleMesh(p0, p1, nx, ny)
V = FunctionSpace(mesh, 'P', 1)
V_g = VectorFunctionSpace(mesh, 'P', 1)

alpha = 1  # m^2/s, https://en.wikipedia.org/wiki/Thermal_diffusivity
k = 100  # kg * m / s^3 / K, https://en.wikipedia.org/wiki/Thermal_conductivity

# Define boundary condition
u_D = Constant('310')
u_D_function = interpolate(u_D, V)
# We will only exchange flux in y direction on coupling interface. No initialization necessary.
V_flux_y = V_g.sub(1)

coupling_boundary = TopBoundary()
bottom_boundary = BottomBoundary()

# Define initial value
u_n = interpolate(u_D, V)
u_n.rename("T", "")

# Adapter definition and initialization
precice = Adapter(adapter_config_filename="precice-adapter-config.json")

precice_dt = precice.initialize(coupling_boundary,
Ejemplo n.º 29
0
                  interpolation_strategy=interpolation_strategy)

if problem is ProblemType.DIRICHLET:
    precice_dt = precice.initialize(coupling_subdomain=coupling_boundary,
                                    mesh=mesh,
                                    read_field=u_D_function,
                                    write_field=f_N_function,
                                    u_n=u_n)
elif problem is ProblemType.NEUMANN:
    precice_dt = precice.initialize(coupling_subdomain=coupling_boundary,
                                    mesh=mesh,
                                    read_field=f_N_function,
                                    write_field=u_D_function,
                                    u_n=u_n)

dt = Constant(0)
dt.assign(np.min([fenics_dt, precice_dt]))

# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Expression(
    'beta + gamma * x[0] * x[0] - 2 * gamma * t - 2 * (1-gamma) - 2 * alpha',
    degree=2,
    alpha=alpha,
    beta=beta,
    gamma=gamma,
    t=0)
F = u * v / dt * dx + dot(grad(u), grad(v)) * dx - (u_n / dt + f) * v * dx

if problem is ProblemType.DIRICHLET:
    determines whether a node is on the coupling boundary
    
    """
    return on_boundary and (not (abs(x[1] < tol))
                            or abs(abs(x[0]) - W / 2) < tol)


# Dimensionless Geometry and material properties
d = 2  #number of dimensions
H = 1
W = 0.1
rho = 1000
E = 100000.0
nu = 0.3

mu = Constant(E / (2.0 * (1.0 + nu)))

lambda_ = Constant(E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)))

# create Mesh
n_x_Direction = 5
n_y_Direction = 25
mesh = RectangleMesh(Point(-W / 2, 0), Point(W / 2, H), n_x_Direction,
                     n_y_Direction)

#create Function Space
V = VectorFunctionSpace(mesh, 'P', 2)

#BCs
tol = 1E-14