def __init__(self, mesh, Vh_STATE, x0):
        """
        Constructor.
        INPUTS:
        
        - mesh: the mesh
        - Vh_STATE: the finite element space for the state variable
        - x0: location at which we want to compute the jet-thickness
        """

        Vh_help = dl.FunctionSpace(mesh, "CG", 1)
        xfun = dl.interpolate(dl.Expression("x[0]", degree=1), Vh_help)
        x_coord = xfun.vector().gather_on_zero()

        mpi_comm = mesh.mpi_comm()
        rank = dl.MPI.rank(mpi_comm)
        nproc = dl.MPI.size(mpi_comm)

        # round x0 so that it is aligned with the mesh
        if nproc > 1:
            from mpi4py import MPI
            comm = MPI.COMM_WORLD
            if rank == 0:
                idx = (np.abs(x_coord - x0)).argmin()
                self.x0 = x_coord[idx]
            else:
                self.x0 = None

            self.x0 = comm.bcast(self.x0, root=0)
        else:
            idx = (np.abs(x_coord - x0)).argmin()
            self.x0 = x_coord[idx]

        line_segment = dl.AutoSubDomain(lambda x: dl.near(x[0], self.x0))
        markers_f = dl.FacetFunction("size_t", mesh)
        markers_f.set_all(0)
        line_segment.mark(markers_f, 1)
        dS = dl.dS[markers_f]

        x_test = dl.TestFunctions(Vh_STATE)
        u_test = x_test[0]

        e1 = dl.Constant(("1.", "0."))

        self.int_u = dl.assemble(dl.avg(dl.dot(u_test, e1)) * dS(1))
        #self.u_cl = dl.assemble( dl.dot(u_test,e1)*dP(1) )

        self.u_cl = dl.Function(Vh_STATE).vector()
        ps = dl.PointSource(Vh_STATE.sub(0).sub(0), dl.Point(self.x0, 0.), 1.)
        ps.apply(self.u_cl)

        scaling = self.u_cl.sum()
        if np.abs(scaling - 1.) > 1e-6:
            print scaling
            raise ValueError()

        self.state = dl.Function(Vh_STATE).vector()
        self.help = dl.Function(Vh_STATE).vector()
Пример #2
0
    def mark_facets(self, facet_func, id):
        """
        Marks the surface facets of the object

        This function is needed for calculating the capacitance matrix
        """
        object_boundary = df.AutoSubDomain(lambda x: self.inside(x, True))
        object_boundary.mark(facet_func, id)
        return facet_func
Пример #3
0
def generate_polygonal_mesh(resolution,
                            ampothem,
                            nedges,
                            radius,
                            plot_mesh=False):
    """
    Sometimes segault is thrown when mshr.generate_mesh() is 
    called. This is because resolution is to low to resolve
    smaller inner-most circle.
    """
    import mshr
    vertices = get_vertices_of_polygon(ampothem, nedges)

    domain_vertices = []
    for vertex in vertices.T:
        domain_vertices.append(dl.Point(vertex[0], vertex[1]))

    domain = mshr.Polygon(domain_vertices)

    cx1, cy1 = 0.0, 0.0
    circle1 = mshr.Circle(dl.Point(cx1, cy1), radius)
    domain.set_subdomain(1, circle1)
    cx2, cy2 = cx1 - radius / np.sqrt(8), cy1 - radius / np.sqrt(8)
    circle2 = mshr.Circle(dl.Point(cx2, cy2), radius / 2)
    domain.set_subdomain(2, circle2)
    mesh = mshr.generate_mesh(domain, resolution)

    if plot_mesh:
        subdomains = dl.MeshFunction('size_t', mesh, mesh.topology().dim(), 2)
        subdomains.set_all(0)
        subdomain1 = dl.AutoSubDomain(lambda x: np.sqrt(
            (x[0] - cx1)**2 + (x[1] - cy1)**2) < radius + 1e-8)
        subdomain1.mark(subdomains, 1)
        subdomain2 = dl.AutoSubDomain(lambda x: np.sqrt(
            (x[0] - cx2)**2 + (x[1] - cy2)**2) < radius / 2 + 1e-8)
        subdomain2.mark(subdomains, 2)
        dl.plot(mesh)
        dl.plot(subdomains)
        plt.show()

    return mesh
