예제 #1
0
파일: mlmc.py 프로젝트: SpuqTeam/spuq
    def updateStatistics(self):
        for curLevel in range(len(self.space4Level)):
            samples = self.y4Level[curLevel]
            self.variance4level[curLevel] = np.var(samples, 0)
            compCost = self.space4Level[curLevel].dim() ** 2 / 1000.

            # Simple for uniform meshes
#             optSamples = self.constCompCost * np.sqrt(
#                 np.sqrt(np.sqrt(np.mean(np.abs(self.variance4level[curLevel]))) / compCost))

            # Same but for general meshes
            space = self.space4Level[curLevel]
            domainArea = assemble(interpolate(Constant(1), space) * dx)
            varianceMean = Function(space)
            varianceMean.vector().set_local(np.abs(self.variance4level[curLevel]))
            varianceIntMean = np.sqrt(assemble(varianceMean * dx) / domainArea)
            optSamples = self.constCompCost * np.sqrt(np.sqrt(
                varianceIntMean / compCost))

            # Alernate from ???
#             l = curLevel + 2
#             maxL = len(self.space4Level) + 1
#             epsOptSamples = 0.1
#             optSamples = l ** (2 + 2 * epsOptSamples) * 2 ** (2 * (maxL - l))

            self.optNumSamples4Level[curLevel] = np.rint(optSamples).astype(int)
        self.compCost4lvl[-1] = sum(list(len(samples) * (space.dim() ** 2)
            for (space, samples) in zip(self.space4Level, self.y4Level)))
예제 #2
0
def local_mass_matrix():
    # Define mesh
    mesh = UnitIntervalMesh(1)

    # Define function space
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define trial and test functions
    u = TrialFunction(V)
    v = TestFunction(V)

    # Define bilinear form
    a = (dot(grad(u), grad(v)) + u * v) * dx

    # Assemble matrix
    A = assemble(a)

    print(A.array())

    # Bilinear form for just the mass matrix part
    a2 = u * v * dx

    # Assemble mass matrix
    A2 = assemble(a2)
    print(6 * A2.array())
예제 #3
0
def _assemble_system_control_diag(a, dummy, bcs, diag_value):
    A = PETScMatrix()
    assemble(a, tensor=A)
    dummy_vec = assemble(dummy)

    for bc in bcs:
        bc.zero(A)
        bc.zero_columns(A, dummy_vec, diag_value)

    return A
예제 #4
0
def tv_reg(lmda, mu, dx, R_lmda=1, R_mu=1, eps=1e-10):

    grad_lamda = grad(lmda)
    grad_mu = grad(mu)
    integrand_lmda = R_lmda * sqrt(inner(grad_lamda, grad_lamda) + eps) * dx
    integrand_mu = R_mu * sqrt(inner(grad_mu, grad_mu) + eps) * dx
    return assemble(integrand_lmda + integrand_mu)
예제 #5
0
def tn_reg(lmda, mu, dx, R_lmda=1, R_mu=1):
    grad_lamda = grad(lmda)
    grad_mu = grad(mu)
    reg = 0.5 * R_lmda * inner(grad_lamda, grad_lamda) * dx + \
        0.5 * R_mu * inner(grad_mu, grad_mu) * dx
    Reg = assemble(reg)
    return Reg
예제 #6
0
    def estimate(self, solution):
        mesh = solution.function_space().mesh()

        # Define cell and facet residuals
        R_T = -(self.rhs_f + div(grad(solution)))
        n = FacetNormal(mesh)
        R_dT = dot(grad(solution), n)

        # Will use space of constants to localize indicator form
        Constants = FunctionSpace(mesh, "DG", 0)
        w = TestFunction(Constants)
        h = CellSize(mesh)

        # Define form for assembling error indicators
        form = (h ** 2 * R_T ** 2 * w * dx + avg(h) * avg(R_dT) ** 2 * 2 * avg(w) * dS)
    #            + h * R_dT ** 2 * w * ds)

        # Assemble error indicators
        indicators = assemble(form)

        # Calculate error
        error_estimate = sqrt(sum(i for i in indicators.array()))

        # Take sqrt of indicators
        indicators = np.array([sqrt(i) for i in indicators])

        # Mark cells for refinement based on maximal marking strategy
        largest_error = max(indicators)
        cell_markers = MeshFunction("bool", mesh, mesh.topology().dim())
        for c in cells(mesh):
            cell_markers[c] = indicators[c.index()] > (self.fraction * largest_error)

        return error_estimate, cell_markers
