| 518 | } |
| 519 | |
| 520 | void |
| 521 | Geometry::computeRoundoffDomain () |
| 522 | { |
| 523 | bool valid_domain = true; |
| 524 | for (int k = 0; k < AMREX_SPACEDIM; k++) |
| 525 | { |
| 526 | offset[k] = prob_domain.lo(k); |
| 527 | dx[k] = prob_domain.length(k)/(Real(domain.length(k))); |
| 528 | inv_dx[k] = 1.0_rt/dx[k]; |
| 529 | valid_domain = valid_domain && (prob_domain.length(k) > 0) && |
| 530 | (domain.length(k) > 0); |
| 531 | } |
| 532 | |
| 533 | std::stringstream ss; |
| 534 | ss << std::setprecision(std::numeric_limits<double>::max_digits10) |
| 535 | << prob_domain << " " << domain << " sizeof Real: " |
| 536 | << sizeof(Real) << " sizeof ParticleReal: " << sizeof(ParticleReal); |
| 537 | auto const error_msg = ss.str(); |
| 538 | |
| 539 | AMREX_ALWAYS_ASSERT_WITH_MESSAGE(valid_domain, error_msg); |
| 540 | |
| 541 | constexpr int maxiters = 200; |
| 542 | |
| 543 | std::string error_msg_2("computeRoundoffDomain failed to converge. To help us improve, please submit a GitHub issue with the following information: "); |
| 544 | error_msg_2.append(error_msg); |
| 545 | |
| 546 | for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) |
| 547 | { |
| 548 | int ilo = Domain().smallEnd(idim); |
| 549 | int ihi = Domain().bigEnd(idim); |
| 550 | int ncells = ihi-ilo+1; |
| 551 | Real plo = ProbLo(idim); |
| 552 | Real phi = ProbHi(idim); |
| 553 | Real dxinv = InvCellSize(idim); |
| 554 | |
| 555 | // Check that the grid is well formed and that deltax > roundoff |
| 556 | AMREX_ALWAYS_ASSERT_WITH_MESSAGE((plo + ihi*CellSize(idim)) < (plo + (ihi + 1)*CellSize(idim)), error_msg_2); |
| 557 | |
| 558 | // roundoff_lo will be the lowest value that will be inside the domain |
| 559 | // roundoff_hi will be the highest value that will be inside the domain |
| 560 | roundoff_lo[idim] = static_cast<ParticleReal>(plo); |
| 561 | roundoff_hi[idim] = static_cast<ParticleReal>(phi); |
| 562 | auto& rlo = roundoff_lo[idim]; |
| 563 | auto& rhi = roundoff_hi[idim]; |
| 564 | |
| 565 | auto is_outside = [=] (auto x) -> bool |
| 566 | { |
| 567 | auto idx = int(std::floor((x - plo)*dxinv)); |
| 568 | return (idx < 0) || (idx >= ncells); |
| 569 | }; |
| 570 | |
| 571 | auto is_inside = [=] (auto x) -> bool |
| 572 | { |
| 573 | return !is_outside(x); |
| 574 | }; |
| 575 | |
| 576 | ParticleReal rlo_out; |
| 577 | if (is_inside(rlo)) |
no test coverage detected