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() 
예제 #2
0
 def plotSol(self, func):
     (Asol, Qsol) = self.U0.split()
     if func == "A":
         fe.plot(Asol)
     elif func == "Q":
         fe.plot(Qsol)
     else:
         raise ValueError('input can either be "Q" or "A"')
예제 #3
0
def impl_dyn(w0, dt=1.e-5, t_end=1.e-4, show_plots=False):

    (u0, p0, v0) = fe.split(w0)

    bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_upv.sub(0), V_upv.sub(1),
                                            V_upv.sub(2), boundaries)

    # Lagrange function (without constraint)

    (u1, p1, v1) = fe.TrialFunctions(V_upv)
    (eta, q, xi) = fe.TestFunctions(V_upv)

    F = deformation_grad(u1)
    I_1, I_2, J = invariants(F)
    F_iso = isochronic_deformation_grad(F, J)
    #I_1_iso, I_2_iso  = invariants(F_iso)[0:2]

    W = material_mooney_rivlin(I_1, I_2, c_10, c_01)
    g = incompr_constr(J)
    L = -W
    P = first_piola_stress(L, F)
    G = incompr_stress(g, F)

    a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v1, eta) * dx
    a_dyn_p = inner(g, q) * dx
    a_dyn_v = rho * inner(v1 - v0, xi) * dx + dt * (inner(
        P, grad(xi)) * dx + inner(p1 * G, grad(xi)) * dx - inner(B, xi) * dx)

    a = a_dyn_u + a_dyn_p + a_dyn_v

    w1 = fe.Function(V_upv)

    sol = []

    t = 0
    while t < t_end:
        print("progress: %f" % (100. * t / t_end))

        fe.solve(a == 0, w1, bcs_u + bcs_p + bcs_v)

        if fe.norm(w1.vector()) > 1e7:
            print('ERROR: norm explosion')
            break

        # update initial values for next step
        w0.assign(w1)
        t += dt

        if show_plots:
            # plot result
            fe.plot(w0.sub(0), mode='displacement')
            plt.show()

        # save solutions
        sol.append(Solution(t=t))
        sol[-1].upv.assign(w0)

    return sol, W, kappa
예제 #4
0
 def drawSolution(self):
     plt.figure(figsize=(10, 5))
     plt.subplot(1, 2, 1)
     imuR = fe.plot(self.uReal, title='Real part of the solution')
     plt.colorbar(imuR)
     plt.subplot(1, 2, 2)
     imuI = fe.plot(self.uImag, title='Imaginary part of the solution')
     plt.colorbar(imuI)
     plt.show()
예제 #5
0
 def plot_diffusion_coef(self, entries='01'):
     indices = [int(entry) for entry in entries]
     vector = np.zeros(2)
     vector[indices] = 1
     print(vector)
     fevec = fe.Constant(vector)
     val = fe.dot(self.composed_diff_coef, fevec)
     val = fe.dot(fevec, val)
     fe.plot(val, mesh=self.mesh)
     plt.show()
예제 #6
0
 def _solve_cell_problems(self):
     # Solves the cell problems (one for each space dimension)
     w = fe.TrialFunction(self.function_space)
     v = fe.TestFunction(self.function_space)
     a = self.a_y * fe.dot(fe.grad(w), fe.grad(v)) * fe.dx
     for i in range(self.dim):
         L = fe.div(self.a_y * self.e_is[i]) * v * fe.dx
         bc = fe.DirichletBC(self.function_space, self.bc_function,
                             PoissonSolver.boundary)
         fe.solve(a == L, self.cell_solutions[i], bc)
         fe.plot(self.cell_solutions[i])
예제 #7
0
    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'))