예제 #7
0
    def computeError4level(self, meanApprox4lvl, lastSpace, meanExact = None):
        if meanExact == None:
            solMesh = lastSpace.mesh()
            solFamily = lastSpace.ufl_element().family()
            solDegree = lastSpace.ufl_element().degree()
            refSpace = FunctionSpace(refine(refine(solMesh)), solFamily, solDegree)
            meanExact = self.solveMean(refSpace)

        refSpace = meanExact.function_space()
        error4lvl = list(
                np.sqrt(assemble(
                    (project(meanApprox, refSpace) - interpolate(meanExact, refSpace)) ** 2 * dx
                )) for meanApprox in meanApprox4lvl)

        return error4lvl
def compute_error(u1, u2):
    # Reference mesh
    mesh_resolution_ref = 500
    mesh_ref = UnitIntervalMesh(mesh_resolution_ref)

    # Reference function space
    V_ref = FunctionSpace(mesh_ref, "CG", 1)

    # Evaluate the input functions on the reference mesh
    Iu1 = interpolate(u1, V_ref)
    Iu2 = interpolate(u2, V_ref)

    # Compute the error
    e = Iu1 - Iu2
    error = sqrt(assemble(e * e * dx))
    return error
def plot_basis_function():
    # Declare mesh and FEM functions
    mesh = UnitSquareMesh(10, 10)
    V = FunctionSpace(mesh, "CG", 1)

    phi = Function(V)
    phi.vector()[:] = 0.0
    phi.vector()[10] = 1.0

    # Plot the basis function
    fig = plt.figure()
    plot(phi, fig=fig)
    plt.show()

    val = assemble(phi * phi * dx)
    print(val)
예제 #10
0
def global_stiffness_matrix():
    # Define mesh
    mesh = UnitIntervalMesh(10)

    # Define function space
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define trial and test functions
    u = TrialFunction(V)
    v = TestFunction(V)

    # Define bilinear form
    a = dot(grad(u), grad(v)) * dx

    # Assemble matrix
    A = assemble(a)

    h = 1 / 10
    print(h * A.array())
예제 #11
0
# Defining displacement space
V = VectorFunctionSpace(mesh, finiteElement.family, finiteElement.order)
# Stresss space
S = TensorFunctionSpace(mesh, finiteElement.family, finiteElement.order)

# Trial and test functions
uTrial = TrialFunction(V)
w = TestFunction(V)

# weak operators
massOp = physics.rho*inner(uTrial, w)*dx
stiffOp = inner(elasticity.stress(physics.mu, physics.lmbda, uTrial), grad(w))*dx

# Assembling
M = assemble(massOp)
R = assemble(stiffOp)

## Create zero boundary condition
#bc = DirichletBC(V, Constant(geo.nDim*[0.0]), dirichletSubdomain)

## Construct dirichlet contribution vectors
#dirichletM = PETScVector(MPI_COMM_WORLD, M.size(0))
#bc.zero(M)
#bc.zero_columns(M, dirichletM, 1)
#dirichletR = PETScVector(MPI_COMM_WORLD, R.size(0))
#bc.zero(R)
#bc.zero_columns(R, dirichletR, 1)