def solve_tr_dir__const_rheo(mesh_name, hol_cyl, deg_choice, T_in_expr,
                             T_inf_expr, HTC, T_old_v, k_mesh, cp_mesh,
                             rho_mesh, k_mesh_old, cp_mesh_old, rho_mesh_old,
                             dt, time_v, theta, bool_plot, bool_solv,
                             savings_do, logger_f):
    '''
    mesh_name: a proper XML file.
    bool_plot: plots if bool_plot = 1.
    
    Solves a direct, steady-state heat conduction problem, and
    returns A_np, b_np, D_np, T_np, bool_ex, bool_in.
    
    A_np: stiffness matrix, ordered by vertices.
    
    b_np: integrated volumetric heat sources and surface heat fluxes, ordered by vertices.
    The surface heat fluxes come from the solution to the direct problem;
    hence, these terms will not be there in a real IHCP. 
    
    D_np: integrated Laplacian of T, ordered by vertices.
    Option 2.
    The Laplacian of q is properly assembled from D_np.
    If do.dx(domain = hol_cyl) -> do.Measure('ds')[boundary_faces] and
    do.Measure('ds')[boundary_faces] -> something representative of Gamma,
    I would get option 1.
    
    T_np: solution to the direct heat conduction problem, ordered by vertices.
    
    bool_ex: boolean array declaring which vertices lie on the outer boundary.
    
    bool_in: boolean array indicating which vertices lie on the inner boundary.
    
    T_sol: solution to the direct heat conduction problem.
    
    deg_choice: degree in FunctionSpace.
    
    hol_cyl: mesh.
    '''

    #comm1 = MPI.COMM_WORLD

    #current proc
    #rank1 = comm1.Get_rank()

    V = do.FunctionSpace(hol_cyl, 'CG', deg_choice)

    if 'hollow' in mesh_name and 'cyl' in mesh_name:
        from hollow_cyl_inv_mesh import geo_fun as geo_fun_hollow_cyl
        geo_params_d = geo_fun_hollow_cyl()[1]
        #x_c is a scalar here
        #y_c is a scalar here

    elif 'four' in mesh_name and 'cyl' in mesh_name:
        from four_hole_cyl_inv_mesh import geo_fun as geo_fun_four_hole_cyl
        geo_params_d = geo_fun_four_hole_cyl()[1]
        #x_c is an array here
        #y_c is an array here
        x_c_l = [geo_params_d['x_0_{}'.format(itera)] for itera in xrange(4)]
        y_c_l = [geo_params_d['y_0_{}'.format(itera)] for itera in xrange(4)]

    elif 'one_hole_cir' in mesh_name:
        from one_hole_cir_adj_mesh import geo_fun as geo_fun_one_hole_cir
        geo_params_d = geo_fun_one_hole_cir()[1]
        #x_c is an array here
        #y_c is an array here
        x_c_l = [geo_params_d['x_0']]
        y_c_l = [geo_params_d['y_0']]

    elif 'reinh_cir' in mesh_name:
        from reinh_cir_adj_mesh import geo_fun as geo_fun_one_hole_cir
        geo_params_d = geo_fun_one_hole_cir()[1]
        #x_c is an array here
        #y_c is an array here
        x_c_l = [geo_params_d['x_0']]
        y_c_l = [geo_params_d['y_0']]

    elif 'small_circle' in mesh_name:
        from four_hole_small_cir_adj_mesh import geo_fun as geo_fun_four_hole_cir
        geo_params_d = geo_fun_four_hole_cir()[1]
        #x_c is an array here
        #y_c is an array here
        x_c_l = [geo_params_d['x_0_{}'.format(itera)] for itera in xrange(4)]
        y_c_l = [geo_params_d['y_0_{}'.format(itera)] for itera in xrange(4)]

    #center of the cylinder base
    x_c = geo_params_d['x_0']
    y_c = geo_params_d['y_0']

    R_in = geo_params_d['R_in']
    R_ex = geo_params_d['R_ex']

    #define variational problem
    T = do.TrialFunction(V)
    g = do.Function(V)
    v = do.TestFunction(V)

    T_old = do.Function(V)
    T_inf = do.Function(V)

    #scalar
    T_old.vector()[:] = T_old_v
    T_inf.vector()[:] = T_inf_expr

    #solution
    T_sol = do.Function(V)

    #scalar
    T_sol.vector()[:] = T_old_v

    # Create boundary markers
    mark_all = 3
    mark_in = 4
    mark_ex = 5

    #x_c is an array here
    #y_c is an array here
    g_in = g_in_mesh(mesh_name, x_c_l, y_c_l, R_in)

    g_ex = g_ex_mesh(mesh_name, x_c, y_c, R_ex)

    in_boundary = do.AutoSubDomain(g_in)
    ex_boundary = do.AutoSubDomain(g_ex)

    #normal
    unitNormal = do.FacetNormal(hol_cyl)
    boundary_faces = do.MeshFunction('size_t', hol_cyl,
                                     hol_cyl.topology().dim() - 1)

    boundary_faces.set_all(mark_all)
    in_boundary.mark(boundary_faces, mark_in)
    ex_boundary.mark(boundary_faces, mark_ex)

    bc_in = do.DirichletBC(V, T_in_expr, boundary_faces, mark_in)
    #bc_ex = do.DirichletBC(V, T_ex_expr, boundary_faces, mark_ex)
    bcs = [bc_in]

    #k = do.Function(V)  #W/m/K
    #k.vector()[:] = k_mesh

    #A0 = k * do.dot(do.grad(T), do.grad(v)) * do.dx(domain = hol_cyl)
    A = dt / 2. * k_mesh * do.dot(do.grad(T), do.grad(v)) * do.dx(domain = hol_cyl) + \
        rho_mesh * cp_mesh * T * v * do.dx(domain = hol_cyl)

    A_full = A + dt / 2. * HTC * T * v * do.ds(
        mark_ex, domain=hol_cyl, subdomain_data=boundary_faces)

    L = -dt / 2. * k_mesh_old * do.dot(do.grad(T_old), do.grad(v)) * \
        do.dx(domain = hol_cyl) + \
        rho_mesh_old * cp_mesh_old * T_old * v * do.dx(domain = hol_cyl) - \
        dt / 2. * HTC * (T_old) * v * do.ds(mark_ex,
                                                    domain = hol_cyl,
                                                    subdomain_data = boundary_faces)  + \
        dt * HTC * T_inf * v * do.ds(mark_ex,
                                                    domain = hol_cyl,
                                                    subdomain_data = boundary_faces)

    #numpy version of A, T, and (L + int_fluxT)
    #A_np__not_v2d = do.assemble(A).array() #before applying BCs - needs v2d
    #L_np__not_v2d = do.assemble(L).array() #before applying BCs - needs v2d

    #Laplacian of T, without any -1/k int_S q*n*v dS
    '''
    Approximated integral of the Laplacian of T.
    Option 2.
    The Laplacian of q is properly assembled from D_np.
    If do.dx(domain = hol_cyl) -> do.Measure('ds')[boundary_faces] and
    do.Measure('ds')[boundary_faces] -> something representative of Gamma,
    I would get option 1.
    '''
    #D_np__not_v2d = do.assemble(-do.dot(do.grad(T), do.grad(v)) * do.dx(domain = hol_cyl) +
    #                             do.dot(unitNormal, do.grad(T)) * v *
    #                             do.Measure('ds')[boundary_faces]).array()
    #print np.max(D_np__not_v2d)#, np.max(A_np__not_v2d)
    #logger_f.warning('shape of D_np = {}, {}'.format(D_np__not_v2d.shape[0],
    #D_np__not_v2d.shape[1]))

    #nonzero_entries = []
    #for row in D_np__not_v2d:
    #    nonzero_entries += [len(np.where(abs(row) > 1e-16)[0])]

    #logger_f.warning('max, min, and mean of nonzero_entries = {}, {}, {}'.format(
    #      max(nonzero_entries), min(nonzero_entries), np.mean(nonzero_entries)))

    #solver parameters
    #linear solvers from
    #list_linear_solver_methods()
    #preconditioners from
    #do.list_krylov_solver_preconditioners()
    solver = do.KrylovSolver('gmres', 'ilu')
    do.info(solver.parameters, True)  #prints default values
    solver.parameters['relative_tolerance'] = 1e-16
    solver.parameters['maximum_iterations'] = 20000000
    solver.parameters['monitor_convergence'] = True  #on the screen
    #http://fenicsproject.org/qa/1124/is-there-a-way-to-set-the-inital-guess-in-the-krylov-solver
    '''solver.parameters['nonzero_initial_guess'] = True'''
    solver.parameters['absolute_tolerance'] = 1e-15
    #uses whatever in q_v as my initial condition

    #the next lines are used for CHECK 3 only
    #A_sys, b_sys = do.assemble_system(A, L, bcs)

    do.File(
        os.path.join(savings_do, '{}__markers.pvd'.format(
            mesh_name.split('.')[0]))) << boundary_faces

    if bool_plot:
        do.plot(boundary_faces, '3D mesh', title='boundary markers')

    #storage
    T_sol_d = {}
    g_d = {}

    if bool_solv == 1:

        xdmf_DHCP_T = do.File(os.path.join(savings_do, 'DHCP', 'T.pvd'))
        xdmf_DHCP_q = do.File(os.path.join(savings_do, 'DHCP', 'q.pvd'))

        for count_t_i, t_i in enumerate(time_v[1:]):

            #T_in_expr.ts = t_i
            #T_ex_expr.ts = t_i

            #storage
            T_sol_d[count_t_i] = do.Function(V)
            T_sol_d[count_t_i].vector()[:] = T_sol.vector().array()

            do.solve(A_full == L, T_sol, bcs)
            '''
            TO BE UPDATED:
            rheology is not updated
            '''

            #updates L
            T_old.assign(T_sol)

            T_sol.rename('DHCP_T', 'temperature from DHCP')

            #write solution to file
            #paraview format
            xdmf_DHCP_T << (T_sol, t_i)

            #plot solution
            if bool_plot:
                do.plot(T_sol, title='T')  #, interactive = True)

            logger_f.warning('len(T) = {}'.format(len(T_sol.vector().array())))

            print 'T: count_t = {}, min(T_DHCP) = {}'.format(
                count_t_i, min(T_sol_d[count_t_i].vector().array()))
            print 'T: count_t = {}, max(T_DHCP) = {}'.format(
                count_t_i, max(T_sol_d[count_t_i].vector().array())), '\n'

            #save flux - required for solving IHCP
            #same result if do.ds(mark_ex, subdomain_data = boundary_faces)
            #instead of do.Measure('ds')[boundary_faces]
            #Langtangen, p. 37:
            #either do.dot(do.nabla_grad(T), unitNormal)
            #or do.dot(unitNormal, do.grad(T))

            #int_fluxT = do.assemble(-k * do.dot(unitNormal, do.grad(T_sol)) * v *
            #                          do.Measure('ds')[boundary_faces])

            fluxT = do.project(
                -k_mesh * do.grad(T_sol),
                do.VectorFunctionSpace(hol_cyl, 'CG', deg_choice, dim=2))

            if bool_plot:
                do.plot(fluxT,
                        title='flux at iteration = {}'.format(count_t_i))

            fluxT.rename('DHCP_flux', 'flux from DHCP')

            xdmf_DHCP_q << (fluxT, t_i)

            print 'DHCP: iteration = {}'.format(count_t_i)

            ####################################################
            #full solution
            #T_sol_full = do.Vector()
            #T_sol.vector().gather(T_sol_full, np.array(range(V.dim()), 'intc'))
            ####################################################

        count_t_i += 1

        #copy previous lines
        #storage
        T_sol_d[count_t_i] = do.Function(V)
        T_sol_d[count_t_i].vector()[:] = T_sol.vector().array()

    for count_t_i, t_i in enumerate(time_v):
        #storage
        g_d[count_t_i] = do.Function(V)
        g_d[count_t_i].vector()[:] = g.vector().array()

    gdim = hol_cyl.geometry().dim()
    dofmap = V.dofmap()
    dofs = dofmap.dofs()

    #Get coordinates as len(dofs) x gdim array
    dofs_x = V.tabulate_dof_coordinates().reshape((-1, gdim))

    #booleans corresponding to the outer boundary -> ints since they are sent to root = 0
    bool_ex = 1. * np.array([g_ex(dof_x) for dof_x in dofs_x])
    #booleans corresponding to the inner boundary -> ints since they are sent to root = 0
    bool_in = 1. * np.array([g_in(dof_x) for dof_x in dofs_x])

    T_np_ex = []
    T_np_in = []

    for i_coor, coor in enumerate(dofs_x):
        if g_ex(coor):
            T_np_ex += [T_sol.vector().array()[i_coor]]
        if g_in(coor):
            T_np_in += [T_sol.vector().array()[i_coor]]

    print 'CHECK: mean(T) on the outer boundary = ', np.mean(np.array(T_np_ex))
    print 'CHECK: mean(T) on the inner boundary = ', np.mean(np.array(T_np_in))
    print 'CHECK: mean(HTC) = ', np.mean(do.project(HTC, V).vector().array())

    #v2d = do.vertex_to_dof_map(V) #orders by hol_cyl.coordinates()
    if deg_choice == 1:
        print 'len(dof_to_vertex_map) = ', len(do.dof_to_vertex_map(V))

    print 'min(dofs) = ', min(dofs), ', max(dofs) = ', max(dofs)
    print 'len(bool ex) = ', len(bool_ex)
    print 'len(bool in) = ', len(bool_in)
    print 'bool ex[:10] = ', repr(bool_ex[:10])
    print 'type(T) = ', type(T_sol.vector().array())

    #first global results, then local results
    return A, L, g_d, \
           V, v, k_mesh, \
           mark_in, mark_ex, \
           boundary_faces, bool_ex, \
           R_in, R_ex, T_sol_d, deg_choice, hol_cyl, \
           unitNormal, dofs_x
