Ejemplo n.º 1
0
def check_ass_penaro(bcsd=None, bcssfuns=None, V=None, plot=False):
    mesh = V.mesh()

    bcone = bcsd[1]
    contshfunone = bcssfuns[1]
    Gammaone = bcone()

    bparts = dolfin.MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
    Gammaone.mark(bparts, 0)

    u = dolfin.TrialFunction(V)
    v = dolfin.TestFunction(V)

    # Robin boundary form
    arob = dolfin.inner(u, v) * dolfin.ds(0)
    brob = dolfin.inner(v, contshfunone) * dolfin.ds(0)

    amatrob = dolfin.assemble(arob, exterior_facet_domains=bparts)
    bmatrob = dolfin.assemble(brob, exterior_facet_domains=bparts)

    amatrob = dts.mat_dolfin2sparse(amatrob)
    amatrob.eliminate_zeros()
    print 'Number of nonzeros in amatrob:', amatrob.nnz
    bmatrob = bmatrob.array()  # [ININDS]

    if plot:
        plt.figure(2)
        plt.spy(amatrob)

    if plot:
        plt.figure(1)
        for x in contshfunone.xs:
            plt.plot(x[0], x[1], 'bo')

    plt.show()
def check_ass_penaro(bcsd=None, bcssfuns=None, V=None, plot=False):
    mesh = V.mesh()

    bcone = bcsd[1]
    contshfunone = bcssfuns[1]
    Gammaone = bcone()

    bparts = dolfin.MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
    Gammaone.mark(bparts, 0)

    u = dolfin.TrialFunction(V)
    v = dolfin.TestFunction(V)

    # Robin boundary form
    arob = dolfin.inner(u, v) * dolfin.ds(0)
    brob = dolfin.inner(v, contshfunone) * dolfin.ds(0)

    amatrob = dolfin.assemble(arob, exterior_facet_domains=bparts)
    bmatrob = dolfin.assemble(brob, exterior_facet_domains=bparts)

    amatrob = dts.mat_dolfin2sparse(amatrob)
    amatrob.eliminate_zeros()
    print('Number of nonzeros in amatrob:', amatrob.nnz)
    bmatrob = bmatrob.array()  # [ININDS]

    if plot:
        plt.figure(2)
        plt.spy(amatrob)

    if plot:
        plt.figure(1)
        for x in contshfunone.xs:
            plt.plot(x[0], x[1], 'bo')

    plt.show()
Ejemplo n.º 3
0
    def __init__(self, V, u, v, b,
                 kappa, rho, cp,
                 source,
                 dirichlet_bcs=[],
                 neumann_bcs={},
                 robin_bcs={},
                 dx=dx,
                 ds=ds
                 ):
        super(HeatCylindrical, self).__init__()
        self.dirichlet_bcs = dirichlet_bcs
        r = Expression('x[0]', degree=1, domain=V.mesh())
        self.V = V
        self.dx_multiplier = 2*pi*r

        self.F0 = kappa * r * dot(grad(u), grad(v / (rho * cp))) \
            * 2*pi * dx
        #F -= dot(b, grad(u)) * v * 2*pi*r * dx_workpiece(0)
        if b:
            self.F0 += (b[0] * u.dx(0) + b[1] * u.dx(1)) * v * 2*pi*r * dx
        # Joule heat
        self.F0 -= 1.0 / (rho * cp) * source * v * 2*pi*r * dx
        # Neumann boundary conditions
        for k, nGradT in neumann_bcs.iteritems():
            self.F0 -= r * kappa * nGradT * v / (rho * cp) \
                * 2 * pi * ds(k)
        # Robin boundary conditions
        for k, value in robin_bcs.iteritems():
            alpha, u0 = value
            self.F0 -= r * kappa * alpha * (u - u0) * v / (rho * cp) \
                * 2 * pi * ds(k)
        return
Ejemplo n.º 4
0
    def solve(self, dt):
        self.u = Function(self.V0)
        self.w = TestFunction(self.V0)
        self.du = TrialFunction(self.V0)

        x = SpatialCoordinate(self.mesh0)

        L = inner( self.S(), self.eps(self.w) )*dx(degree=4)\
        - inner( self.b, self.w )*dx(degree=4)\
        - inner( self.h, self.w )*ds(degree=4)\
        + inner( 1e-6*self.u, self.w )*ds(degree=4)\
        - inner( min_value(x[2]+self.ut[2]+self.u[2], 0) * Constant((0,0,-1.0)), self.w )*ds(degree=4)

        a = derivative(L, self.u, self.du)

        problem = NonlinearVariationalProblem(L, self.u, bcs=[], J=a)
        solver = NonlinearVariationalSolver(problem)

        solver.solve()

        self.ut.vector()[:] = self.ut.vector()[:] + self.u.vector()[:]

        ALE.move(self.mesh, Function(self.V, self.u.vector()))

        self.v.vector()[:] = self.u.vector()[:] / dt
        self.n = FacetNormal(self.mesh)
Ejemplo n.º 5
0
def QoI_FEM(x0,y0,lam1,lam2,gridx,gridy,p):
    mesh = fn.UnitSquareMesh(gridx, gridy)
    V = fn.FunctionSpace(mesh, "Lagrange", p)

    # Define diffusion tensor (here, just a scalar function) and parameters
    A = fn.Expression((('exp(lam1)','a'),
                ('a','exp(lam2)')), a = fn.Constant(0.0), lam1 = lam1, lam2 = lam2, degree=3) 

    u_exact = fn.Expression("sin(lam1*pi*x[0])*cos(lam2*pi*x[1])", lam1 = lam1, lam2 = lam2, degree=2+p)

    # Define the mix of Neumann and Dirichlet BCs
    class LeftBoundary(fn.SubDomain):
        def inside(self, x, on_boundary):
            return (x[0] < fn.DOLFIN_EPS)
    class RightBoundary(fn.SubDomain):
        def inside(self, x, on_boundary):
            return (x[0] > 1.0 - fn.DOLFIN_EPS)
    class TopBoundary(fn.SubDomain):
        def inside(self, x, on_boundary):
            return (x[1] > 1.0 - fn.DOLFIN_EPS)
    class BottomBoundary(fn.SubDomain):
        def inside(self, x, on_boundary):
            return (x[1] < fn.DOLFIN_EPS)

    # Create a mesh function (mf) assigning an unsigned integer ('uint')
    # to each edge (which is a "Facet" in 2D)
    mf = fn.MeshFunction('size_t', mesh, 1)
    mf.set_all(0) # initialize the function to be zero
    # Setup the boundary classes that use Neumann boundary conditions
    NTB = TopBoundary() # instatiate
    NTB.mark(mf, 1) # set all values of the mf to be 1 on this boundary
    NBB = BottomBoundary()
    NBB.mark(mf, 2) # set all values of the mf to be 2 on this boundary
    NRB = RightBoundary()
    NRB.mark(mf, 3)

    # Define Dirichlet boundary conditions
    Gamma_0 = fn.DirichletBC(V, u_exact, LeftBoundary())
    bcs = [Gamma_0]

    # Define data necessary to approximate exact solution
    f = ( fn.exp(lam1)*(lam1*fn.pi)**2 + fn.exp(lam2)*(lam2*fn.pi)**2 ) * u_exact
    g1 = fn.Expression("-exp(lam2)*lam2*pi*sin(lam1*pi*x[0])*sin(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p)    #pointing outward unit normal vector, pointing upaward (0,1)
    g2 = fn.Expression("exp(lam2)*lam2*pi*sin(lam1*pi*x[0])*sin(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p)     #pointing downward (0,1)
    g3 = fn.Expression("exp(lam1)*lam1*pi*cos(lam1*pi*x[0])*cos(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p)

    fn.ds = fn.ds(subdomain_data=mf)
    # Define variational problem
    u = fn.TrialFunction(V)
    v = fn.TestFunction(V)
    a = fn.inner(A*fn.grad(u), fn.grad(v))*fn.dx
    L = f*v*fn.dx + g1*v*fn.ds(1) + g2*v*fn.ds(2) + g3*v*fn.ds(3)  #note the 1, 2 and 3 correspond to the mf

    # Compute solution
    u = fn.Function(V)
    fn.solve(a == L, u, bcs)

    return u(x0,y0)
def conj_coef_fun(derJ, derJ_old, hol_cyl, boundary_faces, mark_in, mark_ex,
                  time_v, cut_end, method, itera, path_to_do):
    '''
    Conjugation coefficient.
    method = 'PR' (Polak-Ribière) or 'FR' (Fletcher-Reeves).
    '''
    num_v = np.zeros(np.shape(time_v))
    den_v = np.zeros(np.shape(time_v))

    for count_t_i, t_i in enumerate(time_v):
        if method == 'PR':
            #Polak-Ribière method
            #scalar
            num_v[count_t_i] = do.assemble(
                derJ[count_t_i] * (derJ[count_t_i] - derJ_old[count_t_i]) *
                do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces))

        elif method == 'FR':
            #Fletcher-Reeves method
            #scalar
            num_v[count_t_i] = do.assemble(
                pow(derJ[count_t_i], 2.) *
                do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces))

        #scalar
        den_v[count_t_i] = do.assemble(
            pow(derJ_old[count_t_i], 2.) *
            do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces))

    fig_inf = plt.figure(figsize=(20, 10))

    ax_inf = fig_inf.add_subplot(211)
    ax_inf.plot(num_v, 'r.', label='num1')
    ax_inf.plot(den_v, 'b.', label='den1')
    ax_inf.legend()

    ax_inf = fig_inf.add_subplot(223)
    ax_inf.plot(num_v[:10], 'r.', label='num1')
    ax_inf.plot(den_v[:10], 'b.', label='den1')
    ax_inf.legend()

    ax_inf = fig_inf.add_subplot(224)
    ax_inf.plot(num_v[-10:], 'r.', label='num1')
    ax_inf.plot(den_v[-10:], 'b.', label='den1')
    ax_inf.legend()

    nam_inf = os.path.join(path_to_do,
                           'gamma_CG_{}_{}.pdf'.format(itera, method))
    fig_inf.savefig(nam_inf, dpi=150)

    #integration
    num_gamma_CG = np.trapz(num_v[:cut_end], x=time_v[:cut_end])
    den_gamma_CG = np.trapz(den_v[:cut_end], x=time_v[:cut_end])

    #https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method
    gamma_CG = max(0., num_gamma_CG / den_gamma_CG)

    return gamma_CG
