| 143 | : sym(sym), countexpr(countexpr), expr(expr) {} |
| 144 | |
| 145 | double generate(const Context& ctx) override { |
| 146 | // Get the count by evaluating the count expression |
| 147 | BoutReal countval = countexpr->generate(ctx); |
| 148 | int count = ROUND(countval); |
| 149 | |
| 150 | // Check that the count is a non-negaitve integer |
| 151 | if (fabs(countval - static_cast<BoutReal>(count)) > 1e-4) { |
| 152 | throw BoutException("Count {:e} is not an integer in sum expression", countval); |
| 153 | } |
| 154 | if (count < 0) { |
| 155 | throw BoutException("Negative count {:d} in sum expression", count); |
| 156 | } |
| 157 | |
| 158 | BoutReal result{0.0}; |
| 159 | Context new_context{ctx}; // Make a copy, so the counter value can be set |
| 160 | for (int i = 0; i < count; i++) { |
| 161 | // Evaluate the expression, setting the given symbol to the loop counter |
| 162 | new_context.set(sym, i); |
| 163 | result += expr->generate(new_context); |
| 164 | } |
| 165 | return result; |
| 166 | } |
| 167 | |
| 168 | std::string str() const override { |
| 169 | return "sum("s + sym + ","s + countexpr->str() + ","s + expr->str() + ")"s; |