Exemplo n.º 1
0
def setup():
    vertices = numpy.zeros((8, 2))
    vertices[0] = [0, 0]
    for i in range(0, 7):
        vertices[i + 1] = [
            math.cos(cornerAngle / 6 * math.pi / 180 * i),
            math.sin(cornerAngle / 6 * math.pi / 180 * i)
        ]
    triangles = numpy.array([[2, 1, 0], [0, 3, 2], [4, 3, 0], [0, 5, 4],
                             [6, 5, 0], [0, 7, 6]])
    domain = {"vertices": vertices, "simplices": triangles}
    gridView = adaptiveGridView(leafGridView(domain))
    gridView.hierarchicalGrid.globalRefine(2)
    space = solutionSpace(gridView, order=order)

    from dune.fem.scheme import galerkin as solutionScheme
    u = TrialFunction(space)
    v = TestFunction(space)
    x = SpatialCoordinate(space.cell())

    # exact solution for this angle
    Phi = cornerAngle / 180 * pi
    phi = atan_2(x[1], x[0]) + conditional(x[1] < 0, 2 * pi, 0)
    exact = dot(x, x)**(pi / 2 / Phi) * sin(pi / Phi * phi)
    a = dot(grad(u), grad(v)) * dx

    # set up the scheme
    laplace = solutionScheme(
        [a == 0, DirichletBC(space, exact, 1)],
        solver="cg",
        parameters={"newton.linear.preconditioning.method": "jacobi"})
    uh = space.interpolate(0, name="solution")
    return uh, exact, laplace
Exemplo n.º 2
0
t = 0


# <markdowncell>
# We use *gmsh* to define the domain and then set up a first order
# scalar Lagrange space which we will use both for $\psi$ and $p$. We can
# construct general grids by either defining the grids directly in Python
# (as demonstrated in the following example) or by reading the grid from
# files using readers provided by Dune, e.g., Dune Grid Format (dgf) files
# or Gmsh files.

# <codecell>
domain = (reader.gmsh, "wave_tank.msh")
gridView  = leafGridView( domain, dimgrid=2 )
gridView.hierarchicalGrid.loadBalance()
V = solutionSpace(gridView, order=1, storage="fem")

p      = V.interpolate(0,name="p")
phi    = V.interpolate(0,name="phi")
pVec   = p.as_numpy
phiVec = phi.as_numpy


# <markdowncell>
# Next we define an operator for the stiffness matrix including the
# boundary condition which are time dependent so we use a `Constant` for
# this. We use the `BoxDirichletBC` class which is derived from the more
# general `DirichletBC` class which takes a function space, the boundary
# function $g$ as a ufl expression, and finally a description of the part
# $\Gamma_D$ of the boundary where this boundary condition is defined.
# This can be a ufl expression which evaluates to $0$ for
Exemplo n.º 3
0
import ufl
from ufl import grad, dot, dx, inner, Identity, sqrt, sin, pi, cos
import dune.ufl
import dune.grid
import dune.fem
from dune.alugrid import aluConformGrid as leafGridView
from dune.fem.view import geometryGridView
from dune.fem.space import lagrange as solutionSpace
from dune.fem.scheme import galerkin as solutionScheme

order = 3
storage = "istl"
# setup reference surface
referenceView = leafGridView("sphere.dgf", dimgrid=2, dimworld=3)
space = solutionSpace(referenceView,
                      dimRange=referenceView.dimWorld,
                      order=order,
                      storage=storage)

# setup deformed surface
x = ufl.SpatialCoordinate(space)
# positions = space.interpolate(x, name="position")
positions = space.interpolate(
    x * (1 + 0.5 * sin(2 * pi * (x[0] + x[1])) * cos(0.25 * pi * x[2])),
    name="position")
gridView = geometryGridView(positions)
space = solutionSpace(gridView,
                      dimRange=gridView.dimWorld,
                      order=order,
                      storage=storage)

