예제 #1
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

        element_v = fe.VectorElement("P", mesh.ufl_cell(), 1)
        element_s = fe.FiniteElement("P", mesh.ufl_cell(), 1)
        mixed_element = fe.MixedElement([element_v, element_v, element_s])
        W = fe.FunctionSpace(mesh, mixed_element)

        # Unknowns, values at previous step and test functions
        w = fe.Function(W)
        self.u, self.v, self.p = fe.split(w)

        w0 = fe.Function(W)
        self.u0, self.v0, self.p0 = fe.split(w0)
        self.a0 = fe.Function(fe.FunctionSpace(mesh, element_v))

        self.ut, self.vt, self.pt = fe.TestFunctions(W)

        self.F = kin.def_grad(self.u)
        self.F0 = kin.def_grad(self.u0)
예제 #2
0
    def time_discrete_terms(self):
        """ Apply first-order implicit Euler finite difference method. """
        wnp1 = fenics.split(self._solutions[0].leaf_node())

        wn = fenics.split(self._solutions[1].leaf_node())

        if self.time_order == 1:

            return tuple([
                phaseflow.backward_difference_formulas.apply_backward_euler(
                    self._timestep_sizes[0], (wnp1[i], wn[i]))
                for i in range(len(wn))
            ])

        if self.time_order > 1:

            wnm1 = fenics.split(self._solutions[2].leaf_node())

        if self.time_order == 2:

            return tuple([
                phaseflow.backward_difference_formulas.apply_bdf2(
                    (self._timestep_sizes[0], self._timestep_sizes[1]),
                    (wnp1[i], wn[i], wnm1[i])) for i in range(len(wn))
            ])

        if self.time_order > 2:

            raise NotImplementedError()
예제 #3
0
 def geneForwardMatrix(self, q_fun=fe.Constant(0.0), fR=fe.Constant(0.0), \
                       fI=fe.Constant(0.0)):
     if self.haveFunctionSpace == False:
         self.geneFunctionSpace()
         
     xx, yy, dPML, sig0_, p_ = self.domain.xx, self.domain.yy, self.domain.dPML,\
                               self.domain.sig0, self.domain.p
     # define the coefficents induced by PML
     sig1 = fe.Expression('x[0] > x1 && x[0] < x1 + dd ? sig0*pow((x[0]-x1)/dd, p) : (x[0] < 0 && x[0] > -dd ? sig0*pow((-x[0])/dd, p) : 0)', 
                  degree=3, x1=xx, dd=dPML, sig0=sig0_, p=p_)
     sig2 = fe.Expression('x[1] > x2 && x[1] < x2 + dd ? sig0*pow((x[1]-x2)/dd, p) : (x[1] < 0 && x[1] > -dd ? sig0*pow((-x[1])/dd, p) : 0)', 
                  degree=3, x2=yy, dd=dPML, sig0=sig0_, p=p_)
     
     sR = fe.as_matrix([[(1+sig1*sig2)/(1+sig1*sig1), 0.0], [0.0, (1+sig1*sig2)/(1+sig2*sig2)]])
     sI = fe.as_matrix([[(sig2-sig1)/(1+sig1*sig1), 0.0], [0.0, (sig1-sig2)/(1+sig2*sig2)]])
     cR = 1 - sig1*sig2
     cI = sig1 + sig2
     
     # define the coefficients with physical meaning
     angl_fre = self.kappa*np.pi
     angl_fre2 = fe.Constant(angl_fre*angl_fre)
     
     # define equations
     u_ = fe.TestFunction(self.V)
     du = fe.TrialFunction(self.V)
     
     u_R, u_I = fe.split(u_)
     duR, duI = fe.split(du)
     
     def sigR(v):
         return fe.dot(sR, fe.nabla_grad(v))
     def sigI(v):
         return fe.dot(sI, fe.nabla_grad(v))
     
     F1 = - fe.inner(sigR(duR)-sigI(duI), fe.nabla_grad(u_R))*(fe.dx) \
         - fe.inner(sigR(duI)+sigI(duR), fe.nabla_grad(u_I))*(fe.dx) \
         - fR*u_R*(fe.dx) - fI*u_I*(fe.dx)
     
     a2 = fe.inner(angl_fre2*q_fun*(cR*duR-cI*duI), u_R)*(fe.dx) \
          + fe.inner(angl_fre2*q_fun*(cR*duI+cI*duR), u_I)*(fe.dx) \
     
     # define boundary conditions
     def boundary(x, on_boundary):
         return on_boundary
     
     bc = [fe.DirichletBC(self.V.sub(0), fe.Constant(0.0), boundary), \
           fe.DirichletBC(self.V.sub(1), fe.Constant(0.0), boundary)]
     
     a1, L1 = fe.lhs(F1), fe.rhs(F1)
     self.u = fe.Function(self.V)
     self.A1 = fe.assemble(a1)
     self.b1 = fe.assemble(L1)
     self.A2 = fe.assemble(a2)
     bc[0].apply(self.A1, self.b1)
     bc[1].apply(self.A1, self.b1)
     bc[0].apply(self.A2)
     bc[1].apply(self.A2)
     self.A = self.A1 + self.A2
