コード例 #1
0
ファイル: solid.py プロジェクト: BenjaminRodenberg/tutorials
    assert (b is not b_forces)
    solve(A, u_np1.vector(), b_forces)

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

    # Write new displacements to preCICE
    precice.write_data(u_np1)

    # Call to advance coupling, also returns the optimum time step value
    precice_dt = precice.advance(dt(0))

    # Either revert to old step if timestep has not converged or move to next timestep
    if precice.is_action_required(precice.action_read_iteration_checkpoint()
                                  ):  # roll back to checkpoint
        u_cp, t_cp, n_cp = precice.retrieve_checkpoint()
        u_n.assign(u_cp)
        t = t_cp
        n = n_cp
    else:
        u_n.assign(u_np1)
        t += float(dt)
        n += 1

    if precice.is_time_window_complete():
        update_fields(u_np1, saved_u_old, v_n, a_n)
        if n % 10 == 0:
            displacement_out << (u_n, t)

# Plot tip displacement evolution
displacement_out << u_n
コード例 #2
0
n = 0
print('output u^%d and u_ref^%d' % (n, n))
solution_out << u_n
ranks << mesh_rank

while precice.is_coupling_ongoing():

    # write checkpoint
    if precice.is_action_required(precice.action_write_iteration_checkpoint()):
        precice.store_checkpoint(u_n, t, n)

    read_data = precice.read_data()

    # Update the coupling expression with the new read data
    precice.update_coupling_expression(volume_term, read_data)
    f.assign(interpolate(volume_term, V))

    dt_inv.assign(1 / dt)

    # Compute solution u^n+1, use bcs u^n and coupling bcs
    a, L = lhs(F), rhs(F)
    solve(a == L, u_np1, bc)

    # Write data to preCICE according to which problem is being solved
    precice.write_data(u_np1)

    dt = precice.advance(dt)

    # roll back to checkpoint
    if precice.is_action_required(precice.action_read_iteration_checkpoint()):
        u_cp, t_cp, n_cp = precice.retrieve_checkpoint()
コード例 #3
0
def step(*, time: float, dt: float, p_prev: Function, p: Function, a: Form,
         l: Form) -> Tuple[float, Function, Function]:
    time += dt
    solve(a == l, p)
    p_prev.assign(p)
    return time, p_prev, p
コード例 #4
0
def relaxation(
    displacement_fluid: Initial,
    velocity_fluid: Initial,
    displacement_solid: Initial,
    velocity_solid: Initial,
    functional_fluid_initial,
    functional_solid_initial,
    bilinear_form_fluid,
    functional_fluid,
    bilinear_form_solid,
    functional_solid,
    first_time_step,
    fluid: Space,
    solid: Space,
    interface: Space,
    param: Parameters,
    fluid_macrotimestep: MacroTimeStep,
    solid_macrotimestep: MacroTimeStep,
    adjoint,
):

    # Define initial values for relaxation method
    displacement_solid_new = Function(solid.function_space_split[0])
    velocity_displacement_new = Function(solid.function_space_split[1])
    number_of_iterations = 0
    stop = False

    while not stop:

        number_of_iterations += 1
        print(
            f"Current iteration of relaxation method: {number_of_iterations}")

        # Save old values
        displacement_solid_new.assign(displacement_solid.new)
        velocity_displacement_new.assign(velocity_solid.new)

        # Perform one iteration
        solve_problem(
            displacement_fluid,
            velocity_fluid,
            displacement_solid,
            velocity_solid,
            fluid,
            solid,
            solid_to_fluid,
            functional_fluid_initial,
            bilinear_form_fluid,
            functional_fluid,
            first_time_step,
            param,
            fluid_macrotimestep,
            adjoint,
        )
        solve_problem(
            displacement_solid,
            velocity_solid,
            displacement_fluid,
            velocity_fluid,
            solid,
            fluid,
            fluid_to_solid,
            functional_solid_initial,
            bilinear_form_solid,
            functional_solid,
            first_time_step,
            param,
            solid_macrotimestep,
            adjoint,
        )

        # Perform relaxation
        displacement_solid.new.assign(
            project(
                param.TAU * displacement_solid.new +
                (1.0 - param.TAU) * displacement_solid_new,
                solid.function_space_split[0],
            ))
        velocity_solid.new.assign(
            project(
                param.TAU * velocity_solid.new +
                (1.0 - param.TAU) * velocity_displacement_new,
                solid.function_space_split[1],
            ))

        # Define errors on the interface
        displacement_error = interpolate(
            project(
                displacement_solid_new - displacement_solid.new,
                solid.function_space_split[0],
            ),
            interface.function_space_split[0],
        )
        displacement_error_linf = norm(displacement_error.vector(), "linf")
        velocity_error = interpolate(
            project(
                velocity_displacement_new - velocity_solid.new,
                solid.function_space_split[1],
            ),
            interface.function_space_split[1],
        )
        velocity_error_linf = norm(velocity_error.vector(), "linf")
        error_linf = max(displacement_error_linf, velocity_error_linf)
        if number_of_iterations == 1:

            error_initial_linf = error_linf

        print(f"Absolute error on the interface: {error_linf}")
        print(
            f"Relative error on the interface: {error_linf / error_initial_linf}"
        )

        # Check stop conditions
        if (error_linf < param.ABSOLUTE_TOLERANCE_RELAXATION
                or error_linf / error_initial_linf <
                param.RELATIVE_TOLERANCE_RELAXATION):

            print(f"Algorithm converged successfully after "
                  f"{number_of_iterations} iterations")
            stop = True

        elif number_of_iterations == param.MAX_ITERATIONS_RELAXATION:

            print("Maximal number of iterations was reached.")
            stop = True
            number_of_iterations = -1

    displacement_fluid.iterations.append(number_of_iterations)
    velocity_fluid.iterations.append(number_of_iterations)
    displacement_solid.iterations.append(number_of_iterations)
    displacement_solid.iterations.append(number_of_iterations)

    return
