| 491 | } |
| 492 | |
| 493 | void ContactEnergy::ApplyAdd(const FiniteElement& primary_fel, |
| 494 | const FiniteElement& secondary_fel, |
| 495 | const BaseMappedIntegrationRule& primary_mir, |
| 496 | FlatVector<double> elx, |
| 497 | FlatVector<double> ely, |
| 498 | LocalHeap& lh) |
| 499 | { |
| 500 | ProxyUserData ud(trial_proxies.Size(), lh); |
| 501 | const_cast<ElementTransformation&>(primary_mir.GetTransformation()).userdata = &ud; |
| 502 | ud.fel = & primary_fel; |
| 503 | |
| 504 | for(auto proxy : trial_proxies) |
| 505 | { |
| 506 | IntRange trial_range = proxy->IsOther() ? |
| 507 | IntRange(proxy->Evaluator()->BlockDim() * primary_fel.GetNDof(), elx.Size()) |
| 508 | : IntRange(0, proxy->Evaluator()->BlockDim() * primary_fel.GetNDof()); |
| 509 | ud.AssignMemory(proxy, primary_mir.Size(), proxy->Dimension(), lh); |
| 510 | if(proxy->IsOther()) |
| 511 | proxy->Evaluator()->Apply(secondary_fel, *primary_mir.GetOtherMIR(), elx.Range(trial_range), |
| 512 | ud.GetMemory(proxy), lh); |
| 513 | else |
| 514 | proxy->Evaluator()->Apply(primary_fel, primary_mir, elx.Range(trial_range), |
| 515 | ud.GetMemory(proxy), lh); |
| 516 | } |
| 517 | |
| 518 | FlatVector<> ely1(ely.Size(), lh); |
| 519 | FlatMatrix<AutoDiff<1>> dval(primary_mir.Size(), 1, lh); |
| 520 | |
| 521 | for (auto proxy : trial_proxies) |
| 522 | { |
| 523 | HeapReset hr(lh); |
| 524 | FlatMatrix<> proxyvalues(primary_mir.Size(), proxy->Dimension(), lh); |
| 525 | for (int k = 0; k < proxy->Dimension(); k++) |
| 526 | { |
| 527 | ud.trialfunction = proxy; |
| 528 | ud.trial_comp = k; |
| 529 | cf -> Evaluate (primary_mir, dval); |
| 530 | for (size_t i = 0; i < primary_mir.Size(); i++) |
| 531 | proxyvalues(i,k) = dval(i,0).DValue(0); |
| 532 | } |
| 533 | |
| 534 | for (int i = 0; i < primary_mir.Size(); i++) |
| 535 | proxyvalues.Row(i) *= primary_mir[i].GetWeight(); |
| 536 | |
| 537 | IntRange test_range = proxy->IsOther() ? |
| 538 | IntRange(proxy->Evaluator()->BlockDim()*primary_fel.GetNDof(), ely.Size()) |
| 539 | : IntRange(0, proxy->Evaluator()->BlockDim()*primary_fel.GetNDof()); |
| 540 | ely1 = 0.; |
| 541 | if(proxy->IsOther()) |
| 542 | proxy->Evaluator()->ApplyTrans(secondary_fel, *primary_mir.GetOtherMIR(), proxyvalues, ely1.Range(test_range), lh); |
| 543 | else |
| 544 | proxy->Evaluator()->ApplyTrans(primary_fel, primary_mir, proxyvalues, ely1.Range(test_range), lh); |
| 545 | ely += ely1; |
| 546 | } |
| 547 | } |
| 548 | |
| 549 | void ContactEnergy::CalcLinearizedAdd(const FiniteElement& primary_fel, |
| 550 | const FiniteElement& secondary_fel, |
no test coverage detected