예제 #4
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)
예제 #5
0
파일: test.py 프로젝트: ZXK666666/FESTIM
def test_formulation_1_extrap_1_material():
    '''
    Test function formulation() with 1 extrinsic trap
    and 1 material
    '''
    dt = 1
    traps = [{
        "energy": 1,
        "materials": [1],
        "type": "extrinsic"
        }]
    materials = [{
            "alpha": 1,
            "beta": 2,
            "density": 3,
            "borders": [0, 1],
            "E_diff": 4,
            "D_0": 5,
            "id": 1
            }]
    
    mesh = fenics.UnitIntervalMesh(10)
    V = fenics.VectorFunctionSpace(mesh, 'P', 1, 2)
    W = fenics.FunctionSpace(mesh, 'P', 1)
    u = fenics.Function(V)
    u_n = fenics.Function(V)
    v = fenics.TestFunction(V)
    n = fenics.interpolate(fenics.Expression('1', degree=0), W)
    solutions = list(fenics.split(u))
    previous_solutions = list(fenics.split(u_n))
    testfunctions = list(fenics.split(v))
    extrinsic_traps = [n]
    mf = fenics.MeshFunction('size_t', mesh, 1, 1)
    dx = fenics.dx(subdomain_data=mf)
    temp = fenics.Expression("300", degree=0)
    flux_ = fenics.Expression("10000", degree=0)

    F, expressions = FESTIM.formulation(
        traps, extrinsic_traps, solutions, testfunctions,
        previous_solutions, dt, dx, materials, temp, flux_)
    expected_form = ((solutions[0] - previous_solutions[0]) / dt) * \
        testfunctions[0]*dx
    expected_form += 5 * fenics.exp(-4/8.6e-5/temp) * \
        fenics.dot(
            fenics.grad(solutions[0]), fenics.grad(testfunctions[0]))*dx(1)
    expected_form += -flux_*testfunctions[0]*dx + \
        ((solutions[1] - previous_solutions[1]) / dt) * \
        testfunctions[1]*dx
    expected_form += - 5 * fenics.exp(-4/8.6e-5/temp)/1/1/2 * \
        solutions[0] * (extrinsic_traps[0] - solutions[1]) * \
        testfunctions[1]*dx(1)
    expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[1] * \
        testfunctions[1]*dx(1)
    expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \
        testfunctions[0]*dx

    assert expected_form.equals(F) is True
예제 #6
0
def dynamic_solver_func(ncells=10,  # количество узлов на заданном итервале
                        init_time=0,  # начальный момент времени
                        end_time=10,  # конечный момент времени
                        dxdphi=1,  # производная от потенциала по х
                        dydphi=1,  # производня от потенциала по у
                        x0=0,  # начальное положение по оси х
                        vx0=1,  # проекция начальной скорости на ось х
                        y0=0,  # начальное положение по оси у
                        vy0=1):  # проекция начальной скорости на ось у
    """ Функция на вход которой подается производная от потенциала
        гравитационного поля, возвращающая координаты смещенных
        материальных точек (частиц).
    """
    # генерация сетки на заданном интервале времени
    mesh = fen.IntervalMesh(ncells, 0, end_time-init_time)

    welm = fen.MixedElement([fen.FiniteElement('Lagrange', fen.interval, 2),
                             fen.FiniteElement('Lagrange', fen.interval, 2),
                             fen.FiniteElement('Lagrange', fen.interval, 2),
                             fen.FiniteElement('Lagrange', fen.interval, 2)])

    # генерация функционального рростаанства
    W = fen.FunctionSpace(mesh, welm)

    # постановка начальных условий задачи
    bcsys = [fen.DirichletBC(W.sub(0), fen.Constant(x0), 'near(x[0], 0)'),
             fen.DirichletBC(W.sub(1), fen.Constant(vx0), 'near(x[0], 0)'),
             fen.DirichletBC(W.sub(2), fen.Constant(y0), 'near(x[0], 0)'),
             fen.DirichletBC(W.sub(3), fen.Constant(vy0), 'near(x[0], 0)')]

    # опееделение тестовых функций для решения задачи
    up = fen.Function(W)
    x_cor, v_x, y_cor, v_y = fen.split(up)
    v1, v2, v3, v4 = fen.split(fen.TestFunction(W))

    # постановка задачи drdt = v; dvdt = - grad(phi) в проекциях на оси системы координат
    weak_form = (x_cor.dx(0) - v_x) * v1 * fen.dx + (v_x.dx(0) + dxdphi) * v2 * fen.dx \
                + (y_cor.dx(0) - v_y) * v3 * fen.dx + (v_y.dx(0) + dydphi) * v4 * fen.dx

    # решние поставленной задачи
    fen.solve(weak_form == 0, up, bcs=bcsys)

    # определение момента времени
    time = fen.Point(end_time - init_time)

    # расчет координат и скоростей
    x_end_time = up(time.x())[0]
    vx_end_time = up(time.x())[1]
    y_end_time = up(time.x())[2]
    vy_end_time = up(time.x())[3]

    return x_end_time, y_end_time, vx_end_time, vy_end_time
