437 amrex::Print()<<
"Reading terrain file: "<< fname_usgs << std::endl;
438 std::ifstream file(fname_usgs);
440 if (!file.is_open()) {
441 amrex::Abort(
"Error: Could not open the file " + fname_usgs +
"\n");
445 if (file.peek() == std::ifstream::traits_type::eof()) {
446 amrex::Abort(
"Error: The file " + fname_usgs +
" is empty.\n");
449 amrex::Gpu::HostVector<amrex::Real> m_xterrain,m_yterrain,m_zterrain;
450 amrex::Real value1,value2,value3;
451 amrex::Real lat_min, lon_min;
454 file >> lon_min >> lat_min;
455 if(std::fabs(lon_min) > 180.0) {
456 amrex::Error(
"The value of longitude for entry in the first line in " + fname_usgs
457 +
" should not exceed 180. It is " + std::to_string(lon_min));
459 if(std::fabs(lat_min) > 90.0) {
460 amrex::Error(
"The value of latitude for entry in the first line in " + fname_usgs
461 +
" should not exceed 90. It is " + std::to_string(lat_min));
464 file >> nlons >> nlats;
467 while(file >> value1 >> value2 >> value3){
468 m_xterrain.push_back(value1);
469 if(counter%nlons==0) {
470 m_yterrain.push_back(value2);
472 m_zterrain.push_back(value3);
477 AMREX_ASSERT(m_xterrain.size() ==
static_cast<long unsigned int>(nlons*nlats));
478 AMREX_ASSERT(m_yterrain.size() ==
static_cast<long unsigned int>(nlats));
479 AMREX_ASSERT(m_zterrain.size() ==
static_cast<long unsigned int>(nlons*nlats));
484 amrex::ParmParse
pp(
"erf");
485 amrex::Real x_shift, y_shift;
486 pp.query(
"windfarm_x_shift",x_shift);
487 pp.query(
"windfarm_x_shift",y_shift);
490 for(
auto& v : m_xterrain){
493 for(
auto& v : m_yterrain){
497 if (m_xterrain.empty()) {
498 amrex::Abort(
"Error: m_xterrain is empty!\n");
501 auto index = std::max_element(m_xterrain.begin(), m_xterrain.end());
502 amrex::Real xmax_terrain = *index;
503 index = std::max_element(m_yterrain.begin(), m_yterrain.end());
504 amrex::Real ymax_terrain = *index;
506 index = std::min_element(m_zterrain.begin(), m_zterrain.end());
507 amrex::Real zmin_terrain = *index;
509 for(
auto& v : m_zterrain){
514 int nnode = nlons*nlats;
515 amrex::Gpu::DeviceVector<amrex::Real> d_xterrain(nnode),d_yterrain(nlats),d_zterrain(nnode);
516 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_xterrain.begin(), m_xterrain.end(), d_xterrain.begin());
517 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_yterrain.begin(), m_yterrain.end(), d_yterrain.begin());
518 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_zterrain.begin(), m_zterrain.end(), d_zterrain.begin());
519 amrex::Real* d_xt = d_xterrain.data();
520 amrex::Real* d_yt = d_yterrain.data();
521 amrex::Real* d_zt = d_zterrain.data();
524 int ngrow = z_phys_nd.nGrow();
525 auto dx = geom.CellSizeArray();
526 auto ProbLoArr = geom.ProbLoArray();
527 int ilo = geom.Domain().smallEnd(0);
528 int jlo = geom.Domain().smallEnd(1);
529 int klo = geom.Domain().smallEnd(2);
530 int ihi = geom.Domain().bigEnd(0) + 1;
531 int jhi = geom.Domain().bigEnd(1) + 1;
533 for (amrex::MFIter mfi(z_phys_nd,amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi )
536 amrex::Box xybx = mfi.growntilebox(ngrow);
539 amrex::Array4<amrex::Real>
const& z_arr = z_phys_nd.array(mfi);
540 amrex::ParallelFor(xybx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int )
543 int ii = amrex::min(amrex::max(i,ilo),ihi);
544 int jj = amrex::min(amrex::max(j,jlo),jhi);
547 amrex::Real
x = ProbLoArr[0] + ii * dx[0] + 1e-3;
548 amrex::Real
y = ProbLoArr[1] + jj * dx[1] + 1e-3;
550 if(x < x_shift or x > xmax_terrain or
551 y < y_shift or y > ymax_terrain) {
552 z_arr(i,j,klo) = 0.0;
554 int jindex_terrain = -1;
555 for (
int it = 0; it < nlats && jindex_terrain == -1; it++) {
557 jindex_terrain = it-1;
565 int iindex_terrain=-1;
566 int gstart = jindex_terrain*nlons;
567 int gend = (jindex_terrain+1)*nlons-1;
568 for (
int it = gstart; it <= gend && iindex_terrain == -1; it++) {
570 iindex_terrain = it-gstart;
578 int ind11, ind12, ind21, ind22;
579 ind11 = jindex_terrain*nlons + iindex_terrain;
583 amrex::Real x1 = d_xt[ind11];
584 amrex::Real x2 = d_xt[ind21];
585 amrex::Real y1 = d_yt[jindex_terrain];
586 amrex::Real y2 = d_yt[jindex_terrain+1];
588 amrex::Real denom = (x2-x1)*(y2-y1);
589 amrex::Real w_11 = (x2-
x)*(y2-
y)/denom;
590 amrex::Real w_12 = (x2-
x)*(
y-y1)/denom;
591 amrex::Real w_21 = (
x-x1)*(y2-
y)/denom;
592 amrex::Real w_22 = (
x-x1)*(
y-y1)/denom;
594 z_arr(i,j,klo) = w_11*d_zt[ind11] + w_12*d_zt[ind12] + w_21*d_zt[ind21] + w_22*d_zt[ind22];