コード例 #5
0
def shooting_function(
    displacement_fluid: Initial,
    velocity_fluid: Initial,
    displacement_solid: Initial,
    velocity_solid: Initial,
    functional_fluid_initial,
    functional_solid_initial,
    bilinear_form_fluid,
    functional_fluid,
    bilinear_form_solid,
    functional_solid,
    first_time_step,
    fluid: Space,
    solid: Space,
    interface: Space,
    param: Parameters,
    fluid_macrotimestep: MacroTimeStep,
    solid_macrotimestep: MacroTimeStep,
    adjoint,
):

    # Save old values
    displacement_solid_new = Function(solid.function_space_split[0])
    displacement_solid_new.assign(displacement_solid.new)
    velocity_solid_new = Function(solid.function_space_split[1])
    velocity_solid_new.assign(velocity_solid.new)

    # Perform one iteration
    solve_problem(
        displacement_fluid,
        velocity_fluid,
        displacement_solid,
        velocity_solid,
        fluid,
        solid,
        solid_to_fluid,
        functional_fluid_initial,
        bilinear_form_fluid,
        functional_fluid,
        first_time_step,
        param,
        fluid_macrotimestep,
        adjoint,
    )
    solve_problem(
        displacement_solid,
        velocity_solid,
        displacement_fluid,
        velocity_fluid,
        solid,
        fluid,
        fluid_to_solid,
        functional_solid_initial,
        bilinear_form_solid,
        functional_solid,
        first_time_step,
        param,
        solid_macrotimestep,
        adjoint,
    )

    # Define shooting function
    shooting_function_1 = interpolate(
        project(
            displacement_solid_new - displacement_solid.new,
            solid.function_space_split[0],
        ),
        interface.function_space_split[0],
    )
    shooting_function_2 = interpolate(
        project(
            velocity_solid_new - velocity_solid.new,
            solid.function_space_split[1],
        ),
        interface.function_space_split[1],
    )

    # Represent shooting function as an array
    shooting_function_1_array = shooting_function_1.vector().get_local()
    shooting_function_2_array = shooting_function_2.vector().get_local()
    shooting_function_array = np.concatenate(
        (shooting_function_1_array, shooting_function_2_array), axis=None)

    return shooting_function_array