예제 #8
0
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
예제 #9
0
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
예제 #10
0
 def solve_pde(self):
     u = fe.Function(self.function_space)
     v = fe.TestFunction(self.function_space)
     u_old = fe.project(self.u_0, self.function_space)
     # Todo: Average right hand side if we choose it non-constant
     flux = self.dt * fe.dot(
         self.composed_diff_coef *
         (fe.grad(u) + self.drift_function(u)), fe.grad(v)) * fe.dx
     bilin_part = u * v * fe.dx + flux
     funtional_part = self.rhs * v * self.dt * fe.dx + u_old * v * fe.dx
     full_form = bilin_part - funtional_part
     num_steps = int(self.T / self.dt) + 1
     bc = fe.DirichletBC(self.function_space, self.u_boundary,
                         MembraneSimulator.full_boundary)
     for n in range(num_steps):
         print("Step %d" % n)
         self.time += self.dt
         fe.solve(full_form == 0, u, bc)
         # fe.plot(u)
         # plt.show()
         # print(fe.errornorm(u_old, u))
         u_old.assign(u)
         self.file << (u, self.time)
     f = fe.plot(u)
     plt.rc('text', usetex=True)
     plt.colorbar(f, format='%.0e')
     plt.title(r'Macroscopic density profile of $u(x,t)$ at $t=1$')
     plt.xlabel(r'$x_1$')
     plt.ylabel(r'$x_2$')
     plt.show()
예제 #11
0
def fplot(f, compare=None, dim=None, xmin=0, xmax=1, npoints=100,
          axes=None, legend=None, mesh=None):
    """plot a function f

    Positional parameter:
    f: the function to be plotted

    Keyword parameters:
    dim=1: dimensionality of the argument of f
    npoints=100: number points to plot
    xmin=0, xmax=1: range to plot
    """
    if not dim:
        if mesh:
            dim = mesh.geometry().dim()
        else:
            dim = 1
    if (dim > 1):
        #
        # compare ignored in this case
        #
        p = fe.plot(f, mesh=mesh, axes=axes)
        plt.colorbar(p)
        return p
    if not axes:
        axes = plt.gca()
    xs = np.linspace(xmin, xmax, npoints)
    if compare:
        p = axes.plot(xs, [f(x) for x in xs], 'b',
                      xs, [compare(x) for x in xs], 'r')
        if legend:
            plt.legend(p, legend)
    else:
        p = axes.plot(xs, [f(x) for x in xs], 'b')
    return p
def test_video_loading():
    m = UnitSquareMesh(30, 30)
    V = FunctionSpace(m, "CG", 4)

    video = VideoData(element=V.ufl_element())
    video.load_video("video_data/ach12.mp4")

    print(video)

    plot(video, mesh=m)
    plt.show()

    video.set_time(10000.)
    plot(video, mesh=m)
    plt.show()

    assert True
예제 #13
0
    def run(self):
        domain = self._create_domain()
        mesh = generate_mesh(domain, MESH_PTS)
        
        # fe.plot(mesh)
        # plt.show()

        self._create_boundary_expression()
        
        Omega = fe.FunctionSpace(mesh, 'CG', 2)
        sigma = self.conductivity
        Theta = fe.Function(Omega)
        v = fe.TestFunction(Omega)
        LHS = sigma * fe.inner(fe.grad(Theta), fe.grad(v)) * fe.dx - self.boundary_exp * v * fe.ds

        fe.solve(LHS == 0, Theta, solver_parameters={"newton_solver": {"absolute_tolerance": 1e-4}})

        fe.plot(Theta, "solution")
        plt.show()
def plot(eigenvalues: np.array, eigenfunctions: List[fenics.Function],
         **kwargs) -> None:
    """Plot eigenvalues and eigenfunctions.

    Convenience function for plotting the results of the eigenfunction
    decomposition.

    """
    num_eigenpairs = len(eigenvalues)
    assert num_eigenpairs == len(eigenfunctions)

    import matplotlib.pyplot as plt

    k = int(np.ceil(np.sqrt(num_eigenpairs - 1)))

    for i, (ew, ev) in enumerate(zip(eigenvalues[1:], eigenfunctions[1:])):
        ax = plt.subplot(k, k, i + 1)
        ax.axis('off')
        ax.set_title('$\lambda_{{{}}} = {:.2f}$'.format(i + 1, ew))
        fenics.plot(ev, **kwargs)
