| 282 | |
| 283 | template<class SCAL> |
| 284 | shared_ptr<BaseMatrix> ConvertOperatorGF (shared_ptr<FESpace> space_a, shared_ptr<FESpace> space_b, |
| 285 | // int inda, int indb, |
| 286 | shared_ptr<DifferentialOperator> diffop, shared_ptr<CoefficientFunction> trial_cf, |
| 287 | VorB vb, const Region * reg, LocalHeap & lh, |
| 288 | shared_ptr<BitArray> range_dofs = nullptr, |
| 289 | bool localop = false, bool parmat = true, bool use_simd = true, |
| 290 | int bonus_intorder_ab = 0, int bonus_intorder_bb = 0) |
| 291 | { |
| 292 | |
| 293 | static Timer t ("ConvertOperatorGF"); |
| 294 | RegionTimer regt(t); |
| 295 | |
| 296 | auto ma = space_b->GetMeshAccess(); |
| 297 | |
| 298 | if ( parmat && (space_a->IsParallel() != space_b->IsParallel()) ) |
| 299 | { throw Exception("Cannot form ConvertOperator between a parallel and a local space!"); } |
| 300 | |
| 301 | if ( parmat && space_a->IsParallel() && space_b->IsParallel() ) { |
| 302 | NG_MPI_Comm comma = space_a->GetParallelDofs()->GetCommunicator(), commb = space_b->GetParallelDofs()->GetCommunicator(); |
| 303 | if (comma != commb) |
| 304 | { throw Exception("Cannot convert between spaces defined on different Communicators!"); } |
| 305 | } |
| 306 | |
| 307 | /** Proxies and Integrators **/ |
| 308 | |
| 309 | shared_ptr<CoefficientFunction> trial_a; |
| 310 | if (trial_cf != nullptr) |
| 311 | { trial_a = trial_cf; } |
| 312 | else if ( diffop != nullptr ) { |
| 313 | trial_a = make_shared<ProxyFunction>(space_a, false, false, diffop, |
| 314 | nullptr, nullptr, nullptr, nullptr, nullptr); |
| 315 | } |
| 316 | else { // Probably most of the time |
| 317 | trial_a = make_shared<ProxyFunction>(space_a, false, false, space_a->GetEvaluator(vb), |
| 318 | nullptr, nullptr, nullptr, nullptr, nullptr); |
| 319 | } |
| 320 | |
| 321 | auto trial_b = make_shared<ProxyFunction>(space_b, false, false, space_b->GetEvaluator(vb), |
| 322 | nullptr, nullptr, nullptr, nullptr, nullptr); |
| 323 | |
| 324 | if (!space_b->GetAdditionalEvaluators().Used("dual")) |
| 325 | throw Exception(string("Dual diffop does not exist for ") + space_b->GetClassName() + string("!")); |
| 326 | auto dual_evaluator = space_b->GetAdditionalEvaluators()["dual"]; |
| 327 | for (VorB avb = dual_evaluator->VB(); avb < vb; avb++) { |
| 328 | dual_evaluator = dual_evaluator->GetTrace(); |
| 329 | if ( dual_evaluator == nullptr ) |
| 330 | { throw Exception(space_b->GetClassName() + string(" has no dual trace operator for vb = ") |
| 331 | + to_string(avb) + string(" -> ") + to_string(avb + 1) + string("!")); } |
| 332 | } |
| 333 | auto dual_b = make_shared<ProxyFunction>(space_b, true, false, dual_evaluator, |
| 334 | nullptr, nullptr, nullptr, nullptr, nullptr); |
| 335 | |
| 336 | if ( trial_a->Dimension() != trial_b->Dimension() ) |
| 337 | { throw Exception(string("Cannot convert from ") + space_a->GetClassName() + string(" to ") + space_b->GetClassName() + |
| 338 | string(" - dimensions mismatch: ") + to_string(trial_a->Dimension()) + |
| 339 | string(" != ") + to_string(trial_b->Dimension()) + string("!")); } |
| 340 | |
| 341 | Array<shared_ptr<BilinearFormIntegrator>> ab_bfis, bb_bfis; |
nothing calls this directly
no test coverage detected