Beispiel #1
0
 def setUp(self):
   super().setUp()
   domain, geom = mesh.rectilinear([numpy.linspace(0,1,9)] * 2)
   gauss = domain.sample('gauss', 5)
   uin = geom[1] * (1-geom[1])
   dx = function.J(geom, 2)
   ubasis = domain.basis('std', degree=2)
   pbasis = domain.basis('std', degree=1)
   if self.single:
     ubasis, pbasis = function.chain([ubasis.vector(2), pbasis])
     dofs = function.Argument('dofs', [len(ubasis)])
     u = ubasis.dot(dofs)
     p = pbasis.dot(dofs)
     dofs = 'dofs'
     ures = gauss.integral((self.viscosity * (ubasis.grad(geom) * (u.grad(geom) + u.grad(geom).T)).sum([-1,-2]) - ubasis.div(geom) * p) * dx)
     dres = gauss.integral((ubasis * (u.grad(geom) * u).sum(-1)).sum(-1) * dx)
   else:
     u = (ubasis[:,numpy.newaxis] * function.Argument('dofs', [len(ubasis), 2])).sum(0)
     p = (pbasis * function.Argument('pdofs', [len(pbasis)])).sum(0)
     dofs = 'dofs', 'pdofs'
     ures = gauss.integral((self.viscosity * (ubasis[:,numpy.newaxis].grad(geom) * (u.grad(geom) + u.grad(geom).T)).sum(-1) - ubasis.grad(geom) * p) * dx)
     dres = gauss.integral(ubasis[:,numpy.newaxis] * (u.grad(geom) * u).sum(-1) * dx)
   pres = gauss.integral((pbasis * u.div(geom)) * dx)
   cons = solver.optimize('dofs', domain.boundary['top,bottom'].integral((u**2).sum(), degree=4), droptol=1e-10)
   cons = solver.optimize('dofs', domain.boundary['left'].integral((u[0]-uin)**2 + u[1]**2, degree=4), droptol=1e-10, constrain=cons)
   self.cons = cons if self.single else {'dofs': cons}
   stokes = solver.solve_linear(dofs, residual=ures + pres if self.single else [ures, pres], constrain=self.cons)
   self.arguments = dict(dofs=stokes) if self.single else stokes
   self.residual = ures + dres + pres if self.single else [ures + dres, pres]
   inertia = gauss.integral(.5 * (u**2).sum(-1) * dx).derivative('dofs')
   self.inertia = inertia if self.single else [inertia, None]
   self.tol = 1e-10
   self.dofs = dofs
   self.frozen = types.frozenarray if self.single else solver.argdict
 def setUp(self):
     super().setUp()
     domain, geom = mesh.rectilinear([numpy.linspace(0, 1, 9)] * 2)
     ubasis = domain.basis('std', degree=2)
     if self.vector:
         u = ubasis.vector(2).dot(
             function.Argument('dofs', [len(ubasis) * 2]))
     else:
         u = (ubasis[:, numpy.newaxis] *
              function.Argument('dofs', [len(ubasis), 2])).sum(0)
     Geom = geom * [1.1, 1] + u
     self.cons = solver.optimize('dofs',
                                 domain.boundary['left,right'].integral(
                                     (u**2).sum(0), degree=4),
                                 droptol=1e-15)
     self.boolcons = ~numpy.isnan(self.cons)
     strain = .5 * (function.outer(Geom.grad(geom), axis=1).sum(0) -
                    function.eye(2))
     self.energy = domain.integral(
         ((strain**2).sum([0, 1]) + 20 *
          (function.determinant(Geom.grad(geom)) - 1)**2) *
         function.J(geom),
         degree=6)
     self.residual = self.energy.derivative('dofs')
     self.tol = 1e-10