예제 #15
0
 def solve_pde(self, name='pde'):
     u = fe.Function(self.function_space)
     v = fe.TestFunction(self.function_space)
     u_old = fe.project(self.u_0, self.function_space)
     # Todo: Average right hand side if we choose it non-constant
     flux = self.dt * fe.dot(
         self.composed_diff_coef *
         (fe.grad(u) + self.drift_function(u)), fe.grad(v)) * fe.dx
     bilin_part = u * v * fe.dx + flux
     funtional_part = self.rhs * v * self.dt * fe.dx + u_old * v * fe.dx
     full_form = bilin_part - funtional_part
     num_steps = int(self.T / self.dt) + 1
     bc = fe.DirichletBC(self.function_space, self.u_boundary,
                         MembraneSimulator.full_boundary)
     for n in range(num_steps):
         print("Step %d" % n)
         self.time += self.dt
         fe.solve(full_form == 0, u, bc)
         fe.plot(u)
         plt.savefig('images/plt%d.pdf' % n)
         plt.show()
         # print(fe.errornorm(u_old, u))
         u_old.assign(u)
         self.file << (u, self.time)
     plt.figure()
     # u=u+1E-9
     f = fe.plot(u)
     # f = fe.plot(u,norm=colors.LogNorm(vmin=1E-9,vmax=2E-4))
     plt.rc('text', usetex=True)
     plt.colorbar(f, format='%.0e')
     plt.title(r'Macroscopic density $u(x,t=1)$ for $\alpha=%.1f$' %
               MembraneSimulator.alpha)
     plt.xlabel(r'$x_1$')
     plt.ylabel(r'$x_2$')
     plt.savefig('%s.pdf' % name)
     plt.show()
def demo_video_complex():

    #comm_mpi4py = fe.mpi_comm_world().tompi4py()

    #rk = comm_mpi4py.Get_rank()
    #if rk == 0:
    g = GmshInterface("geo/movie_2.geo", dim=2)
    g.generate_xml("geo/movie_2.xml",lc=1.,replace=False)

    #comm_mpi4py.Barrier()

    d.load_mesh("geo/movie_2.xml")
    d.boundary_fnc = lambda x: x[0] > -5. and x[1] < 5.
    fe.plot(d.mesh)
    plt.show()


    d.compute_potential_flow()

    fe.plot(d.flow)
    plt.show()
    d.load_video("video_data/ach12.mp4")

    d.compute_conv_diff_reac_video(video_ref=[0,0],video_size=[99.,69.])
예제 #17
0
    def plot(object, **kwargs):
        """
        Plot the given object based on its type.
        Parameters
        ----------
        object: The object to be plotted.
        **kwargs: Same kwargs as the ones defined for fenics.plot().
        Check docs to see all available arguments.
        Returns
        -------
        None.
        """
        kwargs.setdefault('figsize', (12, 7))

        # Check if the given object is a mesh or submesh
        plt.figure(figsize=kwargs.get('figsize'))
        kwargs.pop('figsize')
        pp = fn.plot(object, **kwargs)
        plt.colorbar(pp)
        plt.show()
예제 #18
0
def plot_curves(t, soln, opts=defplotopts):
    min = soln.meshstats['xmin']
    max = soln.meshstats['xmax']
    nplots = len(opts['subspaces'])
    names = opts['names']
    dim = soln.dim
    soln.load(t)
    width = 4.0 * nplots + 2.0 * (nplots - 1)
    fig = plt.figure(1, figsize=(width, 5))
    currplot = 1
    fig.clf()
    params = soln.params(t)
    try:
        labelval = params[opts['label']]
    except KeyError:
        labelval = t
    label = '%s = %.4g' % (opts['label'], labelval)
    for name, subspace in zip(names, opts['subspaces']):
        ra = fig.add_subplot(1, nplots, currplot)
        if type(subspace) == int:
            ssfunc = soln.function.sub(subspace)
        elif subspace == 'V':
            ssfunc = Vufl(soln, t)
        if dim == 1:
            p = fplot(ssfunc, xmin=min, xmax=max)
            plt.title("%s\n%s" % (name, label))
        elif dim == 2:
            p = fe.plot(ssfunc, title="%s\n%s" % (name, label))
            if opts['colorbar']:
                try:
                    plt.colorbar(p)
                except AttributeError:
                    pass
        else:
            raise KSDGException("can only plot 1 or 2 dimensions")
        dofs = np.array(ssfunc.function_space().dofmap().dofs())
        fvec = ssfunc.vector()[:]
        ymin, ymax = np.min(fvec[dofs]), np.max(fvec[dofs])
        plt.xlabel('(%7g, %7g)' % (ymin, ymax), axes=ra)
        currplot += 1
    return (fig)