u = ufl.TrialFunction(space)
Exemplo n.º 4
0
import dune.fem as fem
from dune.grid import cartesianDomain
from dune.alugrid import aluConformGrid as leafGridView
from dune.fem.view import adaptiveLeafGridView as adaptiveGridView
from dune.fem.space import lagrange as solutionSpace

fem.parameter.append({"fem.verboserank": -1})

order = 1
dimDomain = 2  # we are solving this in 2D
dimRange = 2  # we have a system with two unknowns
domain = cartesianDomain(
    [4, 4], [8, 8], [40, 40])  # fails with 20x20 in adapt due to petsc error
gridView = adaptiveGridView(leafGridView(domain, dimgrid=dimDomain))
space = solutionSpace(gridView,
                      dimRange=dimRange,
                      order=order,
                      storage="petscadapt")

# <markdowncell>
# We want to solve the following system of equations of variables $\phi$ (phase field) and $T$ (temperature field)
#
# \begin{gather*}
# \tau \frac{\partial \phi}{\partial t} = \nabla \cdot D \nabla \phi + \phi(1-\phi)m(\phi, T), \\
# \frac{\partial T}{\partial t} = D_T \nabla^2 T + \frac{\partial \phi}{\partial t},
# \end{gather*}
#
# where $D_T$ = 2.25, m is given by
#
# \begin{equation*}
# m(\phi, T) = \phi - \frac{1}{2} - \frac{\kappa_1}{\pi} \arctan(\kappa_2 T),
# \end{equation*}
Exemplo n.º 5
0
# field:

# <codecell>
import matplotlib
matplotlib.rc('image', cmap='jet')
from matplotlib import pyplot
from dune.fem.plotting import plotPointData as plot
from dune.grid import structuredGrid as leafGridView
from dune.fem.space import lagrange as solutionSpace
from dune.fem.scheme import galerkin as solutionScheme

from ufl import *
import dune.ufl

gridView = leafGridView([0, 0], [1, 0.15], [100, 15])
space = solutionSpace(gridView, dimRange=2, order=2, storage="istl")
displacement = space.interpolate([0, 0], name="displacement")

# <markdowncell>
# We want clamped boundary conditions on the left, i.e., zero displacement

# <codecell>
x = SpatialCoordinate(space)
dbc = dune.ufl.DirichletBC(space, as_vector([0, 0]), x[0] < 1e-10)

# <markdowncell>
# Next we define the variational problem starting with a few constants
# describing material properties ($\mu,\lambda,\rho$) and the gravitational
# force

# <codecell>
Exemplo n.º 6
0
except ImportError:  # pygmsh not installed - use a simple cartesian domain
    from dune.grid import cartesianDomain
    domain3d = cartesianDomain([-0.25, -0.25, 0], [0.25, 0.25, 1],
                               [30, 30, 60])

from dune.alugrid import aluSimplexGrid as leafGridView3d
gridView3d = leafGridView3d(domain3d)

# <markdowncell>
# As before we solve a simple Laplace problem
# <codecell>
from dune.fem.space import lagrange as solutionSpace
from dune.fem.scheme import galerkin as solutionScheme
from ufl import TrialFunction, TestFunction, SpatialCoordinate, dot, grad, dx, conditional, sqrt

space3d = solutionSpace(gridView3d, order=1)
u = TrialFunction(space3d)
v = TestFunction(space3d)
x = SpatialCoordinate(space3d)
scheme3d = solutionScheme((dot(grad(u), grad(v)) + u * v) *
                          dx == conditional(dot(x, x) < .01, 100, 0) * v * dx,
                          solver='cg')
uh3d = space3d.interpolate([0], name="solution")
info = scheme3d.solve(target=uh3d)