Beispiel #3
0
def subs0(f):
    if isinstance(f, function.Argument) and f._name == 'lhs':
        return function.Argument(name='lhs0', shape=f.shape, nderiv=f._nderiv)
    if isinstance(f, function.Argument) and f._name == 'meshdofs':
        return function.Argument(name='oldmeshdofs',
                                 shape=f.shape,
                                 nderiv=f._nderiv)
    if isinstance(f, function.Argument) and f._name == 'oldmeshdofs':
        return function.Argument(name='oldoldmeshdofs',
                                 shape=f.shape,
                                 nderiv=f._nderiv)
    if isinstance(f, function.Argument) and f._name == 'oldoldmeshdofs':
        return function.Argument(name='oldoldoldmeshdofs',
                                 shape=f.shape,
                                 nderiv=f._nderiv)
Beispiel #4
0
 def setUp(self):
     super().setUp()
     domain, geom = mesh.rectilinear([numpy.linspace(0, 1, 9)] * 2)
     ubasis, pbasis = function.chain([
         domain.basis('std', degree=2).vector(2),
         domain.basis('std', degree=1),
     ])
     dofs = function.Argument('dofs', [len(ubasis)])
     u = ubasis.dot(dofs)
     p = pbasis.dot(dofs)
     viscosity = 1e-3
     self.inertia = domain.integral((ubasis * u).sum(-1) * function.J(geom),
                                    degree=5)
     stokesres = domain.integral(
         (viscosity * (ubasis.grad(geom) *
                       (u.grad(geom) + u.grad(geom).T)).sum([-1, -2]) -
          ubasis.div(geom) * p + pbasis * u.div(geom)) * function.J(geom),
         degree=5)
     self.residual = stokesres + domain.integral(
         (ubasis *
          (u.grad(geom) * u).sum(-1) * u).sum(-1) * function.J(geom),
         degree=5)
     self.cons = domain.boundary['top,bottom'].project([0,0], onto=ubasis, geometry=geom, ischeme='gauss4') \
               | domain.boundary['left'].project([geom[1]*(1-geom[1]),0], onto=ubasis, geometry=geom, ischeme='gauss4')
     self.lhs0 = solver.solve_linear('dofs',
                                     residual=stokesres,
                                     constrain=self.cons)
     self.tol = 1e-10
Beispiel #5
0
 def test_nonlinear_diagonalshift(self):
     nelems = 10
     domain, geom = mesh.rectilinear([nelems, 1])
     geom *= [2 * numpy.pi / nelems, 1]
     ubasis = domain.basis('spline', degree=2).vector(2)
     u = ubasis.dot(function.Argument('dofs', [len(ubasis)]))
     Geom = [.5 * geom[0], geom[1] + function.cos(geom[0])
             ] + u  # compress by 50% and buckle
     cons = solver.minimize('dofs',
                            domain.boundary['left,right'].integral(
                                (u**2).sum(0), degree=4),
                            droptol=1e-15).solve()
     strain = .5 * (function.outer(Geom.grad(geom), axis=1).sum(0) -
                    function.eye(2))
     energy = domain.integral(
         ((strain**2).sum([0, 1]) + 150 *
          (function.determinant(Geom.grad(geom)) - 1)**2) *
         function.J(geom),
         degree=6)
     nshift = 0
     for iiter, (lhs, info) in enumerate(
             solver.minimize('dofs', energy, constrain=cons)):
         self.assertLess(iiter, 38)
         if info.shift:
             nshift += 1
         if info.resnorm < self.tol:
             break
     self.assertEqual(nshift, 9)
Beispiel #6
0
 def setUp(self):
   super().setUp()
   domain, geom = mesh.rectilinear([8,8])
   basis = domain.basis('std', degree=1)
   self.cons = domain.boundary['left'].project(0, onto=basis, geometry=geom, ischeme='gauss2')
   dofs = function.Argument('dofs', [len(basis)])
   u = basis.dot(dofs)
   self.residual = domain.integral((basis.grad(geom) * u.grad(geom)).sum(-1)*function.J(geom), degree=2) \
                 + domain.boundary['top'].integral(basis*function.J(geom), degree=2)