예제 #19
0
def plot(f):
    """ This patches `fenics.plot` which is incorrect for functions on refind 1D meshes. 
    
    See https://bitbucket.org/fenics-project/dolfin/issues/1029/plotting-1d-function-incorrectly-ignores
    """
    if (type(f) == fenics.Function) and (
            f.function_space().mesh().topology().dim() == 1):

        mesh = f.function_space().mesh()

        C = f.compute_vertex_values(mesh)

        X = list(mesh.coordinates()[:, 0])

        sorted_C = [c for _, c in sorted(zip(X, C))]

        return matplotlib.pyplot.plot(sorted(X), sorted_C)

    else:

        return fenics.plot(f)
예제 #20
0
def preprocess(fname):
    """Loads mesh, defines system of equations and prepares system matrix."""
    mesh = fe.Mesh(fname + ".xml")
    if INPUTS['saving']['mesh']:
        fe.File(fname + "_mesh.pvd") << mesh
    boundaries = fe.MeshFunction('size_t', mesh, fname + '_facet_region.xml')
    if INPUTS['saving']['boundaries']:
        fe.File(fname + "_subdomains.pvd") << boundaries
    subdomains = fe.MeshFunction('size_t', mesh,
                                 fname + '_physical_region.xml')
    if INPUTS['saving']['subdomains']:
        fe.File(fname + "_subdomains.pvd") << subdomains
    if INPUTS['plotting']['mesh']:
        fe.plot(mesh, title='Mesh')
    if INPUTS['plotting']['boundaries']:
        fe.plot(boundaries, title='Boundaries')
    if INPUTS['plotting']['subdomains']:
        fe.plot(subdomains, title='Subdomains')
    fun_space = fe.FunctionSpace(mesh,
                                 INPUTS['element_type'],
                                 INPUTS['element_degree'],
                                 constrained_domain=PeriodicDomain())
    if ARGS['--verbose']:
        dofmap = fun_space.dofmap()
        print('Number of DOFs:', len(dofmap.dofs()))
    field = fe.TrialFunction(fun_space)
    test_func = fe.TestFunction(fun_space)
    cond = Conductivity(subdomains,
                        fe.Constant(INPUTS['conductivity']['gas']),
                        fe.Constant(INPUTS['conductivity']['solid']),
                        degree=0)
    system_matrix = -cond * fe.inner(fe.grad(field),
                                     fe.grad(test_func)) * fe.dx
    bctop = fe.Constant(INPUTS['boundary_conditions']['top'])
    bcbot = fe.Constant(INPUTS['boundary_conditions']['bottom'])
    bcs = [
        fe.DirichletBC(fun_space, bctop, boundaries, 1),
        fe.DirichletBC(fun_space, bcbot, boundaries, 2)
    ]
    field = fe.Function(fun_space)
    return system_matrix, field, bcs, cond
예제 #21
0
파일: possion.py 프로젝트: egalistmir/PDE
bc = fex.DirichletBC(V, u_D, boundary)

# Define variational problem
u = fex.TrialFunction(V)
v = fex.TestFunction(V)
f = fex.Constant(-6.0)
a = fex.dot(fex.grad(u), fex.grad(v)) * fex.dx
L = f * v * fex.dx

# Compute solution
u = fex.Function(V)
fex.solve(a == L, u, bc)
print(u)
# Plot solution and mesh
plt.subplot(2, 1, 1)
fex.plot(u)
#define the boundary conditions
plt.subplot(2, 1, 2)
fex.plot(mesh)
plt.savefig('possion_fex2.png')
#define the boundary conditions
# Save solution to file in VTK format
vtkfile = fex.File('poisson/solution.pvd')
vtkfile << u

# Compute error in L2 norm
error_L2 = fex.errornorm(u_D, u, 'L2')

# Compute maximum error at vertices
vertex_values_u_D = u_D.compute_vertex_values(mesh)
vertex_values_u = u.compute_vertex_values(mesh)
예제 #22
0
 def plot_mesh(self):
     FEN.plot(self._mesh)
예제 #23
0
 def plot_u(self):
     FEN.plot(self._u)
    hessp=SR1(),
    tol=1e-7,
    constraints=volume_constraint,
    bounds=((0, 1.0),) * A.dim(),
    options={"verbose": 3, "gtol": 1e-7, "maxiter": 20},
)

q.assign(0.1)
res = minimize(
    min_f,
    res.x,
    method="trust-constr",
    jac=True,
    hessp=SR1(),
    tol=1e-7,
    constraints=volume_constraint,
    bounds=((0, 1.0),) * A.dim(),
    options={"verbose": 3, "gtol": 1e-7, "maxiter": 100},
)