###
### Output configuration
예제 #12
0
def solve_navier_stokes_equation(interior_circle=True, num_mesh_refinements=0):
    """
    Solve the Navier-Stokes equation on a hard-coded mesh with hard-coded initial and boundary conditions
    """
    mesh, om, im, nm, ymax, sub_domains = setup_geometry(
        interior_circle, num_mesh_refinements)
    dsi = Measure("ds", domain=mesh, subdomain_data=sub_domains)

    # Setup FEM function spaces
    # Function space for the velocity
    V = VectorFunctionSpace(mesh, "CG", 1)
    # Function space for the pressure
    Q = FunctionSpace(mesh, "CG", 1)
    # Mixed function space for velocity and pressure
    W = V * Q

    # Setup FEM functions
    v, q = TestFunctions(W)
    w = Function(W)
    (u, p) = (as_vector((w[0], w[1])), w[2])
    u0 = Function(V)

    # Inlet velocity
    uin = Expression(("4*(x[1]*(YMAX-x[1]))/(YMAX*YMAX)", "0."),
                     YMAX=ymax,
                     degree=1)

    # Viscosity and stabilization parameters
    nu = 1e-6
    h = CellSize(mesh)
    d = 0.2 * h**(3.0 / 2.0)

    # Time parameters
    time_step = 0.1
    t_start, t_end = 0.0, 10.0

    # Penalty parameter
    gamma = 10 / h

    # Time stepping
    t = t_start
    step = 0
    while t < t_end:
        # Time discretization (Crank–Nicolson method)
        um = 0.5 * u + 0.5 * u0

        # Navier-Stokes equations in weak residual form (stabilized FEM)
        # Basic residual
        r = (inner((u - u0) / time_step + grad(p) + grad(um) * um, v) +
             nu * inner(grad(um), grad(v)) + div(um) * q) * dx
        # Weak boundary conditions
        r += gamma * (om * p * q + im * inner(u - uin, v) +
                      nm * inner(u, v)) * ds
        # Stabilization
        r += d * (inner(grad(p) + grad(um) * um,
                        grad(q) + grad(um) * v) + inner(div(um), div(v))) * dx

        # Solve the Navier-Stokes equation (one time step)
        solve(r == 0, w)

        if step % 5 == 0:
            # Plot norm of velocity at current time step
            nov = project(sqrt(inner(u, u)), Q)
            fig = plt.figure()
            plot(nov, fig=fig)
            plt.show()

            # Compute drag force on circle
            n = FacetNormal(mesh)
            drag_force_measure = p * n[0] * dsi(1)  # Drag (only pressure)
            drag_force = assemble(drag_force_measure)
            print("Drag force = " + str(drag_force))

        # Shift to next time step
        t += time_step
        step += 1
        u0 = project(u, V)
예제 #13
0
def L2_norm(u, dx):
    energy = inner(u, u) * dx
    E = assemble(energy)
    return p.sqrt(E)
예제 #14
0
# Save solution in XDMF format (to be viewed in Paraview, for example)
with XDMFFile(MPI.comm_world,
              "plane_wave.xdmf",
              encoding=XDMFFile.Encoding.HDF5) as file:
    file.write(u)
''' Calculate L2 and H1 errors of FEM solution and best approximation.
This demonstrates the error bounds given in Ihlenburg.
Pollution errors are evident for high wavenumbers.'''
# Function space for exact solution - need it to be higher than deg
V_exact = FunctionSpace(mesh, "Lagrange", deg + 3)
# "exact" solution
u_exact = interpolate(ui, V_exact)
# best approximation from V
u_BA = interpolate(ui, V)

# H1 errors
diff = u - u_exact
diff_BA = u_BA - u_exact
H1_diff = np.sqrt(assemble(inner(grad(diff), grad(diff)) * dx))
H1_BA = np.sqrt(assemble(inner(grad(diff_BA), grad(diff_BA)) * dx))
H1_exact = np.sqrt(assemble(inner(grad(u_exact), grad(u_exact)) * dx))
print('Relative H1 error of best approximation:', H1_BA / H1_exact)
print('Relative H1 error of FEM solution:', H1_diff / H1_exact)

# L2 errors
L2_diff = np.sqrt(assemble(inner(diff, diff) * dx))
L2_BA = np.sqrt(assemble(inner(diff_BA, diff_BA) * dx))
L2_exact = np.sqrt(assemble(inner(u_exact, u_exact) * dx))
print('Relative L2 error  of best approximation:', L2_BA / L2_exact)
print('Relative L2 error of FEM solution:', L2_diff / L2_exact)
                grad(w)) * dx
# basisOp = [ inner(psi, w)*ds(i) for psi in psiBasis for i in range(geo.getNoFaces()) ]
basisOp = [inner(psi, w) * ds(1) for psi in psiBasis]