コード例 #6
0
def shooting(
    displacement_fluid: Initial,
    velocity_fluid: Initial,
    displacement_solid: Initial,
    velocity_solid: Initial,
    functional_fluid_initial,
    functional_solid_initial,
    bilinear_form_fluid,
    functional_fluid,
    bilinear_form_solid,
    functional_solid,
    first_time_step,
    fluid: Space,
    solid: Space,
    interface: Space,
    param: Parameters,
    fluid_macrotimestep: MacroTimeStep,
    solid_macrotimestep: MacroTimeStep,
    adjoint,
):

    # Define initial values for Newton's method
    displacement_solid_new = Function(solid.function_space_split[0])
    velocity_solid_new = Function(solid.function_space_split[1])
    displacement_solid_new.assign(displacement_solid.old)
    velocity_solid_new.assign(velocity_solid.old)
    number_of_iterations = 0
    number_of_linear_systems = 0
    stop = False

    # Define Newton's method
    while not stop:

        number_of_iterations += 1
        number_of_linear_systems += 1
        print(f"Current iteration of Newton's method: {number_of_iterations}")

        # Define right hand side
        displacement_solid.new.assign(displacement_solid_new)
        velocity_solid.new.assign(velocity_solid_new)
        shooting_function_value = shooting_function(
            displacement_fluid,
            velocity_fluid,
            displacement_solid,
            velocity_solid,
            functional_fluid_initial,
            functional_solid_initial,
            bilinear_form_fluid,
            functional_fluid,
            bilinear_form_solid,
            functional_solid,
            first_time_step,
            fluid,
            solid,
            interface,
            param,
            fluid_macrotimestep,
            solid_macrotimestep,
            adjoint,
        )
        shooting_function_value_linf = np.max(np.abs(shooting_function_value))
        if number_of_iterations == 1:

            shooting_function_value_initial_linf = shooting_function_value_linf

        print(f"Absolute error on the interface: "
              f"{shooting_function_value_linf}")
        print(
            f"Relative error on the interface: "
            f"{shooting_function_value_linf / shooting_function_value_initial_linf}"
        )

        # Define linear operator
        displacement_solid_interface = interpolate(
            displacement_solid_new, interface.function_space_split[0])
        velocity_solid_interface = interpolate(
            velocity_solid_new, interface.function_space_split[1])
        displacement_solid_interface_array = (
            displacement_solid_interface.vector().get_local())
        velocity_solid_interface_array = (
            velocity_solid_interface.vector().get_local())
        linear_operator_newton = shooting_newton(
            displacement_fluid,
            velocity_fluid,
            displacement_solid,
            velocity_solid,
            functional_fluid_initial,
            functional_solid_initial,
            bilinear_form_fluid,
            functional_fluid,
            bilinear_form_solid,
            functional_solid,
            first_time_step,
            fluid,
            solid,
            interface,
            param,
            fluid_macrotimestep,
            solid_macrotimestep,
            adjoint,
            displacement_solid_interface_array,
            velocity_solid_interface_array,
            shooting_function_value,
        )
        shooting_gmres = LinearOperator(
            (
                2 * param.NUMBER_ELEMENTS_HORIZONTAL + 2,
                2 * param.NUMBER_ELEMENTS_HORIZONTAL + 2,
            ),
            matvec=linear_operator_newton,
        )

        # Solve linear system
        number_of_iterations_gmres = 0

        def callback(vector):

            nonlocal number_of_iterations_gmres
            global residual_norm_gmres
            number_of_iterations_gmres += 1
            print(
                f"Current iteration of GMRES method: {number_of_iterations_gmres}"
            )
            residual_norm_gmres = np.linalg.norm(vector)

        direction, exit_code = gmres(
            shooting_gmres,
            -shooting_function_value,
            tol=param.TOLERANCE_GMRES,
            maxiter=param.MAX_ITERATIONS_GMRES,
            callback=callback,
        )
        number_of_linear_systems += number_of_iterations_gmres
        if exit_code == 0:

            print(f"GMRES method converged successfully after "
                  f"{number_of_iterations_gmres} iterations")

        else:

            print("GMRES method failed to converge.")
            print(f"Norm of residual: {residual_norm_gmres}")

        # Advance solution
        direction_split = np.split(direction, 2)
        displacement_solid_interface_array += direction_split[0]
        velocity_solid_interface_array += direction_split[1]
        displacement_solid_interface.vector().set_local(
            displacement_solid_interface_array)
        velocity_solid_interface.vector().set_local(
            velocity_solid_interface_array)
        displacement_solid_new.assign(
            interpolate(displacement_solid_interface,
                        solid.function_space_split[0]))
        velocity_solid_new.assign(
            interpolate(velocity_solid_interface,
                        solid.function_space_split[1]))

        # Check stop conditions
        if (shooting_function_value_linf < param.ABSOLUTE_TOLERANCE_NEWTON
                or shooting_function_value_linf /
                shooting_function_value_initial_linf <
                param.RELATIVE_TOLERANCE_NEWTON):
            print(f"Newton's method converged successfully after "
                  f"{number_of_iterations} iterations and solving "
                  f"{number_of_linear_systems} linear systems.")
            stop = True

        elif number_of_iterations == param.MAX_ITERATIONS_NEWTON:

            print("Newton's method failed to converge.")
            stop = True
            number_of_linear_systems = -1

    displacement_fluid.iterations.append(number_of_linear_systems)
    velocity_fluid.iterations.append(number_of_linear_systems)
    displacement_solid.iterations.append(number_of_linear_systems)
    displacement_solid.iterations.append(number_of_linear_systems)

    return