# <markdowncell>
# Instead of plotting this using paraview we want to only study the
# solution along a single line. This requires findings points
# $x_i = x_0+\frac{i}{N}(x1-x0)$ for $i=0,\dots,N$ within the unstructured
# grid. This would be expensive to compute on the Python so we implement
# this algorithm in C++ using the `LineSegmentSampler` class available in
Exemplo n.º 7
0
# <markdowncell>
# Now we can setup the functional which will be $J(v)=v(P)$ where
# $P=(0.4,0.4)$ is some point in the computational domain at which we want
# to minimize the error. To compute the dwr estimator we need the solution
# to the dual problem with right hand side $J(\varphi_i)$ for all basis
# functions $\varphi_i$. This is not directly expressible in UFL and we
# therefore implement this using a small C++ function which we then export
# to Python:
#
# .. literalinclude:: laplace-dwr.hh
#
# <codecell>

from dune.fem.scheme import galerkin as solutionScheme
spaceZ = solutionSpace(uh.space.grid, order=order + 1)
u = TrialFunction(spaceZ)
v = TestFunction(spaceZ)
x = SpatialCoordinate(spaceZ)
a = dot(grad(u), grad(v)) * dx
dual = solutionScheme([a == 0, DirichletBC(spaceZ, 0)], solver="cg")
z = spaceZ.interpolate(0, name="dual")
zh = uh.copy(name="dual_h")
point = common.FieldVector([0.4, 0.4])
pointFunctional = z.copy("dual_rhs")
eh = expression2GF(uh.space.grid, abs(exact - uh), order=order + 1)
computeFunctional = algorithm.load("pointFunctional", "laplace-dwr.hh", point,
                                   pointFunctional, eh)

# <markdowncell>
# <codecell>
Exemplo n.º 8
0
gridView.writeVTK('exact', pointdata={'exact': exact})

from dune.fem.function import uflFunction
exact_gf = uflFunction(gridView, name="ufl", order=1, ufl=exact)
mass = 0
for element in gridView.elements:
  mass += exact_gf(element,[0.5,0.5]) * element.geometry.volume
print(mass)

# <markdowncell>
# ## Discrete Spaces
# Setting up a discrete function space and some grid function
# <codecell>

from dune.fem.space import lagrange as solutionSpace
space = solutionSpace(gridView, order=2)

# <markdowncell>
# So far we used grid functions defined globally. An important subclass of
# grid functions are discrete functions over a given discrete function space.
# The easiest way to construct such functions is to use the interpolate
# method on the discrete function space.
# <codecell>

u_h = space.interpolate(exact, name='u_h')

# <markdowncell>
# If a discrete function is already available it is possible to call `copy`
# to obtain further discrete functions:
# <codecell>
Exemplo n.º 9
0
def calculate(use_cpp, gridView):
    # space on Gamma_0 to describe position of Gamma(t)
    space = solutionSpace(gridView, dimRange=gridView.dimWorld, order=order)
    u = TrialFunction(space)
    v = TestFunction(space)
    x = SpatialCoordinate(space.cell())
    positions = space.interpolate(x, name="position")

    # space for discrete solution on Gamma(t)
    surface = geoGridView(positions)
    space = solutionSpace(surface, dimRange=surface.dimWorld, order=order)
    solution = space.interpolate(x, name="solution")

    # set up model using theta scheme
    theta = 0.5  # Crank-Nicholson

    I = Identity(3)
    dt = dune.ufl.Constant(0, "dt")

    a = (inner(u - x, v) + dt * inner(theta * grad(u) +
                                      (1 - theta) * I, grad(v))) * dx

    scheme = solutionScheme(a == 0, space, solver="cg")

    Rexact = lambda t: math.sqrt(R0 * R0 - 4. * t)
    radius = switchCalcRadius(use_cpp, surface)

    scheme.model.dt = 0.02

    numberOfLoops = 3
    times = np.zeros(numberOfLoops)
    errors = np.zeros(numberOfLoops)
    totalIterations = np.zeros(numberOfLoops, np.dtype(np.uint32))
    gridSizes = np.zeros(numberOfLoops, np.dtype(np.uint32))
    for i in range(numberOfLoops):
        positions.interpolate(x * (R0 / sqrt(dot(x, x))))
        solution.interpolate(x)
        t = 0.
        error = abs(radius(surface) - Rexact(t))
        iterations = 0
        start = time.time()
        while t < endTime:
            info = scheme.solve(target=solution)
            # move the surface
            positions.dofVector.assign(solution.dofVector)
            # store some information about the solution process
            iterations += int(info["linear_iterations"])
            t += scheme.model.dt
            error = max(error, abs(radius(surface) - Rexact(t)))
        print("time used:", time.time() - start)
        times[i] = time.time() - start
        errors[i] = error
        totalIterations[i] = iterations
        gridSizes[i] = gridView.size(2)
        if i < numberOfLoops - 1:
            gridView.hierarchicalGrid.globalRefine(1)
            scheme.model.dt /= 2
    eocs = np.log(errors[0:][:numberOfLoops - 1] / errors[1:]) / math.log(
        math.sqrt(2))
    try:
        import pandas as pd
        keys = {
            'size': gridSizes,
            'error': errors,
            "eoc": np.insert(eocs, 0, None),
            'iterations': totalIterations
        }
        table = pd.DataFrame(keys,
                             index=range(numberOfLoops),
                             columns=['size', 'error', 'eoc', 'iterations'])
        print(table)
    except ImportError:
        print("pandas could not be used to show table with results")
        pass
    return gridSizes, times
