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 main(nelems:int, etype:str, btype:str, degree:int, poisson:float, angle:float, restol:float, trim:bool): ''' Deformed hyperelastic plate. .. arguments:: nelems [10] Number of elements along edge. etype [square] Type of elements (square/triangle/mixed). btype [std] Type of basis function (std/spline). degree [1] Polynomial degree. poisson [.25] Poisson's ratio, nonnegative and stricly smaller than 1/2. angle [20] Rotation angle for right clamp (degrees). restol [1e-10] Newton tolerance. trim [no] Create circular-shaped hole. ''' domain, geom = mesh.unitsquare(nelems, etype) if trim: domain = domain.trim(function.norm2(geom-.5)-.2, maxrefine=2) bezier = domain.sample('bezier', 5) ns = function.Namespace(fallback_length=domain.ndims) ns.x = geom ns.angle = angle * numpy.pi / 180 ns.lmbda = 2 * poisson ns.mu = 1 - 2 * poisson ns.ubasis = domain.basis(btype, degree=degree) ns.u_i = 'ubasis_k ?lhs_ki' ns.X_i = 'x_i + u_i' ns.strain_ij = '.5 (d(u_i, x_j) + d(u_j, x_i))' ns.energy = 'lmbda strain_ii strain_jj + 2 mu strain_ij strain_ij' sqr = domain.boundary['left'].integral('u_k u_k J(x)' @ ns, degree=degree*2) sqr += domain.boundary['right'].integral('((u_0 - x_1 sin(2 angle) - cos(angle) + 1)^2 + (u_1 - x_1 (cos(2 angle) - 1) + sin(angle))^2) J(x)' @ ns, degree=degree*2) cons = solver.optimize('lhs', sqr, droptol=1e-15) energy = domain.integral('energy J(x)' @ ns, degree=degree*2) lhs0 = solver.optimize('lhs', energy, constrain=cons) X, energy = bezier.eval(['X', 'energy'] @ ns, lhs=lhs0) export.triplot('linear.png', X, energy, tri=bezier.tri, hull=bezier.hull) ns.strain_ij = '.5 (d(u_i, x_j) + d(u_j, x_i) + d(u_k, x_i) d(u_k, x_j))' ns.energy = 'lmbda strain_ii strain_jj + 2 mu strain_ij strain_ij' energy = domain.integral('energy J(x)' @ ns, degree=degree*2) lhs1 = solver.minimize('lhs', energy, arguments=dict(lhs=lhs0), constrain=cons).solve(restol) X, energy = bezier.eval(['X', 'energy'] @ ns, lhs=lhs1) export.triplot('nonlinear.png', X, energy, tri=bezier.tri, hull=bezier.hull) return lhs0, lhs1
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, 90) if info.shift: nshift += 1 if info.resnorm < self.tol: break self.assertEqual(nshift, 60)
def setUp(self): super().setUp() domain, geom = mesh.rectilinear([numpy.linspace(0,1,9)] * 2) ubasis = domain.basis('std', degree=2).vector(2) u = ubasis.dot(function.Argument('dofs', [len(ubasis)])) Geom = geom * [1.1, 1] + u self.cons = solver.minimize('dofs', domain.boundary['left,right'].integral((u**2).sum(0), degree=4), droptol=1e-15).solve() 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 test_minimize_boolcons(self): self.assert_resnorm( solver.minimize('dofs', energy=self.energy, constrain=self.boolcons).solve(tol=self.tol, maxiter=12))
def setUp(self): super().setUp() self.ns = function.Namespace() self.domain, self.ns.geom = mesh.rectilinear([2,2]) self.ns.ubasis = self.domain.basis('std', degree=1) self.ns.u = 'ubasis_n ?dofs_n' self.optimize = solver.optimize if not self.minimize else lambda *args, newtontol=0, **kwargs: solver.minimize(*args, **kwargs).solve(newtontol)
def test_minimize_iter(self): _test_recursion_cache(self, lambda: ((types.frozenarray(lhs), info.resnorm) for lhs, info in solver.minimize('dofs', energy=self.energy, constrain=self.cons)))
def test_minimize_boolcons(self): self.assert_resnorm(solver.minimize('dofs', energy=self.energy, constrain=self.boolcons).solve(tol=self.tol, maxiter=8))