| 2646 | } |
| 2647 | |
| 2648 | void MultAdd (double val, const BaseVector & v, BaseVector & prod) const override |
| 2649 | { |
| 2650 | auto fx = v.FV<double>(); |
| 2651 | auto fy = prod.FV<double>(); |
| 2652 | ParallelForRange |
| 2653 | (dofs->Size(), [&] (IntRange r) |
| 2654 | { |
| 2655 | constexpr size_t BS = 128; |
| 2656 | Matrix<> hx(BS, elbmat.Width()); |
| 2657 | Matrix<> tmp(BS, elbmat.Height()); |
| 2658 | |
| 2659 | for (size_t bi = r.First(); bi < r.Next(); bi+= BS) |
| 2660 | { |
| 2661 | size_t li = min2(bi+BS, r.Next()); |
| 2662 | size_t num = li-bi; |
| 2663 | |
| 2664 | for (size_t i = 0; i < num; i++) |
| 2665 | hx.Row(i) = fx( (*dofs)[bi+i]); |
| 2666 | |
| 2667 | tmp.Rows(0, num) = hx.Rows(0, num) * Trans(elbmat); |
| 2668 | |
| 2669 | size_t base = r.First()*tmp.Width(); |
| 2670 | for (size_t i : Range(num*tmp.Width())) |
| 2671 | tmp(i) *= rho_jac(base+i); |
| 2672 | |
| 2673 | hx.Rows(0, num) = tmp.Rows(0,num) * elbmat; |
| 2674 | for (size_t i = 0; i < num; i++) |
| 2675 | fy( (*dofs)[bi+i]) += val * hx.Row(i); |
| 2676 | } |
| 2677 | }); |
| 2678 | } |
| 2679 | |
| 2680 | |
| 2681 | }; |