Ejemplo n.º 7
0
 def create_bc(self):
     #Input
     G_rhs_inner, G_rhs_outer = self.inhomogeneity()
     local_bc = 0.0
     df.ds = self.my_mesh_cls.ds  #<---- Important
     local_bc += (-0.5 * df.inner(self.v,((self.BC1_rhs-self.BC2_rhs) \
             * G_rhs_inner))  ) * df.ds(3000) #RHS-2
     local_bc += (-0.5 * df.inner(self.v,((self.BC1_rhs-self.BC2_rhs)\
             * G_rhs_outer))  ) * df.ds(3100) #RHS-2
     return local_bc
Ejemplo n.º 8
0
 def assemble_lui_stiffness(self, g, f, mesh, robin_boundary):
     V = FunctionSpace(mesh, "Lagrange", self.p)
     u = TrialFunction(V)
     v = TestFunction(V)
     n = FacetNormal(mesh)
     robin = MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
     robin_boundary.mark(robin, 1)
     ds = Measure('ds', subdomain_data=robin)
     a = inner(grad(u), grad(v)) * dx
     b = (1 - g) * (inner(grad(u), n)) * v * ds(1)
     c = f * u * v * ds(1)
     k = lhs(a + b - c)
     K = PETScMatrix()
     assemble(k, tensor=K)
     return K, V
Ejemplo n.º 9
0
	def V0constrainedE(self,inverse=False):


		mesh = self.parameters["mesh"]
		u = self.parameters["displacement_variable"]
		ds = dolfin.ds(subdomain_data=self.parameters["facetboundaries"])
		dsendo = ds(self.parameters["endoid"], domain = self.parameters["mesh"], subdomain_data = self.parameters["facetboundaries"])
		pendo = self.parameters["volconst_variable"] 
		V0= self.parameters["constrained_vol"] 

		X = SpatialCoordinate(mesh)
		x = u + X


		F = self.Fmat()
		N = self.parameters["facet_normal"]
		n = cofac(F)*N

		area = assemble(Constant(1.0) * dsendo)
		if inverse:
			V_u = - Constant(0.0/3.0) * inner(x, n)
			Wvol = (Constant(0.0/area) * pendo  * V0 * dsendo) - (pendo * V_u *dsendo)
		else:
		    V_u = - Constant(1.0/3.0) * inner(x, n)
		    Wvol = (Constant(1.0/area) * pendo  * V0 * dsendo) - (pendo * V_u *dsendo)
		return Wvol
Ejemplo n.º 10
0
    def __init__(self, U_m, mesh):
        """Function spaces and BCs"""
        V = VectorFunctionSpace(mesh, 'P', 2)
        Q = FunctionSpace(mesh, 'P', 1)
        self.mesh = mesh
        self.vu, self.vp = TestFunction(V), TestFunction(Q)  # for integration
        self.u_, self.p_ = Function(V), Function(Q)  # for the solution
        self.u_1, self.p_1 = Function(V), Function(Q)  # for the prev. solution
        self.u_k, self.p_k = Function(V), Function(Q)  # for the prev. solution
        self.u, self.p = TrialFunction(V), TrialFunction(Q)  # unknown!

        U0_str = "4.*U_m*x[1]*(.41-x[1])/(.41*.41)"
        x = [0,
             .41 / 2]  # evaluate the Expression at the center of the channel
        self.U_mean = np.mean(2 / 3 * eval(U0_str))

        U0 = Expression((U0_str, "0"), U_m=U_m, degree=2)
        bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall)
        bc1 = DirichletBC(V, Constant((0, 0)), topandbottom)
        bc2 = DirichletBC(V, U0, inlet)
        bc3 = DirichletBC(Q, Constant(0), outlet)
        self.bcu = [bc0, bc1, bc2]
        self.bcp = [bc3]
        # ds is needed to compute drag and lift.
        ASD1 = AutoSubDomain(topandbottom)
        ASD2 = AutoSubDomain(cylinderwall)
        mf = MeshFunction("size_t", mesh, 1)
        mf.set_all(0)
        ASD1.mark(mf, 1)
        ASD2.mark(mf, 2)
        self.ds_ = ds(subdomain_data=mf, domain=mesh)
        return
Ejemplo n.º 11
0
def main():
    fsr = FunctionSubspaceRegistry()

    deg = 2
    mesh = dolfin.UnitSquareMesh(100, 3)
    muc = mesh.ufl_cell()
    el_w = dolfin.FiniteElement('DG', muc, deg - 1)
    el_j = dolfin.FiniteElement('BDM', muc, deg)
    el_DG0 = dolfin.FiniteElement('DG', muc, 0)
    el = dolfin.MixedElement([el_w, el_j])
    space = dolfin.FunctionSpace(mesh, el)
    DG0 = dolfin.FunctionSpace(mesh, el_DG0)
    fsr.register(space)
    facet_normal = dolfin.FacetNormal(mesh)
    xyz = dolfin.SpatialCoordinate(mesh)

    trial = dolfin.Function(space)
    test = dolfin.TestFunction(space)

    w, c = dolfin.split(trial)
    v, phi = dolfin.split(test)

    sympy_exprs = derive_exprs()
    exprs = {
        k: sympy_dolfin_printer.to_ufl(sympy_exprs['R'], mesh, v)
        for k, v in sympy_exprs['quantities'].items()
    }

    f = exprs['f']
    w0 = dolfin.project(dolfin.conditional(dolfin.gt(xyz[0], 0.5), 1.0, 0.3),
                        DG0)
    w_BC = exprs['w']

    dx = dolfin.dx()
    form = (+v * dolfin.div(c) * dx - v * f * dx +
            dolfin.exp(w + w0) * dolfin.dot(phi, c) * dx +
            dolfin.div(phi) * w * dx -
            (w_BC - w0) * dolfin.dot(phi, facet_normal) * dolfin.ds() -
            (w0('-') - w0('+')) * dolfin.dot(phi('+'), facet_normal('+')) *
            dolfin.dS())

    solver = NewtonSolver(form,
                          trial, [],
                          parameters=dict(relaxation_parameter=1.0,
                                          maximum_iterations=15,
                                          extra_iterations=10,
                                          relative_tolerance=1e-6,
                                          absolute_tolerance=1e-7))

    solver.solve()

    with closing(XdmfPlot("out/qflop_test.xdmf", fsr)) as X:
        CG1 = dolfin.FunctionSpace(mesh, dolfin.FiniteElement('CG', muc, 1))
        X.add('w0', 1, w0, CG1)
        X.add('w_c', 1, w + w0, CG1)
        X.add('w_e', 1, exprs['w'], CG1)
        X.add('f', 1, f, CG1)
        X.add('cx_c', 1, c[0], CG1)
        X.add('cx_e', 1, exprs['c'][0], CG1)
