예제 #1
0
def test_fenics_to_numpy_function():
    # Functions in DG0 have nodes at centers of finite element cells
    mesh = fenics.UnitIntervalMesh(10)
    V = fenics.FunctionSpace(mesh, "DG", 0)
    test_input = fenics.interpolate(fenics.Expression("x[0]", degree=1), V)
    expected = numpy.linspace(0.05, 0.95, num=10)
    assert numpy.allclose(to_numpy(test_input), expected)
예제 #2
0
def getSystemMatricesDomain(par):

    #-------- parameter renaming --------
    sigma_a = par['sigma_a']
    sigma_s = par['sigma_s']
    sigma_t = fe.Expression('sigma_a + sigma_s',
                            degree=1,
                            sigma_a=sigma_a,
                            sigma_s=sigma_s)

    #-------- system matrices --------

    systemMatricesDomain = dict()
    systemMatricesDomain['Kzz'] = [
        [-0.33333333 / sigma_t, -0.2981424 / sigma_t, 0.0, 0.0],
        [
            -0.2981424 / sigma_t, -0.52380952 / sigma_t, -0.25555063 / sigma_t,
            0.0
        ],
        [
            0.0, -0.25555063 / sigma_t, -0.50649351 / sigma_t,
            -0.25213645 / sigma_t
        ], [0.0, 0.0, -0.25213645 / sigma_t, -0.5030303 / sigma_t]
    ]

    systemMatricesDomain['S'] = [
        [-1.0 * sigma_a, 0.0, 0.0, 0.0],
        [0.0, -1.0 * sigma_a - 1.0 * sigma_s, 0.0, 0.0],
        [0.0, 0.0, -1.0 * sigma_a - 1.0 * sigma_s, 0.0],
        [0.0, 0.0, 0.0, -1.0 * sigma_a - 1.0 * sigma_s]
    ]

    return systemMatricesDomain
예제 #3
0
    def create_rhs_fun(self):

        if self.mode == 'test': 

            print('Creating rhs function')
            self.rhs_fun = fe.Expression(self.rhs_fun_str, degree=2,\
                    alpha = self.alpha,\
                    beta  = self.beta,\
                    lam   = self.lam,\
                    t     = 0)
        else:
            '''
            Constant RHS for the experimental case
            '''
            self.rhs_fun = fe.Constant(0)
            self.rhs_fun = fe.Expression('1/(2*t)', degree=2, t = 0.01)
def getSystemMatricesDomain(par):

    #-------- parameter renaming --------
    sigma_a = par['sigma_a']
    sigma_s = par['sigma_s']
    sigma_t = fe.Expression('sigma_a + sigma_s',
                            degree=1,
                            sigma_a=sigma_a,
                            sigma_s=sigma_s)

    #-------- system matrices --------

    systemMatricesDomain = dict()
    systemMatricesDomain['Kxx'] = [[
        0.33333333 / (0.5 * sigma_s - 1.0 * sigma_t)
    ]]

    systemMatricesDomain['Kxy'] = [[0.0]]

    systemMatricesDomain['Kyx'] = [[0.0]]

    systemMatricesDomain['Kyy'] = [[
        0.33333333 / (0.5 * sigma_s - 1.0 * sigma_t)
    ]]

    systemMatricesDomain['S'] = [[-1.0 * sigma_a]]

    return systemMatricesDomain
예제 #5
0
    def __call__(self, u_test, return_sol=False, return_permeability=False):

        # Variables
        x, y = sym.symbols('x[0], x[1]', real=True, positive=True)

        # Diffusivities
        diff_1 = np.exp(u_test[0])
        diff_2 = np.exp(u_test[1])

        # Interfaces
        ix = u_test[2]
        iy = u_test[3]

        # Diffusivity
        diff = sym.Piecewise((sym.Piecewise(
            (diff_1, y <= iy), (diff_2, True)), x <= ix), (diff_2, True))
        # if return_permeability:
        # return sym.lambdify((x, y), diff)

        ccode_coeff = sym.ccode(diff)
        diff = fen.Expression(ccode_coeff, degree=2)
        if return_permeability:
            return diff

        # Define bilinear form in variational problem
        a_bil = diff * fen.dot(fen.grad(self.trial_f), fen.grad(
            self.test_f)) * fen.dx

        # Compute solution
        sol = fen.Function(self.f_space)
        fen.solve(a_bil == self.lin_func, sol, self.bound_cond)

        evaluations = [sol(xi, yi) for xi, yi in zip(self.x_obs, self.y_obs)]
        return sol if return_sol else np.array(evaluations)
