コード例 #1
0
ファイル: KineticEnergySGS.py プロジェクト: maalidoost/Oasis
def les_setup(u_, mesh, KineticEnergySGS, assemble_matrix, CG1Function,
              nut_krylov_solver, bcs, **NS_namespace):
    """
    Set up for solving the Kinetic Energy SGS-model.
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)
    dim = mesh.geometry().dim()
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().axpy(1.0, assemble(TestFunction(DG) * dx))
    delta.vector().set_local(delta.vector().array()**(1. / dim))
    delta.vector().apply('insert')

    Ck = KineticEnergySGS["Ck"]
    ksgs = interpolate(Constant(1E-7), CG1)
    bc_ksgs = DirichletBC(CG1, 0, "on_boundary")
    A_mass = assemble_matrix(TrialFunction(CG1) * TestFunction(CG1) * dx)
    nut_form = Ck * delta * sqrt(ksgs)
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form,
                       mesh,
                       method=nut_krylov_solver,
                       bcs=bcs_nut,
                       bounded=True,
                       name="nut")
    At = Matrix()
    bt = Vector(nut_.vector())
    ksgs_sol = KrylovSolver("bicgstab", "additive_schwarz")
    #ksgs_sol.parameters["preconditioner"]["structure"] = "same_nonzero_pattern"
    ksgs_sol.parameters["error_on_nonconvergence"] = False
    ksgs_sol.parameters["monitor_convergence"] = False
    ksgs_sol.parameters["report"] = False
    del NS_namespace
    return locals()
コード例 #2
0
def solver_setup(F_fluid_linear, F_fluid_nonlinear, F_solid_linear,
                 F_solid_nonlinear, DVP, dvp_, up_sol, compiler_parameters,
                 **namespace):
    """
    Pre-assemble the system of equations for the Jacobian matrix for the Newton solver
    """
    F_lin = F_fluid_linear + F_solid_linear
    F_nonlin = F_solid_nonlinear + F_fluid_nonlinear
    F = F_lin + F_nonlin

    chi = TrialFunction(DVP)
    J_linear = derivative(F_lin, dvp_["n"], chi)
    J_nonlinear = derivative(F_nonlin, dvp_["n"], chi)

    A_pre = assemble(J_linear,
                     form_compiler_parameters=compiler_parameters,
                     keep_diagonal=True)
    A = Matrix(A_pre)
    b = None

    # Option not available in FEniCS 2018.1.0
    # up_sol.parameters['reuse_factorization'] = True

    return dict(F=F,
                J_nonlinear=J_nonlinear,
                A_pre=A_pre,
                A=A,
                b=b,
                up_sol=up_sol)
コード例 #3
0
def weighted_gradient_matrix(mesh, i, family='CG', degree=1, constrained_domain=None):
    """Compute weighted gradient matrix

    The matrix allows you to compute the gradient of a P1 Function
    through a simple matrix vector product

    CG family:
        p_ is the pressure solution on CG1
        dPdX = weighted_gradient_matrix(mesh, 0, 'CG', degree)
        V = FunctionSpace(mesh, 'CG', degree)
        dpdx = Function(V)
        dpdx.vector()[:] = dPdX * p_.vector()

        The space for dpdx must be continuous Lagrange of some order

    CR family:
        p_ is the pressure solution on CR
        dPdX = weighted_gradient_matrix(mesh, 0, 'CR', 1)
        V = FunctionSpace(mesh, 'CR', 1)
        dpdx = Function(V)
        dpdx.vector()[:] = dPdX * p_.vector()

    """

    DG = FunctionSpace(mesh, 'DG', 0)

    if family == 'CG':
        # Source and Target spaces are CG_1 and CG_degree
        S = FunctionSpace(mesh, 'CG', 1, constrained_domain=constrained_domain)
        T = FunctionSpace(mesh, 'CG', degree, constrained_domain=constrained_domain)
    elif family == 'CR':
        if degree != 1:
            print('\033[1;37;34m%s\033[0m' % 'Ignoring degree')

        # Source and Target spaces are CR
        S = FunctionSpace(mesh, 'CR', 1, constrained_domain=constrained_domain)
        T = S
    else:
        raise ValueError('Only CG and CR families are allowed.')

    G = assemble(TrialFunction(DG)*TestFunction(T)*dx)
    dg = Function(DG)
    if isinstance(i, (tuple, list)):
        CC = []
        for ii in i:
            dP = assemble(TrialFunction(S).dx(ii)*TestFunction(DG)*dx)
            A = Matrix(G)
            Cp = compiled_gradient_module.compute_weighted_gradient_matrix(A, dP, dg)
            CC.append(Cp)
        return CC
    else:
        dP = assemble(TrialFunction(S).dx(i)*TestFunction(DG)*dx)        
        Cp = compiled_gradient_module.compute_weighted_gradient_matrix(G, dP, dg)
        #info(G, True)        
        #info(dP, True)        
        return Cp
コード例 #4
0
  def assemble(a):
    """
    Assemles a _DofForm_.

    *Arguments*
        a
            _DofForm_ to assemble.
    """
    A = 0
    if a.rank() == 2:
      A = Matrix()
    elif a.rank() == 1:
      A = Vector()

    cpp.DofAssembler.assemble(A, a, True)
    return A
コード例 #5
0
ファイル: utils.py プロジェクト: pezzus/fimh2021
def gaussian_distribution(mb,
                          mu,
                          sigma,
                          function=None,
                          lumping=True,
                          nsteps=100):
    "Gaussian distribution via heat equation"

    tend = 0.5 * sigma**2
    dt = Constant(tend / nsteps, name="smooth")

    # prepare the problem
    P1e = FiniteElement("CG", mb.ufl_cell(), 1)
    Ve = FunctionSpace(mb, P1e)

    u, v = TrialFunction(Ve), TestFunction(Ve)
    uold = Function(Ve)

    if lumping:
        # diffusion
        K = assemble(dt * inner(grad(u), grad(v)) * dx)
        # we use mass lumping to avoid negative values
        Md = assemble(action(u * v * dx, Constant(1.0)))
        # full matrix (divide my mass)
        M = Matrix(K)
        M.zero()
        M.set_diagonal(Md)
        A = M + K
    else:
        a = u * v * dx + dt * inner(grad(u), grad(v)) * dx
        L = uold * v * dx
        A = assemble(a)

    # initial conditions
    dist = function or Function(Ve)

    dist.vector().zero()
    PointSource(Ve, mu, 1.0).apply(dist.vector())

    # iterations
    for t in range(nsteps):
        uold.assign(dist)
        if lumping:
            solve(A, dist.vector(), M * uold.vector())
        else:
            b = assemble(L)
            solve(A, dist.vector(), b)

    # normalize
    area = assemble(dist * dx)
    dist.vector()[:] /= area

    if function is None:
        return dist
コード例 #6
0
ファイル: utilities.py プロジェクト: yonghoonlee/Oasis
    def __init__(self, u_, Space, bcs=[], name="div", method={}):

        solver_type = method.get('solver_type', 'cg')
        preconditioner_type = method.get('preconditioner_type', 'default')
        solver_method = method.get('method', 'default')
        low_memory_version = method.get('low_memory_version', False)

        OasisFunction.__init__(self,
                               div(u_),
                               Space,
                               bcs=bcs,
                               name=name,
                               method=solver_method,
                               solver_type=solver_type,
                               preconditioner_type=preconditioner_type)

        Source = u_[0].function_space()
        if not low_memory_version:
            self.matvec = [[
                A_cache[(self.test * TrialFunction(Source).dx(i) * dx, ())],
                u_[i]
            ] for i in range(Space.mesh().geometry().dim())]

        if solver_method.lower() == "gradient_matrix":
            from fenicstools import compiled_gradient_module
            DG = FunctionSpace(Space.mesh(), 'DG', 0)
            G = assemble(TrialFunction(DG) * self.test * dx())
            dg = Function(DG)
            self.WGM = []
            st = TrialFunction(Source)
            for i in range(Space.mesh().geometry().dim()):
                dP = assemble(st.dx(i) * TestFunction(DG) * dx)
                A = Matrix(G)
                self.WGM.append(
                    compiled_gradient_module.compute_weighted_gradient_matrix(
                        A, dP, dg))
コード例 #7
0
ファイル: scipy_solver.py プロジェクト: MiroK/krylov-solver
np.set_printoptions(formatter={'all': lambda x: '%.5E' % x})

def copy_to_vector(U, U_array):
    assert U.size() == len(U_array)
    U.set_local(U_array)
    U.apply('')

# Get the forms
# a, L, V, bc, Z = neumann_poisson_data()

a, L, V, bc, Z = neumann_elasticity_data()

# Turn to dolfin.la objects
parameters.linear_algebra_backend = 'uBLAS'  # this one provides Matrix.data
A, b = Matrix(), Vector()
assemble_system(a, L, A_tensor=A, b_tensor=b)

# Turn to scipy objects
rows, cols, values = A.data()
AA = csr_matrix((values, cols, rows))

bb = np.array(b.array())

# Okay, first claim is that CG solver can't solve the problem Ax=b if the
# rhs is not perpendicular to the nullspace
ZZ = [np.array(Zi.array()) for Zi in Z]

for ZZi in ZZ:
    print '<b, Zi> =', ZZi.dot(bb)
x, info = la.cg(AA, bb)