Ejemplo n.º 12
0
def test_store_mesh(casedir):
    pp = PostProcessor(dict(casedir=casedir))

    from dolfin import (UnitSquareMesh, CellFunction, FacetFunction,
                        AutoSubDomain, Mesh, HDF5File, assemble, Expression,
                        ds, dx)

    # Store mesh
    mesh = UnitSquareMesh(6, 6)
    celldomains = CellFunction("size_t", mesh)
    celldomains.set_all(0)
    AutoSubDomain(lambda x: x[0] < 0.5).mark(celldomains, 1)

    facetdomains = FacetFunction("size_t", mesh)
    AutoSubDomain(lambda x, on_boundary: x[0] < 0.5 and on_boundary).mark(
        facetdomains, 1)

    pp.store_mesh(mesh, celldomains, facetdomains)

    # Read mesh back
    mesh2 = Mesh()
    f = HDF5File(mpi_comm_world(), os.path.join(pp.get_casedir(), "mesh.hdf5"),
                 'r')
    f.read(mesh2, "Mesh", False)

    celldomains2 = CellFunction("size_t", mesh2)
    f.read(celldomains2, "CellDomains")
    facetdomains2 = FacetFunction("size_t", mesh2)
    f.read(facetdomains2, "FacetDomains")

    e = Expression("1+x[1]", degree=1)

    dx1 = dx(1, domain=mesh, subdomain_data=celldomains)
    dx2 = dx(1, domain=mesh2, subdomain_data=celldomains2)
    C1 = assemble(e * dx1)
    C2 = assemble(e * dx2)
    assert abs(C1 - C2) < 1e-10

    ds1 = ds(1, domain=mesh, subdomain_data=facetdomains)
    ds2 = ds(1, domain=mesh2, subdomain_data=facetdomains2)
    F1 = assemble(e * ds1)
    F2 = assemble(e * ds2)
    assert abs(F1 - F2) < 1e-10
Ejemplo n.º 13
0
def navier_stokes_IPCS(mesh, dt, parameter):
    """
    fenics code: weak form of the problem.
    """
    mu, rho, nu = parameter
    V = VectorFunctionSpace(mesh, 'P', 2)
    Q = FunctionSpace(mesh, 'P', 1)

    bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall)
    bc1 = DirichletBC(V, Constant((0, 0)), topandbottom)
    bc2 = DirichletBC(V, U0, inlet)
    bc3 = DirichletBC(Q, Constant(1), outlet)
    bcs = [bc0, bc1, bc2, bc3]

    # ds is needed to compute drag and lift. Not used here.
    ASD1 = AutoSubDomain(topandbottom)
    ASD2 = AutoSubDomain(cylinderwall)
    mf = MeshFunction("size_t", mesh, 1)
    mf.set_all(0)
    ASD1.mark(mf, 1)
    ASD2.mark(mf, 2)
    ds_ = ds(subdomain_data=mf, domain=mesh)

    vu, vp = TestFunction(V), TestFunction(Q)  # for integration
    u_, p_ = Function(V), Function(Q)  # for the solution
    u_1, p_1 = Function(V), Function(Q)  # for the prev. solution
    u, p = TrialFunction(V), TrialFunction(Q)  # unknown!
    bcu = [bcs[0], bcs[1], bcs[2]]
    bcp = [bcs[3]]

    n = FacetNormal(mesh)
    u_mid = (u + u_1) / 2.0
    F1 = rho*dot((u - u_1) / dt, vu)*dx \
        + rho*dot(dot(u_1, nabla_grad(u_1)), vu)*dx \
        + inner(sigma(u_mid, p_1, mu), epsilon(vu))*dx \
        + dot(p_1*n, vu)*ds - dot(mu*nabla_grad(u_mid)*n, vu)*ds
    a1 = lhs(F1)
    L1 = rhs(F1)
    # Define variational problem for step 2
    a2 = dot(nabla_grad(p), nabla_grad(vp)) * dx
    L2 = dot(nabla_grad(p_1), nabla_grad(vp)) * dx - (
        rho / dt) * div(u_) * vp * dx  # rho missing in FEniCS tutorial
    # Define variational problem for step 3
    a3 = dot(u, vu) * dx
    L3 = dot(u_, vu) * dx - dt * dot(nabla_grad(p_ - p_1), vu) * dx
    # Assemble matrices
    A1 = assemble(a1)
    A2 = assemble(a2)
    A3 = assemble(a3)
    # Apply boundary conditions to matrices
    [bc.apply(A1) for bc in bcu]
    [bc.apply(A2) for bc in bcp]
    return u_, p_, u_1, p_1, L1, A1, L2, A2, L3, A3, bcu, bcp
Ejemplo n.º 14
0
	def cavityvol(self):
	
		u = self.parameters["displacement_variable"]
		N = self.parameters["facet_normal"]
		mesh = self.parameters["mesh"]
		X = SpatialCoordinate(mesh)
		ds = dolfin.ds(subdomain_data=self.parameters["facetboundaries"])
			
		F = self.Fmat()
			
		vol_form = -Constant(1.0/3.0) * inner(det(F)*dot(inv(F).T, N), X + u)*ds(self.parameters["endoid"])
			
		return assemble(vol_form)
Ejemplo n.º 15
0
    def set_FEM(self):
        """
        Define finite element space of elliptic PDE.
        """
        self.mesh = df.UnitSquareMesh(self.nx, self.ny)
        self.mpi_comm = self.mesh.mpi_comm()

        # boundaries
        self.boundaries = df.FacetFunction("size_t", self.mesh, 0)
        self.ds = df.ds(subdomain_data=self.boundaries)

        # 2. Define the finite element spaces and build mixed space
        try:
            V_fe = df.FiniteElement("CG", self.mesh.ufl_cell(), 2)
            L_fe = df.FiniteElement("CG", self.mesh.ufl_cell(), 2)
            self.V = df.FunctionSpace(self.mesh, V_fe)
            self.W = df.FunctionSpace(self.mesh, V_fe * L_fe)
        except TypeError:
            print('Warning: '
                  'MixedFunctionSpace'
                  ' has been deprecated in DOLFIN version 1.7.0.')
            print('It will be removed from version 2.0.0.')
            self.V = df.FunctionSpace(self.mesh, 'CG', 2)
            L = df.FunctionSpace(self.mesh, 'CG', 2)
            self.W = self.V * L

        # 3. Define boundary conditions
        bc_lagrange = df.DirichletBC(
            self.W.sub(1), df.Constant(0.0),
            "fabs(x[0])>2.0*DOLFIN_EPS & fabs(x[0]-1.0)>2.0*DOLFIN_EPS & fabs(x[1])>2.0*DOLFIN_EPS & fabs(x[1]-1.0)>2.0*DOLFIN_EPS"
        )

        self.ess_bc = [bc_lagrange]

        # Create adjoint boundary conditions (homogenized forward BCs)
        def homogenize(bc):
            bc_copy = df.DirichletBC(bc)
            bc_copy.homogenize()
            return bc_copy

        self.adj_bcs = [homogenize(bc) for bc in self.ess_bc]
Ejemplo n.º 16
0
    def compute(self, get):
        u = get("Velocity")
        mu = get("DynamicViscosity")
        if isinstance(mu, (float, int)):
            mu = Constant(mu)

        n = self._n
        T = -mu*dot((grad(u) + grad(u).T), n)
        Tn = dot(T, n)
        Tt = T - Tn*n

        tau_form = dot(self.v, Tt)*ds()
        assemble(tau_form, tensor=self.tau.vector())

        #self.b[self._keys] = self.tau.vector()[self._values] # FIXME: This is not safe!!!
        get_set_vector(self.b, self._keys, self.tau.vector(), self._values, self._temp_array)

        # Ensure proper scaling
        self.solver.solve(self.tau_boundary.vector(), self.b)

        return self.tau_boundary
Ejemplo n.º 17
0
    def compute(self, get):
        u = get("Velocity")
        mu = get("DynamicViscosity")
        if isinstance(mu, (float, int)):
            mu = Constant(mu)

        n = self._n
        T = -mu * dot((grad(u) + grad(u).T), n)
        Tn = dot(T, n)
        Tt = T - Tn * n

        tau_form = dot(self.v, Tt) * ds()
        assemble(tau_form, tensor=self.tau.vector())

        #self.b[self._keys] = self.tau.vector()[self._values] # FIXME: This is not safe!!!
        get_set_vector(self.b, self._keys, self.tau.vector(), self._values,
                       self._temp_array)

        # Ensure proper scaling
        self.solver.solve(self.tau_boundary.vector(), self.b)

        return self.tau_boundary
Ejemplo n.º 18
0
def setup_problem(mesh, U0, coupled=True):
    # Build function space
    V = VectorFunctionSpace(mesh, 'P', 2)
    Q = FunctionSpace(mesh, 'P', 1)
    L = FunctionSpace(mesh, 'P', 1)
    VQL = (V, Q, L)

    # bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall)
    bc1 = DirichletBC(V, Constant((0, 0)), topandbottom)
    bc2 = DirichletBC(V, U0, inlet)
    bc3 = DirichletBC(Q, Constant(1), outlet)
    # bcs = [bc0, bc1, bc2, bc3]
    bcs = [bc1, bc2, bc3]
    warnings.warn("no no-slip for cyl-wall!")

    ASD1 = AutoSubDomain(topandbottom)
    ASD2 = AutoSubDomain(cylinderwall)
    mf = MeshFunction("size_t", mesh, 1)
    mf.set_all(0)
    ASD1.mark(mf, 1)
    ASD2.mark(mf, 2)
    ds_ = ds(subdomain_data=mf, domain=mesh)
    return VQL, bcs, ds_