## Matrices and vectors
#M = PETScMatrix()
#R = PETScMatrix()
#P = [ PETScVector() for i in range(len(basisOp)) ]

## Assembling
#assemble(massOp, tensor=M)
#assemble(stiffOp, tensor=R)
#[ assemble(basisOp[i], tensor=P[i]) for i in range(len(P)) ]

# Assembling
M = assemble(massOp)
R = assemble(stiffOp)
FPsi = [assemble(op) for op in basisOp]
nPsi = len(FPsi)

###
### Output configuration
###

outputFolder = "./new_results/"

pvdFileU = [
    File(outputFolder + "/" + str(i) + "/u_psi.pvd", "compressed")
    for i in range(nPsi)
]
pvdFileV = [
예제 #16
0
def norm(v, norm_type="L2", mesh=None):
    """
    Return the norm of a given vector or function.

    *Arguments*
        v
            a :py:class:`Vector <dolfin.cpp.Vector>` or
            a :py:class:`Function <dolfin.functions.function.Function>`.
        norm_type
            see below for alternatives.
        mesh
            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
            which to compute the norm.

    If the norm type is not specified, the standard :math:`L^2` -norm
    is computed. Possible norm types include:

    *Vectors*

    ================   =================  ================
    Norm               Usage
    ================   =================  ================
    :math:`l^2`        norm(x, 'l2')      Default
    :math:`l^1`        norm(x, 'l1')
    :math:`l^\infty`   norm(x, 'linf')
    ================   =================  ================

    *Functions*

    ================  =================  =================================
    Norm              Usage              Includes the :math:`L^2` -term
    ================  =================  =================================
    :math:`L^2`       norm(v, 'L2')      Yes
    :math:`H^1`       norm(v, 'H1')      Yes
    :math:`H^1_0`     norm(v, 'H10')     No
    :math:`H` (div)   norm(v, 'Hdiv')    Yes
    :math:`H` (div)   norm(v, 'Hdiv0')   No
    :math:`H` (curl)  norm(v, 'Hcurl')   Yes
    :math:`H` (curl)  norm(v, 'Hcurl0')  No
    ================  =================  =================================

    *Examples of usage*

    .. code-block:: python

        v = Function(V)
        x = v.vector()

        print norm(x, 'linf')   # print the infinity norm of vector x

        n = norm(v)             # compute L^2 norm of v
        print norm(v, 'Hdiv')   # print H(div) norm of v
        n = norm(v, 'H1', mesh) # compute H^1 norm of v on given mesh

    """

    # if not isinstance(v, (GenericVector, GenericFunction)):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "expected a GenericVector or GenericFunction")

    # Check arguments
    # if not isinstance(norm_type, string_types):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Norm type must be a string, not " +
    #                      str(type(norm_type)))
    # if mesh is not None and not isinstance(mesh, cpp.Mesh):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Expecting a Mesh, not " + str(type(mesh)))

    # Get mesh from function
    if isinstance(v, cpp.function.Function) and mesh is None:
        mesh = v.function_space().mesh()

    # Define integration measure and domain
    dx = ufl.dx(mesh)

    # Select norm type
    if isinstance(v, cpp.la.GenericVector):
        return v.norm(norm_type.lower())

    elif isinstance(v, ufl.Coefficient):
        if norm_type.lower() == "l2":
            M = v**2*dx
        elif norm_type.lower() == "h1":
            M = (v**2 + grad(v)**2)*dx
        elif norm_type.lower() == "h10":
            M = grad(v)**2*dx
        elif norm_type.lower() == "hdiv":
            M = (v**2 + div(v)**2)*dx
        elif norm_type.lower() == "hdiv0":
            M = div(v)**2*dx
        elif norm_type.lower() == "hcurl":
            M = (v**2 + curl(v)**2)*dx
        elif norm_type.lower() == "hcurl0":
            M = curl(v)**2*dx
        # else:
        #     cpp.dolfin_error("norms.py",
        #                      "compute norm",
        #                      "Unknown norm type (\"%s\") for functions"
        #                      % str(norm_type))
    # else:
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Unknown object type. Must be a vector or a function")

    # Assemble value
    r = assemble(M)

    # Check value
    if r < 0.0:
        pass
        # cpp.dolfin_error("norms.py",
        #                  "compute norm",
        #                  "Square of norm is negative, might be a round-off error")
    elif r == 0.0:
        return 0.0
    else:
        return sqrt(r)
예제 #17
0
def norm(v, norm_type="L2", mesh=None):
    """
    Return the norm of a given vector or function.

    *Arguments*
        v
            a :py:class:`Vector <dolfin.cpp.Vector>` or
            a :py:class:`Function <dolfin.functions.function.Function>`.
        norm_type
            see below for alternatives.
        mesh
            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
            which to compute the norm.

    If the norm type is not specified, the standard :math:`L^2` -norm
    is computed. Possible norm types include:

    *Vectors*

    ================   =================  ================
    Norm               Usage
    ================   =================  ================
    :math:`l^2`        norm(x, 'l2')      Default
    :math:`l^1`        norm(x, 'l1')
    :math:`l^\infty`   norm(x, 'linf')
    ================   =================  ================

    *Functions*

    ================  =================  =================================
    Norm              Usage              Includes the :math:`L^2` -term
    ================  =================  =================================
    :math:`L^2`       norm(v, 'L2')      Yes
    :math:`H^1`       norm(v, 'H1')      Yes
    :math:`H^1_0`     norm(v, 'H10')     No
    :math:`H` (div)   norm(v, 'Hdiv')    Yes
    :math:`H` (div)   norm(v, 'Hdiv0')   No
    :math:`H` (curl)  norm(v, 'Hcurl')   Yes
    :math:`H` (curl)  norm(v, 'Hcurl0')  No
    ================  =================  =================================

    *Examples of usage*

    .. code-block:: python

        v = Function(V)
        x = v.vector()

        print norm(x, 'linf')   # print the infinity norm of vector x

        n = norm(v)             # compute L^2 norm of v
        print norm(v, 'Hdiv')   # print H(div) norm of v
        n = norm(v, 'H1', mesh) # compute H^1 norm of v on given mesh

    """

    if not isinstance(v, (GenericVector, GenericFunction)):
        raise TypeError, "expected a GenericVector or GenericFunction"

    # Check arguments
    if not isinstance(norm_type, str):
        cpp.dolfin_error(
            "norms.py", "compute norm",
            "Norm type must be a string, not " + str(type(norm_type)))
    if mesh is not None and not isinstance(mesh, Mesh):
        cpp.dolfin_error("norms.py", "compute norm",
                         "Expecting a Mesh, not " + str(type(mesh)))

    # Select norm type
    if isinstance(v, GenericVector):
        return v.norm(norm_type.lower())

    elif (isinstance(v, Coefficient) and isinstance(v, GenericFunction)):
        if norm_type.lower() == "l2":
            M = inner(v, v) * dx()
        elif norm_type.lower() == "h1":
            M = inner(v, v) * dx() + inner(grad(v), grad(v)) * dx()
        elif norm_type.lower() == "h10":
            M = inner(grad(v), grad(v)) * dx()
        elif norm_type.lower() == "hdiv":
            M = inner(v, v) * dx() + div(v) * div(v) * dx()
        elif norm_type.lower() == "hdiv0":
            M = div(v) * div(v) * dx()
        elif norm_type.lower() == "hcurl":
            M = inner(v, v) * dx() + inner(curl(v), curl(v)) * dx()
        elif norm_type.lower() == "hcurl0":
            M = inner(curl(v), curl(v)) * dx()
        else:
            cpp.dolfin_error(
                "norms.py", "compute norm",
                "Unknown norm type (\"%s\") for functions" % str(norm_type))
    else:
        cpp.dolfin_error(
            "norms.py", "compute norm",
            "Unknown object type. Must be a vector or a function")

    # Get mesh
    if isinstance(v, Function) and mesh is None:
        mesh = v.function_space().mesh()

    # Assemble value
    r = assemble(M,
                 mesh=mesh,
                 form_compiler_parameters={"representation": "quadrature"})

    # Check value
    if r < 0.0:
        cpp.dolfin_error(
            "norms.py", "compute norm",
            "Square of norm is negative, might be a round-off error")
    elif r == 0.0:
        return 0.0
    else:
        return sqrt(r)
예제 #18
0
def norm(v, norm_type="L2", mesh=None):
    """
    Return the norm of a given vector or function.

    *Arguments*
        v
            a :py:class:`Vector <dolfin.cpp.Vector>` or
            a :py:class:`Function <dolfin.functions.function.Function>`.
        norm_type
            see below for alternatives.
        mesh
            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
            which to compute the norm.

    If the norm type is not specified, the standard :math:`L^2` -norm
    is computed. Possible norm types include:

    *Vectors*

    ================   =================  ================
    Norm               Usage
    ================   =================  ================
    :math:`l^2`        norm(x, 'l2')      Default
    :math:`l^1`        norm(x, 'l1')
    :math:`l^\infty`   norm(x, 'linf')
    ================   =================  ================

    *Functions*

    ================  =================  =================================
    Norm              Usage              Includes the :math:`L^2` -term
    ================  =================  =================================
    :math:`L^2`       norm(v, 'L2')      Yes
    :math:`H^1`       norm(v, 'H1')      Yes
    :math:`H^1_0`     norm(v, 'H10')     No
    :math:`H` (div)   norm(v, 'Hdiv')    Yes
    :math:`H` (div)   norm(v, 'Hdiv0')   No
    :math:`H` (curl)  norm(v, 'Hcurl')   Yes
    :math:`H` (curl)  norm(v, 'Hcurl0')  No
    ================  =================  =================================

    *Examples of usage*

    .. code-block:: python

        v = Function(V)
        x = v.vector()

        print norm(x, 'linf')   # print the infinity norm of vector x

        n = norm(v)             # compute L^2 norm of v
        print norm(v, 'Hdiv')   # print H(div) norm of v
        n = norm(v, 'H1', mesh) # compute H^1 norm of v on given mesh

    """

    if not isinstance(v, (GenericVector, GenericFunction)):
        raise TypeError, "expected a GenericVector or GenericFunction"

    # Check arguments
    if not isinstance(norm_type, str):
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Norm type must be a string, not " + str(type(norm_type)))
    if mesh is not None and not isinstance(mesh, Mesh):
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Expecting a Mesh, not " + str(type(mesh)))

    # Select norm type
    if isinstance(v, GenericVector):
        return v.norm(norm_type.lower())

    elif (isinstance(v, Coefficient) and isinstance(v, GenericFunction)):
        if norm_type.lower() == "l2":
            M = inner(v, v)*dx()
        elif norm_type.lower() == "h1":
            M = inner(v, v)*dx() + inner(grad(v), grad(v))*dx()
        elif norm_type.lower() == "h10":
            M = inner(grad(v), grad(v))*dx()
        elif norm_type.lower() == "hdiv":
            M = inner(v, v)*dx() + div(v)*div(v)*dx()
        elif norm_type.lower() == "hdiv0":
            M = div(v)*div(v)*dx()
        elif norm_type.lower() == "hcurl":
            M = inner(v, v)*dx() + inner(curl(v), curl(v))*dx()
        elif norm_type.lower() == "hcurl0":
            M = inner(curl(v), curl(v))*dx()
        else:
            cpp.dolfin_error("norms.py",
                             "compute norm",
                             "Unknown norm type (\"%s\") for functions" % str(norm_type))
    else:
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Unknown object type. Must be a vector or a function")

    # Get mesh
    if isinstance(v, Function) and mesh is None:
        mesh = v.function_space().mesh()

    # Assemble value
    r = assemble(M, mesh=mesh, form_compiler_parameters={"representation": "quadrature"})

    # Check value
    if r < 0.0:
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Square of norm is negative, might be a round-off error")
    elif r == 0.0:
        return 0.0
    else:
        return sqrt(r)

    # Define variational problem
    F = rho*inner(a_*N_ddot(u) + b_*N_dot(u) + c_*u, w)*dx \
        + inner(N_dot(S).T*Lambda_e + S.T*Lambda_p, grad(w))*dx \
        - inner(g, w)*ds \
        + inner(compliance(a_*N_ddot(S) + b_*N_dot(S) + c_*S), T)*dx \
        - 0.5*inner(grad(u)*Lambda_p + Lambda_p*grad(u).T + grad(N_dot(u))*Lambda_e \
        + Lambda_e*grad(N_dot(u)).T, T)*dx \
        #- inner(f, w)*dx(1) \


    a, L = lhs(F), rhs(F)

    # Assemble rhs (once)
    A = assemble(a)

    # Create GMRES Krylov solver
    solver = KrylovSolver(A, "gmres")

    # Create solution function
    S = Function(W)

    # Solving loop
    xdmf_file = XDMFFile(mesh.mpi_comm(), "output/elastodynamics.xdmf")

    if record:
        pvd  = File("paraview/{}.pvd".format(file_name))
        pvd << (u0, t)

예제 #20
0
    ]

    g = sum(pulses)

    F = rho * inner(a_ * N_ddot(u, u0, a0, v0, dt, beta) \
        + b_ * N_dot(u, u0, v0, a0, dt, beta, gamma) + c_ * u, w) * dx \
        + inner(N_dot(S, U0, V0, A0, dt, beta, gamma).T * Lambda_e + S.T * Lambda_p, grad(w)) * dx \
        - inner(g, w) * ds \
        + inner(compliance(a_ * N_ddot(S, U0, A0, V0, dt, beta) + b_ * N_dot(S, U0, V0, A0, dt, beta, gamma) + c_ * S, u, mu, lmbda), T) * dx \
        - 0.5 * inner(grad(u) * Lambda_p + Lambda_p * grad(u).T + grad(N_dot(u, u0, v0, a0, dt, beta, gamma)) * Lambda_e \
        + Lambda_e * grad(N_dot(u, u0, v0, a0, dt, beta, gamma)).T, T) * dx \

    a, L = lhs(F), rhs(F)

    # Assemble rhs (once)
    A = assemble(a)

    # Create GMRES Krylov solver
    solver = KrylovSolver(A, "gmres")

    # Create solution function
    S = Function(W)

    experiment_count_file = open("experiment_counter", 'rb')
    experiment_count = pickle.load(experiment_count_file)
    experiment_count_file.close()

    paraview_file_name = "experiment_{}".format(experiment_count)
    info_file_name = "{}_experiments_info/info_n{}.txt".format(
        type_of_medium, experiment_count)