コード例 #7
0
def step(*, time: float, dt: float, t_prev: Function, t: Function, a: Form,
         l: Form, bc) -> Tuple[float, Function, Function]:
    time += dt
    solve(a == l, t, bc)
    t_prev.assign(t)
    return time, t_prev, t
コード例 #8
0
def solid_problem(u_f, v_f, u_s, v_s,
                  fluid, solid, param, save = False):

    # Store old solutions
    u_s_n_K = Function(solid.V_split[0])
    v_s_n_K = Function(solid.V_split[1])
    u_s_n_K.assign(u_s.old)
    v_s_n_K.assign(v_s.old)
        
    # Store old boundary values
    v_s_n_i_K = Function(solid.V_split[1])
    v_s_n_i_K.assign(v_s.i_old)
    
    # Initialize interface values
    v_s_i = Function(solid.V_split[1])
    
    # Define Dirichlet boundary conditions
    bc_u_s_0 = DirichletBC(solid.V.sub(0), Constant(0.0), boundary)
    bc_v_s_0 = DirichletBC(solid.V.sub(1), Constant(0.0), boundary)
    bcs_s = [bc_u_s_0, bc_v_s_0]
            
    # Compute fractional steps for solid problem
    for k in range(param.K):
            
        # Update boundary values
        v_s_i.assign(project((param.K - k - 1.0)/param.K*v_s.i_old +
              + (k + 1.0)/param.K*fluid_to_solid(v_f.new,
              fluid, solid, param, 1), solid.V_split[1]))
                
        # Define trial and test functions
        U_s_new = TrialFunction(solid.V)
        (u_s_new, v_s_new) = split(U_s_new)
        Phi_s = TestFunction(solid.V)
        (phi_s, psi_s) = split(Phi_s)
                
        # Define scheme
        A_s = (v_s_new*phi_s*solid.dx
            + u_s_new*psi_s*solid.dx
            + 0.5*param.dt/param.K*a_s(u_s_new, v_s_new, phi_s, psi_s,
                                       solid, param))
        L_s = (v_s_n_K*phi_s*solid.dx 
            + u_s_n_K*psi_s*solid.dx 
            - 0.5*param.dt/param.K*a_s(u_s_n_K, v_s_n_K, phi_s, psi_s, 
                                       solid, param) 
            + 0.5*param.dt/param.K*param.nu*dot(grad(v_s_i), 
                                                solid.n)*phi_s*solid.ds 
            + 0.5*param.dt/param.K*param.nu*dot(grad(v_s_n_i_K),
                                                solid.n)*phi_s*solid.ds) 
                
        # Solve solid problem
        U_s_new = Function(solid.V)
        solve(A_s == L_s, U_s_new, bcs_s)
        (u_s_new, v_s_new) = U_s_new.split(U_s_new)
        
        # Append solutions to the arrays
        if save:
            
            u_s.array.append(u_s_new.copy(deepcopy = True))
            v_s.array.append(v_s_new.copy(deepcopy = True))
            
        # Update solid solution
        u_s_n_K.assign(u_s_new)
        v_s_n_K.assign(v_s_new)
                
        # Update boundary condition
        v_s_n_i_K.assign(project(v_s_i, solid.V_split[1]))
        
    # Save final values
    u_s.new.assign(u_s_new)
    v_s.new.assign(v_s_new)
    v_s.i_new.assign(v_s_i)
    
    return 
