Пример #1
0
class Fluid(object):
    def __init__(self, mesh, coupling_boundary, complementary_boundary, bndry, dt, theta, v_max, 
            mu_f, rho_f, result, *args, **kwargs):

        # initialize meshes and boundaries
        self.mesh  = mesh
        self.coupling_boundary = coupling_boundary
        self.complementary_boundary = complementary_boundary
        bnd_mesh = BoundaryMesh(mesh, 'exterior')
        self.bndry = bndry          # boundary-marking function for integration

        self.fenics_dt  = float(dt)
        self.dt = Constant(dt)
        self.theta = theta
        self.t     = 0.0
        self.v_max = v_max
        self.mu_f     = mu_f
        self.rho_f    = rho_f
        

        # bounding box tree
        self.bb = BoundingBoxTree()
        self.bb.build(self.mesh)

        # Define finite elements
        eV = VectorElement("CG", mesh.ufl_cell(), 2)	    # velocity element
        eU = VectorElement("CG", mesh.ufl_cell(), 2)	    # displacement element
        eP = FiniteElement("CG", mesh.ufl_cell(), 1)	    # pressure element

        eW = MixedElement([eV, eU, eP])                     # mixed element
        W  = FunctionSpace(self.mesh, eW)                   # function space for ALE fluid equation
        self.W = W
        self.U = FunctionSpace(self.mesh, eU)               # function space for projected functions 


        self.W_boundary = VectorFunctionSpace(bnd_mesh, 'CG', 2)    # boundary function space
        self.fun4forces = Function(self.W)                  # function for Variational formulation

        # Set boundary conditions
        self.v_in = Expression(("t<2.0? 0.5*(1.0 - cos(0.5*pi*t))*v_max*4/(gW*gW)*(x[1]*(gW - x[1])): \
                      v_max*4/(gW*gW)*(x[1]*(gW - x[1]))", "0.0"),
                      degree = 2, v_max = Constant(self.v_max), gW = Constant(gW), t = self.t)

        #info("Expression set.")
        bc_v_in     = DirichletBC(self.W.sub(0), self.v_in,            bndry, _INFLOW)
        bc_v_walls  = DirichletBC(self.W.sub(0), Constant((0.0, 0.0)), bndry, _WALLS)
        bc_v_circle = DirichletBC(self.W.sub(0), Constant((0.0, 0.0)), bndry, _FLUID_CYLINDER)
        bc_u_in     = DirichletBC(self.W.sub(1), Constant((0.0, 0.0)), bndry, _INFLOW)
        bc_u_walls  = DirichletBC(self.W.sub(1).sub(1), Constant(0.0), bndry, _WALLS)
        bc_u_circle = DirichletBC(self.W.sub(1), Constant((0.0, 0.0)), bndry, _FLUID_CYLINDER)
        bc_u_out    = DirichletBC(self.W.sub(1), Constant((0.0, 0.0)), bndry, _OUTFLOW)
        self.bcs = [bc_v_in, bc_v_walls, bc_v_circle, bc_u_in, bc_u_walls, bc_u_circle, bc_u_out]


        #info("Normal and Circumradius.")
        self.n = FacetNormal(self.mesh)
        I = Identity(self.W.mesh().geometry().dim())

        # Define functions
        self.w  = Function(self.W)      
        self.w0 = Function(self.W)

        (v_, u_, p_) = TestFunctions(self.W)
        (self.v, self.u, self.p) = split(self.w)
        (self.v0, self.u0, self.p0) = split(self.w0)

        # define coupling BCs
        self.u_D = Constant((0.0, 0.0))                     # Dirichlet BC (for Fluid)
        self.u_D_function = interpolate(self.u_D, self.U)   # Dirichlet BC as function
        self.f_N = Constant((0.0, 0.0))                     # Neumann BC (for Solid)
        self.f_N_function = interpolate(self.f_N, self.U)   # Neumann BC as function

        # start preCICE adapter
        info('Initialize Adapter.')
        self.precice = Adapter()
        # read forces(Neumann condition for solid) and write displacement(Dirichlet condition for fluid)
        info('Call precice.initialize(...).')
        self.precice_dt = self.precice.initialize(
                coupling_subdomain=self.coupling_boundary, mesh=self.mesh, 
                read_field=self.u_D_function, write_field=self.f_N_function, u_n=self.w,#u_n,
                coupling_marker=self.bndry)


        # TODO: need to set DirichletBC for displacement AND velocity
        # functions for displacement BC
        self.u_bc  = self.precice.create_coupling_dirichlet_boundary_condition(self.U)  
        self.u_bc0 = self.u_bc

        dt = self.dt.values()[0]
        self.v_bc = self.u_bc                                   # wrong condition, but code runs
        #self.v_bc = (1.0/self.dt)*(self.u_bc - self.u_bc0)     # I need to do this, but raises error

        bc_u_FSI = DirichletBC(self.W.sub(1), self.u_bc, coupling_boundary)
        bc_v_FSI = DirichletBC(self.W.sub(0), self.v_bc, coupling_boundary)

        self.bcs.append(bc_u_FSI)
        self.bcs.append(bc_v_FSI)

        # define deformation gradient, Jacobian
        self.FF  = I + grad(self.u)
        self.FF0 = I + grad(self.u0)
        self.JJ  = det(self.FF)
        self.JJ0 = det(self.FF0)

        # mesh-moving eqaution (pseudoelasticity)
        self.gamma = 9.0/8.0
        h = CellVolume(self.mesh)**(self.gamma)     # makes mesh stiffer when mesh finer 
                                                    # (our mesh is finer by the FSI -moving- interface)
        E = Constant(1.0)

        E_mesh = E/h                                                    # Young Modulus
        nu_mesh = Constant(-0.02)                                       # Poisson ratio
        mu_mesh = E_mesh/(2*(1.0+nu_mesh))                              # Lame 1
        lambda_mesh = (nu_mesh*E_mesh)/((1+nu_mesh)*(1-2*nu_mesh))      # Lame 2

        # variational formulation for mesh motion
        F_mesh = inner(mu_mesh*2*sym(grad(self.u)), grad(u_))*dx(0) \
                + lambda_mesh*inner(div(self.u), div(u_))*dx(0)


        # define referential Grad and Div shortcuts
        def Grad(f, F): return dot( grad(f), inv(F) )
        def Div(f, F): return tr( Grad(f, F) )

        # approximate time derivatives
        du = (1.0/self.dt)*(self.u - self.u0)
        dv = (1.0/self.dt)*(self.v - self.v0)

        # compute velocuty part of Cauchy stress tensor for fluid
        self.T_f  = -self.p*I + 2*self.mu_f*sym(Grad(self.v,  self.FF))
        self.T_f0 = -self.p*I + 2*self.mu_f*sym(Grad(self.v0, self.FF0))
        # compute 1st Piola-Kirchhoff tensor for fluid
        self.S_f  = self.JJ *( -self.p*I + self.T_f )*inv(self.FF).T
        self.S_f0 = -self.JJ*self.p*I*inv(self.FF).T \
                     + self.JJ0*self.T_f0*inv(self.FF0).T

        # write equations for fluid
        a_fluid  = inner(self.S_f , Grad(v_, self.FF))*self.JJ*dx \
               + inner(self.rho_f*Grad(self.v, self.FF )*(self.v  - du), v_)*self.JJ*dx
        a_fluid0 = inner(self.S_f0, Grad(v_, self.FF0))*self.JJ0*dx \
               + inner(self.rho_f*Grad(self.v0, self.FF0)*(self.v0 - du), v_)*self.JJ0*dx

        b_fluid  = inner(Div( self.v, self.FF ), p_)*self.JJ*dx
        b_fluid0 = inner(Div( self.v, self.FF ), p_)*self.JJ*dx

        # final variationl formulation
        self.F_fluid  = (self.theta*self.JJ+(1.0 - self.theta)*self.JJ0)*self.rho_f*inner(dv, v_)*dx\
                   + self.theta*(a_fluid + b_fluid) + (1.0 - self.theta)*(a_fluid0 + b_fluid0) \
                   + F_mesh

        # differentiate w.r.t. unknown
        dF_fluid = derivative(self.F_fluid, self.w)

        # define problem and its solver
        self.problem = NonlinearVariationalProblem(self.F_fluid, self.w, bcs=self.bcs, J=dF_fluid)
        self.solver  = NonlinearVariationalSolver(self.problem)

        # Variational problem for extracting forces
        (v, u, p) = TrialFunctions(self.W)
        self.traction = self.F_fluid - inner(v, v_)*ds(_FSI)
        self.hBC = DirichletBC(self.W.sub(0), Constant((0.0, 0.0)), self.complementary_boundary)


        # configure solver parameters
        self.solver.parameters['newton_solver']['relative_tolerance'] = 1e-6
        self.solver.parameters['newton_solver']['absolute_tolerance'] = 1e-10
        self.solver.parameters['newton_solver']['maximum_iterations'] = 50
        self.solver.parameters['newton_solver']['linear_solver']      = 'mumps'

        # create files for saving
        if my_rank == 0:
            if not os.path.exists(result):
                os.makedirs(result)
        self.vfile = XDMFFile("%s/velocity.xdmf" % result)
        self.ufile = XDMFFile("%s/displacement.xdmf" % result)
        self.pfile = XDMFFile("%s/pressure.xdmf" % result)
        self.sfile = XDMFFile("%s/stress.xdmf" % result)
        self.vfile.parameters["flush_output"] = True
        self.ufile.parameters["flush_output"] = True
        self.pfile.parameters["flush_output"] = True
        self.sfile.parameters["flush_output"] = True
        with open(result+'/data.csv', 'w') as data_file:
            writer = csv.writer(data_file, delimiter=';', lineterminator='\n')
            writer.writerow(['time',
                              'x-coordinate of end of beam', 'y-coordinate of end of beam',
                              'drag', 'lift'])

        #info("Fluid __init__ done")

    def solve(self, t, n):
        self.t = t
        self.v_in.t = t
        self.dt.assign(np.min([self.fenics_dt, self.precice_dt]))
        # solve fluid equations
        self.solver.solve()

        # force-extracting procedure
        ABdry = assemble(lhs(self.traction),keep_diagonal=True)
        bBdry = assemble(rhs(self.traction))
        self.hBC.apply(ABdry, bBdry)
        solve(ABdry, self.fun4forces.vector(), bBdry)
        self.fun4forces.set_allow_extrapolation(True)
        (self.forces, _, _) = split(self.fun4forces)
        self.forces = project(self.forces, self.U)

        forces_for_solid = interpolate(self.forces, self.W_boundary) 

        # precice coupling step
        t, n, precice_timestep_complete, self.precice_dt \
                = self.precice.advance(forces_for_solid, self.w, self.w0, t, self.dt.values()[0], n)

        return t, n, precice_timestep_complete

    def save(self, t):
        (v, u, p) = self.w.split()

        # save functions to files
        v.rename("v", "velocity")
        u.rename("u", "displacement")
        p.rename("p", "pressure")
        self.vfile.write(v, t)
        self.ufile.write(u, t)
        self.pfile.write(p, t)

        # Compute drag and lift
        w_ = Function(self.W)
        Fbc1 = DirichletBC(self.W.sub(0), Constant((1.0, 0.0)), self.bndry, _FLUID_CYLINDER)
        Fbc2 = DirichletBC(self.W.sub(0), Constant((1.0, 0.0)), self.bndry, _FSI)
        Fbc1.apply(w_.vector())
        Fbc2.apply(w_.vector())
        drag = -assemble(action(self.F_fluid,w_))
        w_ = Function(self.W)
        Fbc1 = DirichletBC(self.W.sub(0), Constant((0.0, 1.0)), self.bndry, _FLUID_CYLINDER)
        Fbc2 = DirichletBC(self.W.sub(0), Constant((0.0, 1.0)), self.bndry, _FSI)
        Fbc1.apply(w_.vector())
        Fbc2.apply(w_.vector())
        lift = -assemble(action(self.F_fluid,w_))

        # MPI trick to extract beam displacement
        self.w.set_allow_extrapolation(True)
        Ax_loc = self.u[0]((A.x(), A.y()))
        Ay_loc = self.u[1]((A.x(), A.y()))
        self.w.set_allow_extrapolation(False)
        
        pi = 0
        if self.bb.compute_first_collision(A) < 4294967295:
            pi = 1
        else:
            Ax_loc = 0.0
            Ay_loc = 0.0
        Ax = MPI.sum(comm, Ax_loc) / MPI.sum(comm, pi)
        Ay = MPI.sum(comm, Ay_loc) / MPI.sum(comm, pi)

        pi = 0
        if self.bb.compute_first_collision(B) < 4294967295:
            pi = 1
        else:
            pB_loc = 0.0
        pB = MPI.sum(comm, pB_loc) / MPI.sum(comm, pi)
        p_diff = pB - pA

        # write data to data file
        if my_rank == 0:
            with open(result+'/data.csv', 'a') as data_file:
                writer = csv.writer(data_file, delimiter=';', lineterminator='\n')
                writer.writerow([t, Ax, Ay, drag, lift])