예제 #6
0
    def __init__(self, K):
        # Variables
        x, y = sym.symbols('x[0], x[1]', real=True, positive=True)
        f = sym.Function('f')(x, y)

        grid = np.linspace(0, 1, K + 2)[1:-1]
        x_obs, y_obs = np.meshgrid(grid, grid)
        self.x_obs, self.y_obs = x_obs.reshape(K * K), y_obs.reshape(K * K)

        # --- THIS PART USED TO NOT BE PARALELLIZABLE --- #
        # Create mesh and define function space
        n_mesh = 80
        self.mesh = fen.UnitSquareMesh(n_mesh, n_mesh)
        self.f_space = fen.FunctionSpace(self.mesh, 'P', 2)

        # Define boundary condition
        # u_boundary = fen.Expression('x[0] + x[1]', degree=2)
        u_boundary = fen.Expression('0', degree=2)
        self.bound_cond = fen.DirichletBC(self.f_space, u_boundary,
                                          lambda x, on_boundary: on_boundary)

        # Define variational problem
        self.trial_f = fen.TrialFunction(self.f_space)
        self.test_f = fen.TestFunction(self.f_space)
        rhs = fen.Constant(50)

        self.lin_func = rhs * self.test_f * fen.dx
예제 #7
0
def getSystemMatricesDomain(par):

    #-------- parameter renaming --------
    sigma_a = par['sigma_a']
    sigma_s = par['sigma_s']
    sigma_t = fe.Expression('sigma_a + sigma_s',
                            degree=1,
                            sigma_a=sigma_a,
                            sigma_s=sigma_s)

    #-------- system matrices --------

    systemMatricesDomain = dict()
    systemMatricesDomain['Kxx'] = [[
        -0.33333333 / sigma_t, 0.0, 0.1490712 / sigma_t, -0.25819889 / sigma_t
    ], [
        0.0, -0.42857143 / sigma_t, 0.0, 0.0
    ], [0.1490712 / sigma_t, 0.0, -0.23809524 / sigma_t, 0.16495722 / sigma_t],
                                   [
                                       -0.25819889 / sigma_t, 0.0,
                                       0.16495722 / sigma_t,
                                       -0.42857143 / sigma_t
                                   ]]

    systemMatricesDomain['Kxy'] = [[0.0, -0.25819889 / sigma_t, 0.0, 0.0],
                                   [
                                       -0.25819889 / sigma_t, 0.0,
                                       0.16495722 / sigma_t, 0.0
                                   ], [0.0, 0.16495722 / sigma_t, 0.0, 0.0],
                                   [0.0, 0.0, 0.0, 0.0]]

    systemMatricesDomain['Kyx'] = [[0.0, -0.25819889 / sigma_t, 0.0, 0.0],
                                   [
                                       -0.25819889 / sigma_t, 0.0,
                                       0.16495722 / sigma_t, 0.0
                                   ], [0.0, 0.16495722 / sigma_t, 0.0, 0.0],
                                   [0.0, 0.0, 0.0, 0.0]]

    systemMatricesDomain['Kyy'] = [[
        -0.33333333 / sigma_t, 0.0, 0.1490712 / sigma_t, 0.25819889 / sigma_t
    ], [0.0, -0.42857143 / sigma_t, 0.0, 0.0],
                                   [
                                       0.1490712 / sigma_t, 0.0,
                                       -0.23809524 / sigma_t,
                                       -0.16495722 / sigma_t
                                   ],
                                   [
                                       0.25819889 / sigma_t, 0.0,
                                       -0.16495722 / sigma_t,
                                       -0.42857143 / sigma_t
                                   ]]

    systemMatricesDomain['S'] = [
        [-1.0 * sigma_a, 0.0, 0.0, 0.0],
        [0.0, -1.0 * sigma_a - 1.0 * sigma_s, 0.0, 0.0],
        [0.0, 0.0, -1.0 * sigma_a - 1.0 * sigma_s, 0.0],
        [0.0, 0.0, 0.0, -1.0 * sigma_a - 1.0 * sigma_s]
    ]

    return systemMatricesDomain