예제 #21
0
def forward(mu_expression,
            lmbda_expression,
            rho,
            Lx=10,
            Ly=10,
            t_end=1,
            omega_p=5,
            amplitude=5000,
            center=0,
            target=False):
    Lpml = Lx / 10
    #c_p = cp(mu.vector(), lmbda.vector(), rho)
    max_velocity = 200  #c_p.max()

    stable_hx = stable_dx(max_velocity, omega_p)
    nx = int(Lx / stable_hx) + 1
    #nx = max(nx, 60)
    ny = int(Ly * nx / Lx) + 1
    mesh = mesh_generator(Lx, Ly, Lpml, nx, ny)
    used_hx = Lx / nx
    dt = stable_dt(used_hx, max_velocity)
    cfl_ct = cfl_constant(max_velocity, dt, used_hx)
    print(used_hx, stable_hx)
    print(cfl_ct)
    #time.sleep(10)
    PE = FunctionSpace(mesh, "DG", 0)
    mu = interpolate(mu_expression, PE)
    lmbda = interpolate(lmbda_expression, PE)

    m = 2
    R = 10e-8
    t = 0.0
    gamma = 0.50
    beta = 0.25

    ff = MeshFunction("size_t", mesh, mesh.geometry().dim() - 1)
    Dirichlet(Lx, Ly, Lpml).mark(ff, 1)

    # Create function spaces
    VE = VectorElement("CG", mesh.ufl_cell(), 1, dim=2)
    TE = TensorElement("DG", mesh.ufl_cell(), 0, shape=(2, 2), symmetry=True)

    W = FunctionSpace(mesh, MixedElement([VE, TE]))
    F = FunctionSpace(mesh, "CG", 2)
    V = W.sub(0).collapse()
    M = W.sub(1).collapse()

    alpha_0 = Alpha_0(m, stable_hx, R, Lpml)
    alpha_1 = Alpha_1(alpha_0, Lx, Lpml, degree=2)
    alpha_2 = Alpha_2(alpha_0, Ly, Lpml, degree=2)

    beta_0 = Beta_0(m, max_velocity, R, Lpml)
    beta_1 = Beta_1(beta_0, Lx, Lpml, degree=2)
    beta_2 = Beta_2(beta_0, Ly, Lpml, degree=2)

    alpha_1 = interpolate(alpha_1, F)
    alpha_2 = interpolate(alpha_2, F)
    beta_1 = interpolate(beta_1, F)
    beta_2 = interpolate(beta_2, F)

    a_ = alpha_1 * alpha_2
    b_ = alpha_1 * beta_2 + alpha_2 * beta_1
    c_ = beta_1 * beta_2

    Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]])
    Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]])

    a_ = alpha_1 * alpha_2
    b_ = alpha_1 * beta_2 + alpha_2 * beta_1
    c_ = beta_1 * beta_2

    Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]])
    Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]])

    # Set up boundary condition
    bc = DirichletBC(W.sub(0), Constant(("0.0", "0.0")), ff, 1)

    # Create measure for the source term
    dx = Measure("dx", domain=mesh)
    ds = Measure("ds", domain=mesh, subdomain_data=ff)

    # Set up initial values
    u0 = Function(V)
    u0.set_allow_extrapolation(True)
    v0 = Function(V)
    a0 = Function(V)
    U0 = Function(M)
    V0 = Function(M)
    A0 = Function(M)

    # Test and trial functions
    (u, S) = TrialFunctions(W)
    (w, T) = TestFunctions(W)

    g = ModifiedRickerPulse(0, omega_p, amplitude, center)

    F = rho * inner(a_ * N_ddot(u, u0, a0, v0, dt, beta) \
        + b_ * N_dot(u, u0, v0, a0, dt, beta, gamma) + c_ * u, w) * dx \
        + inner(N_dot(S, U0, V0, A0, dt, beta, gamma).T * Lambda_e + S.T * Lambda_p, grad(w)) * dx \
        - inner(g, w) * ds \
        + inner(compliance(a_ * N_ddot(S, U0, A0, V0, dt, beta) + b_ * N_dot(S, U0, V0, A0, dt, beta, gamma) + c_ * S, u, mu, lmbda), T) * dx \
        - 0.5 * inner(grad(u) * Lambda_p + Lambda_p * grad(u).T + grad(N_dot(u, u0, v0, a0, dt, beta, gamma)) * Lambda_e \
        + Lambda_e * grad(N_dot(u, u0, v0, a0, dt, beta, gamma)).T, T) * dx \

    a, L = lhs(F), rhs(F)

    # Assemble rhs (once)
    A = assemble(a)

    # Create GMRES Krylov solver
    solver = KrylovSolver(A, "gmres")

    # Create solution function
    S = Function(W)

    if target:
        xdmffile_u = XDMFFile("inversion_temporal_file/target/u.xdmf")
        pvd = File("inversion_temporal_file/target/u.pvd")
        xdmffile_u.write(u0, t)
        timeseries_u = TimeSeries(
            "inversion_temporal_file/target/u_timeseries")
    else:
        xdmffile_u = XDMFFile("inversion_temporal_file/obs/u.xdmf")
        xdmffile_u.write(u0, t)
        timeseries_u = TimeSeries("inversion_temporal_file/obs/u_timeseries")

    rec_counter = 0

    while t < t_end - 0.5 * dt:
        t += float(dt)

        if rec_counter % 10 == 0:
            print(
                '\n\rtime: {:.3f} (Progress: {:.2f}%)'.format(
                    t, 100 * t / t_end), )

        g.t = t

        # Assemble rhs and apply boundary condition
        b = assemble(L)
        bc.apply(A, b)

        # Compute solution
        solver.solve(S.vector(), b)
        (u, U) = S.split(True)

        # Update previous time step
        update(u, u0, v0, a0, beta, gamma, dt)
        update(U, U0, V0, A0, beta, gamma, dt)

        xdmffile_u.write(u, t)
        pvd << (u, t)
        timeseries_u.store(u.vector(), t)

        energy = inner(u, u) * dx
        E = assemble(energy)
        print("E = ", E)
        print(u.vector().max())