def test_calculus_2d_4(): DIM = 2 domain = Domain('Omega', dim=DIM) V = ScalarFunctionSpace('V', domain, kind=None) u, v = elements_of(V, names='u, v') a = Constant('a', is_real=True) # ... jump operator assert (jump(u + v) == jump(u) + jump(v)) assert (jump(a * u) == a * jump(u)) # ... # ... avg operator assert (avg(u + v) == avg(u) + avg(v)) assert (avg(a * u) == a * avg(u)) # ... # ... Dn operator assert (Dn(u + v) == Dn(u) + Dn(v)) assert (Dn(a * u) == a * Dn(u)) # ... # ... minus operator assert (minus(u + v) == minus(u) + minus(v)) assert (minus(a * u) == a * minus(u)) # ... # ... plus operator assert (plus(u + v) == plus(u) + plus(v)) assert (plus(a * u) == a * plus(u))
def test_interface_integral_1(): # ... A = Square('A') B = Square('B') domain = A.join(B, name='domain', bnd_minus=A.get_boundary(axis=0, ext=1), bnd_plus=B.get_boundary(axis=0, ext=-1)) # ... x, y = domain.coordinates V = ScalarFunctionSpace('V', domain, kind=None) assert (V.is_broken) u, v = elements_of(V, names='u, v') # ... I = domain.interfaces # ... # expr = minus(Dn(u)) # print(expr) # import sys; sys.exit(0) # ... bilinear forms # a = BilinearForm((u,v), integral(domain, u*v)) # a = BilinearForm((u,v), integral(domain, dot(grad(u),grad(v)))) # a = BilinearForm((u,v), integral(I, jump(u) * jump(v))) # a = BilinearForm((u,v), integral(I, jump(Dn(u)) * jump(v))) # a = BilinearForm((u,v), integral(domain, dot(grad(u),grad(v))) # + integral(I, jump(u) * jump(v))) # Nitsch kappa = Constant('kappa') expr_I = (-jump(u) * jump(Dn(v)) + kappa * jump(u) * jump(v) + plus(Dn(u)) * minus(v) + minus(Dn(u)) * plus(v)) a = BilinearForm( (u, v), integral(domain, dot(grad(u), grad(v))) + integral(I, expr_I)) # # TODO BUG # bnd_A = A.get_boundary(axis=0, ext=1) # # a = BilinearForm((u,v), integral(domain, dot(grad(u),grad(v))) # + integral(I, jump(u) * jump(v)) # + integral(bnd_A, dx(u)*v)) expr = TerminalExpr(a) print(expr)
def test_logical_expr_2d_2(): dim = 2 A = Square('A') B = Square('B') M1 = Mapping('M1', dim=dim) M2 = Mapping('M2', dim=dim) D1 = M1(A) D2 = M2(B) domain = D1.join(D2, name='domain', bnd_minus=D1.get_boundary(axis=0, ext=1), bnd_plus=D2.get_boundary(axis=0, ext=-1)) V1 = ScalarFunctionSpace('V1', domain, kind='h1') V2 = VectorFunctionSpace('V2', domain, kind='h1') u1, v1 = [element_of(V1, name=i) for i in ['u1', 'v1']] u2, v2 = [element_of(V2, name=i) for i in ['u2', 'v2']] int_0 = lambda expr: integral(domain, expr) int_1 = lambda expr: integral(domain.interfaces, expr) expr = LogicalExpr(int_0(u1 * v1), domain) assert str( expr.args[0] ) == 'Integral(A, u1*v1*sqrt(det(Jacobian(M1).T * Jacobian(M1))))' assert str( expr.args[1] ) == 'Integral(B, u1*v1*sqrt(det(Jacobian(M2).T * Jacobian(M2))))' expr = LogicalExpr(int_1(plus(u1) * plus(v1)), domain) assert str( expr ) == 'Integral(A|B, PlusInterfaceOperator(u1)*PlusInterfaceOperator(v1)*sqrt(det(Jacobian(M1|M2).T * Jacobian(M1|M2))))' expr = LogicalExpr(int_1(minus(u1) * minus(v1)), domain) assert str( expr ) == 'Integral(A|B, MinusInterfaceOperator(u1)*MinusInterfaceOperator(v1)*sqrt(det(Jacobian(M1|M2).T * Jacobian(M1|M2))))' expr = LogicalExpr(int_0(dot(u2, v2)), domain) assert str( expr.args[0] ) == 'Integral(A, Dot(u2, v2)*sqrt(det(Jacobian(M1).T * Jacobian(M1))))' assert str( expr.args[1] ) == 'Integral(B, Dot(u2, v2)*sqrt(det(Jacobian(M2).T * Jacobian(M2))))' expr = LogicalExpr(int_1(dot(plus(u2), plus(v2))), domain) assert str( expr ) == 'Integral(A|B, Dot(PlusInterfaceOperator(u2), PlusInterfaceOperator(v2))*sqrt(det(Jacobian(M1|M2).T * Jacobian(M1|M2))))' expr = LogicalExpr(int_1(dot(minus(u2), minus(v2))), domain) assert str( expr ) == 'Integral(A|B, Dot(MinusInterfaceOperator(u2), MinusInterfaceOperator(v2))*sqrt(det(Jacobian(M1|M2).T * Jacobian(M1|M2))))' expr = LogicalExpr(int_1(dot(grad(minus(u2)), grad(minus(v2)))), domain) assert str( expr ) == 'Integral(A|B, Dot((Jacobian(M1)**(-1)).T * Grad(MinusInterfaceOperator(u2)), (Jacobian(M1)**(-1)).T * Grad(MinusInterfaceOperator(v2)))*sqrt(det(Jacobian(M1|M2).T * Jacobian(M1|M2))))' expr = LogicalExpr(int_1(dot(grad(plus(u2)), grad(plus(v2)))), domain) assert str( expr ) == 'Integral(A|B, Dot((Jacobian(M2)**(-1)).T * Grad(PlusInterfaceOperator(u2)), (Jacobian(M2)**(-1)).T * Grad(PlusInterfaceOperator(v2)))*sqrt(det(Jacobian(M1|M2).T * Jacobian(M1|M2))))'
def _split_expr_over_interface(expr, interface, tests=None, trials=None): """ Splits an expression defined on an interface, into expressions where the test and trial functions are defined on each side of the interface. Parameters: expr: sympde expression interface: interface of a connectivity tests: tests functions as given from linear or bilinear forms trials: trials functions as given from linear or bilinear forms Returns: sympde expression """ # ... is_bilinear = not (trials is None) and not (tests is None) is_linear = (trials is None) and not (tests is None) if trials is None: trials = [] if tests is None: tests = [] # ... int_expressions = {} bnd_expressions = {} # ... # we replace all jumps jumps = expr.atoms(Jump) args = [j._args[0] for j in jumps] for a in args: expr = expr.subs({jump(a): minus(a) - plus(a)}) # ... # ... d_trials = {} for u in trials: u_minus = minus(u) u_plus = plus(u) d_trials[u] = {'-': u_minus, '+': u_plus} # # TODO add sub for avg # expr = expr.subs({jump(u): u_minus - u_plus}) d_tests = {} for v in tests: v_minus = minus(v) v_plus = plus(v) d_tests[v] = {'-': v_minus, '+': v_plus} # # TODO add sub for avg # expr = expr.subs({jump(v): v_minus - v_plus}) # ... # ... trials = [] for u in d_trials.keys(): u_minus = d_trials[u]['-'] u_plus = d_trials[u]['+'] trials += [u_minus, u_plus] tests = [] for u in d_tests.keys(): u_minus = d_tests[u]['-'] u_plus = d_tests[u]['+'] tests += [u_minus, u_plus] # ... # ... def _nullify(expr, u, us): """nullifies all symbols in us except u.""" others = list(set(us) - set([u])) for other in others: expr = expr.subs({other: 0}) return expr # ... if is_bilinear: for u in d_trials.keys(): for v in d_tests.keys(): u_minus = d_trials[u]['-'] u_plus = d_trials[u]['+'] v_minus = d_tests[v]['-'] v_plus = d_tests[v]['+'] # ... newexpr = _nullify(expr, u_minus, trials) newexpr = _nullify(newexpr, v_minus, tests) newexpr = newexpr.subs({u_minus: u, v_minus: v}) mapping = newexpr.atoms(InterfaceMapping) if mapping and not is_zero(newexpr): mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.minus) if not is_zero(newexpr): if interface.minus in bnd_expressions: newexpr += bnd_expressions[interface.minus] bnd_expressions[interface.minus] = newexpr.subs( interface, interface.minus) # ... newexpr = _nullify(expr, u_plus, trials) newexpr = _nullify(newexpr, v_plus, tests) newexpr = newexpr.subs({u_plus: u, v_plus: v}) mapping = newexpr.atoms(InterfaceMapping) if mapping and not is_zero(newexpr): mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.plus) for nn in newexpr.atoms(NormalVector): newexpr = newexpr.subs(nn, -nn) if not is_zero(newexpr): if interface.plus in bnd_expressions: newexpr += bnd_expressions[interface.plus] bnd_expressions[interface.plus] = newexpr.subs( interface, interface.plus) # ... # TODO must call InterfaceExpression afterward newexpr = _nullify(expr, u_minus, trials) newexpr = _nullify(newexpr, v_plus, tests) mapping = newexpr.atoms(InterfaceMapping) if mapping: mapping = list(mapping)[0] for det in newexpr.atoms(SymbolicDeterminant): if det.atoms(InterfaceMapping): newdet = det.subs(mapping, mapping.minus) newexpr = newexpr.subs(det, newdet) if not is_zero(newexpr): if isinstance(u, IndexedVectorFunction): u_minus = minus(u.base) if isinstance(v, IndexedVectorFunction): v_plus = plus(v.base) if (u_minus, v_plus) in int_expressions: newexpr += int_expressions[u_minus, v_plus].expr int_expressions[u_minus, v_plus] = InterfaceExpression( interface, u_minus, v_plus, newexpr) # ... # TODO must call InterfaceExpression afterward newexpr = _nullify(expr, u_plus, trials) newexpr = _nullify(newexpr, v_minus, tests) mapping = newexpr.atoms(InterfaceMapping) if mapping: mapping = list(mapping)[0] for det in newexpr.atoms(SymbolicDeterminant): if det.atoms(InterfaceMapping): newdet = det.subs(mapping, mapping.minus) newexpr = newexpr.subs(det, newdet) if not is_zero(newexpr): if isinstance(u, IndexedVectorFunction): u_plus = plus(u.base) if isinstance(v, IndexedVectorFunction): v_minus = minus(v.base) if (u_plus, v_minus) in int_expressions: newexpr += int_expressions[u_plus, v_minus].expr int_expressions[u_plus, v_minus] = InterfaceExpression( interface, u_plus, v_minus, newexpr) elif is_linear: for v in d_tests.keys(): v_minus = d_tests[v]['-'] v_plus = d_tests[v]['+'] # ... newexpr = _nullify(expr, v_minus, tests) newexpr = newexpr.subs({v_minus: v}) mapping = newexpr.atoms(InterfaceMapping) if mapping: mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.minus) if not is_zero(newexpr): if interface.minus in bnd_expressions: newexpr += bnd_expressions[interface.minus] bnd_expressions[interface.minus] = newexpr # ... # ... newexpr = _nullify(expr, v_plus, tests) newexpr = newexpr.subs({v_plus: v}) mapping = newexpr.atoms(InterfaceMapping) if mapping: mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.plus) if not is_zero(newexpr): if interface.plus in bnd_expressions: newexpr += bnd_expressions[interface.plus] bnd_expressions[interface.plus] = newexpr # ... int_expressions = list(int_expressions.values()) return int_expressions, bnd_expressions
def _split_expr_over_interface(expr, interface, tests=None, trials=None): """ Splits an expression defined on an interface, into expressions where the test and trial functions are defined on each side of the interface. Parameters: expr: sympde expression interface: interface of a connectivity tests: tests functions as given from linear or bilinear forms trials: trials functions as given from linear or bilinear forms Returns: sympde expression """ # ... def _new_atom(v, label): new = '{v}_{label}'.format(v=v.name, label=label) return element_of(v.space, name=new) # ... # ... is_bilinear = not (trials is None) and not (tests is None) is_linear = (trials is None) and not (tests is None) if trials is None: trials = [] if tests is None: tests = [] # ... # ... B_minus = interface.minus B_plus = interface.plus boundaries = (B_minus, B_plus) labels = ('minus', 'plus') # ... int_expressions = [] bnd_expressions = {} # ... # we replace all jumps jumps = expr.atoms(Jump) args = [j._args[0] for j in jumps] for a in args: expr = expr.subs({jump(a): minus(a) - plus(a)}) # ... # ... d_trials = {} for u in trials: u_minus = minus(u) u_plus = plus(u) d_trials[u] = {'-': u_minus, '+': u_plus} # # TODO add sub for avg # expr = expr.subs({jump(u): u_minus - u_plus}) d_tests = {} for v in tests: v_minus = minus(v) v_plus = plus(v) d_tests[v] = {'-': v_minus, '+': v_plus} # # TODO add sub for avg # expr = expr.subs({jump(v): v_minus - v_plus}) expr = expand(expr) # ... # ... trials = [] for u in d_trials.keys(): u_minus = d_trials[u]['-'] u_plus = d_trials[u]['+'] trials += [u_minus, u_plus] tests = [] for u in d_tests.keys(): u_minus = d_tests[u]['-'] u_plus = d_tests[u]['+'] tests += [u_minus, u_plus] # ... # ... def _nullify(expr, u, us): """nullifies all symbols in us except u.""" others = list(set(us) - set([u])) for other in others: expr = expr.subs({other: 0}) return expr # ... # ... def _not_zero_matrix(M): n, m = expr.shape return any([M[i, j] != 0 for i, j in product(range(n), range(m))]) # ... # ... if is_bilinear: for u in d_trials.keys(): u_minus = d_trials[u]['-'] u_plus = d_trials[u]['+'] for v in d_tests.keys(): v_minus = d_tests[v]['-'] v_plus = d_tests[v]['+'] # ... newexpr = _nullify(expr, u_minus, trials) newexpr = _nullify(newexpr, v_minus, tests) newexpr = newexpr.subs({u_minus: u, v_minus: v}) if _not_zero_matrix(newexpr): bnd_expressions[interface.minus] = newexpr # ... # ... # TODO must call InterfaceExpression afterward newexpr = _nullify(expr, u_minus, trials) newexpr = _nullify(newexpr, v_plus, tests) if _not_zero_matrix(newexpr): int_expressions += [ InterfaceExpression(interface, newexpr) ] # ... # ... # TODO must call InterfaceExpression afterward newexpr = _nullify(expr, u_plus, trials) newexpr = _nullify(newexpr, v_minus, tests) if _not_zero_matrix(newexpr): int_expressions += [ InterfaceExpression(interface, newexpr) ] # ... # ... newexpr = _nullify(expr, u_plus, trials) newexpr = _nullify(newexpr, v_plus, tests) newexpr = newexpr.subs({u_plus: u, v_plus: v}) if _not_zero_matrix(newexpr): bnd_expressions[interface.plus] = newexpr # ... elif is_linear: for v in d_tests.keys(): v_minus = d_tests[v]['-'] v_plus = d_tests[v]['+'] # ... newexpr = _nullify(expr, v_minus, tests) newexpr = newexpr.subs({v_minus: v}) if _not_zero_matrix(newexpr): bnd_expressions[interface.minus] = newexpr # ... # ... newexpr = _nullify(expr, v_plus, tests) newexpr = newexpr.subs({v_plus: v}) if _not_zero_matrix(newexpr): bnd_expressions[interface.plus] = newexpr # ... # ... return int_expressions, bnd_expressions
def _split_expr_over_interface(expr, interface, tests=None, trials=None): """ Splits an expression defined on an interface, into expressions where the test and trial functions are defined on each side of the interface. Parameters: expr: sympde expression interface: interface of a connectivity tests: tests functions as given from linear or bilinear forms trials: trials functions as given from linear or bilinear forms Returns: sympde expression """ # ... is_bilinear = not (trials is None) and not (tests is None) is_linear = (trials is None) and not (tests is None) if trials is None: trials = [] if tests is None: tests = [] # ... int_expressions = [] bnd_expressions = OrderedDict() # ... # we replace all jumps jumps = expr.atoms(Jump) args = [j._args[0] for j in jumps] for a in args: expr = expr.subs({jump(a): minus(a) - plus(a)}) # ... # ... d_trials = OrderedDict() for u in trials: u_minus = minus(u) u_plus = plus(u) d_trials[u] = {'-': u_minus, '+': u_plus} # # TODO add sub for avg # expr = expr.subs({jump(u): u_minus - u_plus}) d_tests = OrderedDict() for v in tests: v_minus = minus(v) v_plus = plus(v) d_tests[v] = {'-': v_minus, '+': v_plus} # # TODO add sub for avg # expr = expr.subs({jump(v): v_minus - v_plus}) # ... # ... trials = [] for u in d_trials.keys(): u_minus = d_trials[u]['-'] u_plus = d_trials[u]['+'] trials += [u_minus, u_plus] tests = [] for u in d_tests.keys(): u_minus = d_tests[u]['-'] u_plus = d_tests[u]['+'] tests += [u_minus, u_plus] # ... # ... def _nullify(expr, u, us): """nullifies all symbols in us except u.""" others = list(set(us) - set([u])) for other in others: expr = expr.subs({other: 0}) return expr # ... if is_bilinear: for u in d_trials.keys(): u_minus = d_trials[u]['-'] u_plus = d_trials[u]['+'] for v in d_tests.keys(): v_minus = d_tests[v]['-'] v_plus = d_tests[v]['+'] # ... newexpr = _nullify(expr, u_minus, trials) newexpr = _nullify(newexpr, v_minus, tests) newexpr = newexpr.subs({u_minus: u, v_minus: v}) mapping = newexpr.atoms(InterfaceMapping) if mapping and not newexpr.is_zero: mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.minus) if not newexpr.is_zero: bnd_expressions[interface.minus] = newexpr # ... # TODO must call InterfaceExpression afterward newexpr = _nullify(expr, u_minus, trials) newexpr = _nullify(newexpr, v_plus, tests) mapping = newexpr.atoms(InterfaceMapping) if mapping: mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.plus) if not newexpr.is_zero: int_expressions += [ InterfaceExpression(interface, u_minus, v_plus, newexpr) ] # ... # TODO must call InterfaceExpression afterward newexpr = _nullify(expr, u_plus, trials) newexpr = _nullify(newexpr, v_minus, tests) mapping = newexpr.atoms(InterfaceMapping) if mapping: mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.plus) if not newexpr.is_zero: int_expressions += [ InterfaceExpression(interface, u_plus, v_minus, newexpr) ] # ... newexpr = _nullify(expr, u_plus, trials) newexpr = _nullify(newexpr, v_plus, tests) newexpr = newexpr.subs({u_plus: u, v_plus: v}) mapping = newexpr.atoms(InterfaceMapping) if mapping: mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.plus) if not newexpr.is_zero: bnd_expressions[interface.plus] = newexpr # ... elif is_linear: for v in d_tests.keys(): v_minus = d_tests[v]['-'] v_plus = d_tests[v]['+'] # ... newexpr = _nullify(expr, v_minus, tests) newexpr = newexpr.subs({v_minus: v}) mapping = newexpr.atoms(InterfaceMapping) if mapping: mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.minus) if not newexpr.is_zero: bnd_expressions[interface.minus] = newexpr # ... # ... newexpr = _nullify(expr, v_plus, tests) newexpr = newexpr.subs({v_plus: v}) mapping = newexpr.atoms(InterfaceMapping) if mapping: mapping = list(mapping)[0] newexpr = newexpr.subs(mapping, mapping.plus) if not newexpr.is_zero: bnd_expressions[interface.plus] = newexpr # ... return int_expressions, bnd_expressions