| 1556 | |
| 1557 | template <typename KERNEL> template <typename T> |
| 1558 | void PotentialCF<KERNEL> :: |
| 1559 | AddSourceElementContribution(const BaseMappedIntegrationPoint & mip, |
| 1560 | ElementId ei, |
| 1561 | const IntegrationRule & ir, |
| 1562 | FlatVector<T> result, |
| 1563 | T scale, |
| 1564 | LocalHeap & lh) const |
| 1565 | { |
| 1566 | auto space = this->gf->GetFESpace(); |
| 1567 | auto mesh = space->GetMeshAccess(); |
| 1568 | |
| 1569 | const FiniteElement &fel = space->GetFE(ei, lh); |
| 1570 | const ElementTransformation &trafo = mesh->GetTrafo(ei, lh); |
| 1571 | |
| 1572 | Array<DofId> dnums(fel.GetNDof(), lh); |
| 1573 | space->GetDofNrs(ei, dnums); |
| 1574 | FlatVector<T> elvec(fel.GetNDof(), lh); |
| 1575 | gf->GetElementVector(dnums, elvec); |
| 1576 | |
| 1577 | SIMD_IntegrationRule simd_ir(ir); |
| 1578 | Vector<SIMD<T>> simd_result(Dimension()); |
| 1579 | simd_result = SIMD<T>(0.0); |
| 1580 | |
| 1581 | static constexpr int bs = 64; |
| 1582 | for (int k = 0; k < simd_ir.Size(); k += bs) |
| 1583 | { |
| 1584 | HeapReset hr(lh); |
| 1585 | auto simd_ir_range = simd_ir.Range(k, min(simd_ir.Size(), size_t(k+bs))); |
| 1586 | auto & miry = trafo(simd_ir_range, lh); |
| 1587 | FlatMatrix<SIMD<T>> vals(evaluator->Dim(), miry.Size(), lh); |
| 1588 | |
| 1589 | evaluator->Apply(fel, miry, elvec, vals); |
| 1590 | for (int iy = 0; iy < miry.Size(); iy++) |
| 1591 | { |
| 1592 | Vec<3,SIMD<double>> x = mip.GetPoint(); |
| 1593 | Vec<3,SIMD<double>> nx{0.0}; |
| 1594 | if constexpr (KERNEL::target_type::needs_normal) |
| 1595 | nx = dynamic_cast<const MappedIntegrationPoint<2,3>&>(mip).GetNV(); |
| 1596 | |
| 1597 | Vec<3,SIMD<double>> y = miry[iy].GetPoint(); |
| 1598 | Vec<3,SIMD<double>> ny{0.0}; |
| 1599 | if constexpr (KERNEL::source_type::needs_normal) |
| 1600 | { |
| 1601 | if (source_vb != BND) |
| 1602 | throw Exception("kernel requires boundary source normals"); |
| 1603 | ny = static_cast<const SIMD<MappedIntegrationPoint<2,3>>&>(miry[iy]).GetNV(); |
| 1604 | } |
| 1605 | |
| 1606 | auto eval = kernel.Evaluate(x, y, nx, ny); |
| 1607 | for (auto term : kernel.terms) |
| 1608 | { |
| 1609 | auto kernel_ = term.fac * eval(term.kernel_comp); |
| 1610 | simd_result(term.test_comp) += miry[iy].GetWeight() * kernel_ * vals(term.trial_comp, iy); |
| 1611 | } |
| 1612 | } |
| 1613 | } |
| 1614 | |
| 1615 | for (int i = 0; i < Dimension(); i++) |
nothing calls this directly
no test coverage detected