Ejemplo n.º 19
0
 def ds(self):
     """Return the surface measure of exterior facets using
     self.mesh as domain and self.ffun as subdomain_data
     """
     return dolfin.ds(domain=self.mesh, subdomain_data=self.ffun)
Ejemplo n.º 20
0
    def solve(self):
        """ Find eigenvalues for transformed mesh. """
        self.progress("Building mesh.")
        # build transformed mesh
        mesh = self.refineMesh()
        # dim = mesh.topology().dim()
        if self.bcLast:
            mesh = transform_mesh(mesh, self.transformList)
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
        else:
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
            mesh = transform_mesh(mesh, self.transformList)
            # boundary conditions computed on non-transformed mesh
            # copy the values to transformed mesh
            fun = FacetFunction("size_t", mesh, shift)
            fun.array()[:] = bcs.array()[:]
            bcs = fun
        ds = Measure('ds', domain=mesh, subdomain_data=bcs)
        V = FunctionSpace(mesh, self.method, self.deg)
        u = TrialFunction(V)
        v = TestFunction(V)
        self.progress("Assembling matrices.")
        wTop = Expression(self.wTop, degree=self.deg)
        wBottom = Expression(self.wBottom, degree=self.deg)

        #
        # build stiffness matrix form
        #
        s = dot(grad(u), grad(v))*wTop*dx
        # add Robin parts
        for bc in Robin:
            s += Constant(bc.parValue)*u*v*wTop*ds(bc.value+shift)

        #
        # build mass matrix form
        #
        if len(Steklov) > 0:
            m = 0
            for bc in Steklov:
                m += Constant(bc.parValue)*u*v*wBottom*ds(bc.value+shift)
        else:
            m = u*v*wBottom*dx

        # assemble
        # if USE_EIGEN:
        #     S, M = EigenMatrix(), EigenMatrix()
            # tempv = EigenVector()
        # else:
        S, M = PETScMatrix(), PETScMatrix()
        # tempv = PETScVector()

        if not np.any(bcs.array() == shift+1):
            # no Dirichlet parts
            assemble(s, tensor=S)
            assemble(m, tensor=M)
        else:
            #
            # with EIGEN we could
            #   apply Dirichlet condition symmetrically
            #   completely remove rows and columns
            #
            # Dirichlet parts are marked with shift+1
            #
            # temp = Constant(0)*v*dx
            bc = DirichletBC(V, Constant(0.0), bcs, shift+1)
            # assemble_system(s, temp, bc, A_tensor=S, b_tensor=tempv)
            # assemble_system(m, temp, bc, A_tensor=M, b_tensor=tempv)
            assemble(s, tensor=S)
            bc.apply(S)
            assemble(m, tensor=M)
            # bc.zero(M)

        # if USE_EIGEN:
        #    M = M.sparray()
        #    M.eliminate_zeros()
        #    print M.shape
        #    indices = M.indptr[:-1] - M.indptr[1:] < 0
        #    M = M[indices, :].tocsc()[:, indices]
        #    S = S.sparray()[indices, :].tocsc()[:, indices]
        #    print M.shape
        #
        # solve the eigenvalue problem
        #
        self.progress("Solving eigenvalue problem.")
        eigensolver = SLEPcEigenSolver(S, M)
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["solver"] = "krylov-schur"
        if self.target is not None:
            eigensolver.parameters["spectrum"] = "target real"
            eigensolver.parameters["spectral_shift"] = self.target
        else:
            eigensolver.parameters["spectrum"] = "smallest magnitude"
            eigensolver.parameters["spectral_shift"] = -0.01
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.solve(self.number)
        self.progress("Generating eigenfunctions.")
        if eigensolver.get_number_converged() == 0:
            return None
        eigf = []
        eigv = []
        if self.deg > 1:
            mesh = refine(mesh)
        W = FunctionSpace(mesh, 'CG', 1)
        for i in range(eigensolver.get_number_converged()):
            pair = eigensolver.get_eigenpair(i)[::2]
            eigv.append(pair[0])
            u = Function(V)
            u.vector()[:] = pair[1]
            eigf.append(interpolate(u, W))
        return eigv, eigf
Ejemplo n.º 21
0
def main():
    L = 10.0
    H = 10.0

    mesh = df.UnitSquare(10,10,'left')
    mesh.coordinates()[:,0] *= L
    mesh.coordinates()[:,1] *= H

    U = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=2)
    U_x, U_y = U.split()
    u = df.TrialFunction(U)
    v = df.TestFunction(U)

    E = 2.0E11
    nu = 0.3

    lmbda = nu*E/((1.0 + nu)*(1.0 - 2.0*nu))
    mu = E/(2.0*(1.0 + nu))

    # Elastic Modulus
    C_numpy = np.array([[lmbda + 2.0*mu, lmbda, 0.0],
                        [lmbda, lmbda + 2.0*mu, 0.0],
                        [0.0, 0.0, mu ]])
    C = df.as_matrix(C_numpy)

    from dolfin import dot, dx, grad, inner, ds

    def eps(u):
        """ Returns a vector of strains of size (3,1) in the Voigt notation
        layout {eps_xx, eps_yy, gamma_xy} where gamma_xy = 2*eps_xy"""
        return df.as_vector([u[i].dx(i) for i in range(2)] +
                            [u[i].dx(j) + u[j].dx(i) for (i,j) in [(0,1)]])

    a = inner(eps(v), C*eps(u))*dx
    A = a

    # Dirichlet BC
    class LeftBoundary(df.SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and np.abs(x[0]) < tol

    class RightBoundary(df.SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and np.abs(x[0] - self.L) < tol

    class BottomBoundary(df.SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14
            return on_boundary and np.abs(x[1]) < tol

    left_boundary = LeftBoundary()
    right_boundary = RightBoundary()
    right_boundary.L = L
    bottom_boundary = BottomBoundary()

    zero = df.Constant(0.0)
    bc_left_Ux = df.DirichletBC(U_x, zero, left_boundary)
    bc_bottom_Uy = df.DirichletBC(U_y, zero, bottom_boundary)
    bcs = [bc_left_Ux, bc_bottom_Uy]

    # Neumann BCs
    t = df.Constant(10000.0)
    boundary_parts = df.EdgeFunction("uint", mesh, 1)
    right_boundary.mark(boundary_parts, 0)
    l = inner(t,v[0])*ds(0)

    u_h = df.Function(U)
    problem = df.LinearVariationalProblem(A, l, u_h, bcs=bcs)
    solver = df.LinearVariationalSolver(problem)
    solver.parameters["linear_solver"] = "direct"
    solver.solve()

    u_x, u_y = u_h.split()

    stress = df.project(C*eps(u_h), df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3))

    df.plot(u_x)
    df.plot(u_y)
    df.plot(stress[0])
    df.interactive()
Ejemplo n.º 22
0
 def ds(self):
     """Returns the mesh surface measure using `self.ffun` as `subdomain_data`
     """
     return df.ds(domain=self.mesh, subdomain_data=self.ffun)
def gamma_fun(
        v,
        hol_cyl,
        T_step_d,  #from direct pbm
        boundary_faces,
        mark_in,
        mark_ex,
        T_ex_d,
        g_d,
        gamma_reg0,  #the old gamma_reg
        omegac,  #contraction factor
        muc,
        itera_div,
        unitNormal,
        time_v,
        cut_end,
        itera,
        path_to_do):
    '''
    Returns the optimal regularization parameter.
    
    T_step from direct problem.
    '''
    num1_v = np.zeros((len(T_step_d), ))
    num2_v = np.zeros((len(T_step_d), ))
    num3_v = np.zeros((len(T_step_d), ))
    den1_v = np.zeros((len(T_step_d), ))

    for count_it in sorted(T_step_d):
        #scalar
        num1_v[count_it] = do.assemble(
            pow(T_step_d[count_it] - T_ex_d[count_it], 2.) *
            do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces))

        num2_v[count_it] = do.assemble(
            pow(T_step_d[count_it], 2.) *
            do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces))

        num3_v[count_it] = do.assemble(
            pow(T_ex_d[count_it], 2.) *
            do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces))

        #scalar
        den1_v[count_it] = do.assemble(
            pow(g_d[count_it], 2.) *
            do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces))

        print 'gamma: count_t = {}, num1 = {}'.format(count_it,
                                                      num1_v[count_it])
        print 'gamma: count_t = {}, den1 = {}'.format(count_it,
                                                      den1_v[count_it]), '\n'

    fig_inf = plt.figure(figsize=(20, 10))

    for i_fig in xrange(12):
        vari = 1. * num1_v * (i_fig / 3 == 0) + \
               1. * num2_v * (i_fig / 3 == 1) + \
               1. * num3_v * (i_fig / 3 == 2) + \
               1. * den1_v * (i_fig / 3 == 3)

        ytag = 'num1' * (i_fig / 3 == 0) + \
               'num2' * (i_fig / 3 == 1) + \
               'num3' * (i_fig / 3 == 2) + \
               'den1' * (i_fig / 3 == 3)

        stai =  0 * (i_fig % 3 == 0) + \
                0 * (i_fig % 3 == 1) + \
              -50 * (i_fig % 3 == 2)

        endi = len(vari) * (i_fig % 3 == 0) + \
               50 * (i_fig % 3 == 1) + \
               len(vari) * (i_fig % 3 == 2)

        ax_inf = fig_inf.add_subplot(4, 3, i_fig + 1)
        ax_inf.plot(vari[stai:endi])
        ax_inf.set_ylabel(ytag)
        ax_inf.grid()

    nam_inf = os.path.join(path_to_do, 'gamma_{}.pdf'.format(itera))
    fig_inf.savefig(nam_inf, dpi=150)

    #num1_avg = np.trapz(num1_v[5 : -5], x = time_v[5 : -5])
    #den1_avg = np.trapz(den1_v[5 : -5], x = time_v[5 : -5])

    num1_avg = np.trapz(num1_v[:cut_end], x=time_v[:cut_end])
    num2_avg = np.trapz(num2_v[:cut_end], x=time_v[:cut_end])
    num3_avg = np.trapz(num3_v[:cut_end], x=time_v[:cut_end])
    den1_avg = np.trapz(den1_v[:cut_end], x=time_v[:cut_end])

    if itera > itera_div:
        #divisions are allowed
        C_avg = -1. / den1_avg * (num2_avg + gamma_reg0 * den1_avg)**2.

        T_avg = num2_avg / den1_avg

        #Eq. (2.10) in Heng's paper
        aH = 2. * muc * num3_avg
        bH = +(2. + 4. * muc) * C_avg
        cH = -(2. + 2. * muc) * C_avg * T_avg
        x10 = (-bH + (bH**2. - 4. * aH * cH)**.5) / (2. * aH)
        x20 = (-bH - (bH**2. - 4. * aH * cH)**.5) / (2. * aH)

        x11 = x10 - T_avg
        x21 = x20 - T_avg

        if x11 > 1e-14 and x21 > 1e-14:
            #Two positive roots
            #take the smaller one
            gamma_reg = min(x11, x21)
        else:
            #Remark 3.8 in Heng's paper
            #restart
            gamma_reg = -omegac * (T_avg + cH / bH + aH / bH *
                                   (T_avg + gamma_reg0)**2.)

        gamma_reg_unused = 2. * num1_avg / den1_avg

    else:
        #divisions are not allowed
        gamma_reg = 1. * gamma_reg0
        gamma_reg_unused = 1. * gamma_reg0

    return gamma_reg, gamma_reg_unused, \
           num1_avg, num2_avg, num3_avg, den1_avg