Пример #5
0
import sys, os
sys.path.insert(0,
                os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

import dolfin
import numpy

import sa_thesis
import sa_thesis.helpers.io as io
import sa_thesis.computation.problems as problems

mesh = dolfin.UnitSquareMesh(4, 4)
domains = dolfin.MeshFunction('size_t', mesh, 2, 0)
half = dolfin.AutoSubDomain(lambda xx, on: xx[0] > 0.5)
half.mark(domains, 1)
facets = dolfin.MeshFunction('size_t', mesh, 1, 0)
left = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[0], 0))
right = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[0], 1))
front = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[1], 0))
back = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[1], 1))
left.mark(facets, 1)
right.mark(facets, 2)
front.mark(facets, 3)
back.mark(facets, 4)

h5file = io.H5File('square', 'w')
h5file.set_mesh(mesh)
h5file.add_attribute(domains, 'sides')

problem = problems.PoissonProblem(mesh, domains=domains, facets=facets)
ff = dolfin.Constant(-1.)
def spreadFunction(u, mesh, x_max=None):
    """
    This routine computes the following quantities as a function of the distance x from the inflow:
    - The centerline velocity: u_cl
    - The integral jet thickness: L
    - The spread function (derivative of jet thickness): S
    - The jet thickness: y_1/2
    
    INPUTS:
    - the velocity u
    - the mesh mesh
    """
    boundary_mesh = dl.BoundaryMesh(mesh, "exterior")
    x = boundary_mesh.coordinates()
    x_coord = x[np.abs(x[:, 1]) < 1e-9, 0]
    if x_max is not None:
        x_coord = x_coord[x_coord <= x_max]
    e1 = dl.Expression(("1.", "0."))
    u1, u2 = u.split(deepcopy=True)

    Vh_grad = dl.FunctionSpace(mesh, 'RT', 1)
    grad_u1 = dl.Function(Vh_grad)
    test = dl.TestFunction(Vh_grad)
    n = dl.FacetNormal(mesh)
    dl.solve(
        dl.inner(grad_u1, test) * dl.dx + u1 * dl.div(test) * dl.dx -
        u1 * dl.dot(test, n) * dl.ds == 0, grad_u1)

    axis = dl.AutoSubDomain(lambda x: dl.near(x[1], 0.))
    axis_mesh = dl.SubMesh(boundary_mesh, axis)
    Vh_axis = dl.FunctionSpace(axis_mesh, "CG", 2)
    u1_axis = dl.interpolate(u1, Vh_axis)
    Vh_axis_grad = dl.FunctionSpace(axis_mesh, 'CG', 1)
    du1_dx = dl.Function(Vh_axis_grad)
    test_axis = dl.TestFunction(Vh_axis_grad)
    left_point = dl.AutoSubDomain(
        lambda x, on_boundary: dl.near(x[0], x_coord[0]) and on_boundary)
    right_point = dl.AutoSubDomain(
        lambda x, on_boundary: dl.near(x[0], x_coord[-1]) and on_boundary)
    bb_marker = dl.FacetFunction("size_t", axis_mesh)
    bb_marker.set_all(0)
    left_point.mark(bb_marker, 1)
    right_point.mark(bb_marker, 2)
    dss = dl.Measure("ds")[bb_marker]

    dl.solve(
        du1_dx * test_axis * dl.dx + u1_axis * test_axis.dx(0) * dl.dx +
        u1_axis * test_axis * dss(1) - u1_axis * test_axis * dss(2) == 0,
        du1_dx)

    u_cl = np.zeros(x_coord.shape)
    L = np.zeros(x_coord.shape)
    S = np.zeros(x_coord.shape)
    y_half = np.zeros(x_coord.shape)

    i = 0
    for xi in x_coord:
        line_segment = dl.AutoSubDomain(lambda x: dl.near(x[0], xi))
        markers = dl.FacetFunction("size_t", mesh)
        markers.set_all(0)
        line_segment.mark(markers, 1)

        if i == 0 or (i == (x_coord.shape[0] - 1) and x_max is None):
            ds = dl.ds[markers]
            int_u1 = dl.assemble(u1 * ds(1))
            int_du1_dx = dl.assemble(dl.dot(grad_u1, e1) * ds(1))
        else:
            dS = dl.dS[markers]
            int_u1 = dl.assemble(dl.avg(u1) * dS(1))
            int_du1_dx = dl.assemble(dl.avg(dl.dot(grad_u1, e1)) * dS(1))

        u_cl[i] = u1((xi, 0.))
        du_cl_dx = du1_dx((xi, 0.))
        L[i] = int_u1 / u_cl[i]
        S[i] = (int_du1_dx * u_cl[i] - int_u1 * du_cl_dx) / (u_cl[i] * u_cl[i])
        y_half[i] = _bisection(u1, 9., 0., .5 * u_cl[i], xi)

        i += 1

    out = np.zeros((x_coord.shape[0], 5), dtype=x_coord.dtype)
    out[:, 0] = x_coord
    out[:, 1] = u_cl
    out[:, 2] = L
    out[:, 3] = S
    out[:, 4] = y_half

    return out
