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
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)
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
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)
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)
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
def subs00(f): if isinstance(f, function.Argument) and f._name == 'lhs': return function.Argument(name='lhs00', shape=f.shape, nderiv=f._nderiv)
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
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:]