def nablau_fun(
        V,
        v,
        hol_cyl,
        A,
        boundary_faces,
        mark_in,
        dg_d,  #S_in
        k_mesh_old,
        cp_mesh_old,
        rho_mesh_old,
        dt,
        time_v,
        theta,
        itera):
    '''
    Sensitivity problem.
    Solves A u = L.
    A = dt * theta * 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)
    
    Solved after setting dg_in = p^k.                         
    '''
    #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, False)  #prints default values
    solver.parameters['relative_tolerance'] = 1e-13
    solver.parameters['maximum_iterations'] = 200000
    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

    #starts from 0
    #u_stept = do.TrialFunction(V)
    u_step3 = do.Function(V)

    #starts from 0
    u_old = do.Function(V)

    u_step3_d = {}

    theta = do.Constant(theta)

    dt = do.Constant(dt)

    #A = dt / 2. * k_mesh_old * do.dot(do.grad(u_stept), do.grad(v)) * do.dx(domain = hol_cyl) + \
    #   rho_mesh_old * cp_mesh_old * u_stept * v * do.dx(domain = hol_cyl)

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

        #int_fluxT_ex = 0
        int_fluxT_in = dg_d[count_t_i + 1] * v * do.ds(
            mark_in, domain=hol_cyl, subdomain_data=boundary_faces)
        int_fluxT_in_old = dg_d[count_t_i] * v * do.ds(
            mark_in, domain=hol_cyl, subdomain_data=boundary_faces)

        #L -= (int_fluxT_in + int_fluxT_ex)
        L_old = -dt * (1. - theta) * k_mesh_old * do.dot(do.grad(u_old), do.grad(v)) * \
                do.dx(domain = hol_cyl) + \
                rho_mesh_old * cp_mesh_old * u_old * v * do.dx(domain = hol_cyl)

        L = L_old + (dt * theta * int_fluxT_in + dt *
                     (1. - theta) * int_fluxT_in_old)

        do.solve(A == L, u_step3)

        print 'u: count_t = {}, min(dg) = {}'.format(
            count_t_i, min(dg_d[count_t_i].vector().array()))

        print 'u: count_t = {}, max(dg) = {}'.format(
            count_t_i, max(dg_d[count_t_i].vector().array()))

        print 'u: count_t = {}, min(int_fluxT_in) = {}'.format(
            count_t_i, min(do.assemble(int_fluxT_in).array()))
        print 'u: count_t = {}, max(int_fluxT_in) = {}'.format(
            count_t_i, max(do.assemble(int_fluxT_in).array()))

        print 'u: count_t = {}, min(L) = {}'.format(
            count_t_i, min(do.assemble(L).array()))
        print 'u: count_t = {}, max(L) = {}'.format(
            count_t_i, max(do.assemble(L).array()))

        print 'u: count_t = {}, min(u) = {}'.format(
            count_t_i, min(u_step3.vector().array()))
        print 'u: count_t = {}, max(u) = {}'.format(
            count_t_i, max(u_step3.vector().array())), '\n'

        u_old.assign(u_step3)

    count_t_i += 1

    #storage
    u_step3_d[count_t_i] = do.Function(V)
    u_step3_d[count_t_i].vector()[:] = u_step3.vector().array()

    return u_step3_d
def transport_linear(integrator_type, mesh, subdomains, boundaries, t_start, dt, T, solution0, \
                 alpha_0, K_0, mu_l_0, lmbda_l_0, Ks_0, \
                 alpha_1, K_1, mu_l_1, lmbda_l_1, Ks_1, \
                 alpha, K, mu_l, lmbda_l, Ks, \
                 cf_0, phi_0, rho_0, mu_0, k_0,\
                 cf_1, phi_1, rho_1, mu_1, k_1,\
                 cf, phi, rho, mu, k, \
                 d_0, d_1, d_t,
                 vel_c, p_con, A_0, Temp, c_extrapolate):
    # Create mesh and define function space
    parameters["ghost_mode"] = "shared_facet"  # required by dS

    dx = Measure('dx', domain=mesh, subdomain_data=subdomains)
    ds = Measure('ds', domain=mesh, subdomain_data=boundaries)
    dS = Measure('dS', domain=mesh, subdomain_data=boundaries)

    C_cg = FiniteElement("CG", mesh.ufl_cell(), 1)
    C_dg = FiniteElement("DG", mesh.ufl_cell(), 0)
    mini = C_cg + C_dg
    C = FunctionSpace(mesh, mini)
    C = BlockFunctionSpace([C])
    TM = TensorFunctionSpace(mesh, 'DG', 0)
    PM = FunctionSpace(mesh, 'DG', 0)
    n = FacetNormal(mesh)
    vc = CellVolume(mesh)
    fc = FacetArea(mesh)

    h = vc / fc
    h_avg = (vc('+') + vc('-')) / (2 * avg(fc))

    penalty1 = Constant(1.0)

    tau = Function(PM)
    tau = tau_cal(tau, phi, -0.5)

    tuning_para = 0.25

    vel_norm = (dot(vel_c, n) + abs(dot(vel_c, n))) / 2.0

    cell_size = CellDiameter(mesh)
    vnorm = sqrt(dot(vel_c, vel_c))

    I = Identity(mesh.topology().dim())
    d_eff = Function(TM)
    d_eff = diff_coeff_cal_rev(d_eff, d_0, tau,
                               phi) + tuning_para * cell_size * vnorm * I

    monitor_dt = dt

    # Define variational problem
    dc, = BlockTrialFunction(C)
    dc_dot, = BlockTrialFunction(C)
    psic, = BlockTestFunction(C)
    block_c = BlockFunction(C)
    c, = block_split(block_c)
    block_c_dot = BlockFunction(C)
    c_dot, = block_split(block_c_dot)

    theta = -1.0

    a_time = phi * rho * inner(c_dot, psic) * dx

    a_dif = dot(rho*d_eff*grad(c),grad(psic))*dx \
        - dot(avg_w(rho*d_eff*grad(c),weight_e(rho*d_eff,n)), jump(psic, n))*dS \
        + theta*dot(avg_w(rho*d_eff*grad(psic),weight_e(rho*d_eff,n)), jump(c, n))*dS \
        + penalty1/h_avg*k_e(rho*d_eff,n)*dot(jump(c, n), jump(psic, n))*dS

    a_adv = -dot(rho*vel_c*c,grad(psic))*dx \
        + dot(jump(psic), rho('+')*vel_norm('+')*c('+') - rho('-')*vel_norm('-')*c('-') )*dS \
        + dot(psic, rho*vel_norm*c)*ds(3)

    R_c = R_c_cal(c_extrapolate, p_con, Temp)
    c_D1 = Constant(0.5)
    rhs_c = R_c * A_s_cal(phi, phi_0, A_0) * psic * dx - dot(
        rho * phi * vel_c, n) * c_D1 * psic * ds(1)

    r_u = [a_dif + a_adv]
    j_u = block_derivative(r_u, [c], [dc])

    r_u_dot = [a_time]
    j_u_dot = block_derivative(r_u_dot, [c_dot], [dc_dot])
    r = [r_u_dot[0] + r_u[0] - rhs_c]

    # this part is not applied.
    exact_solution_expression1 = Expression("1.0",
                                            t=0,
                                            element=C[0].ufl_element())

    def bc(t):
        p5 = DirichletBC(C.sub(0),
                         exact_solution_expression1,
                         boundaries,
                         1,
                         method="geometric")
        return BlockDirichletBC([p5])

    # Define problem wrapper
    class ProblemWrapper(object):
        def set_time(self, t):
            pass

        # Residual and jacobian functions
        def residual_eval(self, t, solution, solution_dot):
            return r

        def jacobian_eval(self, t, solution, solution_dot,
                          solution_dot_coefficient):
            return [[
                Constant(solution_dot_coefficient) * j_u_dot[0, 0] + j_u[0, 0]
            ]]

        # Define boundary condition
        def bc_eval(self, t):
            pass

        # Define initial condition
        def ic_eval(self):
            return solution0

        # Define custom monitor to plot the solution
        def monitor(self, t, solution, solution_dot):
            pass

    problem_wrapper = ProblemWrapper()
    (solution, solution_dot) = (block_c, block_c_dot)
    solver = TimeStepping(problem_wrapper, solution, solution_dot)
    solver.set_parameters({
        "initial_time": t_start,
        "time_step_size": dt,
        "monitor": {
            "time_step_size": monitor_dt,
        },
        "final_time": T,
        "exact_final_time": "stepover",
        "integrator_type": integrator_type,
        "problem_type": "linear",
        "linear_solver": "mumps",
        "report": True
    })
    export_solution = solver.solve()

    return export_solution, T