예제 #7
0
def test__deepcopy__ci__():

    tolerance = 1.e-6

    sim = CavityMeltingSimulationWithoutConcentration()

    sim.assign_initial_values()

    for it in range(3):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    sim2 = sim.deepcopy()

    assert (all(sim.solution.vector() == sim2.solution.vector()))

    for it in range(2):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim.solution)

    phi = sim.semi_phasefield(T=T_fine, C=C_fine)

    solid_area = fenics.assemble(phi * fenics.dx)

    assert (abs(solid_area - expected_solid_area) < tolerance)

    assert (not (sim.solution.vector() == sim2.solution.vector()))

    for it in range(2):

        sim2.solve(goal_tolerance=4.e-5)

        sim2.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim2.solution)

    phi = sim2.semi_phasefield(T=T_fine, C=C_fine)

    solid_area = fenics.assemble(phi * fenics.dx)

    assert (abs(solid_area - expected_solid_area) < tolerance)

    assert (all(sim.solution.vector() == sim2.solution.vector()))
예제 #8
0
def test__checkpoint__ci__():

    sim = CavityMeltingSimulationWithoutConcentration()

    sim.assign_initial_values()

    for it in range(2):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    checkpoint_filepath = tempfile.mkdtemp() + "/checkpoint.h5"

    sim.write_checkpoint(checkpoint_filepath)

    sim2 = CavityMeltingSimulationWithoutConcentration()

    sim2.read_checkpoint(checkpoint_filepath)

    for it in range(3):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim.solution)

    phi = sim.semi_phasefield(T=T_fine, C=C_fine)

    solid_area = fenics.assemble(phi * fenics.dx)

    assert (abs(solid_area - expected_solid_area) < 1.e-6)
예제 #9
0
    def set_solution_on_subdomain(self, subdomain, values):
        """ Abuse `fenics.DirichletBC` to set values of a function on a subdomain. 
        
        Parameters
        ----------
        subdomain
        
            `fenics.SubDomain`
            
        values
        
            container of objects that would typically be passed to 
            `fenics.DirichletBC` as the values of the boundary condition,
            one for each subspace of the mixed finite element solution space
        """
        function_space = fenics.FunctionSpace(self.mesh.leaf_node(),
                                              self.element())

        new_solution = fenics.Function(function_space)

        new_solution.vector()[:] = self.solution.vector()

        for function_subspace_index in range(len(fenics.split(self.solution))):

            hack = fenics.DirichletBC(
                function_space.sub(function_subspace_index),
                values[function_subspace_index], subdomain)

            hack.apply(new_solution.vector())

        self.solution.vector()[:] = new_solution.vector()
예제 #10
0
def test__compositional_convection_coupled_melting_benchmark__amr__regression__ci__(
):

    sim = phaseflow.cavity_melting_simulation.CavityMeltingSimulation()

    sim.output_dir = tempfile.mkdtemp() + \
        "/test__compositional_convection_coupled_melting/"

    phaseflow.helpers.mkdir_p(sim.output_dir)

    sim.assign_initial_values()

    sim.timestep_size.assign(10.)

    for it, epsilon_M in zip(range(4), (0.5e-3, 0.25e-3, 0.125e-3, 0.0625e-3)):

        if it == 1:

            sim.regularization_sequence = None

        sim.solve_with_auto_regularization(goal_tolerance=epsilon_M)

        sim.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim.solution)

    phi = sim.semi_phasefield(T=T_fine, C=C_fine)

    expected_solid_area = 0.7405

    solid_area = fenics.assemble(phi * fenics.dx)

    tolerance = 1.e-4

    assert (abs(solid_area - expected_solid_area) < tolerance)