コード例 #9
0
def fluid_problem(u_f, v_f, u_s, v_s, fluid, solid, param, t, save=False):

    # Store old solutions
    u_f_n_M = Function(fluid.V_split[0])
    v_f_n_M = Function(fluid.V_split[1])
    u_f_n_M.assign(u_f.old)
    v_f_n_M.assign(v_f.old)

    # Store old boundary values
    u_f_n_i_M = Function(fluid.V_split[0])
    v_f_n_i_M = Function(fluid.V_split[1])
    u_f_n_i_M.assign(u_f.i_old)
    v_f_n_i_M.assign(v_f.i_old)

    # Initialize interface values
    u_f_i = Function(fluid.V_split[0])
    v_f_i = Function(fluid.V_split[1])

    # Define Dirichlet boundary conditions
    bc_u_f_0 = DirichletBC(fluid.V.sub(0), Constant(0.0), boundary)
    bc_v_f_0 = DirichletBC(fluid.V.sub(1), Constant(0.0), boundary)
    bcs_f = [bc_u_f_0, bc_v_f_0]

    # Compute fractional steps for fluid problem
    for m in range(param.M):

        # Update boundary values
        u_f_i.assign(
            project((param.M - m - 1.0) / param.M * u_f.i_old + (m + 1.0) /
                    param.M * solid_to_fluid(u_s.new, fluid, solid, param, 0),
                    fluid.V_split[0]))
        v_f_i.assign(
            project((param.M - m - 1.0) / param.M * v_f.i_old + (m + 1.0) /
                    param.M * solid_to_fluid(v_s.new, fluid, solid, param, 1),
                    fluid.V_split[1]))

        # Define trial and test functions
        U_f_new = TrialFunction(fluid.V)
        (u_f_new, v_f_new) = split(U_f_new)
        Phi_f = TestFunction(fluid.V)
        (phi_f, psi_f) = split(Phi_f)

        # Define scheme
        A_f = (v_f_new * phi_f * fluid.dx + 0.5 * param.dt / param.M *
               a_f(u_f_new, v_f_new, phi_f, psi_f, fluid, param))
        L_f = (v_f_n_M * phi_f * fluid.dx - 0.5 * param.dt / param.M *
               a_f(u_f_n_M, v_f_n_M, phi_f, psi_f, fluid, param) +
               0.5 * param.dt / param.M * param.gamma / fluid.h * u_f_i *
               psi_f * fluid.ds + 0.5 * param.dt / param.M * param.gamma /
               fluid.h * v_f_i * phi_f * fluid.ds + 0.5 * param.dt / param.M *
               param.gamma / fluid.h * u_f_n_i_M * psi_f * fluid.ds +
               0.5 * param.dt / param.M * param.gamma / fluid.h * v_f_n_i_M *
               phi_f * fluid.ds + param.dt / param.M * f(t) * phi_f * fluid.dx)

        # Solve fluid problem
        U_f_new = Function(fluid.V)
        solve(A_f == L_f, U_f_new, bcs_f)
        (u_f_new, v_f_new) = U_f_new.split(U_f_new)

        # Append solutions to the arrays
        if save:

            u_f.array.append(u_f_new.copy(deepcopy=True))
            v_f.array.append(v_f_new.copy(deepcopy=True))

        # Update fluid solution
        u_f_n_M.assign(u_f_new)
        v_f_n_M.assign(v_f_new)

        # Update boundary conditions
        u_f_n_i_M.assign(project(u_f_i, fluid.V_split[0]))
        v_f_n_i_M.assign(project(v_f_i, fluid.V_split[1]))

    # Save final values
    u_f.new.assign(u_f_new)
    v_f.new.assign(v_f_new)
    u_f.i_new.assign(u_f_i)
    v_f.i_new.assign(v_f_i)

    return