예제 #8
0
def problem(f, nx=8, ny=8, degrees=[1, 2]):
    """
    Plot u along x=const or y=const for Lagrange elements,
    of given degrees, on a nx times ny mesh. f is a SymPy expression.
    """
    f = sym.printing.ccode(f)
    f = fe.Expression(f, degree=2)
    mesh = fe.RectangleMesh(fe.Point(-1, 0), fe.Point(1, 2), 2, 2)
    for degree in degrees:
        if degree == 0:
            # The P0 element is specified like this in FEniCS
            V = fe.FunctionSpace(mesh, 'DG', 0)
        else:
            # The Lagrange Pd family of elements, d=1,2,3,...
            V = fe.FunctionSpace(mesh, 'P', degree)
        u = fe.project(f, V)
        u_error = fe.errornorm(f, u, 'L2')
        print('||u-f||=%g' % u_error, degree)
        comparison_plot2D(u,
                          f,
                          n=50,
                          value=0.4,
                          variation='x',
                          plottitle='Approximation by P%d elements' % degree,
                          filename='approx_fenics_by_P%d' % degree,
                          tol=1E-3)
예제 #9
0
def loadTestCase2():
    """Define test case 2.
    Boundary information (rho, S) ordered according to left (0) / right (1) boundary of mesh.
    """

    p = dict()
    p['spatialDimension'] = 1
    p['kernelName'] = 'isotropic'
    p['domain'] = {'zMin': 0.0, 'zMax': 1.0}
    p['rho'] = [0.5, 0.5]
    p['sigma_a'] = fe.Expression('(2 + sin(2 * PI * x[0])) / 10',
                                 degree=1,
                                 PI=np.pi)
    p['sigma_s'] = fe.Expression('(3 - pow(x[0], 2)) / 10', degree=1)
    p['boundarySource'] = [boundarySource2, boundarySource0]

    return p
예제 #10
0
    def __init__(self, h, eps, dim):
        """
        Initializing poisson solver
        :param h: mesh size (of unit interval discretisation)
        :param eps: small parameter
        :param dim: dimension (in {1,2,3})
        """
        self.h = h
        self.n = int(1 / h)
        self.eps = eps
        self.dim = dim
        self.mesh = fe.UnitIntervalMesh(self.n)
        a_eps = '1./(2+cos(2*pi*x[0]/eps))'
        self.e_is = [fe.Constant(1.)]
        if self.dim == 2:
            self.mesh = fe.UnitSquareMesh(self.n, self.n)
            a_eps = '1./(2+cos(2*pi*(x[0]+2*x[1])/eps))'
            self.e_is = [fe.Constant((1., 0.)), fe.Constant((0., 1.))]
        elif self.dim == 3:
            self.mesh = fe.UnitCubeMesh(self.n, self.n, self.n)
            a_eps = '1./(2+cos(2*pi*(x[0]+3*x[1]+6*x[2])/eps))'
            self.e_is = [
                fe.Constant((1., 0., 0.)),
                fe.Constant((0., 1., 0.)),
                fe.Constant((0., 0., 1.))
            ]
        else:
            self.dim = 1
        print("Solving rapid varying Poisson problem in R^%d" % self.dim)
        self.diff_coef = fe.Expression(a_eps,
                                       eps=self.eps,
                                       degree=2,
                                       domain=self.mesh)
        self.a_y = fe.Expression(a_eps.replace("/eps", ""),
                                 degree=2,
                                 domain=self.mesh)
        self.function_space = fe.FunctionSpace(self.mesh, 'P', 2)
        self.solution = fe.Function(self.function_space)
        self.cell_solutions = [
            fe.Function(self.function_space) for _ in range(self.dim)
        ]
        self.eff_diff = np.zeros((self.dim, self.dim))
        # Define boundary condition
        self.bc_function = fe.Constant(0.0)

        self.f = fe.Constant(1)