예제 #11
0
    def setup_governing_form(self):
        """ Implement the variational form per @cite{zimmerman2018monolithic}. """
        Pr = fenics.Constant(self.prandtl_number)

        Ste = fenics.Constant(self.stefan_number)

        f_B = self.make_buoyancy_function()

        phi = self.make_semi_phasefield_function()

        mu = self.make_phase_dependent_material_property_function(
            P_L=fenics.Constant(self.liquid_viscosity),
            P_S=fenics.Constant(self.solid_viscosity))

        gamma = fenics.Constant(self.penalty_parameter)

        p, u, T = fenics.split(self.state.solution)

        u_t, T_t, phi_t = self.make_time_discrete_terms()

        psi_p, psi_u, psi_T = fenics.TestFunctions(self.function_space)

        dx = self.integration_metric

        inner, dot, grad, div, sym = fenics.inner, fenics.dot, fenics.grad, fenics.div, fenics.sym

        self.governing_form = (
            -psi_p * (div(u) + gamma * p) +
            dot(psi_u, u_t + f_B(T) + dot(grad(u), u)) - div(psi_u) * p +
            2. * mu(phi(T)) * inner(sym(grad(psi_u)), sym(grad(u))) + psi_T *
            (T_t - 1. / Ste * phi_t) +
            dot(grad(psi_T), 1. / Pr * grad(T) - T * u)) * dx
예제 #12
0
def test__coarsen__ci__():

    sim = CavityMeltingSimulationWithoutConcentration()

    sim.assign_initial_values()

    for it in range(3):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    sim.coarsen(absolute_tolerances=(1., 1., 1.e-3, 1., 1.))

    for it in range(2):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim.solution)

    phi = sim.semi_phasefield(T=T_fine, C=C_fine)

    solid_area = fenics.assemble(phi * fenics.dx)

    tolerance = 1.e-3

    assert (abs(solid_area - expected_solid_area) < tolerance)
def eval_cost_fem(w, rho):
    u, _ = fenics.split(w)
    J_form = (
        0.5 * ufl.inner(alpha(rho) * u, u) * ufl.dx
        + mu * ufl.inner(ufl.grad(u), ufl.grad(u)) * ufl.dx
    )
    J = fenics_adjoint.assemble(J_form)
    return J
예제 #14
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
    def melted_length_integrand(self):

        p, u, T, C = fenics.split(self.solution)

        phi = self.semi_phasefield(T=T, C=C)

        dx = self.integration_measure

        return (1. - phi) * dx
예제 #16
0
    def __init__(self,
                 mesh: fe.Mesh,
                 constitutive_model: ConstitutiveModelBase,
                 u_order=1,
                 p_order=0):

        # TODO a lot here...

        element_v = fe.VectorElement("P", mesh.ufl_cell(), u_order)
        element_s = fe.FiniteElement("DG", mesh.ufl_cell(), p_order)
        # mixed_element = fe.MixedElement([element_v, element_v, element_s])
        mixed_element = fe.MixedElement([element_v, element_s])

        self.W = fe.FunctionSpace(mesh, mixed_element)

        self.V, self.Q = self.W.split()

        self.w = fe.Function(self.W)
        self.u, self.p = fe.split(self.w)
        w0 = fe.Function(self.W)
        self.u0, self.p0 = fe.split(w0)
        self.ut, self.pt = fe.TestFunctions(self.W)

        self.F = kin.def_grad(self.u)
        self.F0 = kin.def_grad(self.u0)

        S_iso = constitutive_model.iso_stress(self.u)
        mod_p = constitutive_model.p(self.u)
        J = fe.det(self.F)
        F_inv = fe.inv(self.F)

        if mod_p is None:
            mod_p = J**2 - 1.
        else:
            mod_p -= self.p

        S = S_iso + J * self.p * F_inv * F_inv.T

        self.d_LHS = fe.inner(fe.grad(self.ut), self.F * S) * fe.dx \
                     + fe.inner(mod_p, self.pt) * fe.dx
        # + fe.inner(mod_p, fe.tr(fe.nabla_grad(self.ut)*fe.inv(self.F))) * fe.dx

        self.d_RHS = (fe.inner(fe.Constant((0., 0., 0.)), self.ut) * fe.dx)
    def setup_adaptive_goal_form(self):
        """ Set the adaptive goal based on the semi-phase-field. 
        
        Here the integrated goal is equivalent to the remaining solid area.
        """
        p, u, T = fenics.split(self.state.solution)

        phi = self.make_semi_phasefield_function()

        self.adaptive_goal_form = phi(T) * self.integration_metric
예제 #18
0
    def make_time_discrete_terms(self):

        p_np1, u_np1, T_np1 = fenics.split(self.state.solution)

        p_n, u_n, T_n = fenics.split(self.old_state.solution)

        u = [u_np1, u_n]

        T = [T_np1, T_n]

        _phi = self.make_semi_phasefield_function()

        phi = [_phi(T_np1), _phi(T_n)]

        if self.second_order_time_discretization:

            p_nm1, u_nm1, T_nm1 = fenics.split(self.old_old_state.solution)

            u.append(u_nm1)

            T.append(T_nm1)

            phi.append(_phi(T_nm1))

        if self.second_order_time_discretization:

            Delta_t = [
                self.fenics_timestep_size, self.old_fenics_timestep_size
            ]

        else:

            Delta_t = self.fenics_timestep_size

        u_t = self.apply_time_discretization(Delta_t, u)

        T_t = self.apply_time_discretization(Delta_t, T)

        phi_t = self.apply_time_discretization(Delta_t,
                                               phi)  # @todo This is wrong.

        return u_t, T_t, phi_t