Exemplo n.º 10
0
# <codecell>
order = 2
R0 = 2.


# <markdowncell>
# We begin by setting up reference domain $\Gamma_0$ (```grid```), and the space on $\Gamma_0$ that describes $\Gamma(t)$ (```space```). From this we interpolate the non-spherical initial surface ```positions```, and, then reconstruct ```space``` for the discrete solution on $\Gamma(t)$.


# <codecell>
from dune.fem.view import geometryGridView
from dune.fem.space import lagrange as solutionSpace
from dune.alugrid import aluConformGrid as leafGridView
gridView = leafGridView("sphere.dgf", dimgrid=2, dimworld=3)
space = solutionSpace(gridView, dimRange=gridView.dimWorld, order=order)
u = TrialFunction(space)
v = TestFunction(space)
x = SpatialCoordinate(space)
# positions = space.interpolate(x * (1 + 0.5*sin(2*pi*x[0]*x[1])* cos(pi*x[2])), name="position")
positions = space.interpolate(x * (1 + 0.5*sin(2*pi*(x[0]+x[1]))*cos(0.25*pi*x[2])), name="position")
surface = geometryGridView(positions)
space = solutionSpace(surface, dimRange=surface.dimWorld, order=order)
solution = space.interpolate(x, name="solution")


# <markdowncell>
# We set up the theta scheme with $\theta = 0.5$ (Crank-Nicholson).


# <codecell>
Exemplo n.º 11
0
import matplotlib

matplotlib.rc('image', cmap='jet')

import dune.fem as fem
from dune.grid import cartesianDomain
from dune.alugrid import aluConformGrid as leafGridView
from dune.fem.view import adaptiveLeafGridView as adaptiveGridView
from dune.fem.space import lagrange as solutionSpace

order = 1
dimDomain = 2  # we are solving this in 2D
dimRange = 2  # we have a system with two unknowns
domain = cartesianDomain([4, 4], [8, 8], [3, 3])
gridView = adaptiveGridView(leafGridView(domain))
space = solutionSpace(gridView, dimRange=dimRange, order=order, storage="fem")

# <markdowncell>
# We want to solve the following system of equations of variables $\phi$ (phase field) and $T$ (temperature field)
#
# \begin{equation}
# \begin{aligned}
# \tau \frac{\partial \phi}{\partial t} &= \nabla \cdot D \nabla \phi + \phi(1-\phi)m(\phi, T), \\
# \frac{\partial T}{\partial t} &= D_T \nabla^2 T + \frac{\partial \phi}{\partial t},
# \end{aligned}
# \end{equation}
#
# where $D_T$ = 2.25, m is given by
#
# \begin{equation*}
# m(\phi, T) = \phi - \frac{1}{2} - \frac{\kappa_1}{\pi} \arctan(\kappa_2 T),