예제 #11
0
 def set_bcs_staggered(self):
     self.middle.mark(self.boundaries, 1)
     self.presLoad = fe.Expression("t", t=0.0, degree=1)
     BC_u_left = fe.DirichletBC(self.U, fe.Constant((0., 0.)), self.left, method='pointwise')
     BC_u_right = fe.DirichletBC(self.U.sub(1), fe.Constant(0.), self.right, method='pointwise')
     BC_u_middle = fe.DirichletBC(self.U.sub(1), self.presLoad, self.middle, method='pointwise')
     self.BC_u = [BC_u_left, BC_u_right, BC_u_middle]
     self.BC_d = []
예제 #12
0
    def __init__(self):
        self.h = .4

        # Cell properties
        self.obs_length = 0.7
        self.obs_height = 0.1
        self.obs_ratio = self.obs_height / self.obs_length

        if self.h < self.eta:
            raise ValueError("Eta must be smaller than h")
        self.ref_T = 0.1

        self.eps = 2 * self.eta / MembraneSimulator.length
        self.mesh = fe.RectangleMesh(
            fe.Point(-1, 0),
            fe.Point(1, 2 * self.h / MembraneSimulator.length), 50, 50)
        self.cell_mesh = None
        self.D = np.matrix(((4 * self.ref_T * MembraneSimulator.d1 /
                             MembraneSimulator.length**2, 0),
                            (0, 4 * self.ref_T * MembraneSimulator.d2 /
                             MembraneSimulator.length**2)))
        # Dirichlet boundary conditions
        self.u_l = 6E-5
        self.u_r = 0
        self.u_boundary = fe.Expression(
            '(u_l*(x[0] < - par) + u_r*(x[0] >= par))',
            u_l=self.u_l,
            u_r=self.u_r,
            par=MembraneSimulator.w / MembraneSimulator.length,
            degree=2)
        self.u_0 = self.u_boundary / 2

        # self.rhs = fe.Expression('(x[1]>par)*u',u=self.u_l*4,par=MembraneSimulator.eta/MembraneSimulator.length, degree=2)
        self.rhs = fe.Expression('-0*u', u=self.u_l, degree=2)
        self.time = 0
        self.T = 0.2
        self.dt = 0.005
        self.tol = 1E-4

        self.function_space = fe.FunctionSpace(self.mesh, 'P', 2)
        self.solution = fe.Function(self.function_space)
        self.cell_solutions = self.cell_fs = None
        self.unit_vectors = [fe.Constant((1., 0.)), fe.Constant((0., 1.))]
        self.eff_diff = np.zeros((2, 2))
        self.file = fe.File('results/solution.pvd')
예제 #13
0
 def __init__(self, initial_value: float, cutoff_time: float,
              traction_boundary: str):
     self.force = fenics.Expression(("t <= tc ? p0*t/tc : 0", "0"),
                                    t=0,
                                    tc=cutoff_time,
                                    p0=initial_value,
                                    degree=1)
     self.traction_boundary = traction_boundary
     self.ds = None
예제 #14
0
 def __init__(self,
              mesh: fe.Mesh,
              density: fe.Expression,
              constitutive_model: ConstitutiveModelBase,
              bf: fe.Expression = fe.Expression('0', degree=0)):
     self._mesh = mesh
     self._density = density
     self._constitutive_model = constitutive_model
     self.bf = bf
예제 #15
0
def test_numpy_to_fenics_function():
    test_input = numpy.linspace(0.05, 0.95, num=10)
    mesh = fenics.UnitIntervalMesh(10)
    V = fenics.FunctionSpace(mesh, "DG", 0)
    template = fenics.Function(V)
    fenics_test_input = numpy_to_fenics(test_input, template)
    expected = fenics.interpolate(fenics.Expression("x[0]", degree=1), V)
    assert numpy.allclose(fenics_test_input.vector().get_local(),
                          expected.vector().get_local())