Пример #2
0
V_g = VectorFunctionSpace(mesh, 'P', 1)
flux = Function(V_g)
flux.rename("Flux", "")

while precice.is_coupling_ongoing():

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

    if problem is ProblemType.DIRICHLET:
        # Dirichlet problem obtains flux from solution and sends flux on boundary to Neumann problem
        determine_gradient(V_g, u_np1, flux)
        flux_x, flux_y = flux.split()
        if domain_part is DomainPart.RIGHT:
            flux_x = -1 * flux_x
        t, n, precice_timestep_complete, precice_dt = precice.advance(
            flux_x, u_np1, u_n, t, dt(0), n)
    elif problem is ProblemType.NEUMANN:
        # Neumann problem obtains sends temperature on boundary to Dirichlet problem
        t, n, precice_timestep_complete, precice_dt = precice.advance(
            u_np1, u_np1, u_n, t, dt(0), n)

    dt.assign(
        np.min([fenics_dt, precice_dt])
    )  # todo we could also consider deciding on time stepping size inside the adapter

    if precice_timestep_complete:
        u_ref = interpolate(u_D, V)
        u_ref.rename("reference", " ")
        error, error_pointwise = compute_errors(u_n,
                                                u_ref,
                                                V,
Пример #3
0
class Solid(object):
    """
    Solid is defined as a object for which the subroutines solve() and save() are called externally in the time loop.
    """
    def __init__(self, mesh, coupling_boundary, complementary_boundary, bndry,
                 dt, theta, lambda_s, mu_s, rho_s, result, *args, **kwargs):

        self.mesh = mesh
        self.coupling_boundary = coupling_boundary
        self.complementary_boundary = complementary_boundary

        self.fenics_dt = dt
        self.dt = Constant(dt)
        self.theta = theta

        self.lambda_s = lambda_s
        self.mu_s = mu_s
        self.rho_s = rho_s

        self.bndry = bndry

        # bounding box tree - in parallel computations takes care about proper parallelization
        self.bb = BoundingBoxTree()
        self.bb.build(self.mesh)

        # Define finite elements
        eV = VectorElement("CG", mesh.ufl_cell(), 2)  # velocity space
        eU = VectorElement("CG", mesh.ufl_cell(), 2)  # displacement space

        eW = MixedElement([eV, eU])  # function space
        W = FunctionSpace(self.mesh, eW)
        self.W = W
        self.U = FunctionSpace(self.mesh,
                               eU)  # function space for exchanging BCs

        # define Dirichlet boundary conditions
        bc_u = DirichletBC(self.W.sub(1), Constant((0.0, 0.0)),
                           self.complementary_boundary)
        bc_v = DirichletBC(self.W.sub(0), Constant((0.0, 0.0)),
                           self.complementary_boundary)
        self.bcs = [bc_v, bc_u]

        # define normal
        self.n = FacetNormal(self.mesh)
        # define Identity
        I = Identity(self.W.mesh().geometry().dim())

        # Define functions
        self.w = Function(self.W)  # solution in current time step
        self.w0 = Function(self.W)  # solution from previous time step

        (v_, u_) = TestFunctions(self.W)  # test functions
        # split mixed functions into velocity (v) and displacement part (u)
        (self.v, self.u) = split(self.w)
        (self.v0, self.u0) = split(self.w0)

        # define coupling BCs
        self.u_D = Constant((0.0, 0.0))  # Dirichlet BC (for Fluid)
        self.u_D_function = interpolate(self.u_D,
                                        self.U)  # Dirichlet BC as function
        self.f_N = Constant((0.0, 0.0))  # Neumann BC (for Solid)
        self.f_N_function = interpolate(self.f_N,
                                        self.U)  # Neumann BC as function

        # initial value of Dirichlet BC
        self.u_n = interpolate(self.u_D, self.U)

        # create self.displacement function for exchanging BCs
        self.displacement = Function(self.U)
        self.displacement.assign(project(self.u, self.U))
        self.displacement.rename("Displacement", "")

        # start preCICE adapter
        info('Initialize Adapter.')
        self.precice = Adapter()
        # read forces(Neumann condition for solid) and write displacement(Dirichlet condition for fluid)
        info('Call precice.initialize(...).')
        self.precice_dt = self.precice.initialize(
            coupling_subdomain=self.coupling_boundary,
            mesh=self.mesh,
            read_field=self.f_N_function,
            write_field=self.u_D_function,
            u_n=self.w,  #u_n,
            coupling_marker=self.bndry)

        # choose time step
        self.dt.assign(np.min([self.precice_dt, self.fenics_dt]))

        # define deformation gradient
        self.FF = I + grad(self.u)
        self.FF0 = I + grad(self.u0)

        # approximate time derivatives
        du = (1.0 / self.dt) * (self.u - self.u0)
        dv = (1.0 / self.dt) * (self.v - self.v0)

        # write Green-St. Venant strain tensor
        E_s = 0.5 * (self.FF.T * self.FF - I)
        E_s0 = 0.5 * (self.FF0.T * self.FF0 - I)

        # compute 1st Piola-Kirchhoff tensor for solid (St. Venant - Kirchhoff model)
        S_s = self.FF * (self.lambda_s * tr(E_s) * I + 2.0 * self.mu_s * (E_s))
        S_s0 = self.FF0 * (self.lambda_s * tr(E_s0) * I + 2.0 * self.mu_s *
                           (E_s0))

        #delta_W = 0.01
        alpha = Constant(1.0)  # Constant(1.0/delta_W) # Constant(1000)
        # get surface forces from precice
        self.f_surface = alpha * self.precice.create_coupling_neumann_boundary_condition(
            v_, 1, self.U)
        #self.f_surface = Function(self.U)

        # write equation for solid
        self.F_solid = rho_s*inner(dv, v_)*dx \
                   + self.theta*inner(S_s , grad(v_))*dx \
                   + (1.0 - self.theta)*inner(S_s0, grad(v_))*dx \
                   + inner(du - (self.theta*self.v + (1.0 - self.theta)*self.v0), u_)*dx \
                   - inner(self.f_surface, v_)*dss(1)

        # apply Neumann boundary condition on coupling interface
        #self.F_solid += self.precice.create_coupling_neumann_boundary_condition(v_, 1, self.U)

        # differentiate equation for solid for the Newton scheme
        self.dF_solid = derivative(self.F_solid, self.w)

        # define Nonlinear Variational problem and Newton solver
        self.problem = NonlinearVariationalProblem(self.F_solid,
                                                   self.w,
                                                   bcs=self.bcs,
                                                   J=self.dF_solid)
        self.solver = NonlinearVariationalSolver(self.problem)

        # configure solver parameters
        self.solver.parameters['newton_solver']['relative_tolerance'] = 1e-6
        self.solver.parameters['newton_solver']['absolute_tolerance'] = 1e-10
        self.solver.parameters['newton_solver']['maximum_iterations'] = 50
        self.solver.parameters['newton_solver']['linear_solver'] = 'mumps'

        # create files for saving
        if not os.path.exists(result):
            os.makedirs(result)
        self.vfile = XDMFFile("%s/velocity.xdmf" % result)
        self.ufile = XDMFFile("%s/displacement.xdmf" % result)
        self.sfile = XDMFFile("%s/stress.xdmf" % result)
        #self.ffile = XDMFFile("%s/forces.xdmf" % result)
        self.vfile.parameters["flush_output"] = True
        self.ufile.parameters["flush_output"] = True
        self.sfile.parameters["flush_output"] = True
        #self.ffile.parameters["flush_output"] = True
        with open(result + '/data.csv', 'w') as data_file:
            writer = csv.writer(data_file, delimiter=';', lineterminator='\n')
            writer.writerow(
                ['time', 'Ax_displacement', 'Ay_displacement', 'lift', 'drag'])
        info("Solid __init__ done")

    def solve(self, t, n):
        self.t = t
        self.dt.assign(np.min([self.fenics_dt, self.precice_dt]))

        # solve problem
        self.solver.solve()

        # extract velocity v and displacement u from mixed vector w
        (v, u) = self.w.split()

        # update displacement (Dirichlet BC for fluid)
        self.displacement.assign(project(u, self.U))
        #self.displacement0.assign(self.displacement)
        #self.displacement.assign(project(self.u, self.U))

        # precice coupling step
        t, n, precice_timestep_complete, self.precice_dt \
                = self.precice.advance(self.displacement, self.w, self.w0,#self.displacement, self.displacement0, 
                        t, self.dt.values()[0], n)

        return t, n, precice_timestep_complete

    def save(self, t):
        (v, u) = self.w.split()

        # save velocity and displacement
        v.rename("v", "velocity")
        u.rename("u", "displacement")
        self.vfile.write(v, t)
        self.ufile.write(u, t)
        #self.ffile.write(self.f_surface, t)

        # extract values of displacament in point A = (0.6, 0.2)
        self.w.set_allow_extrapolation(True)
        Ax_loc = self.u[0]((A.x(), A.y()))
        Ay_loc = self.u[1]((A.x(), A.y()))
        self.w.set_allow_extrapolation(False)

        # MPI trick to extract nodal values in case of more processes
        pi = 0
        if self.bb.compute_first_collision(A) < 4294967295:
            pi = 1
        else:
            Ax_loc = 0.0
            Ay_loc = 0.0
        Ax = MPI.sum(comm, Ax_loc) / MPI.sum(comm, pi)
        Ay = MPI.sum(comm, Ay_loc) / MPI.sum(comm, pi)

        # evaluate forces exerted by the fluid (lift and drag)
        drag = -assemble(self.f_surface[0] * dss(1))
        lift = -assemble(self.f_surface[1] * dss(1))

        # write displacement and forces to file
        with open(result + '/data.csv', 'a') as data_file:
            writer = csv.writer(data_file, delimiter=';', lineterminator='\n')
            writer.writerow([t, Ax, Ay, lift, drag])

        info(' Ax: {}\n Ay: {} \n lift: {} \n drag: {}'.format(
            Ax, Ay, lift, drag))
elif Case is StructureCase.RFERENCE:
    displacement_out = File("Reference/u_ref.pvd")

displacement_out << u_n

#time loop for coupling

if Case is not StructureCase.RFERENCE:

    while precice.is_coupling_ongoing():

        #solve for new displacements

        solve(a_form == L_form, u_np1, bc)
        # call precice.advance
        t, n, precice_timestep_complete, precice_dt = precice.advance(
            u_np1, u_np1, u_n, t, float(dt), n)

        if precice_timestep_complete:

            update_fields(u_np1, saved_u_old, v_n, a_n)

            if n % 10 == 0:
                displacement_out << (u_n, t)

            u_tip.append(u_n(0., 1.)[0])
            time.append(t)

    # stop coupling
    precice.finalize()

#time loop for reference calculation
Пример #5
0
    read_data = precice.read_data()

    # Update the coupling expression with the new read data
    precice.update_coupling_expression(coupling_expression, read_data)

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

    # Compute solution
    solve(a == L, u_np1, bcs)

    # Dirichlet problem obtains flux from solution and sends flux on boundary to Neumann problem
    fluxes = fluxes_from_temperature_full_domain(F_known_u, V, k)
    precice.write_data(fluxes)

    precice_dt = precice.advance(dt(0))

    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:  # update solution
        u_n.assign(u_np1)
        t += dt
        n += 1

    if precice.is_time_window_complete():
        # if abs(t % dt_out) < 10e-5:  # output if t is a multiple of dt_out
            file_out << u_n
Пример #6
0
u_np1 = Function(V)
F_known_u = u_np1 * v / dt * dx + alpha * dot(grad(u_np1), grad(v)) * dx - u_n * v / dt * dx
t = 0
u_D.t = t + dt

file_out = File("Solid/VTK/%s.pvd" % precice._solver_name)
n=0

while precice.is_coupling_ongoing():

    # Compute solution
    solve(a == L, u_np1, bcs)

    # Dirichlet problem obtains flux from solution and sends flux on boundary to Neumann problem
    fluxes = fluxes_from_temperature_full_domain(F_known_u, V, k)
    t, n, precice_timestep_is_complete, precice_dt = precice.advance(fluxes, u_np1, u_n, t, dt, n)

    dt = np.min([fenics_dt, precice_dt])  # todo we could also consider deciding on time stepping size inside the adapter

    if precice_timestep_is_complete:
        if abs(t % dt_out) < 10e-5 or abs(t % dt_out) < 10e-5:  # just a very complicated way to only produce output if t is a multiple of dt_out
            file_out << u_n

    # Update dirichlet BC
    u_D.t = t + dt

file_out << u_n

# Hold plot
precice.finalize()
Пример #7
0
                                              grad(v)) * dx - u_n * v / dt * dx
u_np1.rename("T", "")
t = 0
u_D.t = t + precice._precice_tau
assert (dt == precice._precice_tau)

file_out = File("Solid/VTK/%s.pvd" % solver_name)

while precice.is_coupling_ongoing():

    # Compute solution
    solve(a == L, u_np1, bcs)

    # Dirichlet problem obtains flux from solution and sends flux on boundary to Neumann problem
    fluxes = fluxes_from_temperature_full_domain(F_known_u, V, k)
    is_converged = precice.advance(fluxes, dt)

    if is_converged:
        # Update previous solution
        if abs(t % dt_out) < 10e-5 or abs(
                t % dt_out
        ) < 10e-5:  # just a very complicated way to only produce output if t is a multiple of dt_out
            file_out << u_np1
        # Update current time
        t += precice._precice_tau
        # Update dirichlet BC
        u_D.t = t + precice._precice_tau
        u_n.assign(u_np1)

file_out << u_np1