Пример #7
0
cb = plt.colorbar(c, ax=ax2)
ax2.set_xlabel(r"$x$", fontsize=18)
ax2.set_ylabel(r"$y$", fontsize=18)
cb.set_label(r"$u(x, y)$", fontsize=18)
cb.set_ticks([0.0, 5, 10, 15])

fig.savefig("ch11-fdm-2d-ex4.pdf")
fig.savefig("ch11-fdm-2d-ex4.png")
fig.tight_layout()


# ### Post processing

# In[117]:

outer_boundary = dolfin.AutoSubDomain(lambda x, on_bnd: on_bnd and abs(np.sqrt(x[0]**2 + x[1]**2) - r_outer) < 5e-2)


# In[118]:

bc_outer = dolfin.DirichletBC(V, 1, outer_boundary)


# In[119]:

mask_outer = dolfin.Function(V)


# In[120]:

bc_outer.apply(mask_outer.vector())
import sys, os
sys.path.insert(0,
                os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

import dolfin
import numpy

import sa_thesis
import sa_thesis.helpers.io as io
import sa_thesis.computation.problems as problems

mesh = dolfin.UnitCubeMesh(4, 4, 4)
domains = dolfin.MeshFunction('size_t', mesh, 3, 0)
half = dolfin.AutoSubDomain(lambda xx, on: xx[0] > 0.5)
half.mark(domains, 1)
facets = dolfin.MeshFunction('size_t', mesh, 2, 0)
left = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[0], 0))
right = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[0], 1))
front = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[1], 0))
back = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[1], 1))
bottom = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[2], 0))
top = dolfin.AutoSubDomain(lambda xx, on: on and dolfin.near(xx[2], 1))
left.mark(facets, 1)
right.mark(facets, 2)
front.mark(facets, 3)
back.mark(facets, 4)
bottom.mark(facets, 5)
top.mark(facets, 6)

