def recursive_descent(expr, field_index): if expr.is_Number: identity = base.Identity(grid[field_index]) if not expr == sympy.sympify(1): return base.Scaling(float(expr.evalf()), identity) else: return identity elif expr.is_Symbol: op_symbol = expr j = next(k for k, op_info in enumerate(operators) if op_symbol.name == op_info.name) operator = base.Operator(op_symbol.name, grid[field_index], ConstantStencilGenerator(operators[j].stencil)) return operator elif expr.is_Mul: tmp = recursive_descent(expr.args[-1], field_index) for arg in expr.args[-2::-1]: if arg.is_Number: tmp = base.Scaling(float(arg.evalf()), tmp) else: lhs = recursive_descent(arg, field_index) tmp = base.Multiplication(lhs, tmp) elif expr.is_Add: tmp = recursive_descent(expr.args[0], field_index) for arg in expr.args[1:]: tmp = base.Addition(recursive_descent(arg, field_index), tmp) else: raise RuntimeError("Invalid Expression") return tmp
def restrict(restriction_operator, cycle): if FAS: # Special treatment for FAS residual_c = base.mul(restriction_operator, cycle.correction) residual_FAS = base.mul(terminals.coarse_operator, base.Multiplication(restriction_operator, cycle.approximation)) # Add this term for FAS residual_c = base.add(residual_c, residual_FAS) cycle.correction = residual_c return cycle else: return apply(restriction_operator, cycle)
def coarse_grid_correction(prolongation_operator, state, restriction=None): cycle = state[0] if FAS: correction_FAS = base.mul(restriction, cycle.predecessor.approximation) # Subract this term for FAS correction_c = base.sub(cycle, correction_FAS) correction = base.mul(prolongation_operator, correction_c) else: correction = base.Multiplication(prolongation_operator, cycle) cycle.predecessor.correction = correction return cycle.predecessor
def generate_coarse_grid_correction(restriction, prolongation, omega=1): # residual = base.Residual(operator, approximation, rhs) # correction = base.Multiplication(base.Inverse(smoother.generate_collective_jacobi(operator)), residual) # cycle = base.Cycle(approximation, rhs, correction, partitioning=part.RedBlack, relaxation_factor=1) cycle = approximation residual = base.Residual(operator, cycle, rhs) coarse_grid_correction = base.Multiplication(restriction, residual) coarse_grid_correction = \ base.Multiplication(base.CoarseGridSolver(system.get_coarse_operator(operator, coarse_approximation.grid)), coarse_grid_correction) coarse_grid_correction = base.Multiplication(prolongation, coarse_grid_correction) cycle = base.Cycle(cycle, rhs, coarse_grid_correction, relaxation_factor=omega) # residual = base.Residual(operator, cycle, rhs) # correction = base.Multiplication(base.Inverse(smoother.generate_collective_jacobi(operator)), residual) # cycle = base.Cycle(cycle, rhs, correction, partitioning=part.RedBlack, relaxation_factor=1) return cycle
def apply(operator, cycle): cycle.correction = base.Multiplication(operator, cycle.correction) return cycle