REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_init_from_netcdf.cpp
Go to the documentation of this file.
1/**
2 * \file REMORA_init_from_netcdf.cpp
3 */
4
5#include <REMORA.H>
6#include <REMORA_Constants.H>
8#include <REMORA_DataStruct.H>
9
10using namespace amrex;
11
12#ifdef REMORA_USE_NETCDF
13
14/** \brief helper function for reading in initial state data from netcdf */
15void
16read_data_from_netcdf (int /*lev*/, const Box& domain, const std::string& fname,
17 FArrayBox& NC_temp_fab, FArrayBox& NC_salt_fab,
18 FArrayBox& NC_xvel_fab, FArrayBox& NC_yvel_fab);
19
20/** \brief helper function for reading in full domain high-resolution initial state data from netcdf */
21void
22read_data_full_domain_from_netcdf (int /*lev*/, const Box& domain, const std::string& fname,
23 FArrayBox& NC_temp_fab, FArrayBox& NC_salt_fab,
24 FArrayBox& NC_xvel_fab, FArrayBox& NC_yvel_fab,
25 IntVect ngrow);
26
27/** \brief helper function for reading in initial biology data from netcdf */
28void
29read_biology_from_netcdf (int /*lev*/, const Box& domain, const std::string& fname,
30 const Vector<std::string>& biology_names,
32
33/** \brief helper function for reading in full domain high-resolution initial biology data from netcdf */
34void
35read_biology_full_domain_from_netcdf (int /*lev*/, const Box& domain, const std::string& fname,
36 const Vector<std::string>& biology_names,
38
39/** \brief helper function for reading in initial passive (dye) scalar data from netcdf */
40void
41read_scalars_from_netcdf (int /*lev*/, const Box& domain, const std::string& fname,
42 const Vector<std::string>& scalar_names,
44 Vector<int>& scalar_in_file);
45
46/** \brief helper function for reading in full domain high-resolution initial passive (dye) scalar data from netcdf */
47void
48read_scalars_full_domain_from_netcdf (int /*lev*/, const Box& domain, const std::string& fname,
49 const Vector<std::string>& scalar_names,
51 Vector<int>& scalar_in_file, IntVect ngrow);
52
53/** \brief helper function checking that a high-resolution file covers the refined domain plus grow cells */
54void
55check_hires_dims_from_netcdf (const std::string& fname, const std::string& var_name,
56 const Box& domain, const IntVect& ngrow);
57
58/** \brief helper function for reading in the rho-point land-sea mask from netcdf */
59void
60read_masks_from_netcdf (int /*lev*/, const Box& domain, const std::string& fname,
61 FArrayBox& NC_mskr_fab);
62
63/** \brief helper function to initialize state from netcdf */
64void
66 FArrayBox& temp_fab, FArrayBox& salt_fab,
67 FArrayBox& x_vel_fab, FArrayBox& y_vel_fab,
72
73/** \brief helper function to initialize biology tracer state from netcdf */
74void
77
78/** \brief helper function to initialize passive (dye) scalar state from netcdf */
79void
82 const Vector<Vector<int>>& scalar_in_file);
83
84/** \brief helper function to read bathymetry from netcdf */
85void
86read_bathymetry_from_netcdf (int lev, const Box& domain, const std::string& fname,
87 FArrayBox& NC_h_fab);
88
89/** \brief helper function to read grid variables from netcdf */
90void
91read_grid_vars_from_netcdf (int lev, const Box& domain, const std::string& fname,
92 FArrayBox& NC_pm_fab, FArrayBox& NC_pn_fab,
93 FArrayBox& NC_xr_fab, FArrayBox& NC_yr_fab,
94 FArrayBox& NC_xu_fab, FArrayBox& NC_yu_fab,
95 FArrayBox& NC_xv_fab, FArrayBox& NC_yv_fab,
96 FArrayBox& NC_xp_fab, FArrayBox& NC_yp_fab);
97
98/** \brief helper function to read optional spherical psi coordinates from netcdf */
99bool
100read_spherical_grid_vars_from_netcdf (int lev, const Box& domain, const std::string& fname,
101 FArrayBox& NC_lonp_fab, FArrayBox& NC_latp_fab);
102
103/** \brief helper function to read full-domain high resolution bathymetry from netcdf */
104void
105read_bathymetry_full_domain_from_netcdf (const Box& domain, const std::string& fname,
106 FArrayBox& NC_h_fab, IntVect ngrow);
107
108/** \brief helper function to read full-domain high resolution grid variables from netcdf */
109void
110read_grid_vars_full_domain_from_netcdf (const Box& domain, const std::string& fname,
111 FArrayBox& NC_pm_fab, FArrayBox& NC_pn_fab,
112 IntVect ngrow);
113
114/** \brief helper function to read full-domain high resolution land/sea mask from netcdf */
115void
116read_masks_full_domain_from_netcdf (const Box& domain, const std::string& fname,
117 FArrayBox& NC_mskr_fab, IntVect ngrow);
118
119/** \brief helper function to read coriolis factor from netcdf */
120void
121read_coriolis_from_netcdf (int lev, const Box& domain, const std::string& fname, FArrayBox& NC_fcor_fab);
122
123/** \brief helper function to read sea surface height from netcdf */
124void
125read_zeta_from_netcdf (int lev, const Box& domain, const std::string& fname,
126 FArrayBox& NC_zeta_fab);
127
128/** \brief helper function to read high-resolution full-domain sea surface height from netcdf */
129void
130read_zeta_full_domain_from_netcdf (int lev, const Box& domain, const std::string& fname,
131 FArrayBox& NC_zeta_fab, IntVect ngrow);
132
133/** \brief helper function to read climatology nudging from netcdf */
134void
135read_clim_nudg_coeff_from_netcdf (int lev, const Box& domain, const std::string& fname,
136 bool do_m2_clim_nudg,
137 bool do_m3_clim_nudg,
138 const amrex::Vector<int>& do_cons_clim_nudg,
139 const amrex::Vector<std::string>& cons_names,
140 FArrayBox& NC_M2NC_fab,
141 FArrayBox& NC_M3NC_fab,
142 amrex::Vector<FArrayBox>& NC_ConsNC_fab,
143 amrex::Vector<int>& cons_coeff_in_file);
144
145/** \brief helper function to read in vector of data from netcdf */
146void read_vec_from_netcdf (int lev, const amrex::Vector<std::string>& fnames, const std::string& field_name, amrex::Vector<int>& vec_dat);
147
148/**
149 * @param lev Integer specifying the current level
150 */
151void
153{
154 // *** FArrayBox's at this level for holding the INITIAL data
159
160 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++)
161 {
165 }
166
167
168 MultiFab mf_temp(*cons_new[lev], make_alias, Temp_comp, 1);
169 MultiFab mf_salt(*cons_new[lev], make_alias, Salt_comp, 1);
170
171#ifdef _OPENMP
172#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
173#endif
174 {
175 // Don't tile this since we are operating on full FABs in this routine
176 for ( MFIter mfi(*cons_new[lev], false); mfi.isValid(); ++mfi )
177 {
178 // Define fabs for holding the initial data
179 FArrayBox &temp_fab = mf_temp[mfi];
180 FArrayBox &salt_fab = mf_salt[mfi];
181 FArrayBox &xvel_fab = (*xvel_new[lev])[mfi];
182 FArrayBox &yvel_fab = (*yvel_new[lev])[mfi];
183
188 } // mf
189 } // omp
190
191 // Zero every tracer past salinity. This is the starting point for the passive
192 // scalars, which the read below overwrites for each dye the file carries; the
193 // biology block is overwritten by init_biology_ic immediately after, so zeroing it
194 // here only guards against a partially filled biology IC.
196
197 // Passive scalars come from the same file, and from the same remora.ic_type that
198 // brought us here, so they are read here rather than through a source flag of
199 // their own the way biology is.
201}
202
203/**
204 * \brief Initialize the passive (dye) scalars from the initial NetCDF file.
205 *
206 * Unlike biology, dye has no initialization-source flag of its own: it follows
207 * remora.ic_type along with temperature, salinity, and velocity, so this is called
208 * from init_data_from_netcdf rather than from a dispatcher. Each dye whose variable
209 * the file carries is read into its own component; the rest keep the zero written
210 * just before the call.
211 *
212 * @param lev Integer specifying the current level
213 */
214void
216{
217 if (nscalar == 0) {
218 return;
219 }
220
221 Vector<std::string> scalar_names;
222 scalar_names.reserve(nscalar);
223 for (int icomp = Tracer_comp; icomp < Bio_comp; ++icomp) {
224 scalar_names.push_back(cons_names[icomp]);
225 }
226
227 // One FAB and one presence flag per dye per box
230 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++)
231 {
232 NC_scalar_fab[idx].resize(scalar_names.size());
235 }
236
238
239#ifdef _OPENMP
240#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
241#endif
242 {
243 // Don't tile this since we are operating on full FABs in this routine
244 for (MFIter mfi(mf_scalar, false); mfi.isValid(); ++mfi)
245 {
246 FArrayBox& scalar_fab = mf_scalar[mfi];
248 }
249 }
250}
251
252/**
253 * \brief Initialize the biological tracers from the initial NetCDF file.
254 *
255 * Called from init_biology_ic, which chooses between this and the analytic
256 * profile on remora.biology_ic_type rather than on remora.ic_type.
257 *
258 * @param lev Integer specifying the current level
259 */
260void
262{
264 return;
265 }
266
267 Vector<std::string> biology_names;
268 biology_names.reserve(nbio);
269 for (int icomp = Bio_comp; icomp < ncons; ++icomp) {
270 biology_names.push_back(cons_names[icomp]);
271 }
272
275 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++)
276 {
277 NC_biology_fab[idx].resize(biology_names.size());
280 }
281
283
284#ifdef _OPENMP
285#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
286#endif
287 {
288 // Dont tile this since we are operating on full FABs in this routine
289 for (MFIter mfi(mf_biology, false); mfi.isValid(); ++mfi)
290 {
291 FArrayBox& biology_fab = mf_biology[mfi];
293 }
294 }
295}
296
297void
299{
300 if (nc_init_file_hires.empty()) {
301 Abort("Must specify high-resolution initial file when initializing from NetCDF and hires_init_level > 0");
302 }
305
306 // *** FArrayBox's at this level for holding the INITIAL data
311
316
319
320#ifdef _OPENMP
321#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
322#endif
323 {
324 // Don't tile this since we are operating on full FABs in this routine
325 for ( MFIter mfi(mf_temp, false); mfi.isValid(); ++mfi )
326 {
327 // Define fabs for holding the initial data
328 FArrayBox &temp_fab = mf_temp[mfi];
329 FArrayBox &salt_fab = mf_salt[mfi];
332
337 } // mf
338 } // omp
339
341
342 // Passive scalars, before the average down below carries this level's data to the
343 // levels beneath it. Biology is filled separately by init_biology_ic_full_domain,
344 // which does its own average down.
346
347 // Average down to fill levels below hires_grid_level. Use a special average_down so
348 // grow cells get populated by averaged down fine data
349 for (int lev=hires_init_level-1; lev >= 0; lev--) {
353 }
354}
355
356/**
357 * \brief Full-domain counterpart of init_scalars_from_netcdf, for the hires_init_level
358 * average-down path. Called from init_data_full_domain_from_netcdf before that
359 * routine averages vec_cons_full_domain down, so no average down is needed here.
360 */
361void
363{
364 if (nscalar == 0) {
365 return;
366 }
367
368 Vector<std::string> scalar_names;
369 scalar_names.reserve(nscalar);
370 for (int icomp = Tracer_comp; icomp < Bio_comp; ++icomp) {
371 scalar_names.push_back(cons_names[icomp]);
372 }
373
376 NC_scalar_fab[0].resize(scalar_names.size());
377
381
383
384#ifdef _OPENMP
385#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
386#endif
387 {
388 // Don't tile this since we are operating on full FABs in this routine
389 for (MFIter mfi(mf_scalar, false); mfi.isValid(); ++mfi)
390 {
391 FArrayBox& scalar_fab = mf_scalar[mfi];
393 }
394 }
395}
396
397/** \brief Biology initialization from full-domain NetCDF file */
398void
400{
402 return;
403 }
404
405 Vector<std::string> biology_names;
406 biology_names.reserve(nbio);
407 for (int icomp = Bio_comp; icomp < ncons; ++icomp) {
408 biology_names.push_back(cons_names[icomp]);
409 }
410
412 NC_biology_fab.resize(1);
413 NC_biology_fab[0].resize(biology_names.size());
414
418
420
421#ifdef _OPENMP
422#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
423#endif
424 {
425 // Dont tile this since we are operating on full FABs in this routine
426 for (MFIter mfi(mf_biology, false); mfi.isValid(); ++mfi)
427 {
428 FArrayBox& biology_fab = mf_biology[mfi];
430 }
431 }
432
433 // The average-down lives in init_biology_ic_full_domain, which owns both sources.
434}
435
436/**
437 * @param lev Integer specifying the current level
438 */
439void
441{
442 // *** FArrayBox's at this level for holding the INITIAL data
444
445 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++)
446 {
449
450#ifdef _OPENMP
451#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
452#endif
453 {
454 // Don't tile this since we are operating on full FABs in this routine
455 for ( MFIter mfi(*cons_new[lev], false); mfi.isValid(); ++mfi )
456 {
457 FArrayBox &zeta_fab = (*vec_zeta[lev])[mfi];
458
459 //
460 // FArrayBox to FArrayBox copy does "copy on intersection"
461 // This only works here because we have broadcast the FArrayBox of data from the netcdf file to all ranks
462 //
463
465 } // mf
466 } // omp
467 } // idx
468
469 vec_zeta[lev]->FillBoundary(geom[lev].periodicity());
470 (*physbcs[lev])(*vec_zeta[lev],*vec_mskr[lev].get(),0,1,vec_zeta[lev]->nGrowVect(),t_new[lev],zeta_bc(),0,*vec_zeta[lev],*vec_msku[lev],*vec_mskv[lev]);
471// (*physbcs[lev])(*vec_zeta[lev],*vec_mskr[lev].get(),1,1,vec_zeta[lev]->nGrowVect(),t_new[lev],BCVars::zeta_bc);
472// (*physbcs[lev])(*vec_zeta[lev],*vec_mskr[lev].get(),2,1,vec_zeta[lev]->nGrowVect(),t_new[lev],BCVars::zeta_bc);
473
475 Real told = t_new[lev];
477 *vec_zeta[lev]);
478 }
479 if (lev>0) {
481 0, false,false,0,0,zero,*vec_zeta[lev]);
482 }
483}
484
485void
487{
488 if (nc_init_file_hires.empty()) {
489 Abort("Must specify high-resolution initial file when initializing from NetCDF and hires_init_level > 0");
490 }
493
494 // *** FArrayBox's at this level for holding the INITIAL data
496
499
500#ifdef _OPENMP
501#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
502#endif
503 {
504 // Don't tile this since we are operating on full FABs in this routine
505 for ( MFIter mfi(*vec_zeta_full_domain[hires_init_level], false); mfi.isValid(); ++mfi )
506 {
508
509 //
510 // FArrayBox to FArrayBox copy does "copy on intersection"
511 // This only works here because we have broadcast the FArrayBox of data from the netcdf file to all ranks
512 //
513
514 zeta_fab.template copy<RunOn::Device>(NC_zeta_fab[0],0,0,1);
515 } // mf
516 } // omp
517
518 // Average down to fill levels below hires_grid_level. Use a special average_down so
519 // grow cells get populated by averaged down fine data
520 for (int lev=hires_init_level-1; lev >= 0; lev--) {
522 }
523}
524
525
526/**
527 * @param lev Integer specifying the current level
528 */
529void
531{
532 // *** FArrayBox's at this level for holding the INITIAL data
535
544
545 // Optional spherical psi coordinates (see read_spherical_grid_vars_from_netcdf)
548 bool have_spherical_psi = true;
549
550 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++)
551 {
558
559 // All boxes at this level must agree: a partial set would leave holes in
560 // the corner mesh that a conservative remap cannot detect.
564
565 // Mirror vec_xp exactly: same nodal psi BoxArray, DistributionMap and ngrow.
566 if (have_spherical_psi && vec_lonp[lev] == nullptr) {
567 vec_lonp[lev].reset(new MultiFab(vec_xp[lev]->boxArray(), vec_xp[lev]->DistributionMap(),
568 1, vec_xp[lev]->nGrowVect()));
569 vec_latp[lev].reset(new MultiFab(vec_xp[lev]->boxArray(), vec_xp[lev]->DistributionMap(),
570 1, vec_xp[lev]->nGrowVect()));
571 }
572
573#ifdef _OPENMP
574#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
575#endif
576 {
577 // Don't tile this since we are operating on full FABs in this routine
578 for ( MFIter mfi(*cons_new[lev], false); mfi.isValid(); ++mfi )
579 {
580 FArrayBox &pm_fab = (*vec_pm[lev])[mfi];
581 FArrayBox &pn_fab = (*vec_pn[lev])[mfi];
582 FArrayBox &xr_fab = (*vec_xr[lev])[mfi];
583 FArrayBox &yr_fab = (*vec_yr[lev])[mfi];
584 FArrayBox &xu_fab = (*vec_xu[lev])[mfi];
585 FArrayBox &yu_fab = (*vec_yu[lev])[mfi];
586 FArrayBox &xv_fab = (*vec_xv[lev])[mfi];
587 FArrayBox &yv_fab = (*vec_yv[lev])[mfi];
588 FArrayBox &xp_fab = (*vec_xp[lev])[mfi];
589 FArrayBox &yp_fab = (*vec_yp[lev])[mfi];
590
591 //
592 // FArrayBox to FArrayBox copy does "copy on intersection"
593 // This only works here because we have broadcast the FArrayBox of data from the netcdf file to all ranks
594 //
595
598
607
608 if (have_spherical_psi) {
611 }
612 } // mf
613 } // omp
614 } // idx
615
616 // Drop any partial allocation so the getter's null contract stays honest.
617 if (!have_spherical_psi) {
618 vec_lonp[lev].reset();
619 vec_latp[lev].reset();
620 }
621
622 Real dummy_time = zero;
623 if (lev > 0) {
626 BdyVars::null,0,false);
629 BdyVars::null,0,false);
630 }
631
632
633 int ng = vec_pm[lev]->nGrow();
634
635 const auto& dom_lo = amrex::lbound(geom[lev].Domain());
636 const auto& dom_hi = amrex::ubound(geom[lev].Domain());
637
638 //
639 // We need values of pm and pn outside the domain so we fill
640 // them here with foextrap
641 //
642 // We first fill interior ghost cells because we will need to extrapolate
643 // from ghost cells inside the domain to ghost cells outside the domain
644 //
645 vec_pm[lev]->FillBoundary(geom[lev].periodicity());
646 vec_pn[lev]->FillBoundary(geom[lev].periodicity());
647
648 vec_xr[lev]->FillBoundary(geom[lev].periodicity());
649 vec_yr[lev]->FillBoundary(geom[lev].periodicity());
650 vec_xu[lev]->FillBoundary(geom[lev].periodicity());
651 vec_yu[lev]->FillBoundary(geom[lev].periodicity());
652 vec_xv[lev]->FillBoundary(geom[lev].periodicity());
653 vec_yv[lev]->FillBoundary(geom[lev].periodicity());
654 vec_xp[lev]->FillBoundary(geom[lev].periodicity());
655 vec_yp[lev]->FillBoundary(geom[lev].periodicity());
656 if (vec_lonp[lev] != nullptr) {
657 vec_lonp[lev]->FillBoundary(geom[lev].periodicity());
658 vec_latp[lev]->FillBoundary(geom[lev].periodicity());
659 }
660
663}
664
665/**
666 * @param lev Integer specifying the current level
667 */
668void
670{
671 // *** FArrayBox's at this level for holding the INITIAL data
673 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++)
674 {
676 NC_h_fab[idx]);
677
678#ifdef _OPENMP
679#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
680#endif
681 {
682 // Don't tile this since we are operating on full FABs in this routine
683 for ( MFIter mfi(*cons_new[lev], false); mfi.isValid(); ++mfi )
684 {
685 FArrayBox &h_fab = (*vec_h[lev])[mfi];
686
687 //
688 // FArrayBox to FArrayBox copy does "copy on intersection"
689 // This only works here because we have broadcast the FArrayBox of data from the netcdf file to all ranks
690 //
691
692 // Copy into both components of h
693 h_fab.template copy<RunOn::Device>(NC_h_fab[idx],0,0,1);
694 h_fab.template copy<RunOn::Device>(NC_h_fab[idx],0,1,1);
695 } // mf
696 } // omp
697 } // idx
698
699 const double dummy_time = zero;
700 // Unconditional foextrap will overwrite periodicity, but EnforcePeriodicity will
701 // be called on h afterwards
704 BdyVars::null,0,false,false,1);
707 BdyVars::null,1,false,false,1);
708
709 vec_h[lev]->FillBoundary(geom[lev].periodicity());
710}
711
712/**
713 * @param lev Integer specifying the current level
714 */
715void
717{
718 // *** FArrayBox's at this level for holding the INITIAL data
720
721 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++)
722 {
725
726#ifdef _OPENMP
727#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
728#endif
729 {
730 // Don't tile this since we are operating on full FABs in this routine
731 for ( MFIter mfi(*cons_new[lev], false); mfi.isValid(); ++mfi )
732 {
733 FArrayBox &fcor_fab = (*vec_fcor[lev])[mfi];
734
735 //
736 // FArrayBox to FArrayBox copy does "copy on intersection"
737 // This only works here because we have broadcast the FArrayBox of data from the netcdf file to all ranks
738 //
739
741 } // mf
742 } // omp
743 } // idx
744 vec_fcor[lev]->FillBoundary(geom[lev].periodicity());
745}
746
747/**
748 * @param lev Integer specifying the current level
749 */
750void
752{
753 // *** FArrayBox's at this level for holding the INITIAL data
755
756 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++)
757 {
760
761#ifdef _OPENMP
762#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
763#endif
764 {
765 // Don't tile this since we are operating on full FABs in this routine
766 for ( MFIter mfi(*cons_new[lev], false); mfi.isValid(); ++mfi )
767 {
768 FArrayBox &mskr_fab = (*vec_mskr[lev])[mfi];
769
770 //
771 // FArrayBox to FArrayBox copy does "copy on intersection"
772 // This only works here because we have broadcast the FArrayBox of data from the netcdf file to all ranks
773 //
774
776 } // mf
777 } // omp
778 } // idx
779
780 // Ghosts first: update_nodal_masks reaches mskr(i-1,j-1).
781 vec_mskr[lev]->FillBoundary(geom[lev].periodicity());
783}
784
785/**
786 * @param lev Integer specifying the current level
787 */
788void
790{
791 if (nc_bdry_file.empty() || nc_bdry_file[0].empty()) {
792 amrex::Error("NetCDF boundary file name must be provided via input");
793 }
794
795 // One boundary series per BdyVars slot. Every cell-centered tracer gets one, named
796 // for the variable itself ("temp", "salt", "NO3", ...), so the file is expected to
797 // hold e.g. NO3_west following the same convention ROMS uses. A series whose
798 // variable needs no boundary data reads nothing -- NCTimeSeriesBoundary only asks
799 // for the sides flagged in phys_bc_need_data -- so tracers left on a local BC do
800 // not require the file to contain anything for them.
801 amrex::Vector<std::string> field_name (num_bdy_vars());
802 amrex::Vector<IntVect > index_types(num_bdy_vars());
803 std::vector<bool > is_2d (num_bdy_vars());
804
805 field_name[BdyVars::u] = "u"; index_types[BdyVars::u] = IntVect(1,0,0); is_2d[BdyVars::u] = false;
806 field_name[BdyVars::v] = "v"; index_types[BdyVars::v] = IntVect(0,1,0); is_2d[BdyVars::v] = false;
807 for (int icomp = 0; icomp < ncons; ++icomp) {
808 const int ibdy = BdyVars::cons(icomp);
809 field_name[ibdy] = cons_names[icomp];
810 index_types[ibdy] = IntVect(0,0,0);
811 is_2d[ibdy] = false;
812 }
813 field_name[bdy_ubar()] = "ubar"; index_types[bdy_ubar()] = IntVect(1,0,0); is_2d[bdy_ubar()] = true;
814 field_name[bdy_vbar()] = "vbar"; index_types[bdy_vbar()] = IntVect(0,1,0); is_2d[bdy_vbar()] = true;
815 field_name[bdy_zeta()] = "zeta"; index_types[bdy_zeta()] = IntVect(0,0,0); is_2d[bdy_zeta()] = true;
816
817 amrex::Print() << "DOING INIT AT LEVEL " << lev << std::endl;
818 int rx = 1; int ry = 1;
819 if (lev > 0) {
820 for (int k = lev-1; k >= 0; k--) {
821 rx *= ref_ratio[k][0];
822 ry *= ref_ratio[k][1];
823 }
824 }
825 for (int ivar = 0; ivar < num_bdy_vars(); ivar++) {
826 boundary_series[lev].push_back(std::unique_ptr<NCTimeSeriesBoundary>(new NCTimeSeriesBoundary(lev, geom, nc_bdry_file, field_name[ivar],
830 boundary_series[lev][ivar]->Initialize();
831 }
832}
833
834/**
835 * \brief Helper function to initialize state and velocity data in a Fab.
836 *
837 * @param lev Integer specifying current level
838 * @param state_fab FArrayBox object holding the state data we initialize
839 * @param temp_fab FArrayBox object holding the temperature data we initialize
840 * @param salt_fab FArrayBox object holding the salt data we initialize
841 * @param x_vel_fab FArrayBox object holding the x-velocity data we initialize
842 * @param y_vel_fab FArrayBox object holding the y-velocity data we initialize
843 * @param NC_temp_fab Vector of FArrayBox objects with the REMORA dataset specifying temperature
844 * @param NC_salt_fab Vector of FArrayBox objects with the REMORA dataset specifying salinity
845 * @param NC_xvel_fab Vector of FArrayBox objects with the REMORA dataset specifying x-velocity
846 * @param NC_yvel_fab Vector of FArrayBox objects with the REMORA dataset specifying y-velocity
847 */
848void
850 FArrayBox& temp_fab, FArrayBox& salt_fab,
851 FArrayBox& x_vel_fab, FArrayBox& y_vel_fab,
856{
857 int nboxes = NC_xvel_fab.size();
858 for (int idx = 0; idx < nboxes; idx++)
859 {
860 //
861 // FArrayBox to FArrayBox copy does "copy on intersection"
862 // This only works here because we have broadcast the FArrayBox of data from the netcdf file to all ranks
863 //
868 } // idx
869}
870
871/**
872 * @param lev Integer specifying current level
873 * @param biology_fab FArrayBox object holding the biology components we initialize
874 * @param NC_biology_fab Vector of FArrayBox objects with the REMORA dataset specifying
875 * each biological tracer, one per component per box
876 */
877void
880{
881 int nboxes = NC_biology_fab.size();
882 for (int idx = 0; idx < nboxes; idx++)
883 {
884 AMREX_ALWAYS_ASSERT(static_cast<int>(NC_biology_fab[idx].size()) == biology_fab.nComp());
885 for (int ibio = 0; ibio < biology_fab.nComp(); ++ibio) {
887 }
888 }
889}
890
891/**
892 * @param lev Integer specifying current level
893 * @param scalar_fab FArrayBox object holding the passive scalar components we initialize
894 * @param NC_scalar_fab Vector of FArrayBox objects with the REMORA dataset specifying
895 * each dye, one per component per box
896 * @param scalar_in_file Per box and component, whether the file carried that dye; a dye
897 * the file omits keeps the zero written before the read
898 */
899void
902 const Vector<Vector<int>>& scalar_in_file)
903{
904 int nboxes = NC_scalar_fab.size();
905 for (int idx = 0; idx < nboxes; idx++)
906 {
907 AMREX_ALWAYS_ASSERT(static_cast<int>(NC_scalar_fab[idx].size()) == scalar_fab.nComp());
908 AMREX_ALWAYS_ASSERT(static_cast<int>(scalar_in_file[idx].size()) == scalar_fab.nComp());
909 for (int iscal = 0; iscal < scalar_fab.nComp(); ++iscal) {
910 // A dye the file does not carry has no FAB built for it, so leave the zero
911 // that was written before the read.
912 if (!scalar_in_file[idx][iscal]) { continue; }
914 }
915 }
916}
917
918/**
919 * @param lev Integer specifying the current level
920 */
921void
923{
924 // *** FArrayBox's at this level for holding the INITIAL data
927 // One coefficient FAB per cons component per box
929 // Per box, whether each tracer's coefficient was actually present in the file
931 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++) {
932 NC_ConsNC_fab[idx].resize(ncons);
933 cons_coeff_in_file[idx].assign(ncons, 0);
934 }
935 // Aggregated over boxes: whether each tracer's coefficient came from the file
936 Vector<int> cons_coeff_read(ncons, 0);
937
938 for (int idx = 0; idx < num_boxes_at_level[lev]; idx++)
939 {
947
948#ifdef _OPENMP
949#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
950#endif
951 {
952 // Don't tile this since we are operating on full FABs in this routine
953 for ( MFIter mfi(*cons_new[lev], false); mfi.isValid(); ++mfi )
954 {
956 FArrayBox &ubarNC_fab = (*vec_nudg_coeff[bdy_ubar()][lev])[mfi];
958 FArrayBox &vbarNC_fab = (*vec_nudg_coeff[bdy_vbar()][lev])[mfi];
960 }
962 FArrayBox &uNC_fab = (*vec_nudg_coeff[BdyVars::u][lev])[mfi];
964 FArrayBox &vNC_fab = (*vec_nudg_coeff[BdyVars::v][lev])[mfi];
966 }
967 for (int icomp = 0; icomp < ncons; ++icomp) {
968 if (!cons_coeff_in_file[idx][icomp]) { continue; }
971 }
972
973 } // mf
974 } // omp
975
976 for (int icomp = 0; icomp < ncons; ++icomp) {
978 }
979 } // idx
980
982 vec_nudg_coeff[bdy_ubar()][lev]->FillBoundary(geom[lev].periodicity());
983 vec_nudg_coeff[bdy_vbar()][lev]->FillBoundary(geom[lev].periodicity());
986 }
988 vec_nudg_coeff[BdyVars::u][lev]->FillBoundary(geom[lev].periodicity());
989 vec_nudg_coeff[BdyVars::v][lev]->FillBoundary(geom[lev].periodicity());
992 }
993 // Only convert the tracers whose coefficient actually came from the file: the rest
994 // still hold the constant set by init_clim_nudg_coeff, which is already in 1/s.
995 for (int icomp = 0; icomp < ncons; ++icomp) {
996 if (!cons_coeff_read[icomp]) { continue; }
999 }
1000}
1001
1002/**
1003 * @param[in ] lev level to read in river data
1004 */
1005void
1007{
1008 amrex::Vector<int> river_pos_x;
1009 amrex::Vector<int> river_pos_y;
1010 amrex::Vector<int> river_direction_tmp;
1011
1012 std::string river_x_name = "river_Xposition";
1013 std::string river_y_name = "river_Eposition";
1014 std::string river_dir_name = "river_direction";
1015
1019
1020 if (river_pos_x.empty() ||
1021 river_pos_y.size() != river_pos_x.size() ||
1022 river_direction_tmp.size() != river_pos_x.size())
1023 {
1024 amrex::Abort("River metadata arrays must be nonempty and have matching lengths: " +
1025 river_x_name + "=" + std::to_string(river_pos_x.size()) + ", " +
1026 river_y_name + "=" + std::to_string(river_pos_y.size()) + ", " +
1027 river_dir_name + "=" + std::to_string(river_direction_tmp.size()));
1028 }
1029
1030 int nriv = river_pos_x.size();
1031 amrex::Gpu::DeviceVector<int> xpos_d(nriv);
1032 amrex::Gpu::DeviceVector<int> ypos_d(nriv);
1033 river_direction.resize(nriv);
1034
1035 int rrx = (lev > 0) ? cum_ref_ratios[lev][0] : 1;
1036 int rry = (lev > 0) ? cum_ref_ratios[lev][1] : 1;
1037
1038 // Map river source indices to the target AMR level while keeping one source
1039 // point per river so total prescribed transport is unchanged.
1040 amrex::Vector<int> river_pos_x_lev(nriv);
1041 amrex::Vector<int> river_pos_y_lev(nriv);
1042 for (int iriv = 0; iriv < nriv; ++iriv) {
1043 int x0 = river_pos_x[iriv] - 1;
1044 int y0 = river_pos_y[iriv] - 1;
1045
1046 if (river_direction_tmp[iriv] == 0) {
1047 // u-face aligned in x, centered in y within the refined coarse cell.
1049 river_pos_y_lev[iriv] = y0 * rry + (rry - 1) / 2;
1050 } else {
1051 // v-face aligned in y, centered in x within the refined coarse cell.
1052 river_pos_x_lev[iriv] = x0 * rrx + (rrx - 1) / 2;
1054 }
1055 }
1056#ifdef AMREX_USE_GPU
1057 Gpu::htod_memcpy(xpos_d.data(), river_pos_x_lev.data(), sizeof(int)*nriv);
1058 Gpu::htod_memcpy(ypos_d.data(), river_pos_y_lev.data(), sizeof(int)*nriv);
1059 Gpu::htod_memcpy(river_direction.data(), river_direction_tmp.data(), sizeof(int)*nriv);
1060#else
1061 std::memcpy(xpos_d.data(), river_pos_x_lev.data(), sizeof(int)*nriv);
1062 std::memcpy(ypos_d.data(), river_pos_y_lev.data(), sizeof(int)*nriv);
1063 std::memcpy(river_direction.data(), river_direction_tmp.data(), sizeof(int)*nriv);
1064#endif
1065 const int* xpos_ptr = xpos_d.data();
1066 const int* ypos_ptr = ypos_d.data();
1067
1068 for (amrex::MFIter mfi(*(vec_river_position[lev]).get(),true); mfi.isValid(); ++mfi) {
1069 amrex::Box bx = mfi.growntilebox(amrex::IntVect(NGROW,NGROW,0));
1070 auto river_pos = vec_river_position[lev]->array(mfi);
1071 ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int ) {
1072 for (int iriv=0; iriv < nriv; iriv++) {
1073 int xriv = xpos_ptr[iriv];
1074 int yriv = ypos_ptr[iriv];
1075 if (i==xriv && j==yriv) {
1076 river_pos(i,j,0) = iriv;
1077 }
1078 }
1079 });
1080 }
1081
1082 if (verbose) {
1083 amrex::Print() << "[river-debug] lev=" << lev
1084 << " ref_ratio=(" << rrx << "," << rry << ")"
1085 << " nriv=" << nriv << '\n';
1086 for (int iriv = 0; iriv < nriv; ++iriv) {
1087 amrex::Print() << "[river-debug] river " << iriv
1088 << " dir=" << river_direction_tmp[iriv]
1089 << " nc=(" << river_pos_x[iriv] << "," << river_pos_y[iriv] << ")"
1090 << " lev=(" << river_pos_x_lev[iriv] + 1 << "," << river_pos_y_lev[iriv] + 1 << ")"
1091 << '\n';
1092 }
1093 }
1094}
1095
1096/**
1097 * @param[inout] mf multifab of data to convert
1098 */
1099void
1101 Real inv_days_to_inv_s = one / (Real(3600.0) * Real(24.0));
1102
1103 for ( MFIter mfi(*mf, TilingIfNotGPU()); mfi.isValid(); ++mfi )
1104 {
1105 Array4<Real> const& arr = mf->array(mfi);
1106 Box bx = mfi.growntilebox(IntVect(NGROW,NGROW,0));
1107 ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) {
1109 });
1110 }
1111
1112}
1113
1114void
1116{
1117 if (nc_grid_file_hires.empty()) {
1118 Abort("Must specify high-resolution grid file when initializing from NetCDF and hires_grid_level > 0");
1119 }
1122
1125
1126 // Don't tile this since we are operating on full FABs in this routine
1127 for ( MFIter mfi(*vec_h_full_domain[hires_grid_level], false); mfi.isValid(); ++mfi )
1128 {
1129 FArrayBox &h_fab = (*vec_h_full_domain[hires_grid_level])[mfi];
1130 h_fab.template copy<RunOn::Device>(NC_h_fab[0]);
1131 }
1132
1133 // Coarsen to fill levels below hires_grid_level, grow cells included. Mask-weighted, so a
1134 // coarse cell only partly covered by water takes the depth of that water.
1135 for (int lev=hires_grid_level-1; lev >= 0; lev--) {
1137 }
1138}
1139
1140void
1142{
1143 if (nc_grid_file_hires.empty()) {
1144 Abort("Must specify high-resolution grid file when remora.mask_type = netcdf and hires_grid_level > 0");
1145 }
1148
1152
1153 // Don't tile this since we are operating on full FABs in this routine
1154 for ( MFIter mfi(*vec_mskr_full_domain[hires_grid_level], false); mfi.isValid(); ++mfi )
1155 {
1158 }
1159
1160 // Coarsen to fill the levels below hires_grid_level. Not average_down_with_grow_cells:
1161 // a mask has to stay exactly 0 or 1, so this takes "wet if any fine cell is wet".
1162 for (int lev=hires_grid_level-1; lev >= 0; lev--) {
1164 }
1165}
1166
1167void
1169{
1170 if (nc_grid_file_hires.empty()) {
1171 Abort("Must specify high-resolution grid file when initializing from NetCDF and hires_grid_level > 0");
1172 }
1175
1178
1180 NC_pm_fab[0], NC_pn_fab[0],
1182
1183 // Don't tile this since we are operating on full FABs in this routine
1184 for ( MFIter mfi(*vec_h_full_domain[hires_grid_level], false); mfi.isValid(); ++mfi )
1185 {
1190 }
1191
1192 // Average down to fill levels below hires_grid_level. Use a special average_down so
1193 // grow cells get populated by averaged down fine data
1194 for (int lev=hires_grid_level-1; lev >= 0; lev--) {
1197
1198 int rrx = ref_ratio[lev][0];
1199 int rry = ref_ratio[lev][1];
1200 // pm and pn need to be rescaled by the refinement ratio
1201 for ( MFIter mfi(*vec_h_full_domain[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi )
1202 {
1203 Array4<Real> const& pm = vec_pm_full_domain[lev]->array(mfi);
1204 Array4<Real> const& pn = vec_pn_full_domain[lev]->array(mfi);
1205 Box ubx = mfi.growntilebox(cum_ref_ratios[lev] - IntVect(1,0,0));;
1206 Box vbx = mfi.growntilebox(cum_ref_ratios[lev] - IntVect(0,1,0));;
1207 ParallelFor(makeSlab(ubx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int ) {
1208 pm(i,j,0) = pm(i,j,0) / Real(rrx);
1209 });
1210 ParallelFor(makeSlab(vbx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int ) {
1211 pn(i,j,0) = pn(i,j,0) / Real(rry);
1212 });
1213 }
1214 }
1215
1216 for (int lev=0; lev<=hires_grid_level; lev++) {
1219 }
1220}
1221
1222/**
1223 * @param[inout] mf multifab of data to extrapolate on
1224 * @param[in ] geom geometry
1225 */
1226void
1228{
1229 const IntVect ng = mf.nGrowVect();
1230
1231 const auto& dom_lo = amrex::lbound(geom.Domain());
1232 const auto& dom_hi = amrex::ubound(geom.Domain());
1233
1234 for ( MFIter mfi(mf); mfi.isValid(); ++mfi )
1235 {
1236 Box bx = mfi.tilebox();
1237
1238 auto mf_arr = mf.array(mfi);
1239
1240 Box gbx_lox = adjCellLo(bx,0,ng[0]); gbx_lox.grow(1,ng[1]); gbx_lox.setBig (0,dom_lo.x-2);
1241 Box gbx_hix = adjCellHi(bx,0,ng[0]); gbx_hix.grow(1,ng[1]); gbx_hix.setSmall(0,dom_hi.x+2);
1242 Box gbx_loy = adjCellLo(bx,1,ng[1]); gbx_loy.grow(0,ng[0]); gbx_loy.setBig (1,dom_lo.y-2);
1243 Box gbx_hiy = adjCellHi(bx,1,ng[1]); gbx_hiy.grow(0,ng[0]); gbx_hiy.setSmall(1,dom_hi.y+2);
1244
1245 if (gbx_lox.ok()) {
1246 ParallelFor(gbx_lox, [=] AMREX_GPU_DEVICE (int i, int j, int k)
1247 {
1248 mf_arr(i,j,k,0) = mf_arr(dom_lo.x-1,j,k,0);
1249 });
1250 }
1251 if (gbx_hix.ok()) {
1252 ParallelFor(gbx_hix, [=] AMREX_GPU_DEVICE (int i, int j, int k)
1253 {
1254 mf_arr(i,j,k,0) = mf_arr(dom_hi.x+1,j,k,0);
1255 });
1256 }
1257 if (gbx_loy.ok()) {
1258 ParallelFor(gbx_loy, [=] AMREX_GPU_DEVICE (int i, int j, int k)
1259 {
1260 mf_arr(i,j,k,0) = mf_arr(i,dom_lo.y-1,k,0);
1261 });
1262 }
1263 if (gbx_hiy.ok()) {
1264 ParallelFor(gbx_hiy, [=] AMREX_GPU_DEVICE (int i, int j, int k)
1265 {
1266 mf_arr(i,j,k,0) = mf_arr(i,dom_hi.y+1,k,0);
1267 });
1268 }
1269 } // mfi
1270}
1271
1272#endif // REMORA_USE_NETCDF
constexpr amrex::Real one
constexpr amrex::Real zero
#define NGROW
#define Temp_comp
#define Tracer_comp
#define Salt_comp
mf_h setVal(geomdata.ProbHi(2))
AMREX_ALWAYS_ASSERT(!NSPeriodic||!EWPeriodic)
void read_vec_from_netcdf(int lev, const amrex::Vector< std::string > &fnames, const std::string &field_name, amrex::Vector< int > &vec_dat)
helper function to read in vector of data from netcdf
void read_coriolis_from_netcdf(int lev, const Box &domain, const std::string &fname, FArrayBox &NC_fcor_fab)
helper function to read coriolis factor from netcdf
void read_grid_vars_from_netcdf(int lev, const Box &domain, const std::string &fname, FArrayBox &NC_pm_fab, FArrayBox &NC_pn_fab, FArrayBox &NC_xr_fab, FArrayBox &NC_yr_fab, FArrayBox &NC_xu_fab, FArrayBox &NC_yu_fab, FArrayBox &NC_xv_fab, FArrayBox &NC_yv_fab, FArrayBox &NC_xp_fab, FArrayBox &NC_yp_fab)
helper function to read grid variables from netcdf
void read_masks_full_domain_from_netcdf(const Box &domain, const std::string &fname, FArrayBox &NC_mskr_fab, IntVect ngrow)
helper function to read full-domain high resolution land/sea mask from netcdf
void read_zeta_from_netcdf(int lev, const Box &domain, const std::string &fname, FArrayBox &NC_zeta_fab)
helper function to read sea surface height from netcdf
void read_bathymetry_from_netcdf(int lev, const Box &domain, const std::string &fname, FArrayBox &NC_h_fab)
helper function to read bathymetry from netcdf
void read_scalars_full_domain_from_netcdf(int, const Box &domain, const std::string &fname, const Vector< std::string > &scalar_names, Vector< FArrayBox > &NC_scalar_fab, Vector< int > &scalar_in_file, IntVect ngrow)
helper function for reading in full domain high-resolution initial passive (dye) scalar data from net...
void read_data_full_domain_from_netcdf(int, const Box &domain, const std::string &fname, FArrayBox &NC_temp_fab, FArrayBox &NC_salt_fab, FArrayBox &NC_xvel_fab, FArrayBox &NC_yvel_fab, IntVect ngrow)
helper function for reading in full domain high-resolution initial state data from netcdf
void init_state_from_netcdf(int lev, FArrayBox &temp_fab, FArrayBox &salt_fab, FArrayBox &x_vel_fab, FArrayBox &y_vel_fab, const Vector< FArrayBox > &NC_temp_fab, const Vector< FArrayBox > &NC_salt_fab, const Vector< FArrayBox > &NC_xvel_fab, const Vector< FArrayBox > &NC_yvel_fab)
helper function to initialize state from netcdf
void check_hires_dims_from_netcdf(const std::string &fname, const std::string &var_name, const Box &domain, const IntVect &ngrow)
helper function checking that a high-resolution file covers the refined domain plus grow cells
void read_biology_from_netcdf(int, const Box &domain, const std::string &fname, const Vector< std::string > &biology_names, Vector< FArrayBox > &NC_biology_fab)
helper function for reading in initial biology data from netcdf
void read_bathymetry_full_domain_from_netcdf(const Box &domain, const std::string &fname, FArrayBox &NC_h_fab, IntVect ngrow)
helper function to read full-domain high resolution bathymetry from netcdf
void init_biology_state_from_netcdf(int lev, FArrayBox &biology_fab, const Vector< Vector< FArrayBox > > &NC_biology_fab)
helper function to initialize biology tracer state from netcdf
void read_biology_full_domain_from_netcdf(int, const Box &domain, const std::string &fname, const Vector< std::string > &biology_names, Vector< FArrayBox > &NC_biology_fab, IntVect ngrow)
helper function for reading in full domain high-resolution initial biology data from netcdf
void read_masks_from_netcdf(int, const Box &domain, const std::string &fname, FArrayBox &NC_mskr_fab)
helper function for reading in the rho-point land-sea mask from netcdf
void read_data_from_netcdf(int, const Box &domain, const std::string &fname, FArrayBox &NC_temp_fab, FArrayBox &NC_salt_fab, FArrayBox &NC_xvel_fab, FArrayBox &NC_yvel_fab)
helper function for reading in initial state data from netcdf
void read_zeta_full_domain_from_netcdf(int lev, const Box &domain, const std::string &fname, FArrayBox &NC_zeta_fab, IntVect ngrow)
helper function to read high-resolution full-domain sea surface height from netcdf
void read_scalars_from_netcdf(int, const Box &domain, const std::string &fname, const Vector< std::string > &scalar_names, Vector< FArrayBox > &NC_scalar_fab, Vector< int > &scalar_in_file)
helper function for reading in initial passive (dye) scalar data from netcdf
void init_scalar_state_from_netcdf(int lev, FArrayBox &scalar_fab, const Vector< Vector< FArrayBox > > &NC_scalar_fab, const Vector< Vector< int > > &scalar_in_file)
helper function to initialize passive (dye) scalar state from netcdf
bool read_spherical_grid_vars_from_netcdf(int lev, const Box &domain, const std::string &fname, FArrayBox &NC_lonp_fab, FArrayBox &NC_latp_fab)
helper function to read optional spherical psi coordinates from netcdf
void read_grid_vars_full_domain_from_netcdf(const Box &domain, const std::string &fname, FArrayBox &NC_pm_fab, FArrayBox &NC_pn_fab, IntVect ngrow)
helper function to read full-domain high resolution grid variables from netcdf
void read_clim_nudg_coeff_from_netcdf(int lev, const Box &domain, const std::string &fname, bool do_m2_clim_nudg, bool do_m3_clim_nudg, const amrex::Vector< int > &do_cons_clim_nudg, const amrex::Vector< std::string > &cons_names, FArrayBox &NC_M2NC_fab, FArrayBox &NC_M3NC_fab, amrex::Vector< FArrayBox > &NC_ConsNC_fab, amrex::Vector< int > &cons_coeff_in_file)
helper function to read climatology nudging from netcdf
A class to hold and interpolate time series data read from a NetCDF file.
std::string nc_grid_file_hires
Grid file for high resolution bathymetry.
Definition REMORA.H:2014
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr_full_domain
Land/sea mask at cell centers on the whole domain at each potential level. Specified at hires_grid_le...
Definition REMORA.H:421
amrex::Vector< std::string > nc_riv_file
NetCDF river file(s)
Definition REMORA.H:2031
int foextrap_periodic_bc() const noexcept
Definition REMORA.H:1455
int ncons
Number of conserved scalars in the state (temperature + salt + passive scalars + biology tracers)
Definition REMORA.H:1797
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta_full_domain
high resolution initial free surface height (2D)
Definition REMORA.H:581
std::string nc_init_file_hires
Init file for high resolution.
Definition REMORA.H:2021
void init_bathymetry_from_netcdf(int lev)
Bathymetry data initialization from NetCDF file.
amrex::Vector< std::string > cons_names
Names of scalars for plotfile output.
Definition REMORA.H:1941
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_fcor
coriolis factor (2D)
Definition REMORA.H:612
void init_biology_from_netcdf(int lev)
Biology initialization from NetCDF file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_xvel_full_domain
multilevel data container for high res initial x velocities (u in ROMS)
Definition REMORA.H:404
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_h
multilevel data container for current step's z velocities (largely unused; W stored separately)
Definition REMORA.H:413
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pm
horizontal scaling factor: 1 / dx (2D)
Definition REMORA.H:603
void init_zeta_full_domain_from_netcdf()
Full-domain high res sea-surface height data initialization from NetCDF file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_yv
y_grid on v-points (2D)
Definition REMORA.H:627
amrex::Vector< amrex::MultiFab * > cons_new
multilevel data container for current step's scalar data: temperature, salinity, passive tracer
Definition REMORA.H:393
void init_masks_full_domain_from_netcdf()
Full domain high-res mask data initialization from NetCDF file.
REMORABiology::BiologyModel biology_model
Active biology package.
Definition REMORA.H:1799
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr
land/sea mask at cell centers (2D)
Definition REMORA.H:584
void init_grid_vars_from_netcdf(int lev)
Grid variable initialization from NetCDF file.
void update_nodal_masks(int lev)
Rebuild the u-, v- and psi-point masks from vec_mskr and fill their ghosts.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_yp
y_grid on psi-points (2D)
Definition REMORA.H:632
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_xr
x_grid on rho points (2D)
Definition REMORA.H:615
void init_biology_full_domain_from_netcdf()
Full-domain high-res biology initialization from NetCDF file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_xv
x_grid on v-points (2D)
Definition REMORA.H:625
void fill_from_bdyfiles(int lev, amrex::MultiFab &mf_to_fill, const amrex::MultiFab &mf_mask, const amrex::Real time, const int bccomp, const int bdy_var_type, const int icomp_to_fill, const int icomp_calc=0, const amrex::MultiFab &mf_calc=amrex::MultiFab(), const amrex::Real=zero)
Fill boundary data from netcdf file.
amrex::Vector< amrex::Vector< amrex::Box > > boxes_at_level
the boxes specified at each level by tagging criteria
Definition REMORA.H:1686
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_msku
land/sea mask at x-faces (2D)
Definition REMORA.H:586
void extrapolate_metric_to_physical_boundaries(amrex::MultiFab &mf, const amrex::Geometry &geom)
Extrapolate grid metrics to edge of MultiFab.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pm_full_domain
horizontal scaling factor: 1 / dx (2D) on whole domain
Definition REMORA.H:607
void init_scalars_full_domain_from_netcdf()
Full-domain high-res passive (dye) scalar initialization from NetCDF file.
void init_data_from_netcdf(int lev)
Problem initialization from NetCDF file.
void init_masks_from_netcdf(int lev)
Mask data initialization from NetCDF file.
amrex::Vector< amrex::MultiFab * > yvel_new
multilevel data container for current step's y velocities (v in ROMS)
Definition REMORA.H:397
amrex::Box nc_hires_init_box
Box for the full domain at nc_hires_init_level.
Definition REMORA.H:2023
int zeta_bc() const noexcept
Definition REMORA.H:1453
int num_bdy_vars() const noexcept
Definition REMORA.H:1467
amrex::Vector< amrex::IntVect > cum_ref_ratios
Cumulative refinement ratio between level 0 and level i.
Definition REMORA.H:2026
void coarsen_bathymetry_with_grow_cells(int crse_lev)
Coarsen the full-domain bathymetry from crse_lev+1 onto crse_lev, grow cells included,...
Definition REMORA.cpp:1272
amrex::Vector< int > num_boxes_at_level
how many boxes specified at each level by tagging criteria
Definition REMORA.H:1682
amrex::Vector< amrex::MultiFab * > xvel_new
multilevel data container for current step's x velocities (u in ROMS)
Definition REMORA.H:395
void init_scalars_from_netcdf(int lev)
Passive (dye) scalar initialization from NetCDF file. Called from init_data_from_netcdf: dye follows ...
int Bio_comp
First cons component of the biology block, i.e. Tracer_comp + nscalar. The state is laid out as temp,...
Definition REMORA.H:1794
int bdy_zeta() const noexcept
Definition REMORA.H:1466
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_lonp
longitude on psi-points (2D, degrees east); only filled when the grid NetCDF file carries lon_psi
Definition REMORA.H:636
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskv
land/sea mask at y-faces (2D)
Definition REMORA.H:588
amrex::Vector< std::unique_ptr< REMORAPhysBCFunct > > physbcs
Vector (over level) of functors to apply physical boundary conditions.
Definition REMORA.H:1710
int nbio
Number of biology tracers, set by the active biology model. Zero when no biology model is active.
Definition REMORA.H:1791
std::string nc_clim_coeff_file
NetCDF climatology coefficient file.
Definition REMORA.H:2036
void coarsen_masks_with_grow_cells(int crse_lev)
Coarsen the full-domain rho-mask from crse_lev+1 onto crse_lev, grow cells included,...
Definition REMORA.cpp:1014
amrex::Vector< std::string > bdry_time_name_byvar
Name of time fields for boundary data.
Definition REMORA.H:2041
void init_riv_pos_from_netcdf(int lev)
static amrex::Vector< std::string > nc_bdry_file
NetCDF boundary data.
Definition REMORA.H:58
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_yvel_full_domain
multilevel data container for high res initial y velocities (v in ROMS)
Definition REMORA.H:406
void init_zeta_from_netcdf(int lev)
Sea-surface height data initialization from NetCDF file.
void init_coriolis_from_netcdf(int lev)
Coriolis parameter data initialization from NetCDF file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_h_full_domain
Bathymetry data on the whole domain at each potential level.
Definition REMORA.H:416
void init_data_full_domain_from_netcdf()
High resolution roblem initialization from NetCDF file.
int hires_init_level
Which level the high resolution initialization data is at.
Definition REMORA.H:2019
int bdy_vbar() const noexcept
Definition REMORA.H:1465
int nscalar
Number of passive (dye) scalars carried in the state, beyond temperature and salinity....
Definition REMORA.H:1788
amrex::Vector< amrex::Real > t_new
new time at each level, in seconds since start_time
Definition REMORA.H:1700
void init_bdry_from_netcdf(int lev)
Boundary data initialization from NetCDF file.
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1949
amrex::Vector< std::unique_ptr< amrex::iMultiFab > > vec_river_position
iMultiFab for river positions; contents are indices of rivers
Definition REMORA.H:1627
amrex::Vector< amrex::Vector< std::unique_ptr< NCTimeSeriesBoundary > > > boundary_series
Vector over BdyVars of boundary series data containers.
Definition REMORA.H:1623
int bdy_ubar() const noexcept
Definition REMORA.H:1464
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_xp
x_grid on psi-points (2D)
Definition REMORA.H:630
static amrex::Vector< amrex::Vector< std::string > > nc_grid_file
NetCDF grid file.
Definition REMORA.H:60
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta
free surface height (2D)
Definition REMORA.H:578
amrex::Gpu::DeviceVector< int > river_direction
Vector over rivers of river direction: 0: u-face; 1: v-face; 2: w-face.
Definition REMORA.H:1629
amrex::Box nc_hires_grid_box
Box for the full domain at nc_hires_grid_level.
Definition REMORA.H:2016
void FillPatch(int lev, amrex::Real time, amrex::MultiFab &mf_to_be_filled, amrex::Vector< amrex::MultiFab * > const &mfs, const int bccomp, const int bdy_var_type=BdyVars::null, const int icomp=0, const bool fill_all=true, const bool fill_set=false, const int n_not_fill=0, const int icomp_calc=0, const amrex::Real dt=zero, const amrex::MultiFab &mf_calc=amrex::MultiFab(), amrex::Vector< amrex::MultiFab * > const &mfs_crse_old={}, amrex::Vector< amrex::MultiFab * > const &mfs_crse_new={})
Fill a new MultiFab by copying in phi from valid region and filling ghost cells.
void init_clim_nudg_coeff_from_netcdf(int lev)
Climatology nudging coefficient initialization from NetCDF file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_cons_full_domain
multilevel data container for high res initial data: temperature, salinity, passive tracer
Definition REMORA.H:402
void init_bathymetry_full_domain_from_netcdf()
Full domain high-res bathymetry data initialization from NetCDF file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_yu
y_grid on u-points (2D)
Definition REMORA.H:622
void init_grid_vars_full_domain_from_netcdf()
Full domain high-res grid variable initialization from NetCDF file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_xu
x_grid on u-points (2D)
Definition REMORA.H:620
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pn_full_domain
horizontal scaling factor: 1 / dy (2D) on whole domain
Definition REMORA.H:609
amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab > > > vec_nudg_coeff
Climatology nudging coefficients.
Definition REMORA.H:678
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pn
horizontal scaling factor: 1 / dy (2D)
Definition REMORA.H:605
amrex::Vector< amrex::GpuArray< bool, AMREX_SPACEDIM *2 > > phys_bc_need_data
These are flags that indicate whether we need to read in boundary data from file.
Definition REMORA.H:1746
static int verbose
Verbosity level of output.
Definition REMORA.H:1985
void average_down_with_grow_cells(int lev, amrex::Vector< std::unique_ptr< amrex::MultiFab > > &mf, bool use_mask=false)
Average down from level lev+1 to lev in mf, including grow cells.
Definition REMORA.cpp:3217
static amrex::Vector< amrex::Vector< std::string > > nc_init_file
NetCDF initialization file.
Definition REMORA.H:59
amrex::Vector< amrex::Real > t_old
old time at each level, in seconds since start_time
Definition REMORA.H:1702
int hires_grid_level
Which level the high resolution bathymetry is at.
Definition REMORA.H:2012
void convert_inv_days_to_inv_s(amrex::MultiFab *)
Convert data in a multifab from inverse days to inverse seconds.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_yr
y_grid on rho points (2D)
Definition REMORA.H:617
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_latp
latitude on psi-points (2D, degrees north); only filled when the grid NetCDF file carries lat_psi
Definition REMORA.H:639
static constexpr int u
static constexpr int v
int cons(int icomp) noexcept
static constexpr int null
bool has_biology(BiologyModel model) noexcept
amrex::Vector< int > do_cons_clim_nudg