302 amrex::Vector<amrex::Real> m_xterrain,m_yterrain,m_zterrain;
304 int nx = 0;
int ny = 0;
306 if (amrex::ParallelDescriptor::IOProcessor()) {
308 amrex::Print()<<
"Reading terrain file: "<< fname<< std::endl;
309 std::ifstream file(fname);
311 if (!file.is_open()) {
312 amrex::Abort(
"Error: Could not open the file " + fname+
"\n");
316 if (file.peek() == std::ifstream::traits_type::eof()) {
317 amrex::Abort(
"Error: The file " + fname+
" is empty.\n");
320 amrex::Real value1,value2,value3;
323 amrex::Real lat_min, lon_min;
325 file >> lon_min >> lat_min;
326 if(std::fabs(lon_min) > 180.0) {
327 amrex::Error(
"The value of longitude for entry in the first line in " + fname
328 +
" should not exceed 180. It is " + std::to_string(lon_min));
330 if(std::fabs(lat_min) > 90.0) {
331 amrex::Error(
"The value of latitude for entry in the first line in " + fname
332 +
" should not exceed 90. It is " + std::to_string(lat_min));
338 while (file >> value1 >> value2 >> value3) {
339 m_xterrain.push_back(value1);
341 m_yterrain.push_back(value2);
343 m_zterrain.push_back(value3);
346 AMREX_ASSERT(m_xterrain.size() ==
static_cast<long int>(nx*ny));
347 AMREX_ASSERT(m_yterrain.size() ==
static_cast<long int>(ny));
348 AMREX_ASSERT(m_zterrain.size() ==
static_cast<long int>(nx*ny));
351 file >> nx; file >> ny;
352 AMREX_ALWAYS_ASSERT(nx > 0);
353 AMREX_ALWAYS_ASSERT(ny > 0);
354 m_xterrain.resize(nx);
355 m_yterrain.resize(ny);
356 m_zterrain.resize(nx * ny);
357 for (
int n = 0; n < nx; n++) {
358 file >> m_xterrain[n];
360 for (
int n = 0; n < ny; n++) {
361 file >> m_yterrain[n];
363 for (
int n = 0; n < nx * ny; n++) {
364 file >> m_zterrain[n];
368 amrex::Print() <<
"NX " << nx <<
" " << ny << std::endl;
374 amrex::ParallelDescriptor::Bcast(&nx,1,amrex::ParallelDescriptor::IOProcessorNumber());
375 amrex::ParallelDescriptor::Bcast(&ny,1,amrex::ParallelDescriptor::IOProcessorNumber());
379 m_xterrain.resize(nx);
380 m_yterrain.resize(ny);
381 m_zterrain.resize(nz);
383 amrex::ParallelDescriptor::Bcast(m_xterrain.data(),nx,amrex::ParallelDescriptor::IOProcessorNumber());
384 amrex::ParallelDescriptor::Bcast(m_yterrain.data(),ny,amrex::ParallelDescriptor::IOProcessorNumber());
385 amrex::ParallelDescriptor::Bcast(m_zterrain.data(),nz,amrex::ParallelDescriptor::IOProcessorNumber());
388 amrex::Gpu::DeviceVector<amrex::Real> d_xterrain(nx),d_yterrain(ny),d_zterrain(nz);
389 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_xterrain.begin(), m_xterrain.end(), d_xterrain.begin());
390 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_yterrain.begin(), m_yterrain.end(), d_yterrain.begin());
391 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_zterrain.begin(), m_zterrain.end(), d_zterrain.begin());
393 amrex::Real* d_xt = d_xterrain.data();
394 amrex::Real* d_yt = d_yterrain.data();
395 amrex::Real* d_zt = d_zterrain.data();
397 auto dx = geom.CellSizeArray();
398 auto ProbLoArr = geom.ProbLoArray();
400 int ilo = geom.Domain().smallEnd(0);
401 int jlo = geom.Domain().smallEnd(1);
402 int klo = geom.Domain().smallEnd(2);
403 int ihi = geom.Domain().bigEnd(0) + 1;
404 int jhi = geom.Domain().bigEnd(1) + 1;
406 amrex::Box zbx = terrain_fab.box();
407 amrex::Array4<amrex::Real>
const& z_arr = terrain_fab.array();
409 amrex::ParallelFor(zbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int )
412 int ii = amrex::min(amrex::max(i,ilo),ihi);
413 int jj = amrex::min(amrex::max(j,jlo),jhi);
416 amrex::Real
x = ProbLoArr[0] + ii * dx[0] + 1e-3;
417 amrex::Real
y = ProbLoArr[1] + jj * dx[1] + 1e-3;
419 int jindex_terrain = -1;
420 for (
int it = 0; it < ny && jindex_terrain == -1; it++) {
422 jindex_terrain = it-1;
425 if (jindex_terrain == -1) {
426 jindex_terrain = ny-1;
429 int ind11, ind12, ind21, ind22;
430 amrex::Real x1, x2, y1, y2;
432 int iindex_terrain=-1;
434 int gstart = (jindex_terrain )*nx;
435 int gend = (jindex_terrain+1)*nx-1;
436 for (
int it = gstart; it <= gend && iindex_terrain == -1; it++) {
438 iindex_terrain = it-gstart;
443 ind11 = jindex_terrain*nx + iindex_terrain;
449 y1 = d_yt[jindex_terrain];
450 y2 = d_yt[jindex_terrain+1];
453 for (
int it = 0; it < nx && iindex_terrain == -1; it++) {
455 iindex_terrain = it-1;
458 if (iindex_terrain == -1) {
459 iindex_terrain = nx-1;
463 x1 = d_xt[iindex_terrain];
464 x2 = d_xt[iindex_terrain+1];
465 y1 = d_yt[jindex_terrain];
466 y2 = d_yt[jindex_terrain+1];
468 ind11 = jindex_terrain * nx + iindex_terrain;
469 ind21 = std::min(jindex_terrain+1,ny-1) * nx + iindex_terrain;
471 ind12 = jindex_terrain * nx + std::min(iindex_terrain+1,nx-1);
472 ind22 = std::min(jindex_terrain+1,ny-1) * nx + std::min(iindex_terrain+1,nx-1);
476 amrex::Real denom = (x2-x1)*(y2-y1);
477 amrex::Real w_11 = (x2-
x)*(y2-
y)/denom;
478 amrex::Real w_12 = (x2-
x)*(
y-y1)/denom;
479 amrex::Real w_21 = (
x-x1)*(y2-
y)/denom;
480 amrex::Real w_22 = (
x-x1)*(
y-y1)/denom;
482 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];