Ejemplo n.º 26
0
    def __ufl_forms(self, nu, f):
        (w, q, wbar, qbar) = self.__test_functions()
        (u, p, ubar, pbar) = self.__trial_functions()

        # Infer geometric dimension
        zero_vec = np.zeros(self.gdim)

        ds = self.ds
        n = self.n
        he = self.he
        alpha = self.alpha
        h_d = self.h_d
        beta_stab = self.beta_stab
        facet_integral = self.facet_integral

        pI = p * Identity(
            self.mixedL.sub(1).ufl_cell().topological_dimension())
        pbI = pbar * \
            Identity(self.mixedL.sub(1).ufl_cell().topological_dimension())

        # Upper left block
        # Contribution comes from local momentum balance
        AB = inner(2*nu*sym(grad(u)), grad(w))*dx \
            + facet_integral(dot(-2*nu*sym(grad(u))*n
                                 + (2*nu*alpha/he)*u, w)) \
            + facet_integral(dot(-2*nu*u, sym(grad(w))*n)) \
            - inner(pI, grad(w))*dx
        # Contribution comes from local mass balance
        BtF = -dot(q, div(u))*dx - \
            facet_integral(beta_stab*he/(nu+1)*dot(p, q))
        A_S = AB + BtF

        # Upper right block
        # Contribution from local momentum
        CD = facet_integral(-alpha/he*2*nu*inner(ubar, w)) \
            + facet_integral(2*nu*inner(ubar, sym(grad(w))*n)) \
            + facet_integral(dot(pbI*n, w))
        H = facet_integral(beta_stab * he / (nu + 1) * dot(pbar, q))
        G_S = CD + H

        # Transpose block
        CDT = facet_integral(- alpha/he*2*nu*inner(wbar, u)) \
            + facet_integral(2*nu*inner(wbar, sym(grad(u))*n)) \
            + facet_integral(qbar * dot(u, n))
        HT = facet_integral(beta_stab * he / (nu + 1) * dot(p, qbar))
        G_ST = CDT + HT

        # Lower right block, penalty on ds(98) approximates free-slip
        KL = facet_integral(alpha/he * 2 * nu*dot(ubar, wbar)) \
            - facet_integral(dot(pbar*n, wbar)) \
            + Constant(1E12)/he * inner(outer(ubar, wbar), outer(n, n)) * ds(98)
        LtP = - facet_integral(dot(ubar, n)*qbar) \
            - facet_integral(beta_stab*he/(nu+1) * pbar * qbar)
        B_S = KL + LtP

        # Righthandside
        Q_S = dot(f, w) * dx
        S_S = facet_integral(dot(Constant(zero_vec), wbar))
        S_S += dot(h_d[0], wbar) * ds(99) + dot(h_d[1], wbar) * ds(
            100)  #Neumann BC
        return {
            'A_S': A_S,
            'G_S': G_S,
            'G_ST': G_ST,
            'B_S': B_S,
            'Q_S': Q_S,
            'S_S': S_S
        }
Ejemplo n.º 27
0
boundary_markers = dolfin.MeshFunction('size_t', mesh, boundary_dim)
boundary_markers.set_all(0)  # Assign all elements the default value

id_subdomain_fix = 1  # Fixed boundary id
id_subdomain_msr = 2  # Loaded boundary id
id_subdomains_dic = 3  # displacement field measurement boundary id

boundary_fix.mark(boundary_markers, id_subdomain_fix)
boundary_msr.mark(boundary_markers, id_subdomain_msr)
boundary_dic.mark(boundary_markers, id_subdomains_dic)

### Integration measures

dx = dolfin.dx(domain=mesh)  # for the whole domain
ds = dolfin.ds(domain=mesh)  # for the entire boundary

ds_msr_T = dolfin.Measure('ds',
                          mesh,
                          subdomain_id=id_subdomain_msr,
                          subdomain_data=boundary_markers)

ds_msr_u = dolfin.Measure('ds',
                          mesh,
                          subdomain_id=id_subdomains_dic,
                          subdomain_data=boundary_markers)

### Finite element function spaces

V = dolfin.VectorFunctionSpace(mesh, 'CG', FINITE_ELEMENT_DEGREE)
Ejemplo n.º 28
0
        dolfin.lt((x[0] - 0.5)**2, 0.35**2), 1.0, 0.0)

bcs = [dolfin.DirichletBC(space, lower_boundary_value, lower_boundary)]

if not no_side_bc:

    def _side_bc(subdomain):
        bcs.append(dolfin.DirichletBC(space, dolfin.Constant(0.0), subdomain))

    if theta < np.pi / 2:
        _side_bc(left_boundary)
    else:
        _side_bc(right_boundary)

# alpha = dolfin.Constant(1.0)
alpha = dolfin.conditional(
    dolfin.lt((x[0] - 0.5)**2 + (x[1] - 0.5)**2, 0.2**2), 6.0, 1.0)
# alpha = dolfin.conditional(dolfin.And(dolfin.gt(x[0], 0.5), dolfin.gt(x[1], 0.5)), 4.0, 1.0)

alpha = dolfin.project(alpha, space)  # needs to be continuous
S = dolfin.Constant(0.0) * x[0]

dsf, dxf = make_form(I=u, v=test_function, omega=omega, beta=alpha, S=S)
form = dsf * dolfin.ds() + dxf * dolfin.dx()

solver = NewtonSolver(form, u, bcs)
solver.solve()

# dolfin.plot(u)
# dolfin.plot(alpha)
Ejemplo n.º 29
0
    MPI.barrier(mpicomm)
    t0 = time()
    KV = assemble(weak_V)
    MPI.barrier(mpicomm)
    t1 = time()
    if mpirank == 0: print 'Time to assemble KV = {}'.format(t1-t0)
elif myrun == 2:
    class LeftRight(SubDomain):
        def inside(self, x, on_boundary):
            return (x[0] < 1e-16 or x[0] > 1.0 - 1e-16) \
            and on_boundary
    class_bc_abc = LeftRight()
    abc_boundaryparts = FacetFunction("size_t", mesh)
    class_bc_abc.mark(abc_boundaryparts, 1)
    ds = Measure("ds")[abc_boundaryparts]
    weak_1 = inner(sqrt(lam1*rho1)*nabla_grad(trial), nabla_grad(test))*ds(1)
    weak_2 = inner(sqrt(lam2*rho2)*nabla_grad(trial), nabla_grad(test))*ds(1)

    lam1.vector()[:] = 1.0
    rho1.vector()[:] = 1.0
    print 'Start assembling K2'
    t0 = time()
    K2 = assemble(weak_2)
    t1 = time()
    print 'Time to assemble K2 = {}'.format(t1-t0)

    lam2.vector()[:] = 1.0
    rho2.vector()[:] = 1.0
    print 'Start assembling K1'
    t0 = time()
    K1 = assemble(weak_1)