예제 #16
0
def test_jax_to_fenics_function(test_input, expected_expr):
    mesh = fenics.UnitIntervalMesh(10)
    V = fenics.FunctionSpace(mesh, "DG", 0)
    template = fenics.Function(V)
    fenics_test_input = numpy_to_fenics(test_input, template)
    expected = fenics.interpolate(fenics.Expression(expected_expr, degree=1), V)
    assert numpy.allclose(
        fenics_test_input.vector().get_local(), expected.vector().get_local()
    )
예제 #17
0
 def set_bcs_staggered(self):
     self.upper.mark(self.boundaries, 1)
     self.presLoad = fe.Expression(("t", 0), t=0.0, degree=1)
     BC_u_lower = fe.DirichletBC(self.U, fe.Constant((0., 0.)), self.lower)
     BC_u_upper = fe.DirichletBC(self.U, self.presLoad, self.upper)
     BC_u_left = fe.DirichletBC(self.U.sub(1), fe.Constant(0), self.left)
     BC_u_right = fe.DirichletBC(self.U.sub(1), fe.Constant(0), self.right)
     self.BC_u = [BC_u_lower, BC_u_upper, BC_u_left, BC_u_right]
     self.BC_d = []
예제 #18
0
def assemble_fenics(u, kappa0, kappa1):

    f = fenics.Expression(
        "10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree=2)

    inner, grad, dx = ufl.inner, ufl.grad, ufl.dx
    J_form = 0.5 * inner(kappa0 * grad(u), grad(u)) * dx - kappa1 * f * u * dx
    J = fenics.assemble(J_form)
    return J, J_form
예제 #19
0
    def initial_values(self):

        p0, u0_0, u0_1, T0, C0 = "0.", "1.", "0.", "0.", "0."

        w0 = fenics.interpolate(
            fenics.Expression((p0, u0_0, u0_1, T0, C0),
                              element=self.element()), self.function_space)

        return w0
예제 #20
0
 def set_bcs_staggered(self):
     self.lower.mark(self.boundaries, 1)
     self.presLoad = fe.Expression("t", t=0.0, degree=1)
     BC_u_lower = fe.DirichletBC(self.U, fe.Constant((0., 0.)), self.lower)
     BC_u_segment = fe.DirichletBC(self.U.sub(1),
                                   self.presLoad,
                                   self.segment,
                                   method="pointwise")
     self.BC_u = [BC_u_lower, BC_u_segment]
     self.BC_d = []
예제 #21
0
def test_fenics_to_numpy_mixed_function():
    # Functions in DG0 have nodes at centers of finite element cells
    mesh = fenics.UnitIntervalMesh(10)
    vec_dim = 4
    V = fenics.VectorFunctionSpace(mesh, "DG", 0, dim=vec_dim)
    test_input = fenics.interpolate(
        fenics.Expression(vec_dim * ("x[0]", ), element=V.ufl_element()), V)
    expected = numpy.linspace(0.05, 0.95, num=10)
    expected = numpy.reshape(numpy.tile(expected, (4, 1)).T, V.dim())
    assert numpy.allclose(fenics_to_numpy(test_input), expected)
    def initial_values(self):

        initial_values = fenics.interpolate(
            fenics.Expression(
                ("0.", "0.", "0.", "(T_c - T_h)*x[0] + T_h", "0."),
                T_h=self.T(self.hot_wall_temperature_degC),
                T_c=self.T(self.cold_wall_temperature_degC),
                element=self.element()), self.function_space)

        return initial_values
예제 #23
0
파일: test.py 프로젝트: ZXK666666/FESTIM
def test_formulation_no_trap_1_material():
    '''
    Test function formulation() with 1 intrinsic trap
    and 1 material
    '''
    dt = 1
    traps = []
    materials = [{
            "alpha": 1,
            "beta": 2,
            "density": 3,
            "borders": [0, 1],
            "E_diff": 4,
            "D_0": 5,
            "id": 1
            }]
    extrinsic_traps = []
    mesh = fenics.UnitIntervalMesh(10)
    V = fenics.VectorFunctionSpace(mesh, 'P', 1, 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_)
    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

    assert expected_form.equals(F) is True
예제 #24
0
    def initial_values(self):

        initial_values = fenics.interpolate(
            fenics.Expression(
                ("0.", "0.", "0.", "(T_h - T_c)*(x[0] < x_m0) + T_c", "0."),
                T_h=self.hot_wall_temperature,
                T_c=self.cold_wall_temperature,
                x_m0=1. / 2.**(self.initial_hot_wall_refinement_cycles - 1),
                element=self.element()), self.function_space)

        return initial_values
예제 #25
0
 def set_bcs_staggered(self):
     self.upper.mark(self.boundaries, 1)
     self.presLoad = fe.Expression("t", t=0.0, degree=1)
     BC_u_lower = fe.DirichletBC(self.U.sub(1), fe.Constant(0), self.lower)
     BC_u_upper = fe.DirichletBC(self.U.sub(1), self.presLoad, self.upper)
     BC_u_corner = fe.DirichletBC(self.U.sub(0),
                                  fe.Constant(0.0),
                                  self.corner,
                                  method='pointwise')
     self.BC_u = [BC_u_lower, BC_u_upper, BC_u_corner]
     self.BC_d = []
예제 #26
0
def loadTestCase6():
    """Define test case 6.
    Boundary information (rho, S) ordered according to boundary ID in 
    meshTestCase6 (quarter circle)
    """

    buildFolder = '../build/testCase6/'
    aux = sio.loadmat(buildFolder + 'meshTestCase6Normals.mat')
    nLeft = int(
        aux['geoGenParams']['nLeft']) - 1  # check .geo file for this number
    nTop = int(aux['geoGenParams']['nTop']) - 1
    nInnerOuter = int(aux['geoGenParams']['nInnerOuter']) - 1

    p = dict()
    p['spatialDimension'] = 2
    p['kernelName'] = 'isotropic'
    p['meshPrefix'] = 'meshTestCase6'
    p['sigma_a'] = fe.Expression('0.0', degree=1)
    p['sigma_s'] = fe.Expression('0.1', degree=1)

    # reflectivity
    p['rho'] = np.hstack((0.5 * np.ones(nInnerOuter), np.zeros(nTop),
                          0.5 * np.ones(nInnerOuter), np.zeros(nLeft)))

    # boundarySource
    p['boundarySource'] = []

    # outer curve
    for k in range(0, nInnerOuter):
        p['boundarySource'].append(boundarySource0)
    # top
    for k in range(0, nTop):
        p['boundarySource'].append(boundarySource0)
    # inner curve
    for k in range(0, nInnerOuter):
        p['boundarySource'].append(boundarySource0)
    # left
    for k in range(0, nLeft):
        p['boundarySource'].append(boundarySource6)

    return p
예제 #27
0
def darcy_problem_1():
    s = Scenario()
    s.problem_number = 1
    s.source_function = fenics.Constant(3.0)
    s.dirichlet_bc = fenics.Expression("0.0", degree=1)

    def boundary(x, on_boundary):
        return x[0] < fenics.DOLFIN_EPS or x[0] > 1.0 - fenics.DOLFIN_EPS

    s.gamma_dirichlet = boundary
    s.g = fenics.Constant(0.0)
    return s
예제 #28
0
    def solve(self, Ain=None, Qin=None, Aout=None, Qout=None):

        # -- Define boundaries
        def bcL(x, on_boundary):
            return on_boundary and x[0] < fe.DOLFIN_EPS

        def bcR(x, on_boundary):
            return on_boundary and self.L - x[0] < fe.DOLFIN_EPS

        # -- Define initial conditions
        bcs = []
        if Ain is not None:
            bc_Ain = fe.DirichletBC(self.V_A,
                                    fe.Expression("Ain", Ain=Ain, degree=1),
                                    bcL)
            bcs.append(bc_Ain)
        if Qin is not None:
            bc_Qin = fe.DirichletBC(self.V_Q,
                                    fe.Expression("Qin", Qin=Qin, degree=1),
                                    bcL)
            bcs.append(bc_Qin)
        if Aout is not None:
            bc_Aout = fe.DirichletBC(
                self.V_A, fe.Expression("Aout", Aout=Aout, degree=1), bcR)
            bcs.append(bc_Aout)
        if Qout is not None:
            bc_Qout = fe.DirichletBC(
                self.V_Q, fe.Expression("Qout", Qout=Qout, degree=1), bcR)
            bcs.append(bc_Qout)

        # -- Setup problem
        problem = fe.NonlinearVariationalProblem(self.wf,
                                                 self.Un,
                                                 bcs,
                                                 J=self.J)
        solver = fe.NonlinearVariationalSolver(problem)

        # -- Solve
        solver.solve()
        self.U0.assign(self.Un)
예제 #29
0
    def compute_effective_diffusion(self):
        """
        Computes the effective diffusion coefficient according to manuscript
        Shape of this coefficient:
        1/|Z| \int (D*(I + [[0,0],[\partial_{Y_2} w_1,\partial_{Y_2} w_2]]
        :return:
        """
        cell_size = 2 * self.eta / MembraneSimulator.length * 2 * self.w / MembraneSimulator.length
        print("Cell size is ", cell_size)
        self.eff_diff = np.zeros([2, 2])
        for i in range(2):
            grad = fe.grad(self.cell_solutions[i])
            part_div = fe.dot(self.unit_vectors[1], grad)
            integrand = fe.project(part_div, self.cell_fs)
            # integrand = fe.project(fe.dot(self.unit_vectors[1], fe.grad(self.cell_solutions[i])), self.cell_fs)
            self.eff_diff[1, i] += fe.assemble(integrand * fe.dx)
            print("integrand for cell problem", i,
                  self.eff_diff[1, i] / cell_size)
        self.eff_diff = self.D + np.dot(self.D, self.eff_diff) / cell_size
        d1 = self.D[0, 0]
        d2 = self.D[1, 1]
        hom_d1 = self.eff_diff[0, 0]
        hom_d2 = self.eff_diff[1, 1]
        ratio = self.obs_height * self.obs_length
        print("Obstacle has a filling ratio of %.2f" % ratio)
        print(
            "Homogenization: diff outside is %.4f, %.4f, diff inside is %.4f, %.4f"
            % (d1, d2, hom_d1, hom_d2))

        rad = MembraneSimulator.w / MembraneSimulator.length
        # self.composed_diff_coef = fe.Expression(
        #     (('d1*(x[0]*x[0]>=rad*rad) + dd1*(x[0]*x[0]<rad*rad)', '0'),
        #      ('0', 'd2*(x[0]*x[0]>=rad*rad) + dd2*(x[0]*x[0]<rad*rad)')),
        #     d1=d1, d2=d2, rad=rad, dd1=hom_d1, dd2=hom_d2, degree=1)
        outside = fe.Expression('(x[0]*x[0]>=rad*rad)', degree=2, rad=rad)
        inside = fe.Expression('(x[0]*x[0]<rad*rad)', degree=2, rad=rad)
        self.composed_diff_coef = fe.Constant(self.D) * outside + fe.Constant(
            self.eff_diff) * inside
예제 #30
0
    def create_boundary_conditions(self):

        if self.mode == 'test':

            print('Creating boundary function')
            self.boundary_fun = fe.Expression(self.u_exact_str, degree=2,\
                    alpha = self.alpha, beta = self.beta, t = 0)

        else:
            '''
            Constant boundary conditions
            '''


        if self.dimension == 2:
            self.boundary_fun = fe.Constant(1)
            def is_on_the_boundary(x, on_boundary):
                return on_boundary and 4.34 < x[0]

        tol = 1e-6
        if self.dimension == 1:

            self.boundary_fun = fe.Expression('x[0] < 1e-6 ? 1 : 0', degree=0)

            c    = -5 / np.sqrt(6)
            txt = 'pow(1+exp((x[0]+C*t)/sqrt(6)), -2)'
            self.boundary_fun = fe.Expression(txt, degree=2, C=c, t=0)

            #self.boundary_fun = fe.Expression(\
                    #'exp(-x[0]*x[0]/(4*t))', degree=2, t=0.01)

            def is_on_the_boundary(x, on_boundary):
                return on_boundary
                #return on_boundary and x[0] < 1e-6
                #return False

        self.boundary_conditions = fe.DirichletBC(\
                self.function_space, self.boundary_fun, is_on_the_boundary)