rho_opt_final = from_numpy(res.x, fenics.Function(A))

c = fenics.plot(rho_opt_final)
plt.colorbar(c)
plt.show()

rho_opt_file = fenics.XDMFFile(
    fenics.MPI.comm_world, "output/control_solution_final.xdmf"
)
rho_opt_file.write(rho_opt_final)
예제 #25
0

constraints = [{
    "type": "ineq",
    "fun": volume_inequality_fun,
    "jac": lambda x: jax.grad(volume_inequality_fun)(x),
}]

x0 = np.ones(C.dim()) * max_volume / (L * h)
res = minimize_ipopt(
    min_f,
    x0,
    jac=True,
    bounds=((0.0, 1.0), ) * C.dim(),
    constraints=constraints,
    options={
        "print_level": 5,
        "max_iter": 100
    },
)

rho_opt_final = numpy_to_fenics(res.x, fa.Function(C))

c = fn.plot(rho_opt_final)
plt.colorbar(c)
plt.show()

# Save optimal solution for visualizing with ParaView
# with XDMFFile("1_dist_load/control_solution_1.xdmf") as f:
#     f.write(rho_opt)
예제 #26
0
#         values[0] = sin(3.0*x[0])*sin(3.0*x[1])*sin(3.0*x[2])

# f0 = F0(name="f0", label="My expression", degree=2)


class F0(UserExpression):
    def eval(self, values, x):
        values[0] = sin(3.0 * x[0]) * sin(3.0 * x[1]) * sin(3.0 * x[2])


class F1(UserExpression):
    def __init__(self, mesh, *arg, **kwargs):
        super().__init__(*arg, **kwargs)
        self.mesh = mesh

    def eval_cell(self, values, x, cell):
        c = Cell(self.mesh, cell.index)
        values[0] = sin(3.0 * x[0]) * sin(3.0 * x[1]) * sin(3.0 * x[2])


e0 = F0(degree=2)
e1 = F1(mesh, degree=2)
e2 = Expression("sin(3.0*x[0])*sin(3.0*x[1])*sin(3.0*x[2])", degree=2)

u0 = interpolate(e0, V)
u1 = interpolate(e1, V)
u2 = interpolate(e2, V)