예제 #19
0
def Vufl(soln, t):
    "Make a UFL object for plotting V"
    split = fe.split(soln.function)
    irho = split[0]
    iUs = split[1:]
    soln.ksdg.set_time(t)
    V = (soln.V(iUs, irho, params=soln.ksdg.iparams) /
         (soln.ksdg.iparams['sigma']**2 / 2))
    fs = soln.function.function_space()
    cell = fs.ufl_cell()
    CE = fe.FiniteElement('CG', cell, soln.degree)
    CS = fe.FunctionSpace(fs.mesh(), CE)
    pV = fe.project(V, CS, solver_type='petsc')
    return pV
예제 #20
0
def solve_steady_state_heiser_weissinger(kappa):

    w = fe.Function(V_up)
    (u, p) = fe.split(w)
    p = fe.variable(p)
    (eta, q) = fe.TestFunctions(V_up)
    dw = fe.TrialFunction(V_up)

    kappa = fe.Constant(kappa)

    bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_up.sub(0), V_up.sub(1), None,
                                            boundaries)

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

    W = material_mooney_rivlin(I_1_iso, I_2_iso, c_10,
                               c_01)  #+ incompr_relaxation(p, kappa)
    g = incompr_constr(J)

    # Lagrange function (without constraint)
    L = -W

    # Modified Lagrange function (with constraints)
    L_mod = L - p * g
    P = first_piola_stress(L, F)
    G = incompr_stress(g, F)  # = J*fe.inv(F.T)

    Lp = const_eq(L_mod, p)

    a_static = weak_div_term(P + p * G,
                             eta) + inner(B, eta) * dx + inner(Lp, q) * dx

    J_static = fe.derivative(a_static, w, dw)
    ffc_options = {"optimize": True}
    problem = fe.NonlinearVariationalProblem(
        a_static,
        w,
        bcs_u + bcs_p,
        J=J_static,
        form_compiler_parameters=ffc_options)
    solver = fe.NonlinearVariationalSolver(problem)

    solver.solve()

    return w
예제 #21
0
def test__cavity_melting_without_concentration__amr__regression__ci__():

    sim = CavityMeltingSimulationWithoutConcentration()

    sim.assign_initial_values()

    for it in range(5):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim.solution)

    phi = sim.semi_phasefield(T=T_fine, C=C_fine)

    solid_area = fenics.assemble(phi * fenics.dx)

    assert (abs(solid_area - expected_solid_area) < 1.e-6)
def forward(rho):
    """Solve the forward problem for a given fluid distribution rho(x)."""
    w = fenics_adjoint.Function(W)
    (u, p) = fenics.split(w)
    (v, q) = fenics.TestFunctions(W)

    inner, grad, dx, div = ufl.inner, ufl.grad, ufl.dx, ufl.div
    F = (
        alpha(rho) * inner(u, v) * dx
        + inner(grad(u), grad(v)) * dx
        + inner(grad(p), v) * dx
        + inner(div(u), q) * dx
    )
    bcs = [
        fenics_adjoint.DirichletBC(W.sub(0).sub(1), 0, "on_boundary"),
        fenics_adjoint.DirichletBC(W.sub(0).sub(0), inflow_outflow_bc, "on_boundary"),
    ]
    fenics_adjoint.solve(F == 0, w, bcs=bcs)
    return w
예제 #23
0
    def bottom_wall_shear_integrand(self):

        nhat = fenics.FacetNormal(self.mesh)

        p, u, T, C = fenics.split(self.solution)

        bottom_wall_id = 2

        mesh_function = fenics.MeshFunction("size_t", self.mesh,
                                            self.mesh.topology().dim() - 1)

        self.bottom_wall.mark(mesh_function, bottom_wall_id)

        dot, grad = fenics.dot, fenics.grad

        ds = fenics.ds(domain=self.mesh,
                       subdomain_data=mesh_function,
                       subdomain_id=bottom_wall_id)

        return dot(grad(u[0]), nhat) * ds