コード例 #10
0
    def compute_conv_diff_reac_video(self, initial_condition=None, video_ref=None, video_size=None):

        names = {'Cl', 'K'}


        P1 = FiniteElement('P', fe.triangle, 1)
        element = fe.MixedElement([P1, P1])
        V_single = FunctionSpace(self.mesh, P1)
        V = FunctionSpace(self.mesh, element)
        self.V_conc = V

        # load video
        video = VideoData(element=P1)
        video.load_video(self.video_filename)

        if( video_ref is not None and video_size is not None):
            video.set_reference_frame(video_ref, video_size)


        print(video)

        dt = 0.05
        t = 0.
        t_end = 20.

        u_init = Function(V)
        (u_cl, u_k) = TrialFunction(V)
        (v_cl, v_k) = TestFunction(V)

        #u_na = video


        if initial_condition is None:
            #initial_condition = Expression(("f*exp(-0.5*((x[0]-a)*(x[0]-a)+(x[1]-b)*(x[1]-b))/var)/(sqrt(2*pi)*var)",
            #                                "0."), a = 80, b= 55, var=10, f=10, pi=fe.pi, element=element)

            initial_condition = Expression(("f",
                                            "0."), a=80, b=55, var=0.1, f=0.1, pi=fe.pi, element=element)

        u_init = fe.interpolate(initial_condition, V)
        u_init_cl = u_init[0]

        u_init_k = u_init[1]
        u_init_na : VideoData= video

        assert (self.flow is not None)

        n = fe.FacetNormal(self.mesh)

        dx, ds = self.dx, self.ds
        flow = 5. * self.flow
        f_in = fe.Constant(0.00)
        f_in_cl = fe.Constant(-0.05)
        D = fe.Constant(0.1)

        C_na = fe.Constant(0.1)
        k1 = fe.Constant(0.2)
        k_1 = fe.Constant(0.00001)
        # explicit
        F = (
                (u_cl - u_init_cl) * v_cl * dx
                + dt * D * inner(grad(u_cl), grad(v_cl)) * dx
                + dt * inner(flow, grad(u_cl)) * v_cl * dx
                #+ (u_na - u_init_na) * v_na * dx
                #+ dt * D * inner(grad(u_na), grad(v_na)) * dx
                #+ dt * inner(flow, grad(u_na)) * v_na * dx
                + (u_k - u_init_k) * v_k * dx
                + dt * D * inner(grad(u_k), grad(v_k)) * dx
                + dt * inner(flow, grad(u_k)) * v_k * dx
                + f_in_cl * v_cl * dx
                #+ f_in * v_na * dx
                + f_in * v_k * dx
                + dt * k1 * u_init_cl * C_na * u_init_na * v_cl * dx
                #+ dt * k1 * u_init_cl * u_init_na * v_na * dx
                - dt * k1 * u_init_cl * C_na * u_init_na * v_k * dx
                - dt * k_1 * u_init_k * v_cl * dx
                #- dt * k_1 * u_init_k * v_na * dx
                + dt * k_1 * u_init_k * v_k * dx
        )
        # implicit
        F = (
                (u_cl - u_init_cl) * v_cl * dx
                + dt * D * inner(grad(u_cl), grad(v_cl)) * dx
                + dt * inner(flow, grad(u_cl)) * v_cl * dx
                # + (u_na - u_init_na) * v_na * dx
                # + dt * D * inner(grad(u_na), grad(v_na)) * dx
                # + dt * inner(flow, grad(u_na)) * v_na * dx
                + (u_k - u_init_k) * v_k * dx
                + dt * D * inner(grad(u_k), grad(v_k)) * dx
                + dt * inner(flow, grad(u_k)) * v_k * dx
                + f_in_cl * v_cl * dx
                # + f_in * v_na * dx
                + f_in * v_k * dx
                + dt * k1 * u_cl * C_na * u_init_na * v_cl * dx
                # + dt * k1 * u_init_cl * u_init_na * v_na * dx
                - dt * k1 * u_cl * C_na * u_init_na * v_k * dx
                - dt * k_1 * u_k * v_cl * dx
                # - dt * k_1 * u_init_k * v_na * dx
                + dt * k_1 * u_k * v_k * dx
        )

        self.F = F

        a, L = fe.lhs(F), fe.rhs(F)
        a_mat = fe.assemble(a)
        L_vec = fe.assemble(L)

        output1 = fe.File('/tmp/cl_dyn.pvd')
        output2 = fe.File('/tmp/na_dyn.pvd')
        output3 = fe.File('/tmp/k_dyn.pvd')
        output4 = fe.File('/tmp/all_dyn.pvd')
        # solve

        self.sol = []

        u_na = Function(V_single)
        u_na = fe.interpolate(u_init_na,V_single)

        na_inflow = 0

        t_plot = 0.5
        t_last_plot = 0

        while t < t_end:
            t = t + dt
            t_last_plot += dt
            print(t)

            u = Function(V)

            u_init_na.set_time(5*t)

            a_mat = fe.assemble(a)
            L_vec = fe.assemble(L)
            fe.solve(a_mat, u.vector(), L_vec)
            # NonlinearVariationalProblem(F,u)
            u_init.assign(u)

            u_cl, u_k = u.split()

            # u_init_cl.assign(u_cl)
            # u_init_na.assign(u_na)
            # u_init_k.assign(u_k)

            u_na = fe.interpolate(u_init_na, V_single)

            u_cl.rename("cl", "cl")
            u_na.rename("na", "na")
            u_k.rename("k", "k")
            output1 << u_cl, t
            output2 << u_na, t
            output3 << u_k, t
            self.sol.append((u_cl, u_na, u_k))

            print( fe.assemble(u_cl*self.dx))

            if t_last_plot > t_plot:
                t_last_plot = 0
                plt.figure(figsize=(8,16))
                plt.subplot(211)
                fe.plot(u_cl)
                plt.subplot(212)
                fe.plot(u_k)
                plt.show()



        self.u_cl = u_cl
        #self.u_na = u_na
        self.u_k = u_k