Beispiel #7
0
def method_library(g, method='Elliptic', degree=None):
    assert len(g) == 2

    if degree is None:
        degree = g.ischeme * 4

    target = function.Argument('target', [len(g.x)])

    if method in ['Elliptic', 'Elliptic_unscaled']:
        G = metric_tensor(g, target)
        J = jacobian(g, target)
        ((g11, g12), (g21, g22)) = G
        s = function.stack
        G = s([s([g22, -g12]), s([-g12, g11])], axis=1)
        lapl = (J.grad(g.geom) * G[None]).sum([1, 2])
        res = (g.basis.vector(2) * lapl).sum(-1)
        res /= (1 if method == 'Elliptic_unscaled' else (g11 + g22 + 0.0001))
        res = g.domain.integral(res, geometry=g.geom, degree=degree)

    elif method == 'Elliptic_forward':
        res = function.trace(metric_tensor(g, target))
        res = g.domain.integral(res, geometry=g.geom,
                                degree=degree).derivative('target')

    elif method == 'Winslow':
        res = function.trace(metric_tensor(g, target)) / function.determinant(
            jacobian(g, target))
        res = g.domain.integral(res, geometry=g.geom,
                                degree=degree).derivative('target')

    elif method == 'Elliptic_partial':
        x = g.basis.vector(2).dot(target)
        res = (g.basis.vector(2).grad(x) * (g.geom.grad(x)[None])).sum([1, 2])
        res = g.domain.integral(res, geometry=x, degree=degree)

    elif method == 'Liao':
        G = metric_tensor(g, target)
        ((g11, g12), (g21, g22)) = G
        res = g.domain.integral(g11**2 + 2 * g12**2 + g22**2,
                                geometry=g.geom,
                                degree=degree).derivative('target')

    else:
        raise 'Unknown method {}'.format(method)

    return res
Beispiel #8
0
def subs00(f):
    if isinstance(f, function.Argument) and f._name == 'lhs':
        return function.Argument(name='lhs00', shape=f.shape, nderiv=f._nderiv)
Beispiel #9
0
def elliptic_control_mapping(g,
                             f,
                             eps=1e-4,
                             ltol=1e-5,
                             degree=None,
                             **solveargs):
    '''
        Nutils implementation of the corresponding method from the ``fsol`` module.
        It's slower but accepts any control mapping function. Unline in the ``fsol``
        case, all derivatives are computed automatically.
    '''

    assert len(g) == len(f) == 2
    assert eps >= 0

    if degree is None:
        degree = 4 * g.ischeme

    if isinstance(f, go.TensorGridObject):
        if not (f.knotvector <= g.knotvector).all():
            raise AssertionError('''
                    Error, the control-mapping knotvector needs
                    to be a subset of the target GridObject knotvector
                ''')

        # refine, just in case
        f = go.refine_GridObject(f, g.knotvector)
        G = metric_tensor(g, f.x)
    else:
        # f is a nutils function
        jacT = function.transpose(f.grad(g.geom))
        G = function.outer(jacT, jacT).sum(-1)

    target = function.Argument('target', [len(g.x)])
    basis = g.basis.vector(2)
    x = basis.dot(target)

    (g11, g12), (g21, g22) = metric_tensor(g, target)
    lapl = g22 * x.grad(g.geom)[:, 0].grad(g.geom)[:, 0] - \
        2 * g12 * x.grad(g.geom)[:, 0].grad(g.geom)[:, 1] + \
        g11 * x.grad(g.geom)[:, 1].grad(g.geom)[:, 1]

    G_tilde = G / function.sqrt(function.determinant(G))
    (G11, G12), (G12, G22) = G_tilde

    P = g11 * G12.grad(g.geom)[1] - g12 * G11.grad(g.geom)[1]
    Q = 0.5 * (g11 * G22.grad(g.geom)[0] - g22 * G11.grad(g.geom)[0])
    S = g12 * G22.grad(g.geom)[0] - g22 * G12.grad(g.geom)[0]
    R = 0.5 * (g11 * G22.grad(g.geom)[1] - g22 * G11.grad(g.geom)[1])

    control_term = -x.grad( g.geom )[:, 0] * ( G22*(P-Q) + G12*(S-R) ) \
                   -x.grad( g.geom )[:, 1] * ( G11*(R-S) + G12*(Q-P) )

    scale = g11 + g22 + eps

    res = g.domain.integral((basis * (control_term + lapl)).sum(-1) / scale,
                            geometry=g.geom,
                            degree=degree)

    init, cons = g.x, g.cons
    lhs = solver.newton('target', res, lhs0=init,
                        constrain=cons.where).solve(ltol, **solveargs)

    g.x = lhs