예제 #24
0
def _create_variational_problem(m0, u0, W, dt):
    """We set up the variational problem."""
    
    p, q = fc.TestFunctions(W)
    w = fc.Function(W)  # Function to solve for
    m, u = fc.split(w)
    # Relabel i.e. initialise m_prev, u_prev as m0, u0.
    m_prev, u_prev = m0, u0
    m_mid = 0.5 * (m + m_prev)
    u_mid = 0.5 * (u + u_prev)
    F = (
        (q * u + q.dx(0) * u.dx(0) - q * m) * fc.dx +                                          # q part
        (p * (m - m_prev) + dt * (p * m_mid * u_mid.dx(0) - p.dx(0) * m_mid * u_mid)) * fc.dx  # p part
        )
    J = fc.derivative(F, w)
    problem = fc.NonlinearVariationalProblem(F, w, J=J)
    solver = fc.NonlinearVariationalSolver(problem)
    solver.parameters["newton_solver"]["maximum_iterations"] = 100  # Default is 50
    solver.parameters["newton_solver"]["error_on_nonconvergence"] = False
    
    return solver, w, m_prev, u_prev
예제 #25
0
# Define Boundaries
left = fe.CompiledSubDomain("near(x[0], side) && on_boundary", side=0.0)
right = fe.CompiledSubDomain("near(x[0], side) && on_boundary", side=1.0)

# Define Dirichlet boundary (x = 0 or x = 1)
u_left = fe.Expression(("0.0", "0.0", "0.0"), element=element_3)
u_right = fe.Expression(("0.0", "0.0", "0.0"), element=element_3)
p_left = fe.Constant(0.)

# Define acting force
b = fe.Constant((0.0, 0.0, 0.0))  # Body force per unit volume
t_bar = fe.Constant((0.0, 0.0, 0.0))  # Traction force on the boundary

# Define test and trial functions
w = fe.Function(V)  # most recently computed solution
(u, p) = fe.split(w)
(v, q) = fe.TestFunctions(V)
dw = fe.TrialFunction(V)

# Kinematics
d = u.geometric_dimension()
I = fe.Identity(d)  # Identity tensor

F = fe.variable(I + grad(u))  # Deformation gradient
C = fe.variable(F.T * F)  # Right Cauchy-Green tensor
J = fe.det(C)

DE = lambda v: 0.5 * (F.T * grad(v) + grad(v).T * F)

a_0 = fe.as_vector([[1.0], [0.], [0.]])
예제 #26
0
V = fn.FunctionSpace(mesh, Mixed)

# %%
# define potentials and concentrations
u_GND = fn.Expression('0', degree=2)  #Ground
u_DD = fn.Expression('0.5', degree=2)  #pontential
c_avg = fn.Expression('0.0001', degree=2)  #average concentration

# set boundary conditions
bcs = []
bcs += [fn.DirichletBC(V.sub(0), u_DD, mf, 3)]
bcs += [fn.DirichletBC(V.sub(0), u_GND, mf, 1)]

# define problem
UC = fn.Function(V)
uc = fn.split(UC)  # trial function potential concentration lagrange multi
u, c, lam = uc[0], uc[1:M + 1], uc[M + 1:]

VW = fn.TestFunctions(
    V)  # test function potential concentration lagrange multi
v, w, mu = VW[0], VW[1:M + 1], VW[M + 1:]

#lets try rot
r = fn.Expression('x[0]', degree=0)

# changing concentrations charges
Rho = 0
for i in range(M):
    if i % 2:
        Rho += -c[i]
    else:
