REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_ReadFromInitNetcdf.cpp
Go to the documentation of this file.
1#include "REMORA_NCFile.H"
2#include "AMReX_FArrayBox.H"
3#include "REMORA_DataStruct.H"
4
5using namespace amrex;
6
7#ifdef REMORA_USE_NETCDF
8/**
9 * @param lev level of data to read
10 * @param domain simulation domain
11 * @param fname file name to read from
12 * @param NC_temp_fab container for temperature data
13 * @param NC_salt_fab container for salinity data
14 * @param NC_u_fab container for u velocity data
15 * @param NC_v_fab container for v velocity data
16 */
17void
19 const Box& domain,
20 const std::string& fname,
21 FArrayBox& NC_temp_fab, FArrayBox& NC_salt_fab,
22 FArrayBox& NC_xvel_fab, FArrayBox& NC_yvel_fab)
23{
24 amrex::Print() << "Loading initial solution data from NetCDF file " << fname << std::endl;
25
27 Vector<std::string> NC_names;
29
30 NC_fabs.push_back(&NC_temp_fab); NC_names.push_back("temp"); NC_dim_types.push_back(NC_Data_Dims_Type::Time_BT_SN_WE); // 0
31 NC_fabs.push_back(&NC_salt_fab); NC_names.push_back("salt"); NC_dim_types.push_back(NC_Data_Dims_Type::Time_BT_SN_WE); // 1
32 NC_fabs.push_back(&NC_xvel_fab); NC_names.push_back("u"); NC_dim_types.push_back(NC_Data_Dims_Type::Time_BT_SN_WE); // 2
33 NC_fabs.push_back(&NC_yvel_fab); NC_names.push_back("v"); NC_dim_types.push_back(NC_Data_Dims_Type::Time_BT_SN_WE); // 3
34
35 // Read the netcdf file and fill these FABs
37}
38
39/**
40 * @param lev level of data to read
41 * @param domain simulation domain
42 * @param fname file name to read from
43 * @param NC_temp_fab container for temperature data
44 * @param NC_salt_fab container for salinity data
45 * @param NC_u_fab container for u velocity data
46 * @param NC_v_fab container for v velocity data
47 * @param ngrow number of grow cells to read
48 */
49void
51 const Box& domain,
52 const std::string& fname,
53 FArrayBox& NC_temp_fab, FArrayBox& NC_salt_fab,
54 FArrayBox& NC_xvel_fab, FArrayBox& NC_yvel_fab,
55 IntVect ngrow)
56{
57 amrex::Print() << "Loading initial solution data from NetCDF file " << fname << std::endl;
58
60 Vector<std::string> NC_names;
62
63 NC_fabs.push_back(&NC_temp_fab); NC_names.push_back("temp"); NC_dim_types.push_back(NC_Data_Dims_Type::Time_BT_SN_WE); // 0
64 NC_fabs.push_back(&NC_salt_fab); NC_names.push_back("salt"); NC_dim_types.push_back(NC_Data_Dims_Type::Time_BT_SN_WE); // 1
65 NC_fabs.push_back(&NC_xvel_fab); NC_names.push_back("u"); NC_dim_types.push_back(NC_Data_Dims_Type::Time_BT_SN_WE); // 2
66 NC_fabs.push_back(&NC_yvel_fab); NC_names.push_back("v"); NC_dim_types.push_back(NC_Data_Dims_Type::Time_BT_SN_WE); // 3
67
68 // Read the netcdf file and fill these FABs
70}
71
72/**
73 * @param lev level of data to read
74 * @param domain simulation domain
75 * @param fname file name to read from
76 * @param biology_names names of the biological tracer variables to read
77 * @param NC_biology_fab containers for the biological tracer data, one per name
78 */
79void
81 const Box& domain,
82 const std::string& fname,
83 const Vector<std::string>& biology_names,
85{
86 if (biology_names.empty()) {
87 return;
88 }
89
90 amrex::Print() << "Loading initial biology data from NetCDF file " << fname << std::endl;
91
92 NC_biology_fab.resize(biology_names.size());
95
96 for (int ibio = 0; ibio < static_cast<int>(biology_names.size()); ++ibio) {
97 NC_fabs.push_back(&NC_biology_fab[ibio]);
99 }
100
102}
103
104/**
105 * @param lev level of data to read
106 * @param domain simulation domain
107 * @param fname file name to read from
108 * @param biology_names names of the biological tracer variables to read
109 * @param NC_biology_fab containers for the biological tracer data, one per name
110 * @param ngrow number of grow cells to read
111 */
112void
114 const Box& domain,
115 const std::string& fname,
116 const Vector<std::string>& biology_names,
118 IntVect ngrow)
119{
120 if (biology_names.empty()) {
121 return;
122 }
123
124 amrex::Print() << "Loading high resolution biology data from NetCDF file " << fname << std::endl;
125
126 NC_biology_fab.resize(biology_names.size());
129
130 for (int ibio = 0; ibio < static_cast<int>(biology_names.size()); ++ibio) {
131 NC_fabs.push_back(&NC_biology_fab[ibio]);
133 }
134
136}
137
138/**
139 * @param fname file name the hires data will be read from
140 * @param var_name a rho-point variable in that file whose horizontal extent is checked
141 * @param domain the refined full-domain box the data has to cover
142 * @param ngrow grow cells the read asks for, i.e. cum_ref_ratios[hires_*_level]
143 *
144 * A high-resolution file has to carry the refined domain plus ngrow rings on every side
145 * (Docs/sphinx_doc/Inputs.rst). Checking that up front is not a nicety: BuildFABsFromNetCDFFile
146 * copies on intersection and fill_fab_from_arrays only asserts that the destination box is big
147 * enough for the source, so a file with too FEW grow cells reads cleanly and silently leaves
148 * the outer rings of the FAB at whatever they held -- which then gets averaged down into
149 * level 0. Only rho-point variables are checked; that is enough to catch an undersized file,
150 * and it avoids re-deriving the staggered offsets here.
151 */
152void
154 const std::string& var_name,
155 const Box& domain,
156 const IntVect& ngrow)
157{
158 int too_small = 0, missing = 0;
159 long found_x = 0, found_y = 0;
160 const long need_x = static_cast<long>(domain.length(0)) + 2L * ngrow[0];
161 const long need_y = static_cast<long>(domain.length(1)) + 2L * ngrow[1];
162
165 if (amrex::ParallelDescriptor::IOProcessor())
166 {
167 if (!ncf.has_var(var_name)) {
168 // Say so here. The reader that follows would otherwise fail inside ncmpi_inq_varid,
169 // which names neither the file nor the variable it was asked for.
170 missing = 1;
171 } else {
172 // Whatever the leading time or vertical dimensions are, the last two are (eta, xi).
173 const std::vector<MPI_Offset> shape = ncf.var(var_name).shape();
174 if (shape.size() >= 2) {
175 found_y = static_cast<long>(shape[shape.size()-2]);
176 found_x = static_cast<long>(shape[shape.size()-1]);
177 too_small = (found_x < need_x || found_y < need_y) ? 1 : 0;
178 }
179 }
180 }
181 ncf.close();
182
183 const int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
184 amrex::ParallelDescriptor::Bcast(&too_small, 1, ioproc);
185 amrex::ParallelDescriptor::Bcast(&found_x, 1, ioproc);
186 amrex::ParallelDescriptor::Bcast(&found_y, 1, ioproc);
187 amrex::ParallelDescriptor::Bcast(&missing, 1, ioproc);
188
189 if (missing) {
190 amrex::Abort("High-resolution file " + fname + " has no variable " + var_name
191 + ". With remora.hires_grid_level set, that file is the only source for it: "
192 "level 0 is coarsened down from it rather than read. Regenerate the file "
193 "with " + var_name + " in it (Tests/tools/make_hires_test_data.py writes h, "
194 "pm, pn and mask_rho), or, if this is mask_rho and the run wants no "
195 "land/sea mask, set remora.mask_type = none.");
196 }
197
198 if (too_small) {
199 amrex::Abort("High-resolution file " + fname + " is too small: " + var_name + " is "
200 + std::to_string(found_x) + " x " + std::to_string(found_y)
201 + " (xi x eta) but covering the refined domain ("
202 + std::to_string(domain.length(0)) + " x " + std::to_string(domain.length(1))
203 + " cells) with " + std::to_string(ngrow[0]) + " x " + std::to_string(ngrow[1])
204 + " grow cells requires at least " + std::to_string(need_x) + " x "
205 + std::to_string(need_y) + ". Regenerate the file with the grow cells the "
206 "cumulative refinement ratio implies, or lower the refinement ratio.");
207 }
208}
209
210/**
211 * @param domain simulation domain
212 * @param fname file name to read from
213 * @param scalar_names per passive scalar, name of the variable in the file
214 * @param NC_scalar_fab per passive scalar, container for the dye data
215 * @param scalar_in_file filled on output: per passive scalar, whether the variable was
216 * found in the file and its FAB was built
217 * @param full_domain whether this is the high resolution full-domain read, which
218 * needs ngrow grow cells rather than the reader's default
219 * @param ngrow number of grow cells to read, for the full-domain read
220 *
221 * A passive scalar's initial field is optional. Initial files written for runs that
222 * carry no dye -- which is every ROMS initial file predating the dye variables, and
223 * most idealized ones -- have no "tracer" variable, so requiring the field would break
224 * every existing NetCDF-initialized run. Each name the file does carry is read; the rest
225 * keep the zero that init_data_from_netcdf set, which is the behavior those runs had
226 * before this read existed.
227 *
228 * Shared by the per-box and full-domain entry points below: the presence testing is
229 * the same for both, and only the grow cells and the wording of the log differ.
230 */
231namespace {
232void
233read_scalars_impl (const Box& domain,
234 const std::string& fname,
235 const Vector<std::string>& scalar_names,
237 Vector<int>& scalar_in_file,
238 bool full_domain,
239 IntVect ngrow)
240{
241 scalar_in_file.assign(scalar_names.size(), 0);
242 if (scalar_names.empty()) {
243 return;
244 }
245
246 NC_scalar_fab.resize(scalar_names.size());
248 Vector<std::string> NC_names;
250 Vector<std::string> missing;
251
252 for (int iscal = 0; iscal < static_cast<int>(scalar_names.size()); ++iscal) {
254 missing.push_back(scalar_names[iscal]);
255 continue;
256 }
258 NC_fabs.push_back(&NC_scalar_fab[iscal]);
259 NC_names.push_back(scalar_names[iscal]);
261 }
262
263 if (!missing.empty()) {
264 amrex::Print() << "Initial file " << fname << " does not contain";
265 for (const auto& name : missing) { amrex::Print() << " " << name; }
266 amrex::Print() << "; those passive scalars start at zero" << std::endl;
267 }
268 if (NC_names.empty()) {
269 return;
270 }
271
272 amrex::Print() << "Loading " << (full_domain ? "high resolution " : "initial ")
273 << "passive scalar data from NetCDF file " << fname << std::endl;
274
275 // Read the netcdf file and fill these FABs. The per-box read takes the reader's
276 // default grow cells, as the temperature and salinity read does.
277 if (full_domain) {
279 } else {
281 }
282}
283} // namespace
284
285/**
286 * @param lev level of data to read
287 * @param domain simulation domain
288 * @param fname file name to read from
289 * @param scalar_names names of the passive scalar variables to look for
290 * @param NC_scalar_fab containers for the passive scalar data, one per name
291 * @param scalar_in_file set per name to whether the file carried that variable
292 */
293void
295 const Box& domain,
296 const std::string& fname,
297 const Vector<std::string>& scalar_names,
299 Vector<int>& scalar_in_file)
300{
302 false, IntVect(0,0,0));
303}
304
305/**
306 * @param lev level of data to read
307 * @param domain simulation domain
308 * @param fname file name to read from
309 * @param scalar_names names of the passive scalar variables to look for
310 * @param NC_scalar_fab containers for the passive scalar data, one per name
311 * @param scalar_in_file set per name to whether the file carried that variable
312 * @param ngrow number of grow cells to read
313 */
314void
316 const Box& domain,
317 const std::string& fname,
318 const Vector<std::string>& scalar_names,
320 Vector<int>& scalar_in_file,
321 IntVect ngrow)
322{
324 true, ngrow);
325}
326
327/**
328 * @param lev level of data to read
329 * @param domain simulation domain
330 * @param fname file name to read from
331 * @param NC_zeta_fab container for sea surface height data
332 */
333void
335 const Box& domain,
336 const std::string& fname,
337 FArrayBox& NC_zeta_fab)
338{
339 amrex::Print() << "Loading initial sea surface height from NetCDF file " << fname << std::endl;
340
342 Vector<std::string> NC_names;
344
345 NC_fabs.push_back(&NC_zeta_fab ) ; NC_names.push_back("zeta") ; NC_dim_types.push_back(NC_Data_Dims_Type::Time_SN_WE); // 0
346
347 // Read the netcdf file and fill these FABs
349}
350
351/**
352 * @param lev level of data to read
353 * @param domain simulation domain
354 * @param fname file name to read from
355 * @param NC_zeta_fab container for sea surface height data
356 * @param ngrow number of grow cells to read in, if not default
357 */
358void
360 const Box& domain,
361 const std::string& fname,
362 FArrayBox& NC_zeta_fab,
363 IntVect ngrow)
364{
365 amrex::Print() << "Loading initial sea surface height from NetCDF file " << fname << std::endl;
366
368 Vector<std::string> NC_names;
370
371 NC_fabs.push_back(&NC_zeta_fab ) ; NC_names.push_back("zeta") ; NC_dim_types.push_back(NC_Data_Dims_Type::Time_SN_WE); // 0
372
373 // Read the netcdf file and fill these FABs
375}
376
377/**
378 * @param lev level of data to read
379 * @param domain simulation domain
380 * @param fname file name to read from
381 * @param NC_h_fab container for bathymetry data
382 */
383void
385 const Box& domain,
386 const std::string& fname,
387 FArrayBox& NC_h_fab)
388{
389 amrex::Print() << "Loading initial bathymetry from NetCDF file " << fname << std::endl;
390
392 Vector<std::string> NC_names;
394
395 NC_fabs.push_back(&NC_h_fab ) ; NC_names.push_back("h") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 0
396
397 // Read the netcdf file and fill these FABs
399}
400
401/**
402 * @param lev level of data to read
403 * @param domain simulation domain
404 * @param fname file name to read from
405 * @param NC_pm_fab container for pm data
406 * @param NC_pn_fab container for pn data
407 * @param NC_xr_fab container for x_rho data
408 * @param NC_yr_fab container for y_rho data
409 * @param NC_xu_fab container for x_u data
410 * @param NC_yu_fab container for y_u data
411 * @param NC_xv_fab container for x_v data
412 * @param NC_yv_fab container for y_v data
413 * @param NC_xp_fab container for x_p data
414 * @param NC_yp_fab container for y_p data
415 */
416void
418 const Box& domain,
419 const std::string& fname,
420 FArrayBox& NC_pm_fab, FArrayBox& NC_pn_fab,
421 FArrayBox& NC_xr_fab, FArrayBox& NC_yr_fab,
422 FArrayBox& NC_xu_fab, FArrayBox& NC_yu_fab,
423 FArrayBox& NC_xv_fab, FArrayBox& NC_yv_fab,
424 FArrayBox& NC_xp_fab, FArrayBox& NC_yp_fab)
425{
426 amrex::Print() << "Loading grid variables from NetCDF file " << fname << std::endl;
427
429 Vector<std::string> NC_names;
431
432 NC_fabs.push_back(&NC_pm_fab) ; NC_names.push_back("pm") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 1
433 NC_fabs.push_back(&NC_pn_fab) ; NC_names.push_back("pn") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 2
434 NC_fabs.push_back(&NC_xr_fab) ; NC_names.push_back("x_rho") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 3
435 NC_fabs.push_back(&NC_yr_fab) ; NC_names.push_back("y_rho") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 4
436 NC_fabs.push_back(&NC_xu_fab) ; NC_names.push_back("x_u") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 5
437 NC_fabs.push_back(&NC_yu_fab) ; NC_names.push_back("y_u") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 6
438 NC_fabs.push_back(&NC_xv_fab) ; NC_names.push_back("x_v") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 7
439 NC_fabs.push_back(&NC_yv_fab) ; NC_names.push_back("y_v") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 8
440 NC_fabs.push_back(&NC_xp_fab) ; NC_names.push_back("x_psi") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 9
441 NC_fabs.push_back(&NC_yp_fab) ; NC_names.push_back("y_psi") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 10
442
443 // Read the netcdf file and fill these FABs
445}
446
447/**
448 * @param domain simulation domain
449 * @param fname file name to read from
450 * @param NC_lonp_fab container for lon_psi data
451 * @param NC_latp_fab container for lat_psi data
452 * @returns whether the file carried spherical psi coordinates and they were read
453 *
454 * ROMS grid files for spherical grids carry lon_psi/lat_psi alongside
455 * x_psi/y_psi, and those degree-valued corner arrays are what a coupled driver
456 * needs when the two components do not share a projected Cartesian frame
457 * (SCRIP/COAWST selects the same way; see Lib/SCRIP_COAWST/read_roms.f).
458 * Idealized grid files carry no spherical coordinates, so this read is optional
459 * and reports whether it happened rather than aborting.
460 */
461bool
463 const Box& domain,
464 const std::string& fname,
465 FArrayBox& NC_lonp_fab, FArrayBox& NC_latp_fab)
466{
467 Vector<std::string> NC_names;
468 NC_names.push_back("lon_psi");
469 NC_names.push_back("lat_psi");
470
472 amrex::Print() << "Grid file " << fname << " has no lon_psi/lat_psi; "
473 << "spherical psi coordinates unavailable" << std::endl;
474 return false;
475 }
476
477 amrex::Print() << "Loading spherical psi coordinates from NetCDF file " << fname << std::endl;
478
481
484
486 return true;
487}
488
489/**
490 * @param domain simulation domain at nc_hires_grid_level
491 * @param fname file name to read from
492 * @param NC_h_fab container for bathymetry data
493 * @param ngrow number of grow cells to read in, if not default
494 */
495void
497 const std::string& fname,
498 FArrayBox& NC_h_fab, IntVect ngrow)
499{
500 amrex::Print() << "Loading high resolution bathymetry from NetCDF file " << fname << std::endl;
501
503 Vector<std::string> NC_names;
505
506 NC_fabs.push_back(&NC_h_fab ) ; NC_names.push_back("h") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 0
507
508 // Read the netcdf file and fill these FABs
510}
511
512/**
513 * @param domain simulation domain at nc_hires_grid_level
514 * @param fname file name to read from
515 * @param NC_mskr_fab container for rho-point land/sea mask data
516 * @param ngrow number of grow cells to read in, if not default
517 *
518 * Only mask_rho is read. The u-, v- and psi-point masks are derived from it, the way ROMS
519 * set_masks.F defines them, rather than read independently -- which also means a coarsened
520 * level's staggered masks stay consistent with its rho-mask.
521 */
522void
524 const std::string& fname,
525 FArrayBox& NC_mskr_fab, IntVect ngrow)
526{
527 amrex::Print() << "Loading high resolution land/sea mask from NetCDF file " << fname << std::endl;
528
530 Vector<std::string> NC_names;
532
533 NC_fabs.push_back(&NC_mskr_fab) ; NC_names.push_back("mask_rho") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 0
534
535 // Read the netcdf file and fill these FABs
537}
538
539/**
540 * @param lev level of data to read
541 * @param domain simulation domain
542 * @param fname file name to read from
543 * @param NC_pm_fab container for pm data
544 * @param NC_pn_fab container for pn data
545 * @param ngrow number of grow cells to read in, if not default
546 */
547void
549 const std::string& fname,
550 FArrayBox& NC_pm_fab, FArrayBox& NC_pn_fab,
551 IntVect ngrow)
552{
553 amrex::Print() << "Loading high resolution grid variables from NetCDF file " << fname << std::endl;
554
556 Vector<std::string> NC_names;
558
559 NC_fabs.push_back(&NC_pm_fab) ; NC_names.push_back("pm") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 0
560 NC_fabs.push_back(&NC_pn_fab) ; NC_names.push_back("pn") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 1
561 // Read the netcdf file and fill these FABs
563}
564
565/**
566 * @param lev level of data to read
567 * @param domain simulation domain
568 * @param fname file name to read from
569 * @param NC_fcor_fab container for Coriolis parameter data
570 */
571void
573 const Box& domain,
574 const std::string& fname,
575 FArrayBox& NC_fcor_fab)
576{
577 amrex::Print() << "Loading initial coriolis from NetCDF file " << fname << std::endl;
578
580 Vector<std::string> NC_names;
582
583 NC_fabs.push_back(&NC_fcor_fab ) ; NC_names.push_back("f") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 0
584
585 // Read the netcdf file and fill these FABs
587}
588
589/**
590 * @param lev level of data to read
591 * @param domain simulation domain
592 * @param fname file name to read from
593 * @param NC_mskr_fab container for rho-point land/sea mask data
594 *
595 * Only mask_rho is read. The u-, v- and psi-point masks are derived from it as ROMS
596 * set_masks.F defines them, so a file whose staggered masks disagree with its mask_rho cannot
597 * put the two out of step.
598 */
599void
601 const Box& domain,
602 const std::string& fname,
603 FArrayBox& NC_mskr_fab)
604{
605 amrex::Print() << "Loading masks from NetCDF file " << fname << std::endl;
606
608 Vector<std::string> NC_names;
610
611 NC_fabs.push_back(&NC_mskr_fab ) ; NC_names.push_back("mask_rho") ; NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE); // 0
612
613 // Read the netcdf file and fill these FABs
615}
616
617/**
618 * @param lev level of data to read
619 * @param domain simulation domain
620 * @param fname file name to read from
621 * @param do_m2_clim_nudg whether to do 2d momentum climatology nudging
622 * @param do_m3_clim_nudg whether to do 3d momentum climatology nudging
623 * @param do_cons_clim_nudg per cons component, whether to do climatology nudging
624 * @param cons_names per cons component, name of the tracer
625 * @param NC_M2NC_fab container for 2d momentum climatology data
626 * @param NC_M3NC_fab container for 3d momentum climatology data
627 * @param NC_ConsNC_fab per cons component, container for tracer climatology data
628 * @param cons_coeff_in_file filled on output: per cons component, whether a spatially
629 * varying coefficient was found in the file
630 */
631void
633 const Box& domain,
634 const std::string& fname,
635 bool do_m2_clim_nudg,
636 bool do_m3_clim_nudg,
637 const amrex::Vector<int>& do_cons_clim_nudg,
638 const amrex::Vector<std::string>& cons_names,
639 FArrayBox& NC_M2NC_fab,
640 FArrayBox& NC_M3NC_fab,
641 amrex::Vector<FArrayBox>& NC_ConsNC_fab,
642 amrex::Vector<int>& cons_coeff_in_file)
643{
644 amrex::Print() << "Loading nudging coefficients from NetCDF file " << fname << std::endl;
645
646 const int l_ncons = do_cons_clim_nudg.size();
647
649 Vector<std::string> NC_names;
651
652 if (do_m3_clim_nudg) {
653 NC_fabs.push_back(&NC_M3NC_fab ); NC_names.push_back("M3_NudgeCoef"); NC_dim_types.push_back(NC_Data_Dims_Type::BT_SN_WE);
654 }
655 if (do_m2_clim_nudg) {
656 NC_fabs.push_back(&NC_M2NC_fab ); NC_names.push_back("M2_NudgeCoef"); NC_dim_types.push_back(NC_Data_Dims_Type::SN_WE);
657 }
658 // Each tracer's spatially varying coefficient is stored under its own name, as in
659 // ROMS: temp_NudgeCoef, salt_NudgeCoef, NO3_NudgeCoef, ... A tracer whose field is
660 // absent from the file keeps the constant coefficient derived from remora.tnudg, so
661 // a file written for temp and salt alone still works when biology tracers are nudged.
662 cons_coeff_in_file.assign(l_ncons, 0);
663 Vector<std::string> missing;
664 for (int icomp = 0; icomp < l_ncons; ++icomp) {
665 if (!do_cons_clim_nudg[icomp]) { continue; }
666 const std::string coeff_name = cons_names[icomp] + "_NudgeCoef";
668 missing.push_back(coeff_name);
669 continue;
670 }
673 }
674 if (!missing.empty()) {
675 amrex::Print() << "Nudging coefficient file " << fname << " does not contain";
676 for (const auto& name : missing) { amrex::Print() << " " << name; }
677 amrex::Print() << "; those tracers will use the constant coefficient from remora.tnudg"
678 << std::endl;
679 }
680
681 // Read the netcdf file and fill these FABs
683}
684
685/**
686 * @param lev level of data to read
687 * @param fnames file name(s) to read from
688 * @param field_name field name to read
689 * @param vec_dat vector to fill data
690 */
691//template <typename DType>
692void read_vec_from_netcdf (int /*lev*/, const amrex::Vector<std::string>& fnames, const std::string& field_name, amrex::Vector<int>& vec_dat)
693{
694 AMREX_ALWAYS_ASSERT(!fnames.empty());
695 const std::string& fname = fnames[0];
696
697 amrex::Print() << "Reading " << field_name << " from NetCDF file" << std::endl;
698
699 // get x-positions and put in array
700 using ARRAY = NDArray<int>;
701 amrex::Vector<ARRAY> array_dat(1);
702 ReadNetCDFFile(fname, {field_name}, array_dat); // filled only on proc 0
703 if (amrex::ParallelDescriptor::IOProcessor())
704 {
705 int n = array_dat[0].get_vshape()[0];
706 for (int i(0); i < n; i++)
707 {
708 vec_dat.push_back((*(array_dat[0].get_data() + i)));
709 }
710 }
711 int nvals = vec_dat.size();
712 int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
713 amrex::ParallelDescriptor::Bcast(&nvals,1,ioproc);
714 if (!(amrex::ParallelDescriptor::IOProcessor())) {
715 vec_dat.resize(nvals);
716 }
717 amrex::ParallelDescriptor::Bcast(vec_dat.data(), vec_dat.size(), ioproc);
718}
719
720#endif // ROMSX_USE_NETCDF
mf_h setVal(geomdata.ProbHi(2))
AMREX_ALWAYS_ASSERT(!NSPeriodic||!EWPeriodic)
void ReadNetCDFFile(const std::string &fname, amrex::Vector< std::string > names, amrex::Vector< NDArray< DType > > &arrays, bool one_time=false, int fill_time=0)
Read in data from netcdf file and save to data arrays.
bool QueryNetCDFHasVars(const std::string &fname, const amrex::Vector< std::string > &var_names)
Helper function for testing whether a file carries every named variable.
void read_zeta_full_domain_from_netcdf(int, 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_bathymetry_from_netcdf(int, const Box &domain, const std::string &fname, FArrayBox &NC_h_fab)
helper function to read bathymetry 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_vec_from_netcdf(int, 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_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 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_grid_vars_from_netcdf(int, 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_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 read_clim_nudg_coeff_from_netcdf(int, 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
void read_coriolis_from_netcdf(int, const Box &domain, const std::string &fname, FArrayBox &NC_fcor_fab)
helper function to read coriolis factor 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_zeta_from_netcdf(int, const Box &domain, const std::string &fname, FArrayBox &NC_zeta_fab)
helper function to read sea surface height 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
bool read_spherical_grid_vars_from_netcdf(int, 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_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_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 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
static NCFile open(const std::string &name, const int cmode=NC_NOWRITE, MPI_Comm comm=MPI_COMM_WORLD, MPI_Info info=MPI_INFO_NULL)
Open an existing file.
NDArray is the datatype designed to hold any data, including scalars, multidimensional arrays,...