fp = fe.interpolate(f0, V)
fe.plot(fp)
plt.show()
예제 #27
0
    def solve_cell_problems(self, method='regularized', plot=False):
        """
        Solve the cell problems for the given PDE by changing the geometry to exclude the zone in the middle
        :return:
        """
        class PeriodicBoundary(fe.SubDomain):

            # Left boundary is "target domain" G
            def inside(self, x, on_boundary):
                par = MembraneSimulator.w / MembraneSimulator.length
                tol = 1E-4
                return on_boundary and x[1] >= -tol and x[1] <= tol

            # Map right boundary (H) to left boundary (G)
            def map(self, x, y):
                y[1] = x[1] + 2 * self.eta / MembraneSimulator.length
                y[0] = x[0]

        mesh_size = 50
        # Domain

        if method == 'circle':
            self.obstacle_radius = self.eta / MembraneSimulator.length / 2
            box_begin_point = fe.Point(-self.w / MembraneSimulator.length, 0)
            box_end_point = fe.Point(self.w / MembraneSimulator.length,
                                     2 * self.eta / MembraneSimulator.length)
            box = mshr.Rectangle(box_begin_point, box_end_point)
            cell = box - mshr.Circle(
                fe.Point(0, self.eta / MembraneSimulator.length),
                self.obstacle_radius, mesh_size)
            self.cell_mesh = mshr.generate_mesh(cell, mesh_size)
            diff_coef = fe.Constant(
                ((0, 0), (0, self.D[1, 1])))  # limit for regularisation below.
        # elif method == 'diff_coef':
        #     print("Haha this is going to crash. Also it is horrible in accuracy")
        #     self.cell_mesh = fe.RectangleMesh(fe.Point(-self.w / MembraneSimulator.length, 0),
        #                                       fe.Point(self.w / MembraneSimulator.length,
        #                                                2 * self.eta / MembraneSimulator.length), mesh_size, mesh_size)
        #     diff_coef = fe.Expression(
        #         (('0', '0'), ('0', 'val * ((x[0] - c_x)*(x[0] - c_x) + (x[1] - c_y)*(x[1] - c_y) > r*r)')),
        #         val=(4 * self.ref_T * MembraneSimulator.d2 / MembraneSimulator.length ** 2), c_x=0,
        #         c_y=(self.eta / MembraneSimulator.length),
        #         r=self.obstacle_radius, degree=2, domain=self.cell_mesh)
        elif method == 'regularized':
            box_begin_point = fe.Point(-self.w / MembraneSimulator.length, 0)
            box_end_point = fe.Point(self.w / MembraneSimulator.length,
                                     2 * self.eta / MembraneSimulator.length)
            box = mshr.Rectangle(box_begin_point, box_end_point)
            obstacle_begin_point = fe.Point(
                -self.w / MembraneSimulator.length * self.obs_length,
                self.eta / MembraneSimulator.length * (1 - self.obs_height))
            obstacle_end_point = fe.Point(
                self.w / MembraneSimulator.length * self.obs_length,
                self.eta / MembraneSimulator.length * (1 + self.obs_height))
            obstacle = mshr.Rectangle(obstacle_begin_point, obstacle_end_point)
            cell = box - obstacle
            self.cell_mesh = mshr.generate_mesh(cell, mesh_size)
            diff_coef = fe.Constant(((self.obs_ratio * self.D[0, 0], 0),
                                     (0, self.D[1, 1])))  # defect matrix.
        else:
            raise ValueError("%s not a valid method to solve cell problem" %
                             method)
        self.cell_fs = fe.FunctionSpace(self.cell_mesh, 'P', 2)
        self.cell_solutions = [
            fe.Function(self.cell_fs),
            fe.Function(self.cell_fs)
        ]
        w = fe.TrialFunction(self.cell_fs)
        phi = fe.TestFunction(self.cell_fs)
        scaled_unit_vectors = [
            fe.Constant((1. / np.sqrt(self.obs_ratio), 0.)),
            fe.Constant((0., 1.))
        ]
        for i in range(2):
            weak_form = fe.dot(
                diff_coef *
                (fe.grad(w) + scaled_unit_vectors[i]), fe.grad(phi)) * fe.dx
            print("Solving cell problem")
            bc = fe.DirichletBC(self.cell_fs, fe.Constant(0),
                                MembraneSimulator.cell_boundary)
            if i == 0:
                # Periodicity is applied automatically
                bc = None
            fe.solve(
                fe.lhs(weak_form) == fe.rhs(weak_form), self.cell_solutions[i],
                bc)
            if plot:
                plt.rc('text', usetex=True)
                f = fe.plot(self.cell_solutions[i])
                plt.colorbar(f)
                plt.title(r'Solution to cell problem $w_%d$' % (i + 1))
                plt.xlabel(r'$Y_1$')
                plt.ylabel(r'$Y_2$')
                print("Cell solution")
                print(np.min(self.cell_solutions[i].vector().get_local()),
                      np.max(self.cell_solutions[i].vector().get_local()))
                plt.show()
예제 #28
0
from gmsh_interface import GmshInterface

g = GmshInterface("../geo/simple_muscle_3d.geo")
g.set_parameter("lc",0.1)
g.generate_xml("../geo/test.xml")




from fenics import Mesh, plot
import matplotlib.pyplot as plt