coeff = problems.PoissonProblem.default_coefficient
problem = problems.PoissonProblem(mesh,
Пример #9
0
def create_patches(box=np.array([0, 0, 0, 1, 1, 1]),
                   patch_num=3,
                   patch_nums=None,
                   alpha=1.25,
                   beta=2.0,
                   max_resolution=0.5,
                   num=6,
                   create_inclusions=False,
                   skip_patches=[],
                   prefix='test',
                   logger=None,
                   ldomain=False,
                   corner_refine=3,
                   hole=False,
                   hole_radius=None,
                   layers=1,
                   max_refines=1,
                   elem_per_layer=3):
    if logger is not None:
        info = logger.info
    else:
        info = print

    basedim = 3
    low = box[:basedim].copy()
    high = box[basedim:].copy()
    lengths = high - low
    diameter = np.sqrt(lengths @ lengths)
    myeps = sa_utils.myeps * diameter
    center = (high + low) * .5
    info('low {:s}, high {:s}, lengths {:s}, center {:s}, diameter {:.2e}'.
         format(str(low), str(high), str(lengths), str(center), diameter))

    layer_bricks = []
    layer_hz = lengths[2] / layers
    layer_low = np.array(
        [low[0] - lengths[0], low[1] - lengths[1], low[2] - lengths[2]])
    layer_high = np.array(
        [low[0] + lengths[0], low[1] + lengths[1], low[2] + 2 * lengths[2]])
    for ii in range(layers - 1):
        for jj in range(1, elem_per_layer + 1):
            layer_bricks.append(
                OrthoBrick(
                    Pnt(*layer_low),
                    Pnt(low[0] + lengths[0], low[1] + lengths[1],
                        low[2] + (ii + jj * 1. / elem_per_layer) * layer_hz)))
        info('layer [{:d}/{:d}], {:s}, {:s}'.format(
            ii, layers, str(layer_low),
            str(
                np.array([
                    low[0] + lengths[0], low[1] + lengths[1],
                    low[2] + ii * layer_hz
                ]))))
    for jj in range(1, elem_per_layer):
        layer_bricks.append(
            OrthoBrick(
                Pnt(*layer_low),
                Pnt(
                    low[0] + lengths[0], low[1] + lengths[1], low[2] +
                    (layers - 1 + jj * 1. / elem_per_layer) * layer_hz)))
    layer_bricks.append(OrthoBrick(Pnt(*layer_low), Pnt(*layer_high)))
    sublayers = len(layer_bricks)
    info('layer [{:d}/{:d}], {:s}, {:s}'.format(layers, layers, str(layer_low),
                                                str(layer_high)))

    info('{:d} layers, {:d} sublayers, {:d} bricks'.format(
        layers, sublayers, len(layer_bricks)))

    bc_dict = dict()
    left = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[0], low[0], eps=myeps))
    bc_dict[1] = left
    right = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[0], high[0], eps=myeps))
    bc_dict[2] = right
    front = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[1], low[1], eps=myeps))
    bc_dict[3] = front
    back = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[1], high[1], eps=myeps))
    bc_dict[4] = back
    bottom = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[2], low[2], eps=myeps))
    bc_dict[5] = bottom
    top = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[2], high[2], eps=myeps))
    bc_dict[6] = top
    border = dolfin.AutoSubDomain(lambda xx, on: on)
    if ldomain:
        corner_lr = dolfin.AutoSubDomain(
            lambda xx, on: on and (xx >= center - myeps).all() and dolfin.near(
                xx[0], center[0], eps=myeps))
        bc_dict[7] = corner_lr
        corner_fb = dolfin.AutoSubDomain(
            lambda xx, on: on and (xx >= center - myeps).all() and dolfin.near(
                xx[1], center[1], eps=myeps))
        bc_dict[8] = corner_fb
        corner_bt = dolfin.AutoSubDomain(
            lambda xx, on: on and (xx >= center - myeps).all() and dolfin.near(
                xx[2], center[2], eps=myeps))
        bc_dict[9] = corner_bt
        corner_subdomains = []
        corner_close = 0.1 * diameter + myeps
        for ii in range(corner_refine):
            corner_subdomains.append(
                dolfin.AutoSubDomain(
                    (lambda what: lambda xx, on: np.sqrt(xx @ xx) < what
                     )(corner_close)))
            corner_close *= 0.5
    if create_inclusions and num:
        info('random inclusions')
        if num:
            number = num * num * num
            info('n = ' + str(number))
            inc_radius = 0.5 / num
            info('r = ' + str(inc_radius))
            nodes = []
            radii = []
            rnd_low = low - 0.5 * inc_radius
            rnd_high = high + 0.5 * inc_radius
            width = rnd_high - rnd_low
            while (len(nodes) < number):
                notok = True
                while (notok):
                    new = rnd.rand(3) * width + rnd_low
                    radius = (0.5 + rnd.rand()) * inc_radius
                    notok = False
                    for old, rr in zip(nodes, radii):
                        diff = new - old
                        if np.sqrt(diff.dot(diff)) < 1.3 * (radius + rr):
                            notok = True
                            break
                nodes.append(new.copy())
                radii.append(radius)
            nodes = np.array(nodes)
            radii = np.array(radii)
            info('found locations for ' + str(len(nodes)) + ' inclusions')
            np.savetxt(prefix + '/' + prefix + '_inclusions.csv',
                       np.hstack((nodes, radii.reshape(len(nodes), 1))),
                       fmt='%.15e',
                       delimiter=', ')
            del nodes, radii, number, inc_radius

    nohole_whole = OrthoBrick(Pnt(*low), Pnt(*high))
    if ldomain is True:
        nohole_whole = nohole_whole - OrthoBrick(
            Pnt(*center), Pnt(*(center + 2 * (high - center))))
    if num:
        data = np.loadtxt(prefix + '/' + prefix + '_inclusions.csv',
                          delimiter=', ')
        number = len(data)
    else:
        number = 0
    if number:
        nodes = data[:, :3]
        radii = data[:, 3]

        inclusions = Sphere(Pnt(*nodes[0]), radii[0])
        for kk in range(1, len(nodes)):
            inclusions += Sphere(Pnt(*nodes[kk]), radii[kk])
        nohole_matrix = nohole_whole - inclusions
        nohole_incs = nohole_whole * inclusions
    if hole_radius is not None:
        hole = True
    if hole:
        if hole_radius is None:
            hole_radius = lengths[1] / 9.
        near_hole = dolfin.AutoSubDomain(lambda xx, on: on and np.sqrt(
            (xx[0] - center[0]) * (xx[0] - center[0]) + (xx[1] - center[1]) *
            (xx[1] - center[1])) < hole_radius + 1e4 * myeps)
        bc_dict[10] = near_hole

    if patch_nums is None:
        hh = lengths[0] / float(patch_num)
        patch_nums = np.array(np.ceil(lengths / hh), dtype=int)
    hs = lengths / patch_nums
    hs_alpha = hs * alpha * 0.5
    hs_beta = hs_alpha * beta

    patches = []
    patches_ext = []
    for kk in range(patch_nums[2]):
        pt_z = low[0] + (0.5 + kk) * hs[2]
        for jj in range(patch_nums[1]):
            pt_y = low[1] + (0.5 + jj) * hs[1]
            for ii in range(patch_nums[0]):
                pt_x = low[2] + (0.5 + ii) * hs[0]
                pt_center = np.array([pt_x, pt_y, pt_z])
                pt_low = pt_center - hs_alpha
                if ldomain and (p_low >= center - myeps).all():
                    print('[{:d}, {:d}, {:d}] skipped'.format(ii, jj, kk))
                    continue

                patches.append(
                    OrthoBrick(Pnt(*(pt_center - hs_alpha)),
                               Pnt(*(pt_center + hs_alpha))))
                patches_ext.append(
                    OrthoBrick(Pnt(*(pt_center -
                                     hs_beta)), Pnt(*(pt_center + hs_beta))) -
                    patches[-1])
    patch_num = len(patches)
    print('[{:d}] patches total'.format(patch_num))
    patch_fill = int(np.log(patch_num) / np.log(10.)) + 1

    pt_low = dict()
    pt_high = dict()
    pt_inside = dict()

    info('Patch size computations')
    sa_utils.makedirs_norace(prefix + '/' + prefix + '_patch_descriptors')
    ff = open(prefix + '/' + prefix + '_patch_descriptors/0.csv', 'w')
    ff.write('idx, left, right, front, back, bottom, top\n')
    for kk in range(patch_num):
        info(str(kk + 1) + '/' + str(patch_num))
        geo = CSGeometry()
        geo.Add(nohole_whole * patches[kk])
        mesh = geo.GenerateMesh(maxh=max_resolution)
        del geo
        mesh.Export('tmp.msh', 'Gmsh2 Format')
        del mesh
        meshconvert.convert2xml('tmp.msh', 'tmp.xml')
        os.remove('tmp.msh')
        os.remove('tmp_facet_region.xml')
        os.remove('tmp_physical_region.xml')

        mesh = dolfin.Mesh('tmp.xml')
        os.remove('tmp.xml')
        nodes = mesh.coordinates()
        del mesh
        pt_low[kk] = np.min(nodes, axis=0)
        pt_high[kk] = np.max(nodes, axis=0)
        ff.write('%d, %.15e, %.15e, %.15e, %.15e, %.15e, %.15e\n' %
                 (kk, pt_low[kk][0], pt_high[kk][0], pt_low[kk][1],
                  pt_high[kk][1], pt_low[kk][2], pt_high[kk][2]))
        del nodes
        pt_inside[kk] = dolfin.AutoSubDomain(lambda xx, on: (pt_low[
            kk] - myeps <= xx).all() and (xx <= pt_high[kk] + myeps).all())
    ff.close()
    info('Patch size computations finished')

    hole_ratio = hole_radius / lengths[1]
    for ref in range(max_refines):
        info('Start meshing resolution {:d}/{:d}'.format(ref + 1, max_refines))
        res = max_resolution * 0.5**ref

        if hole:
            hole_maxh = res * hole_ratio
            #           hole_maxh = np.min([res*hole_ratio, lengths[2]/layers])
            if number:
                matrix = nohole_matrix - Cylinder(
                    Pnt(center[0], center[1], center[2] - diameter),
                    Pnt(center[0], center[1], center[2] + diameter),
                    hole_radius).maxh(hole_maxh)
                incs = nohole_matrix - Cylinder(
                    Pnt(center[0], center[1], center[2] - diameter),
                    Pnt(center[0], center[1], center[2] + diameter),
                    hole_radius).maxh(hole_maxh)
            else:
                whole = nohole_whole - Cylinder(
                    Pnt(center[0], center[1], center[2] - diameter),
                    Pnt(center[0], center[1], center[2] + diameter),
                    hole_radius).maxh(hole_maxh)

        dirname = '{:s}/{:s}_{:d}_patches/0/'.format(prefix, prefix, ref)
        sa_utils.makedirs_norace(dirname)

        basename = '{:s}/{:s}_{:d}'.format(prefix, prefix, ref)
        info('Global CSG')
        geo = CSGeometry()

        if number:
            geo.Add(matrix * layer_bricks[0])
            for ii in range(1, sublayers):
                geo.Add(matrix * (layer_bricks[ii] - layer_bricks[ii - 1]))
            geo.Add(incs * layer_bricks[0])
            for ii in range(1, sublayers):
                geo.Add(incs * (layer_bricks[ii] - layer_bricks[ii - 1]))
        else:
            geo.Add(whole * layer_bricks[0])
            for ii in range(1, sublayers):
                geo.Add(whole * (layer_bricks[ii] - layer_bricks[ii - 1]))
        info('Global CSG constructed')
        mesh = geo.GenerateMesh(maxh=res)
        info('Global surface meshed')
        del geo

        gc.collect()

        mesh.GenerateVolumeMesh()
        mesh.Export(basename + '.msh', 'Gmsh2 Format')
        meshconvert.convert2xml(basename + '.msh', basename + '.xml')
        del mesh
        os.remove(basename + '.msh')
        os.remove(basename + '_facet_region.xml')
        info('Global volume meshed')

        gc.collect()

        global_mesh = dolfin.Mesh(basename + '.xml')
        tmp_nodes = global_mesh.coordinates()
        tmp_low = np.min(tmp_nodes, axis=0)
        tmp_high = np.max(tmp_nodes, axis=0)
        info('global mesh: {:s}, {:s}, {:s}'.format(
            str(tmp_low), str(tmp_high), str(top.inside(tmp_high, True))))

        os.remove(basename + '.xml')
        info('Correcting cell markers')
        global_domains_tmp = dolfin.MeshFunction(
            'size_t', global_mesh, basename + '_physical_region.xml')
        os.remove(basename + '_physical_region.xml')
        global_domains_tmp.array()[:] -= np.min(global_domains_tmp.array())
        global_domains_tmp.array()[:] //= elem_per_layer
        global_domains = dolfin.MeshFunction('size_t', global_mesh, basedim, 0)
        if number:
            where = np.where(global_domains_tmp.array() < layers)
            global_domains.array(
            )[where] = 4 * global_domains_tmp.array()[where]
            where = np.where(layers <= global_domains_tmp.array())
            global_domains.array(
            )[where] = 4 * (global_domains_tmp.array()[where] - layers) + 1
            del where
        else:
            global_domains.array()[:] = 4 * global_domains_tmp.array()
        del global_domains_tmp
        if ldomain:
            for ii in range(corner_refine):
                mf = dolfin.CellFunction('bool', global_mesh, False)
                corner_subdomains[ii].mark(mf, True)
                global_mesh = dolfin.refine(global_mesh, mf)
                global_domains = dolfin.adapt(global_domains, global_mesh)
                del mf
        inside_fun = dolfin.MeshFunction('bool', global_mesh, basedim, True)
        global_mesh = dolfin.refine(global_mesh, inside_fun)
        global_domains = dolfin.adapt(global_domains, global_mesh)
        info('Correcting facet markers')
        global_facets = dolfin.MeshFunction('size_t', global_mesh, basedim - 1,
                                            0)
        for key in bc_dict:
            bc_dict[key].mark(global_facets, key)
        sa_hdf5.write_dolfin_mesh(global_mesh,
                                  basename,
                                  cell_function=global_domains,
                                  facet_function=global_facets)
        del global_facets, global_mesh, global_domains, basename

        gc.collect()

        for kk in range(patch_num):
            if kk in skip_patches:
                continue
            info(str(kk) + '/' + str(patch_num))
            basename = 'patch_' + str(kk).zfill(patch_fill)
            extname = basename + '_' + str(beta)

            info('    csg')
            geo = CSGeometry()
            if number:
                geo.Add(matrix * layer_bricks[0] * patches[kk])
                for ii in range(1, sublayers):
                    geo.Add(matrix *
                            (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches[kk])
                geo.Add(incs * layer_bricks[0] * patches[kk])
                for ii in range(1, sublayers):
                    geo.Add(incs * (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches[kk])
                geo.Add(matrix * layer_bricks[0] * patches_ext[kk])
                for ii in range(1, sublayers):
                    geo.Add(matrix *
                            (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches_ext[kk])
                geo.Add(incs * layer_bricks[0] * patches_ext[kk])
                for ii in range(1, sublayers):
                    geo.Add(incs * (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches_ext[kk])
            else:
                geo.Add(whole * layer_bricks[0] * patches[kk])
                for ii in range(1, sublayers):
                    geo.Add(whole * (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches[kk])
                geo.Add(whole * layer_bricks[0] * patches_ext[kk])
                for ii in range(1, sublayers):
                    geo.Add(whole * (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches_ext[kk])
            info('    csg done')
            mesh = geo.GenerateMesh(maxh=res)
            info('    surface meshed')
            del geo

            gc.collect()

            mesh.GenerateVolumeMesh()
            info('    volume meshed')
            mesh.Export(dirname + '/' + basename + '.msh', 'Gmsh2 Format')
            meshconvert.convert2xml(dirname + '/' + basename + '.msh',
                                    dirname + '/' + basename + '.xml')
            del mesh
            os.remove(dirname + '/' + basename + '.msh')
            os.remove(dirname + '/' + basename + '_facet_region.xml')

            gc.collect()

            ext_mesh = dolfin.Mesh(dirname + '/' + basename + '.xml')
            os.remove(dirname + '/' + basename + '.xml')
            info('    cell function')
            ext_domains_tmp = dolfin.MeshFunction(
                'size_t', ext_mesh,
                dirname + '/' + basename + '_physical_region.xml')
            os.remove(dirname + '/' + basename + '_physical_region.xml')
            ext_domains_tmp.array()[:] -= np.min(ext_domains_tmp.array())
            ext_domains_tmp.array()[:] //= elem_per_layer
            ext_domains = dolfin.MeshFunction('size_t', ext_mesh, basedim, 0)
            if number:
                where = np.where(ext_domains_tmp.array() < layers)
                ext_domains.array()[where] = 4 * ext_domains_tmp.array()[where]
                where = np.where(
                    layers <= ext_domains_tmp.array() < 2 * layers)
                ext_domains.array(
                )[where] = 4 * (ext_domains_tmp.array()[where] - layers) + 1
                where = np.where(
                    2 * layers <= ext_domains_tmp.array() < 3 * layers)
                ext_domains.array()[where] = 4 * (
                    ext_domains_tmp.array()[where] - 2 * layers) + 2
                where = np.where(3 * layers <= ext_domains_tmp.array())
                ext_domains.array()[where] = 4 * (
                    ext_domains_tmp.array()[where] - 3 * layers) + 3
                del where
            else:
                where = np.where(ext_domains_tmp.array() < layers)
                ext_domains.array()[where] = 4 * ext_domains_tmp.array()[where]
                where = np.where(layers <= ext_domains_tmp.array())
                ext_domains.array(
                )[where] = 4 * (ext_domains_tmp.array()[where] - layers) + 2
            del ext_domains_tmp
            if ldomain:
                for ii in range(corner_refine):
                    mf = dolfin.CellFunction('bool', ext_mesh, False)
                    corner_subdomains[ii].mark(mf, True)
                    ext_mesh = dolfin.refine(ext_mesh, mf)
                    ext_domains = dolfin.adapt(ext_domains, ext_mesh)
                    del mf
            inside_fun = dolfin.MeshFunction('bool', ext_mesh, basedim, False)
            pt_inside[kk].mark(inside_fun, True)
            ext_mesh = dolfin.refine(ext_mesh, inside_fun)
            del inside_fun
            ext_domains = dolfin.adapt(ext_domains, ext_mesh)
            info('    cell function done')

            pt_mesh = dolfin.SubMesh(ext_mesh, pt_inside[kk])

            pt_domains = dolfin.MeshFunction('size_t', pt_mesh, basedim, 0)
            tree = ext_mesh.bounding_box_tree()
            for cell in dolfin.cells(pt_mesh):
                global_index = tree.compute_first_entity_collision(
                    cell.midpoint())
                pt_domains[cell] = ext_domains[dolfin.Cell(
                    ext_mesh, global_index)]
            del tree

            pt_facets = dolfin.MeshFunction('size_t', pt_mesh, basedim - 1, 0)
            border.mark(pt_facets, 100)
            for key in bc_dict:
                bc_dict[key].mark(pt_facets, key)
            sa_hdf5.write_dolfin_mesh(pt_mesh,
                                      '{:s}/{:s}'.format(dirname, basename),
                                      cell_function=pt_domains,
                                      facet_function=pt_facets)

            tmp_nodes = ext_mesh.coordinates()
            tmp_low = np.min(tmp_nodes, axis=0)
            tmp_high = np.max(tmp_nodes, axis=0)
            is_part = (tmp_low > low + myeps).any() or (tmp_high <
                                                        high - myeps).any()
            del tmp_low, tmp_high, tmp_nodes
            info('patch [{:d}/{:d}], beta [{:.2e}] is real subdomain [{:}]'.
                 format(kk + 1, patch_num, beta, is_part))

            if is_part:
                vals = np.arange(1, 11)
            else:
                vals = np.unique(pt_facets.array())
                vals = vals[np.where(vals > 0)]
            patch_dict = dict()
            for key in bc_dict:
                if key in vals:
                    patch_dict[key] = bc_dict[key]
                else:
                    patch_dict[key] = dolfin.AutoSubDomain(
                        (lambda what: (lambda xx, on: bc_dict[what].inside(
                            xx, on) and pt_inside[kk].inside(xx, on)))(key))
            ext_facets = dolfin.MeshFunction('size_t', ext_mesh, basedim - 1,
                                             0)
            border.mark(ext_facets, 100)
            for key in patch_dict:
                patch_dict[key].mark(ext_facets, key)
            del patch_dict, vals
            sa_hdf5.write_dolfin_mesh(ext_mesh,
                                      dirname + '/' + basename + '_' +
                                      str(beta),
                                      cell_function=ext_domains,
                                      facet_function=ext_facets)
            del ext_mesh, ext_domains, ext_facets, pt_mesh, pt_domains, pt_facets

            gc.collect()

    del pt_low, pt_high, pt_inside
def navier_stokes_IPCS_cavity(mesh, dt, parameter):
    """
    fenics code: weak form of the problem.
    """
    dx, ds = df.dx, df.ds
    dot, inner, outer, div = df.dot,  df.inner,  df.outer, df.div
    nabla_grad, grad = df.nabla_grad, df.grad
    test_f, trial_f = df.TestFunction, df.TrialFunction

    U0, D, mu_solid = parameter
    g = 9.81/1.0000000000
    # function space
    V = df.VectorFunctionSpace(mesh, 'P', 2)
    Q = df.FunctionSpace(mesh, 'P', 1)
    T = df.FunctionSpace(mesh, 'P', 1)

    ASD1 = df.AutoSubDomain(top)
    ASD2 = df.AutoSubDomain(left)
    ASD3 = df.AutoSubDomain(bottom)
    ASD4 = df.AutoSubDomain(right)
    mf = df.MeshFunction("size_t", mesh, 1)
    mf.set_all(9999)
    ASD1.mark(mf, 1)
    ASD2.mark(mf, 2)
    ASD3.mark(mf, 3)
    ASD4.mark(mf, 4)
    ds_ = ds(subdomain_data=mf, domain=mesh)
    print(np.unique(ds_(3).subdomain_data().array()))

    vu, vp, vt = test_f(V), test_f(Q), test_f(T)
    u_, p_, t_ = df.Function(V), df.Function(Q), df.Function(T)  # solution
    mu_k, rho_k = df.Function(T), df.Function(T)
    u_1, p_1, t_1, rho_1 = df.Function(V), df.Function(Q), df.Function(T), df.Function(T)  # solution1
    u, p, t = trial_f(V), trial_f(Q), trial_f(T)  # unknown!
    u_k = df.Function(V)

    # boundary conditions
    no_slip = df.Constant((0., 0))
    topflow = df.Expression(("-x[0] * (x[0] - 1.0) * 6.0 * m", "0.0"),
                            m=U0, degree=2)
    bc0 = df.DirichletBC(V, topflow, top)
    bc1 = df.DirichletBC(V, no_slip, left)
    bc2 = df.DirichletBC(V, no_slip, bottom)
    bc3 = df.DirichletBC(V, no_slip, right)
    # bc4 = df.DirichletBC(Q, df.Constant(0), top)
    # bc3 = df.DirichletBC(T, df.Constant(800), top)
    bcu = [bc0, bc1, bc2, bc3]
    # no boundary conditions for the pressure
    bcp = []
    # bcp = [df.DirichletBC(Q, df.Constant(0), top)]
    bct = []

    # set initial temp: 500°C  y=0, 800°C at y=1
    x, y = np.split(T.tabulate_dof_coordinates(), 2, 1)
    u_1.vector().vec().array[:] = 1e-6
    u_k.vector().vec().array[:] = 1e-6
    p_.vector().vec().array[:] = -rho(750)*g*y.ravel()
    p_1.vector().vec().array[:] = -rho(750)*g*y.ravel()
    t_1.vector().vec().array = (y.ravel())*100 + 700
    t_.assign(t_1)
    mu_k.vector().vec().array = mu(t_1.vector().vec().array, mu_solid)
    rho_k.vector().vec().array = rho(t_1.vector().vec().array)
    rho_1.vector().vec().array = rho(t_1.vector().vec().array)

    n = df.FacetNormal(mesh)

    # implicit:
    acceleration = inner((rho_k*u - rho_1*u_1)/dt, vu) * dx
    convection = dot(div(rho_k*outer(u_k, u)), vu) * dx
    pressure = inner(p_1, div(vu))*dx - dot(p_1*n, vu)*ds  # integrated by parts
    diffusion = -inner(mu_k * (grad(u) + grad(u).T), grad(vu))*dx \
                + dot(mu_k * (grad(u) + grad(u).T)*n, vu)*ds  # integrated by parts
    body_force = dot(df.Constant((0.0, -g))*rho_k, vu)*dx \
               + dot(df.Constant((0.0, 0.0)), vu) * ds
    F1 = -acceleration - convection + diffusion + pressure + body_force
    a1, L1 = df.lhs(F1), df.rhs(F1)

    # Define variational problem for step 2
    F2 = rho_k / dt * dot(div(u_), vp) * dx + dot(grad(p-p_1), grad(vp)) * dx  # grad(p-p_1)/2 * grad(vp) * dx does not work
    a2, L2 = df.lhs(F2), df.rhs(F2)

    # Define variational problem for step 3, where u_ = u* from step 1
    F3 = -rho_k / dt * dot(u-u_, vu) * dx - dot(grad(p_-p_1), vu) * dx
    a3, L3 = df.lhs(F3), df.rhs(F3)

    # Step 4: Transport of rho / Convection-diffusion and SUPG
    # vr = vr + tau_SUPG * inner(u_, grad(vr))  # SUPG stabilization
    # F4 = dot((t - t_1) / dt, vt)*dx + dot(div(t*u_), vt) * dx       + D*dot(grad(t), grad(vt)) * dx
    # above does not work, below works fine, but is mathematically not correct, since d/dt (rho) is not 0
    F4 = dot((t - t_1) / dt, vt)*dx + dot(dot(grad(t), u_), vt)*dx \
        + D*dot(grad(t), grad(vt)) * dx
    a4, L4 = df.lhs(F4), df.rhs(F4)

    # Robin BC: HT on the walls. ht coefficient k is arbitray
    t_amb, t_feeder = 100., 800.
    k_top, k_lft, k_btm, k_rgt = (1e-3, 3.33e-4, 3.33e-4, 3.33e-4)
    F4 += k_top*(t - t_feeder)*vt*ds_(1)
    F4 += k_lft*(t - t_amb)*vt*ds_(2)
    F4 += k_btm*(t - t_amb)*vt*ds_(3)
    F4 += k_rgt*(t - t_amb)*vt*ds_(4)

    # Assemble matrices
    A1 = df.assemble(a1)
    A2 = df.assemble(a2)
    A3 = df.assemble(a3)
    # A4 = assemble(a4)
    # Apply boundary conditions to matrices
    [bc.apply(A1) for bc in bcu]
    [bc.apply(A2) for bc in bcp]
    [bc.apply(A3) for bc in bcu]
    return (u_1, p_1, t_1, mu_k, rho_k, u_, p_, t_, u_k, D,
            L1, a1, L2, A2, L3, A3, L4, a4, bcu, bcp, bct)
#define a mesh with a finder resolution along the boundary
mesh = df.RectangleMesh(df.Point(0., -Ly / 2), df.Point(Lx, Ly / 2), Nx, Ny)
x = mesh.coordinates()[:]
x[:, 1] = (np.arctan(2. * np.pi * x[:, 1] / Ly) / np.arctan(1. * np.pi)
           )  #the stretching of a finer resolution close to the boundary
x[:, 1] *= (1 + eps * np.cos(2 * np.pi * x[:, 0] / Lx))

Eu = df.VectorElement("Lagrange", mesh.ufl_cell(), 2)
Ep = df.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
Echi = df.FiniteElement("Lagrange", mesh.ufl_cell(), 1)

#define walls and periodicity
pbc = PBC(Lx)
walls = Walls(Lx, Ly, eps)
inlet = df.AutoSubDomain(inlet)

#define a descrete function on the mesh, zero on fluid, 1 on boundary, and 2 on inlet
subd = df.MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
subd.set_all(0)
walls.mark(subd, 1)
inlet.mark(subd, 2)

#make folders
if rank == 0 and not os.path.exists(folder):
    os.makedirs(folder)

with df.XDMFFile(mesh.mpi_comm(), "{}/subd.xdmf".format(folder)) as xdmff:
    xdmff.write(subd)

#define variational functions for velocity field and Pressure (Eu, Ep) and Brenner field (Echi)
Пример #12
0
	def __init__(self, mesh, hh, *, domains = None, boundaries = None, alpha = 0.25, oversampling = 2., rel_eps = 1e-7, weight_degree = 1):
		self.mesh = mesh
		self.basedim = mesh.geometric_dimension()
		if domains is None:
			self.domains = dolfin.MeshFunction('size_t', mesh, self.basedim, 0)
		else:
			self.domains = domains
		if boundaries is None:
			self.boundaries = dolfin.MeshFunction('size_t', mesh, self.basedim-1, 0)
		else:
			self.boundaries = boundaries
		coordinates = mesh.coordinates()
		low = numpy.min(coordinates, 0)
		high = numpy.max(coordinates, 0)
		diag = numpy.linalg.norm(high-low)
		eps = diag*rel_eps
		center = (low+high)*0.5
		subdivisions = numpy.int64(numpy.round((high-center-eps)/hh))
		alpha_hh = alpha*hh
		flattop_hh = hh-alpha_hh
		overlapping_hh = hh+alpha_hh
		oversampled_hh = oversampling*overlapping_hh
		index_list = numpy.vstack(map(numpy.ravel, numpy.meshgrid(*map(lambda ll: range(-ll,ll+1), subdivisions)))).T
		flat_top_indices = numpy.zeros(mesh.num_vertices(), dtype=int)
		space = dolfin.FunctionSpace(mesh, 'CG', 1)
		dof_to_vertex_map = dolfin.dof_to_vertex_map(space)
		self.markers = []
		self.pu = []
		
		poly = WeightPolynomial(weight_degree)
		weight = numpy.zeros(mesh.num_vertices())
		for index in index_list:
			box_center = center+index*hh
			box_low = box_center-0.5*hh
			box_high = box_center+0.5*hh
			# ignore patches which don't contain points from the mesh (without the overlapping part)
			if not (((box_low-eps) < coordinates).all(1)*(coordinates < (box_high+eps)).all(1)).any():
				continue

			flattop_low = box_center-0.5*flattop_hh
			flattop_high = box_center+0.5*flattop_hh
			overlapping_low = box_center-0.5*overlapping_hh
			overlapping_high = box_center+0.5*overlapping_hh
			oversampled_low = box_center-0.5*oversampled_hh
			oversampled_high = box_center+0.5*oversampled_hh
			
			flattop_domain = dolfin.AutoSubDomain(lambda xx, on: (flattop_low-eps < xx).all()*(xx < flattop_high+eps).all())
			patch_domain = dolfin.AutoSubDomain(lambda xx, on: (overlapping_low-eps < xx).all()*(xx < overlapping_high+eps).all())
			oversampled_domain = dolfin.AutoSubDomain(lambda xx, on: (oversampled_low-eps < xx).all()*(xx < oversampled_high+eps).all())
			marker = dolfin.MeshFunction('size_t', mesh, self.basedim, 0)
			oversampled_domain.mark(marker, 1)
			patch_domain.mark(marker, 2)
			#flattop_domain.mark(marker, 3)
			self.markers.append(marker)
			
			inside_flattop = ((flattop_low-eps) < coordinates).all(1)*(coordinates < (flattop_high+eps)).all(1)
			inside_overlapping = ((overlapping_low-eps) < coordinates).all(1)*(coordinates < (overlapping_high+eps)).all(1)
			overlapping = numpy.where((inside_overlapping > 0)*(inside_flattop == 0))
			overlapping_coords = coordinates[overlapping]
			dd = numpy.max([flattop_low-overlapping_coords, numpy.zeros_like(overlapping_coords), overlapping_coords-flattop_high], 0)
			dist = numpy.sqrt(numpy.sum(dd*dd, 1)) / alpha_hh
			dist[numpy.where(dist > 1)] = 1.
			coeff = numpy.zeros(mesh.num_vertices())
			coeff[overlapping] = poly(dist)
			coeff[numpy.where(inside_flattop > 0)] = 1.
			pu = dolfin.Function(space)
			pu.vector().set_local(coeff[dof_to_vertex_map])
			weight += pu.vector().get_local()
			self.pu.append(pu)

		self.init_submeshes()