def nablaT_fun(
        V,
        v,
        hol_cyl,
        A,
        boundary_faces,
        mark_in,
        mark_ex,
        T_old_v,
        g_d,  #S_in
        T_sol_d,
        T_ex,  #S_ex   
        unitNormal,
        k_mesh_old,
        cp_mesh_old,
        rho_mesh_old,
        dt,
        time_v,
        theta,
        itera,
        mesh_name,
        savings_do):
    '''
    Direct problem.
    Solves A T = L.
    A = dt * theta * 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)
        
    int_fluxT_ex = -k_mesh * do.dot(unitNormal, do.grad(T_sol)) * v * \
                         do.ds(mark_ex, 
                               domain = hol_cyl,
                               subdomain_data = boundary_faces)
                         
    no T_ex on outer boundary.                         
    '''
    #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, False)  #prints default values
    solver.parameters['relative_tolerance'] = 1e-13
    solver.parameters['maximum_iterations'] = 2000000
    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

    #T_stept = do.TrialFunction(V)
    T_step1 = do.Function(V)
    T_old = do.Function(V)

    #T_old_v is a scalar
    T_step1.vector()[:] = T_old_v
    T_old.vector()[:] = T_old_v

    T_step1_d = {}

    print 'T: min(g_d[0]) = ', min(g_d[0].vector().array())
    print 'T: max(g_d[0]) = ', max(g_d[0].vector().array())

    theta = do.Constant(theta)

    dt = do.Constant(dt)

    T_step1_f = do.File(os.path.join(savings_do, str(itera), 'dir_IHCP.pvd'))

    #A = dt / 2. * k_mesh_old * do.dot(do.grad(T_stept), do.grad(v)) * do.dx(domain = hol_cyl) + \
    #    rho_mesh_old * cp_mesh_old * T_stept * v * do.dx(domain = hol_cyl)

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

        #g is a k * dot(grad(T), n)
        int_fluxT_in = g_d[count_t_i + 1] * v * do.ds(
            mark_in, domain=hol_cyl, subdomain_data=boundary_faces)

        int_fluxT_in_old = g_d[count_t_i] * v * do.ds(
            mark_in, domain=hol_cyl, subdomain_data=boundary_faces)

        int_fluxT_ex = + k_mesh_old * do.dot(unitNormal, do.grad(T_sol_d[count_t_i + 1])) * \
                                  v * do.ds(mark_ex,
                                            domain = hol_cyl,
                                            subdomain_data = boundary_faces)

        int_fluxT_ex_old = + k_mesh_old * do.dot(unitNormal, do.grad(T_sol_d[count_t_i])) * \
                                      v * do.ds(mark_ex,
                                                domain = hol_cyl,
                                                subdomain_data = boundary_faces)

        #print 'T: type(int_fluxT_in) = ', type(int_fluxT_in)
        #print 'T: type(int_fluxT_in_old) = ', type(int_fluxT_in_old)
        #print 'T: min(int_fluxT_in) = ', min(do.assemble(int_fluxT_in))

        #L -= (int_fluxT_in + int_fluxT_ex)
        L_old = -dt * (1. - theta) * 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)

        L = L_old + (dt * theta * int_fluxT_in + dt *
                     (1. - theta) * int_fluxT_in_old +
                     dt * theta * int_fluxT_ex + dt *
                     (1. - theta) * int_fluxT_ex_old)

        do.solve(A == L, T_step1)  #, bc_ex)

        print 'T: count_t = {}, avg(g) = {}'.format(
            count_t_i, np.mean(g_d[count_t_i + 1].vector().array()))
        print 'T: count_t = {}, min(L) = {}'.format(
            count_t_i, min(do.assemble(L).array()))
        print 'T: count_t = {}, max(L) = {}'.format(
            count_t_i, max(do.assemble(L).array()))
        print 'T: count_t = {}, min(T) = {}'.format(
            count_t_i, min(T_step1.vector().array()))
        print 'T: count_t = {}, max(T) = {}'.format(
            count_t_i, max(T_step1.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'

        T_old.assign(T_step1)

        #rename
        T_step1.rename('IHCP_T', 'temperature from IHCP')

        T_step1_f << (T_step1, t_i)

    count_t_i += 1

    #storage
    T_step1_d[count_t_i] = do.Function(V)
    T_step1_d[count_t_i].vector()[:] = T_step1.vector().array()

    return T_step1_d
Ejemplo n.º 31
0
g_v = dolfin.Constant(-2.0)


# In[164]:

g_h = dolfin.Constant(1.0)


# In[165]:

L = f * v * dolfin.dx(domain=mesh, subdomain_data=boundary_parts)


# In[166]:

L += g_v * v * dolfin.ds(0, domain=mesh, subdomain_data=boundary_parts)


# In[167]:

L += g_h * v * dolfin.ds(1, domain=mesh, subdomain_data=boundary_parts)


# In[168]:

u_sol = dolfin.Function(V)


# In[169]:

dolfin.solve(a == L, u_sol, bc)
def nablap_fun(
        V,
        v,
        hol_cyl,
        A,
        boundary_faces,
        mark_ex,
        T_step_d,
        T_exp_d,  #S_ex 
        k_mesh_oldp,
        cp_mesh_oldp,
        rho_mesh_oldp,
        dt,
        time_v,
        theta,
        itera,
        mesh_name,
        savings_do):
    '''
    Adjoint problem.
    Solves A p = L.
    A = dt * theta * k_mesh * do.dot(do.grad(p), do.grad(v)) * do.dx(domain = hol_cyl) + \
        rho_mesh * cp_mesh * p * v * do.dx(domain = hol_cyl)
        
    T_stepp: from T_step flipped.
    T_exp  : from T_ex flipped.
    '''
    #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, False)  #prints default values
    solver.parameters['relative_tolerance'] = 1e-13
    solver.parameters['maximum_iterations'] = 2000000
    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

    #p_stept = do.TrialFunction(V)
    p_step2 = do.Function(V)

    #starts from 0
    p_old = do.Function(V)

    p_step2_d = {}

    #e.g., e.g., count_t_i = 100
    #storage
    p_step2_d[len(time_v) - 1] = do.Function(V)
    p_step2_d[len(time_v) - 1].vector()[:] = p_old.vector().array()

    theta = do.Constant(theta)

    dt = do.Constant(dt)

    p_step2_f = do.File(os.path.join(savings_do, str(itera), 'adj_IHCP.pvd'))

    #A = dt / 2. * k_mesh_oldp * do.dot(do.grad(p_stept), do.grad(v)) * do.dx(domain = hol_cyl) + \
    #    rho_mesh_oldp * cp_mesh_oldp * p_stept * v * do.dx(domain = hol_cyl)

    #runs backwards in time
    for count_t_i, t_i in reversed(list(enumerate(time_v[:-1]))):

        #int_fluxT_in = 0
        #e.g., count_t_i = 99
        int_fluxT_ex = (T_step_d[count_t_i] - T_exp_d[count_t_i]) * v * \
                       do.ds(mark_ex,
                             domain = hol_cyl,
                             subdomain_data = boundary_faces)

        #'old' = old tau = new time; e.g., count_t_i + 1 = 100
        int_fluxT_ex_old = (T_step_d[count_t_i + 1] - T_exp_d[count_t_i + 1]) * v * \
                           do.ds(mark_ex,
                                 domain = hol_cyl,
                                 subdomain_data = boundary_faces)

        L_oldp = -dt * (1. - theta) * k_mesh_oldp * do.dot(do.grad(p_old), do.grad(v)) * \
                 do.dx(domain = hol_cyl) + \
                 rho_mesh_oldp * cp_mesh_oldp * p_old * v * do.dx(domain = hol_cyl)

        #before:
        #L = L_oldp - (dt * theta * int_fluxT_ex + dt * (1. - theta) * int_fluxT_ex_old)
        L = L_oldp + (dt * theta * int_fluxT_ex + dt *
                      (1. - theta) * int_fluxT_ex_old)

        do.solve(A == L, p_step2)

        print 'p: count_t = {}, min(T_step_d) = {}'.format(
            count_t_i, min(T_step_d[count_t_i].vector().array()))

        print 'p: count_t = {}, max(T_step_d) = {}'.format(
            count_t_i, max(T_step_d[count_t_i].vector().array()))

        print 'p: count_t = {}, min(int_fluxT_ex) = {}'.format(
            count_t_i, min(do.assemble(int_fluxT_ex).array()))
        print 'p: count_t = {}, max(int_fluxT_ex) = {}'.format(
            count_t_i, max(do.assemble(int_fluxT_ex).array()))

        print 'p: count_t = {}, min(L) = {}'.format(
            count_t_i, min(do.assemble(L).array()))
        print 'p: count_t = {}, max(L) = {}'.format(
            count_t_i, max(do.assemble(L).array()))

        print 'p: count_t = {}, min(p) = {}'.format(count_t_i,
                                                    min(p_step2.vector()))
        print 'p: count_t = {}, max(p) = {}'.format(
            count_t_i, max(p_step2.vector())), '\n'

        p_old.assign(p_step2)

        p_step2.rename('dual_T', 'dual temperature')

        #storage
        p_step2_d[count_t_i] = do.Function(V)
        p_step2_d[count_t_i].vector()[:] = p_step2.vector().array()

        p_step2_f << (p_step2, t_i)

    return p_step2_d
        print 'err: len(keys in T_sol_d2) = ', len(T_sol_d2.keys())
        print 'err: len(keys in T_step_d2) = ', len(T_step_d2.keys())

        #update variables
        for count_t_i1, t_i1 in enumerate(time_v1):
            #heat flux
            g_d2[count_t_i1].vector()[:] = g_d2[count_t_i1].vector().array() + \
                                           alpha_step2 * p_step_d2[count_t_i1].vector().array()

            #adjoint variable
            derJ_step_old_d2[count_t_i1].vector(
            )[:] = derJ_step_d2[count_t_i1].vector().array()

            #exit criterion
            exit_crit_v[count_t_i1] = do.assemble(
                pow(alpha_step2 * p_step_d2[count_t_i1], 2.) * do.ds(
                    mark_in2, domain=hol_cyl2, subdomain_data=boundary_faces2))

            #do.File(os.path.join(savings_dol1,
            #'{}__T_from_IHCP.pvd'.format(mesh_name1.split('.')[0]))) << T_step11
            print 'err: count_t_i1 = ', count_t_i1
            #T_sol_d3 instead of T_sol_d2
            e11_v[count_t_i1], e21_v[count_t_i1] = err_est_fun(
                mesh_name2, hol_cyl2, T_sol_d3[count_t_i1],
                T_step_d2[count_t_i1], deg_choice1, hol_cyl2, count_t_i1)

        #functional
        J2 = .5 * obj_f1 + .5 * gamma_reg2 * obj_f2

        #store the error
        err_d2.append(
            [gamma_reg2_old,
def eta_fun(
        v,
        hol_cyl,
        #k, #conductivity
        gamma,  #regularization
        T_step_d,  #from direct pbm
        p_step_d,  #from adjoint pbm and gamma_CG1
        u_step_d,  #from sensitivity pbm
        boundary_faces,
        mark_in,
        mark_ex,
        g_d,
        dg_d,
        T_ex_d,
        unitNormal,
        time_v,
        cut_end,
        itera,
        path_to_do):
    '''
    Returns the optimal step size.
    
    T_step from direct problem.
    p_step from adjoint problem.
    u_step from sensitivity problem.
    '''
    num1_v = np.zeros((len(T_step_d), ))
    num2_v = np.zeros((len(T_step_d), ))
    den1_v = np.zeros((len(T_step_d), ))
    den2_v = np.zeros((len(T_step_d), ))

    for count_it in sorted(T_step_d):
        #scalar
        '''
        num1_v[count_it] = do.assemble(dg_d[count_it] * p_step_d[count_it] * 
                                       do.ds(mark_in, 
                                             domain = hol_cyl,
                                             subdomain_data = boundary_faces))
        '''

        num1_v[count_it] = do.assemble(
            (T_step_d[count_it] - T_ex_d[count_it]) * u_step_d[count_it] *
            do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces))
        #scalar
        num2_v[count_it] = do.assemble(
            p_step_d[count_it] * g_d[count_it] *
            do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces))
        #scalar
        den1_v[count_it] = do.assemble(
            pow(u_step_d[count_it], 2.) *
            do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces))
        #scalar
        den2_v[count_it] = do.assemble(
            pow(p_step_d[count_it], 2.) *
            do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces))

        print 'eta: count_t = {}, num1 = {}'.format(count_it, num1_v[count_it])
        print 'eta: count_t = {}, num2 = {}'.format(count_it, num2_v[count_it])
        print 'eta: count_t = {}, den1 = {}'.format(count_it, den1_v[count_it])
        print 'eta: count_t = {}, den2 = {}'.format(count_it,
                                                    den2_v[count_it]), '\n'

    fig_inf = plt.figure(figsize=(20, 10))

    for i_fig in xrange(12):
        vari = 1. * num1_v * (i_fig / 3 == 0) + \
               1. * num2_v * (i_fig / 3 == 1) + \
               1. * den1_v * (i_fig / 3 == 2) + \
               1. * den2_v * (i_fig / 3 == 3)

        ytag = 'num1' * (i_fig / 3 == 0) + \
               'num2' * (i_fig / 3 == 1) + \
               'den1' * (i_fig / 3 == 2) + \
               'den2' * (i_fig / 3 == 3)

        stai =  0 * (i_fig % 3 == 0) + \
                0 * (i_fig % 3 == 1) + \
              -50 * (i_fig % 3 == 2)

        endi = len(vari) * (i_fig % 3 == 0) + \
               50 * (i_fig % 3 == 1) + \
               len(vari) * (i_fig % 3 == 2)

        ax_inf = fig_inf.add_subplot(4, 3, i_fig + 1)
        ax_inf.plot(vari[stai:endi])
        ax_inf.set_ylabel(ytag)
        ax_inf.grid()

    nam_inf = os.path.join(path_to_do, 'eta_{}.pdf'.format(itera))
    fig_inf.savefig(nam_inf, dpi=150)

    num1_avg = np.trapz(num1_v[:cut_end], x=time_v[:cut_end])
    num2_avg = np.trapz(num2_v[:cut_end], x=time_v[:cut_end])
    den1_avg = np.trapz(den1_v[:cut_end], x=time_v[:cut_end])
    den2_avg = np.trapz(den2_v[:cut_end], x=time_v[:cut_end])

    return -(num1_avg + gamma * num2_avg) / (den1_avg + gamma * den2_avg)