mesh = Mesh("../geo/test.xml")
plot(mesh)
plt.show()
예제 #29
0
def main():
    """Main function. Organizes workflow."""
    fname = str(INPUTS['filename'])
    term = Terminal()
    print(
        term.yellow
        + "Working on file {}.".format(fname)
        + term.normal
    )
    # Load mesh and physical domains from file.
    mesh = fe.Mesh(fname + ".xml")
    if INPUTS['saving']['mesh']:
        fe.File(fname + "_mesh.pvd") << mesh
    if INPUTS['plotting']['mesh']:
        fe.plot(mesh, title='Mesh')
    subdomains = fe.MeshFunction(
        'size_t', mesh, fname + '_physical_region.xml')
    if INPUTS['saving']['subdomains']:
        fe.File(fname + "_subdomains.pvd") << subdomains
    if INPUTS['plotting']['subdomains']:
        fe.plot(subdomains, title='Subdomains')
    # function space for temperature/concentration
    func_space = fe.FunctionSpace(
        mesh,
        INPUTS['element_type'],
        INPUTS['element_degree'],
        constrained_domain=PeriodicDomain()
    )
    # discontinuous function space for visualization
    dis_func_space = fe.FunctionSpace(
        mesh,
        'DG',
        INPUTS['element_degree'],
        constrained_domain=PeriodicDomain()
    )
    if ARGS['--verbose']:
        print('Number of cells:', mesh.num_cells())
        print('Number of faces:', mesh.num_faces())
        print('Number of edges:', mesh.num_edges())
        print('Number of vertices:', mesh.num_vertices())
        print('Number of DOFs:', len(func_space.dofmap().dofs()))
    # temperature/concentration field
    field = fe.TrialFunction(func_space)
    # test function
    test_func = fe.TestFunction(func_space)
    # function, which is equal to 1 everywhere
    unit_function = fe.Function(func_space)
    unit_function.assign(fe.Constant(1.0))
    # assign material properties to each domain
    if INPUTS['mode'] == 'conductivity':
        mat_prop = SubdomainConstant(
            subdomains,
            fe.Constant(INPUTS['conductivity']['gas']),
            fe.Constant(INPUTS['conductivity']['solid']),
            degree=0
        )
    elif INPUTS['mode'] == 'diffusivity':
        mat_prop = SubdomainConstant(
            subdomains,
            fe.Constant(INPUTS['diffusivity']['gas']),
            fe.Constant(INPUTS['diffusivity']['solid']) *
            fe.Constant(INPUTS['solubility'] *
                        gas_constant * INPUTS['temperature']),
            degree=0
        )
    # assign 1 to gas domain, and 0 to solid domain
    gas_content = SubdomainConstant(
        subdomains,
        fe.Constant(1.0),
        fe.Constant(0.0),
        degree=0
    )
    # define structure of foam over whole domain
    structure = fe.project(unit_function * gas_content, dis_func_space)
    # calculate porosity and wall thickness
    porosity = fe.assemble(structure *
                           fe.dx) / ((XMAX - XMIN) * (YMAX - YMIN) * (ZMAX - ZMIN))
    print('Porosity: {0}'.format(porosity))
    dwall = wall_thickness(
        porosity, INPUTS['morphology']['cell_size'],
        INPUTS['morphology']['strut_content'])
    print('Wall thickness: {0} m'.format(dwall))
    # calculate effective conductivity/diffusivity by analytical model
    if INPUTS['mode'] == 'conductivity':
        eff_prop = analytical_conductivity(
            INPUTS['conductivity']['gas'], INPUTS['conductivity']['solid'],
            porosity, INPUTS['morphology']['strut_content'])
        print('Analytical model: {0} W/(mK)'.format(eff_prop))
    elif INPUTS['mode'] == 'diffusivity':
        eff_prop = analytical_diffusivity(
            INPUTS['diffusivity']['solid'] *
            INPUTS['solubility'], INPUTS['solubility'],
            porosity, INPUTS['morphology']['cell_size'], dwall,
            INPUTS['temperature'], INPUTS['morphology']['enhancement_par'])
        print('Analytical model: {0} m^2/s'.format(eff_prop))
    # create system matrix
    system_matrix = -mat_prop * \
        fe.inner(fe.grad(field), fe.grad(test_func)) * fe.dx
    left_side, right_side = fe.lhs(system_matrix), fe.rhs(system_matrix)
    # define boundary conditions
    bcs = [
        fe.DirichletBC(func_space, fe.Constant(
            INPUTS['boundary_conditions']['top']), top_bc),
        fe.DirichletBC(func_space, fe.Constant(
            INPUTS['boundary_conditions']['bottom']), bottom_bc)
    ]
    # compute solution
    field = fe.Function(func_space)
    fe.solve(left_side == right_side, field, bcs)
    # output temperature/concentration at the boundaries
    if ARGS['--verbose']:
        print('Checking periodicity:')
        print('Value at XMIN:', field(XMIN, (YMIN + YMAX) / 3, (ZMIN + ZMAX) / 3))
        print('Value at XMAX:', field(XMAX, (YMIN + YMAX) / 3, (ZMIN + ZMAX) / 3))
        print('Value at YMIN:', field((XMIN + XMAX) / 3, YMIN, (ZMIN + ZMAX) / 3))
        print('Value at YMAX:', field((XMIN + XMAX) / 3, YMAX, (ZMIN + ZMAX) / 3))
        print('Value at ZMIN:', field((XMIN + XMAX) / 3, (YMIN + YMAX) / 3, ZMIN))
        print('Value at ZMAX:', field((XMIN + XMAX) / 3, (YMIN + YMAX) / 3, ZMAX))
    # calculate flux, and effective properties
    vec_func_space = fe.VectorFunctionSpace(
        mesh,
        INPUTS['element_type'],
        INPUTS['element_degree']
    )
    flux = fe.project(-mat_prop * fe.grad(field), vec_func_space)
    divergence = fe.project(-fe.div(mat_prop * fe.grad(field)), func_space)
    flux_x, flux_y, flux_z = flux.split()
    av_flux = fe.assemble(flux_z * fe.dx) / ((XMAX - XMIN) * (YMAX - YMIN))
    eff_prop = av_flux * (ZMAX - ZMIN) / (
        INPUTS['boundary_conditions']['top']
        - INPUTS['boundary_conditions']['bottom']
    )
    if INPUTS['mode'] == 'conductivity':
        print('Numerical model: {0} W/(mK)'.format(eff_prop))
    elif INPUTS['mode'] == 'diffusivity':
        print('Numerical model: {0} m^2/s'.format(eff_prop))
    # projection of concentration has to be in discontinuous function space
    if INPUTS['mode'] == 'diffusivity':
        sol_field = SubdomainConstant(
            subdomains,
            fe.Constant(1.0),
            fe.Constant(INPUTS['solubility'] *
                        gas_constant * INPUTS['temperature']),
            degree=0
        )
        field = fe.project(field * sol_field, dis_func_space)
    # save results
    with open(fname + "_eff_prop.csv", 'w') as textfile:
        textfile.write('eff_prop\n')
        textfile.write('{0}\n'.format(eff_prop))
    fe.File(fname + "_solution.pvd") << field
    fe.File(fname + "_structure.pvd") << structure
    if INPUTS['saving']['flux']:
        fe.File(fname + "_flux.pvd") << flux
    if INPUTS['saving']['flux_divergence']:
        fe.File(fname + "_flux_divergence.pvd") << divergence
    if INPUTS['saving']['flux_components']:
        fe.File(fname + "_flux_x.pvd") << flux_x
        fe.File(fname + "_flux_y.pvd") << flux_y
        fe.File(fname + "_flux_z.pvd") << flux_z
    # plot results
    if INPUTS['plotting']['solution']:
        fe.plot(field, title="Solution")
    if INPUTS['plotting']['flux']:
        fe.plot(flux, title="Flux")
    if INPUTS['plotting']['flux_divergence']:
        fe.plot(divergence, title="Divergence")
    if INPUTS['plotting']['flux_components']:
        fe.plot(flux_x, title='x-component of flux (-kappa*grad(u))')
        fe.plot(flux_y, title='y-component of flux (-kappa*grad(u))')
        fe.plot(flux_z, title='z-component of flux (-kappa*grad(u))')
    if True in INPUTS['plotting'].values():
        fe.interactive()
    print(
        term.yellow
        + "End."
        + term.normal
    )
예제 #30
0
 def plot(self):
     # Quickplot of the solution
     fe.plot(self.diff_coef, mesh=self.mesh)
     fe.plot(self.solution)
     fe.interactive()
예제 #31
0
 # Update current time
 t += dt
 
 # Step 1: Tentative velocity step
 b1 = fs.assemble(L1)
 [bc.apply(b1) for bc in bcu]
 fs.solve(A1, u_.vector(), b1)
 
 # Step 2: Pressure correction step
 b2 = fs.assemble(L2)
 [bc.apply(b2) for bc in bcp]
 fs.solve(A2, p_.vector(), b2)
 
 # Step 3: Velocity correction step
 b3 = fs.assemble(L3)
 fs.solve(A3, u_.vector(), b3)
 
 # Plot solutions
 fs.plot(u_)
 plt.pause(0.1)
 
 # Compute error
 u_e = fs.Expression(('4*x[1]*(1.0 - x[1])', '0'), degree=2)
 u_e = fs.interpolate(u_e, V)
 error = np.abs(u_e.vector() - u_.vector()).max()
 print('t = %.2f: error = %.3g' % (t, error))
 print('max u:', u_.vector().max())
 
 # Update previous solution
 u_n.assign(u_)
 p_n.assign(p_)