コード例 #11
0
    def compute_conv_diff_reac(self, initial_condition=None):

        names = {'Cl', 'Na', 'K'}

        dt = 0.1
        t = 0.
        t_end = 1.

        P1 = FiniteElement('P', fe.triangle, 3)
        element = MixedElement([P1, P1, P1])
        V = FunctionSpace(self.mesh, element)
        self.V_conc = V

        u_init = Function(V)
        (u_cl, u_na, u_k) = TrialFunction(V)
        (v_cl, v_na, v_k) = TestFunction(V)

        if initial_condition is None:
            initial_condition = Expression(("exp(-((x[0]-0.1)*(x[0]-0.1)+x[1]*x[1])/0.01)",
                                            "exp(-((x[0]-0.12)*(x[0]-0.12)+x[1]*x[1])/0.01)",
                                            "0."), element=element)

        u_init = fe.interpolate(initial_condition, V)
        u_init_cl = u_init[0]
        u_init_na = u_init[1]
        u_init_k = u_init[2]

        assert (self.flow is not None)

        n = fe.FacetNormal(self.mesh)

        dx, ds = self.dx, self.ds
        flow = 10 * self.flow
        f_in = fe.Constant(0.00)
        D = fe.Constant(0.01)
        k1 = fe.Constant(0.1)
        k_1 = fe.Constant(0.001)
        F = (
                (u_cl - u_init_cl) * v_cl * dx
                + dt * D * inner(grad(u_cl), grad(v_cl)) * dx
                + dt * inner(flow, grad(u_cl)) * v_cl * dx
                + (u_na - u_init_na) * v_na * dx
                + dt * D * inner(grad(u_na), grad(v_na)) * dx
                + dt * inner(flow, grad(u_na)) * v_na * dx
                + (u_k - u_init_k) * v_k * dx
                + dt * D * inner(grad(u_k), grad(v_k)) * dx
                + dt * inner(flow, grad(u_k)) * v_k * dx
                + f_in * v_cl * dx
                + f_in * v_na * dx
                + f_in * v_k * dx
                + dt * k1 * u_init_cl * u_init_na * v_cl * dx
                + dt * k1 * u_init_cl * u_init_na * v_na * dx
                - dt * k1 * u_init_cl * u_init_na * v_k * dx
                - dt * k_1 * u_init_k * v_cl * dx
                - dt * k_1 * u_init_k * v_na * dx
                + dt * k_1 * u_init_k * v_k * dx
        )

        self.F = F

        a, L = fe.lhs(F), fe.rhs(F)
        a_mat = fe.assemble(a)
        L_vec = fe.assemble(L)

        output1 = fe.File('/tmp/cl_dyn.pvd')
        output2 = fe.File('/tmp/na_dyn.pvd')
        output3 = fe.File('/tmp/k_dyn.pvd')
        output4 = fe.File('/tmp/all_dyn.pvd')
        # solve

        self.sol = []

        while t < t_end:
            t = t + dt
            print(t)

            u = Function(V)

            a_mat = fe.assemble(a)
            L_vec = fe.assemble(L)
            fe.solve(a_mat, u.vector(), L_vec)
            # NonlinearVariationalProblem(F,u)
            u_init.assign(u)

            u_cl, u_na, u_k = u.split()

            # u_init_cl.assign(u_cl)
            # u_init_na.assign(u_na)
            # u_init_k.assign(u_k)

            u_cl.rename("cl", "cl")
            u_na.rename("na", "na")
            u_k.rename("k", "k")
            output1 << u_cl, t
            output2 << u_na, t
            output3 << u_k, t
            self.sol.append((u_cl, u_na, u_k))



        self.u_cl = u_cl
        self.u_na = u_na
        self.u_k = u_k