Beispiel #10
0
def mixed_fem(g, ltol=1e-5, coordinate_directions=None, **solveargs):
    assert len(g) == 2
    n = len(g.x)
    basis = g.basis

    def c0(g):
        return tuple(
            [i for i in range(2) if g.degree[i] in g.knotmultiplicities[i]])

    if coordinate_directions is None:
        coordinate_directions = c0(g)

    assert len(coordinate_directions) in (1, 2) and all(
        [i in (0, 1) for i in coordinate_directions])

    s = function.stack

    veclength = {1: 4, 2: 6}[len(coordinate_directions)]
    target = function.Argument('target', [veclength * len(basis)])

    U = g.basis.vector(veclength).dot(target)

    G = metric_tensor(g, target[-n:])
    (g11, g12), (g21, g22) = G

    scale = g11 + g22

    if len(coordinate_directions) == 2:
        u, v, x_ = U[:2], U[2:4], U[4:]
        expr = function.concatenate(x_.grad(g.geom) - s([u, v], axis=1))
        res1 = (basis.vector(4) * expr).sum(-1)
        res2 = g22 * u.grad(g.geom)[:, 0] - g12 * u.grad(
            g.geom)[:, 1] - g12 * v.grad(g.geom)[:, 0] + g11 * v.grad(
                g.geom)[:, 1]

    if len(coordinate_directions) == 1:
        index = coordinate_directions[0]
        u, x_ = U[:2], U[2:4]
        expr = x_.grad(g.geom)[:, index] - u
        res1 = (basis.vector(2) * expr).sum(-1)
        if index == 0:
            x_eta = x_.grad(g.geom)[:, 1]
            res2 = g22 * u.grad(g.geom)[:, 0] - g12 * u.grad(
                g.geom)[:, 1] - g12 * x_eta.grad(
                    g.geom)[:, 0] + g11 * x_eta.grad(g.geom)[:, 1]
        if index == 1:
            x_xi = x_.grad(g.geom)[:, 0]
            res2 = g22 * x_xi.grad(g.geom)[:, 0] - g12 * u.grad(
                g.geom)[:, 0] - g12 * x_xi.grad(g.geom)[:, 1] + g11 * u.grad(
                    g.geom)[:, 1]

    res = function.concatenate(
        [res1, (basis.vector(2) * res2).sum(-1) / scale])
    res = g.domain.integral(res, geometry=g.geom, degree=g.ischeme * 4)

    mapping0 = g.basis.vector(2).dot(g.x)

    cons = util.NanVec(n * (len(coordinate_directions) + 1))
    cons[-n:] = g.cons
    init = np.concatenate([
        g.domain.project(mapping0.grad(g.geom)[:, i],
                         geometry=g.geom,
                         onto=g.basis.vector(2),
                         ischeme='gauss12') for i in coordinate_directions
    ] + [g.x])

    lhs = solver.newton('target', res, lhs0=init,
                        constrain=cons.where).solve(ltol, **solveargs)

    g.x = lhs[-n:]