Ejemplo n.º 35
0
import dolfin

mesh = dolfin.UnitSquareMesh(50, 20)
el = dolfin.FiniteElement("BDM", mesh.ufl_cell(), 1)
x = dolfin.SpatialCoordinate(mesh)
expr = dolfin.as_vector((dolfin.sin(1 / x[0] + x[1]), 2 * x[1]))
W = dolfin.FunctionSpace(mesh, el)
w = dolfin.project(expr, W)

example_testfunc = dolfin.TestFunction(W)
example_form = dolfin.dot(w,
                          example_testfunc) * dolfin.dx() + w[0] * dolfin.ds()
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
Ejemplo n.º 37
0
def femsolve():
    
    ''' Bilineaarinen muoto:

        a(u,v) = L(v)
        a(u,v) = (inner(grad(u), grad(v)) + u*v)*dx
        L(v) = f*v*dx - g*v*ds
        g(x) = -du/dx = -u1, x = x1
        u(x0) = u0
        Omega = {xeR|x0<=x<=x1}

    '''

    from dolfin import UnitInterval, FunctionSpace, DirichletBC, TrialFunction
    from dolfin import TestFunction, grad, Constant, Function, solve, inner, dx, ds
    from dolfin import MeshFunction, assemble
    import dolfin
#    from dolfin import set_log_level, PROCESS

    # Create mesh and define function space
    mesh = UnitInterval(30)
    V = FunctionSpace(mesh, 'Lagrange', 2)

    boundaries  = MeshFunction('uint', mesh, mesh.topology().dim()-1)

    boundaries.set_all(0)

    class Left(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14   # tolerance for coordinate comparisons
            return on_boundary and abs(x[0]) < tol

    class Right(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            return dolfin.near(x[0], 1.0)
    
    left = Left()
    right = Right()
    
    left.mark(boundaries, 1)
    right.mark(boundaries, 2)

#    def u0_boundary(x):
#        return abs(x[0]) < tol
#    
#    bc = DirichletBC(V, Constant(u0), lambda x: abs(x[0]) < tol)
    
    bcs = [DirichletBC(V, Constant(u0), boundaries, 1)]
    
    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    a = (inner(grad(u), grad(v)) + u*v)*dx
    g = Constant(-u1)
    L = Constant(f)*v*dx - g*v*ds(2)
    
 #   set_log_level(PROCESS)
    # Compute solution
    
    A = assemble(a, exterior_facet_domains=boundaries)
    b = assemble(L, exterior_facet_domains=boundaries)
    for bc in bcs: 
        bc.apply(A, b)
    
    u = Function(V)
    solve(A, u.vector(), b, 'lu')
    
    coor = mesh.coordinates()
    u_array = u.vector().array()
    a = []
    b = []
    for i in range(mesh.num_vertices()):
        a.append(coor[i])
        b.append(u_array[i])
        print('u(%3.2f) = %0.14E'%(coor[i],u_array[i]))
    
    import numpy as np
    np.savez('fem',a,b)