예제 #27
0
    def __init__(
            self,
            mesh=None,
            width=1.0,
            dim=1,
            nelements=8,
            degree=2,
            parameters={},
            V=(lambda U: U),
            U0=None,
            rho0=None,
            t0=0.0,
            debug=False,
            solver_type = 'lu',
            preconditioner_type = 'default',
            periodic=True,
            ligands=None
            ):
        """DG solver for the periodic Keller-Segel PDE system

        Keyword parameters:
        mesh=None: the mesh on which to solve the problem
        width=1.0: the width of the domain
        dim=1: # of spatial dimensions.
        nelements=8: If mesh is not supplied, one will be
        contructed using UnitIntervalMesh, UnitSquareMesh, or
        UnitCubeMesh (depending on dim). dim and nelements are not
        needed if mesh is supplied.
        degree=2: degree of the polynomial approximation
        parameters={}: a dict giving the values of scalar parameters of
            .V, U0, and rho0 Expressions. This dict needs to also
            define numerical parameters that appear in the PDE. Some
            of these have defaults:
            dim = dim: # of spatial dimensions
            sigma: organism movement rate
            s: attractant secretion rate
            gamma: attractant decay rate
            D: attractant diffusion constant
            rho_min=10.0**-7: minimum feasible worm density
            U_min=10.0**-7: minimum feasible attractant concentration
            rhopen=10: penalty for discontinuities in rho
            Upen=1: penalty for discontinuities in U
            grhopen=1, gUpen=1: penalties for discontinuities in gradients
        V=(lambda U: U): a callable taking two numerical arguments, U
            and rho, or a single argument, U, and returning a single
            number, V, the potential corresponding to U. Use fenics
            versions of mathematical functions, e.g. fe.ln, abs,
            fe.exp.
        U0, rho0: Expressions, Functions, or strs specifying the
            initial condition.
        t0=0.0: initial time
        solver_type='lu'
        preconditioner_type='default'
        periodic=True: Allowed for compatibility, but ignored
        ligands=None: ignored for compatibility
        """
        logPERIODIC('creating KSDGSolverPeriodic')
        self.args = dict(
            mesh=mesh,
            width=width,
            dim=dim,
            nelements=nelements,
            degree=degree,
            parameters=parameters,
            V=V,
            U0=U0,
            rho0=rho0,
            t0=t0,
            debug=debug,
            solver_type = solver_type,
            preconditioner_type = preconditioner_type,
            periodic=True,
            ligands=ligands
        )
        self.debug = debug
        self.solver_type = solver_type
        self.preconditioner_type = preconditioner_type
        self.periodic = True
        self.params = self.default_params.copy()
        #
        # Store the original mesh in self.omesh. self.mesh will be the
        # corner mesh.
        #
        if (mesh):
            self.omesh = mesh
        else:
            self.omesh = box_mesh(width=width, dim=dim, nelements=nelements)
            self.nelements = nelements
        try:
            comm = self.omesh.mpi_comm().tompi4py()
        except AttributeError:
            comm = self.omesh.mpi_comm()
        self.lmesh = gather_mesh(self.omesh)
        omeshstats = mesh_stats(self.omesh)
        logPERIODIC('omeshstats', omeshstats)
        self.xmin = omeshstats['xmin']
        self.xmax = omeshstats['xmax']
        self.xmid = omeshstats['xmid']
        self.delta_ = omeshstats['dx']
        self.mesh = corner_submesh(self.lmesh)
        meshstats = mesh_stats(self.mesh)
        logPERIODIC('meshstats', meshstats)
        logPERIODIC('self.omesh', self.omesh)
        logPERIODIC('self.mesh', self.mesh)
        logPERIODIC('self.mesh.mpi_comm().size', self.mesh.mpi_comm().size)
        self.nelements = nelements
        self.degree = degree
        self.dim = self.mesh.geometry().dim()
        self.params['dim'] = self.dim
        self.params.update(parameters)
        # 
        # Solution spaces and Functions
        #
        # The solution function space is a vector space with
        # 2*(2**dim) elements. The first 2**dim components are even
        # and odd parts of rho; These are followed by even and
        # odd parts of U. The array self.evenodd identifies even
        # and odd components. Each row is a length dim sequence 0s and
        # 1s and represnts one component. For instance, if evenodd[i]
        # is [0, 1, 0], then component i of the vector space is even
        # in dimensions 0 and 2 (x and z conventionally) and off in
        # dimension 1 (y).
        #
        self.symmetries = evenodd_symmetries(self.dim)
        self.signs = [fe.as_matrix(np.diagflat(1.0 - 2.0*eo))
                      for eo in self.symmetries]
        self.eomat = evenodd_matrix(self.symmetries)
        fss = self.make_function_space()
        (self.SE, self.SS, self.VE, self.VS) = [
            fss[fs] for fs in ('SE', 'SS', 'VE', 'VS')
        ]
        (self.SE, self.SS, self.VE, self.VS) = self.make_function_space()
        self.sol = Function(self.VS)                  # sol, current soln
        logPERIODIC('self.sol', self.sol)
        # srhos and sUs are fcuntions defiend on subspaces
        self.srhos = self.sol.split()[:2**self.dim]
        self.sUs = self.sol.split()[2**self.dim:]
        # irhos and iUs are Indexed UFL expressions
        self.irhos = fe.split(self.sol)[:2**self.dim]
        self.iUs = fe.split(self.sol)[2**self.dim:]
        self.wrhos = TestFunctions(self.VS)[: 2**self.dim]
        self.wUs = TestFunctions(self.VS)[2**self.dim :]
        self.tdsol = TrialFunction(self.VS) # time derivatives
        self.tdrhos = fe.split(self.tdsol)[: 2**self.dim]
        self.tdUs = fe.split(self.tdsol)[2**self.dim :]
        bc_method = 'geometric' if self.dim > 1 else 'pointwise'
        rhobcs = [DirichletBC(
            self.VS.sub(i),
            Constant(0),
            FacesDomain(self.mesh, self.symmetries[i]),
            method=bc_method
        ) for i in range(2**self.dim) if np.any(self.symmetries[i] != 0.0)]
        Ubcs = [DirichletBC(
            self.VS.sub(i + 2**self.dim),
            Constant(0),
            FacesDomain(self.mesh, self.symmetries[i]),
            method=bc_method
        ) for i in range(2**self.dim)  if np.any(self.symmetries[i] != 0.0)]
        self.bcs = rhobcs + Ubcs
        self.n = FacetNormal(self.mesh)
        self.h = CellDiameter(self.mesh)
        self.havg = fe.avg(self.h)
        self.dx = fe.dx
        self.dS = fe.dS
        #
        # record initial state
        #
        if not U0:
            U0 = Constant(0.0)
        if isinstance(U0, ufl.coefficient.Coefficient):
            self.U0 = U0
        else:
            self.U0 = Expression(U0, **self.params,
                                 degree=self.degree, domain=self.mesh)
        if not rho0:
            rho0 = Constant(0.0)
        if isinstance(rho0, ufl.coefficient.Coefficient):
            self.rho0 = rho0
        else:
            self.rho0 = Expression(rho0, **self.params,
                                   degree=self.degree, domain=self.mesh)
        try:
            V(self.U0, self.rho0)
            def realV(U, rho):
                return V(U, rho)
        except TypeError:
            def realV(U, rho):
                return V(U)
        self.V = realV
        self.t0 = t0
        #
        # initialize state
        #
        # cache assigners
        logPERIODIC('restarting')
        self.restart()
        logPERIODIC('restart returned')
        return(None)
예제 #28
0
rho = fe.Constant(1)
RE = 0.01
lmx = 1  # mixing length
dt = 0.1
# Re = 10 / 1e-4 = 1e5

V = fe.VectorElement("Lagrange", mesh.ufl_cell(), 2)
P = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
NU = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
if MODEL: M = fe.MixedElement([V, P, NU])
else: M = fe.MixedElement([V, P])
W = fe.FunctionSpace(mesh, M)

W0 = fe.Function(W)
We = fe.Function(W)
u0, p0 = fe.split(We)
#u0 = fe.Function((W0[0], W0[1]), 'Velocity000023.vtu')
#p0 = fe.Function(W0[2])
v, q = fe.TestFunctions(W)
#u, p = fe.split(W0)
u, p = (fe.as_vector((W0[0], W0[1])), W0[2])

#-------------------------------------------------------
# Defining essential/Dirichlet boundary conditions
# Step 1: Identify all boundary segments forming Gamma_d
#-------------------------------------------------------
#   (-3., 2.5)
#  |
#  |
#  |_______(0, 1.)
#    bc1  |
예제 #29
0
RE = 50
lmx = 1  # mixing length :)
# Re = 10 / 1e-4 = 1e5

V = fe.VectorElement("Lagrange", mesh.ufl_cell(), 2)
P = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
NU = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
if MODEL: M = fe.MixedElement([V, P, NU])
else: M = fe.MixedElement([V, P])
W = fe.FunctionSpace(mesh, M)

W0 = fe.Function(W)

if MODEL:
    (v, q, nu_test) = fe.TestFunctions(W)
    (u, p, nu_trial) = fe.split(W0)
else:
    (
        v,
        q,
    ) = fe.TestFunctions(W)
    (
        u,
        p,
    ) = fe.split(W0)
    nu_trial = fe.Constant(5)  # artificial viscosity!!!
    fv1 = fe.Constant(1)

#-------------------------------------------------------
# Defining essential/Dirichlet boundary conditions
# Step 1: Identify all boundary segments forming Gamma_d

# %%
# set boundary conditions
GammaGND  = fn.DirichletBC(V.sub(0), u_GND, boundaryGND)  # ground potential at straight electrode
GammaHigh = fn.DirichletBC(V.sub(0), u_DD, boundaryHigh)  # high potential at shaped electrode
#GammaC_GND0 = fn.DirichletBC(V.sub(0) , c_INIT, boundaryGND)
#GammaC_GND1 = fn.DirichletBC(V.sub(1) , c_INIT, boundaryGND) 
#GammaC_GND2 = fn.DirichletBC(V.sub(2) , c_INIT, boundaryGND)
bcs=[GammaGND,GammaHigh]
#bcs=[GammaGND,GammaHigh,GammaC_GND0,GammaC_GND1,GammaC_GND2]

# %%
# define problem
UC    = fn.Function(V)
uc    = fn.split(UC)
u, c1, c2, lam1, lam2  = uc[0], uc[1], uc[2], uc[3], uc[4]

VW    = fn.TestFunctions(V)                    
v, w1, w2, mu1, mu2  = VW[0], VW[1], VW[2], VW[3], VW[4]

#create rotation
#r = fn.Expression('x[0]', degree=1)

# changing concentrations charges
PoissonLeft     = (fn.dot(fn.grad(u), fn.grad(v)))*fn.dx
PoissonRight    = c1*v*fn.dx - c2*v*fn.dx
NernstPlanck1   = fn.dot((-fn.grad(c1) - (c1)*fn.grad(u)),fn.grad(w1))*fn.dx
NernstPlanck2   = fn.dot((-fn.grad(c2) + (c2)*fn.grad(u)),fn.grad(w2))*fn.dx

Constraint1     = lam1 * w1 * fn.dx + ((c1) - c_AVG) * mu1 * fn.dx