17 const int clearval = TagBox::CLEAR;
18 const int tagval = TagBox::SET;
23 std::unique_ptr<MultiFab> mf = std::make_unique<MultiFab>(grids[levc], dmap[levc], 1, 1);
25 for (
int j=0; j <
ref_tags.size(); ++j)
36 }
else if (
ref_tags[j].Field() ==
"temp") {
38 }
else if (
ref_tags[j].Field() ==
"salt") {
40 }
else if (
ref_tags[j].Field() ==
"x_velocity") {
42 MultiFab::Copy(*mf,*
xvel_new[levc],0,0,1,1);
43 }
else if (
ref_tags[j].Field() ==
"y_velocity") {
45 MultiFab::Copy(*mf,*
yvel_new[levc],0,0,1,1);
46 }
else if (
ref_tags[j].Field() ==
"z_velocity") {
48 MultiFab::Copy(*mf,*
zvel_new[levc],0,0,1,1);
49 }
else if (
ref_tags[j].Field() ==
"vorticity") {
50 MultiFab mf_cc_vel(grids[levc],dmap[levc],3,1);
51 average_face_to_cellcenter(mf_cc_vel,0,
52 Array<const MultiFab*,3>{
xvel_new[levc],
59#pragma omp parallel if (Gpu::notInLaunchRegion())
61 for (MFIter mfi(*mf, TilingIfNotGPU()); mfi.isValid(); ++mfi)
63 const Box& bx = mfi.tilebox();
64 auto& dfab = (*mf)[mfi];
65 auto& sfab = mf_cc_vel[mfi];
66 auto pm =
vec_pm[levc]->const_array(mfi);
67 auto pn =
vec_pn[levc]->const_array(mfi);
68 auto maskr =
vec_mskr[levc]->const_array(mfi);
69 derived::remora_dervort(bx, dfab, 0, 1, sfab, pm, pn, maskr, Geom(levc), time,
nullptr, levc);
72 mf->FillBoundary(geom[levc].periodicity());
77 }
else if (
ref_tags[j].Field() ==
"mask") {
78 MultiFab::Copy(*mf,*
vec_mskr3d[levc],0,0,1,IntVect(1,1,0));
79#ifdef REMORA_USE_PARTICLES
89 const auto& particles_namelist( particleData.getNames() );
91 for (ParticlesNamesVector::size_type i = 0; i < particles_namelist.size(); i++)
93 std::string tmp_string(particles_namelist[i]+
"_count");
94 IntVect rr = IntVect::TheUnitVector();
95 if (
ref_tags[j].Field() == tmp_string) {
96 for (
int lev = levc; lev <= finest_level; lev++)
98 MultiFab temp_dat(grids[lev], dmap[lev], 1, 0); temp_dat.setVal(0);
99 particleData[particles_namelist[i]]->IncrementWithTotal(temp_dat, lev);
101 MultiFab temp_dat_crse(grids[levc], dmap[levc], 1, 0); temp_dat_crse.setVal(0);
104 MultiFab::Copy(*mf, temp_dat, 0, 0, 1, 0);
106 for (
int d = 0; d < AMREX_SPACEDIM; d++) {
107 rr[d] *= ref_ratio[levc][d];
109 average_down(temp_dat, temp_dat_crse, 0, 1, rr);
110 MultiFab::Add(*mf, temp_dat_crse, 0, 0, 1, 0);
120 ref_tags[j](tags,mf.get(),clearval,tagval,time,levc,geom[levc]);
133 Vector<std::string> refinement_indicators;
134 pp.queryarr(
"refinement_indicators",refinement_indicators,0,pp.countval(
"refinement_indicators"));
136 for (
int i=0; i<refinement_indicators.size(); ++i)
138 std::string ref_prefix =
pp_prefix +
"." + refinement_indicators[i];
140 ParmParse ppr(ref_prefix);
144 int num_real_lo = ppr.countval(
"in_box_lo");
145 int num_indx_lo = ppr.countval(
"in_box_lo_indices");
146 int num_indx_lo_crse = ppr.countval(
"in_box_lo_indices_crse");
148 int num_real_hi = ppr.countval(
"in_box_hi");
149 int num_indx_hi = ppr.countval(
"in_box_hi_indices");
150 int num_indx_hi_crse = ppr.countval(
"in_box_hi_indices_crse");
152 AMREX_ALWAYS_ASSERT( (num_real_lo == num_real_hi) && (num_real_lo == 0 || num_real_lo >= 2) );
153 AMREX_ALWAYS_ASSERT( (num_indx_lo == num_indx_hi) && (num_indx_lo == 0 || num_indx_lo >= 2) );
154 AMREX_ALWAYS_ASSERT( (num_indx_lo_crse == num_indx_hi_crse) && (num_indx_lo_crse == 0 || num_indx_lo_crse >= 2) );
157 if ( !((num_real_lo >= AMREX_SPACEDIM-1 && num_indx_lo == 0 && num_indx_lo_crse == 0) ||
158 (num_indx_lo >= AMREX_SPACEDIM-1 && num_real_lo == 0 && num_indx_lo_crse == 0) ||
159 (num_indx_lo == 0 && num_real_lo == 0 && num_indx_lo_crse == 0) ||
160 (num_indx_lo_crse >= AMREX_SPACEDIM-1 && num_real_lo == 0 && num_indx_lo == 0)
163 amrex::Abort(
"Must only specify box for refinement using real OR index space with fine/coarse grid indices");
166 if (num_real_lo > 0) {
167 std::vector<Real> box_lo(3), box_hi(3);
168 ppr.get(
"max_level",lev_for_box);
169 if (lev_for_box > 0 && lev_for_box <= max_level)
171 ppr.getarr(
"in_box_lo",box_lo,0,2);
172 ppr.getarr(
"in_box_hi",box_hi,0,2);
173 box_lo[2] = geom[0].ProbLo(2);
174 box_hi[2] = geom[0].ProbHi(2);
175 realbox = RealBox(&(box_lo[0]),&(box_hi[0]));
177 amrex::Print() <<
"Reading " << realbox <<
" at level " << lev_for_box << std::endl;
180 const auto* dx = geom[lev_for_box].CellSize();
181 const Real* plo = geom[lev_for_box].ProbLo();
183 int ilo =
static_cast<int>((box_lo[0] - plo[0])/dx[0]);
184 int jlo =
static_cast<int>((box_lo[1] - plo[1])/dx[1]);
185 int klo =
static_cast<int>((box_lo[2] - plo[2])/dx[2]);
186 int ihi =
static_cast<int>((box_hi[0] - plo[0])/dx[0]-1);
187 int jhi =
static_cast<int>((box_hi[1] - plo[1])/dx[1]-1);
188 int khi =
static_cast<int>((box_hi[2] - plo[2])/dx[2]-1);
190 Box bx_old(IntVect(ilo,jlo,klo),IntVect(ihi,jhi,khi));
192 int mod_ilo = ilo%ref_ratio[lev_for_box-1][0];
193 int mod_jlo = jlo%ref_ratio[lev_for_box-1][1];
195 int mod_ihi = (ihi+1)%ref_ratio[lev_for_box-1][0];
196 int mod_jhi = (jhi+1)%ref_ratio[lev_for_box-1][1];
205 ihi += ref_ratio[lev_for_box-1][0] - mod_ihi;
208 jhi += ref_ratio[lev_for_box-1][1] - mod_jhi;
210 Box bx(IntVect(ilo,jlo,klo),IntVect(ihi,jhi,khi));
211 if (mod_ilo !=0 || mod_jlo !=0 || mod_ihi != 0 || mod_jhi != 0) {
212 amrex::Print() <<
"Fine box on level " << lev_for_box <<
" adjusted from " << bx_old <<
" to " << bx <<
" to make it valid for refinement." << std::endl;
215 amrex::Print() <<
"Saving in 'boxes at level' as " << bx << std::endl;
218 }
else if (num_indx_lo > 0) {
220 std::vector<int> box_lo(3), box_hi(3);
221 ppr.get(
"max_level",lev_for_box);
222 if (lev_for_box > 0 && lev_for_box <= max_level)
224 if (n_error_buf[0] != IntVect::TheZeroVector()) {
225 amrex::Abort(
"Don't use n_error_buf > 0 when setting the box explicitly");
228 ppr.getarr(
"in_box_lo_indices",box_lo,0,num_indx_lo);
229 ppr.getarr(
"in_box_hi_indices",box_hi,0,num_indx_hi);
231 if (num_indx_lo < AMREX_SPACEDIM) {
232 box_lo[2] = geom[lev_for_box].Domain().smallEnd(2);
233 box_hi[2] = geom[lev_for_box].Domain().bigEnd(2);
236 Box bx(IntVect(box_lo[0],box_lo[1],box_lo[2]),IntVect(box_hi[0],box_hi[1],box_hi[2]));
237 const Box& domain = geom[lev_for_box].Domain();
239 if (!domain.contains(bx)) {
240 amrex::Print() <<
"\n";
241 amrex::Print() <<
"Box specified is " << bx << std::endl;
242 amrex::Print() <<
"But domain at level is " << domain << std::endl;
243 amrex::Error(
"Specified box doesn't fit in the domain");
246 const auto* dx = geom[lev_for_box].CellSize();
247 const Real* plo = geom[lev_for_box].ProbLo();
248 realbox = RealBox(plo[0]+ box_lo[0] *dx[0], plo[1]+ box_lo[1] *dx[1], plo[2]+ box_lo[2] *dx[2],
249 plo[0]+(box_hi[0]+1)*dx[0], plo[1]+(box_hi[1]+1)*dx[1], plo[2]+(box_hi[2]+1)*dx[2]);
251 Print() <<
"Reading " << bx <<
" at level " << lev_for_box << std::endl;
254 if(box_lo[0]%ref_ratio[lev_for_box-1][0] != 0){
255 amrex::Print()<<
"Requested ilo in x-direction : " << box_lo[0] << std::endl;
256 amrex::Print() <<
"ilo = " << box_lo[0] <<
" is not divisible by ref_ratio in x direction = " <<
257 ref_ratio[lev_for_box-1][0] << std::endl;
258 amrex::Error(
"Adjust in_box_lo_indices in x-direction to be divisible by ref_ratio and try again");
260 if((box_hi[0]+1)%ref_ratio[lev_for_box-1][0] != 0){
261 amrex::Print()<<
"Requested ihi in x-direction : " << box_hi[0] << std::endl;
262 amrex::Print() <<
"ihi+1 = " << box_hi[0]+1 <<
" is not divisible by ref_ratio in x direction = " <<
263 ref_ratio[lev_for_box-1][0] << std::endl;
264 amrex::Error(
"Adjust in_box_hi_indices in x-direction to be divisible by ref_ratio and try again");
266 if(box_lo[1]%ref_ratio[lev_for_box-1][1] != 0){
267 amrex::Print()<<
"Requested jlo in y-direction : " << box_lo[1] << std::endl;
268 amrex::Print() <<
"jlo = " << box_lo[1] <<
" is not divisible by ref_ratio in y direction = " <<
269 ref_ratio[lev_for_box-1][1] << std::endl;
270 amrex::Error(
"Adjust in_box_lo_indices in y-direction to be divisible by ref_ratio and try again");
272 if((box_hi[1]+1)%ref_ratio[lev_for_box-1][1] != 0){
273 amrex::Print()<<
"Requested jhi in y-direction : " << box_hi[1] << std::endl;
274 amrex::Print() <<
"jhi+1 = " << box_hi[1]+1 <<
" is not divisible by ref_ratio in y direction = " <<
275 ref_ratio[lev_for_box-1][1] << std::endl;
276 amrex::Error(
"Adjust in_box_hi_indices in y-direction to be divisible by ref_ratio and try again");
278 if(box_lo[2]%ref_ratio[lev_for_box-1][2] != 0){
279 amrex::Print()<<
"Requested klo in z-direction : " << box_lo[2] << std::endl;
280 amrex::Print() <<
"klo = " << box_lo[2] <<
" is not divisible by ref_ratio in z direction = " <<
281 ref_ratio[lev_for_box-1][2] << std::endl;
282 amrex::Error(
"Adjust in_box_lo_indices in z-direction to be divisible by ref_ratio and try again");
284 if((box_hi[2]+1)%ref_ratio[lev_for_box-1][2] != 0){
285 amrex::Print()<<
"Requested khi in z-direction : " << box_hi[2] << std::endl;
286 amrex::Print() <<
"khi+1 = " << box_hi[2]+1 <<
" is not divisible by ref_ratio in z direction = " <<
287 ref_ratio[lev_for_box-1][2] << std::endl;
288 amrex::Error(
"Adjust in_box_hi_indices in z-direction to be divisible by ref_ratio and try again");
292 Print() <<
"Saving in 'boxes at level' as " << bx << std::endl;
295 }
else if (num_indx_lo_crse > 0) {
297 std::vector<int> box_lo(3), box_hi(3);
298 ppr.get(
"max_level",lev_for_box);
299 if (lev_for_box > 0 && lev_for_box <= max_level)
301 if (n_error_buf[0] != IntVect::TheZeroVector()) {
302 amrex::Abort(
"Don't use n_error_buf > 0 when setting the box explicitly");
305 ppr.getarr(
"in_box_lo_indices_crse",box_lo,0,num_indx_lo_crse);
306 ppr.getarr(
"in_box_hi_indices_crse",box_hi,0,num_indx_hi_crse);
308 if (num_indx_lo_crse < AMREX_SPACEDIM) {
309 box_lo[2] = geom[lev_for_box-1].Domain().smallEnd(2);
310 box_hi[2] = geom[lev_for_box-1].Domain().bigEnd(2);
313 Box bx(IntVect(box_lo[0],box_lo[1],box_lo[2]),IntVect(box_hi[0],box_hi[1],box_hi[2]));
315 if (!geom[lev_for_box-1].Domain().contains(bx)) {
316 amrex::Print() <<
"\n";
317 amrex::Print() <<
"(Coarse) Box specified is " << bx << std::endl;
318 amrex::Print() <<
"But (coarse) domain at level is " << geom[lev_for_box-1].Domain() << std::endl;
319 amrex::Error(
"Specified box doesn't fit in the domain");
322 bx.refine(ref_ratio[lev_for_box-1]);
324 const auto* dx = geom[lev_for_box-1].CellSize();
326 const Real* plo = geom[lev_for_box].ProbLo();
327 realbox = RealBox(plo[0]+ box_lo[0] *dx[0], plo[1]+ box_lo[1] *dx[1], plo[2]+ box_lo[2] *dx[2],
328 plo[0]+(box_hi[0]+1)*dx[0], plo[1]+(box_hi[1]+1)*dx[1], plo[2]+(box_hi[2]+1)*dx[2]);
330 Print() <<
"Reading " << bx <<
" at level " << lev_for_box << std::endl;
334 Print() <<
"Saving in 'boxes at level' as " << bx << std::endl;
338 AMRErrorTagInfo info;
341 info.SetRealBox(realbox);
343 if (ppr.countval(
"start_time") > 0) {
344 Real ref_min_time; ppr.get(
"start_time",ref_min_time);
345 info.SetMinTime(ref_min_time);
347 if (ppr.countval(
"end_time") > 0) {
348 Real ref_max_time; ppr.get(
"end_time",ref_max_time);
349 info.SetMaxTime(ref_max_time);
351 if (ppr.countval(
"max_level") > 0) {
352 int ref_max_level; ppr.get(
"max_level",ref_max_level);
353 info.SetMaxLevel(ref_max_level);
356 if (ppr.countval(
"value_greater")) {
357 int num_val = ppr.countval(
"value_greater");
358 Vector<Real> value(num_val);
359 ppr.getarr(
"value_greater",value,0,num_val);
360 std::string field; ppr.get(
"field_name",field);
361 ref_tags.push_back(AMRErrorTag(value,AMRErrorTag::GREATER,field,info));
363 else if (ppr.countval(
"value_less")) {
364 int num_val = ppr.countval(
"value_less");
365 Vector<Real> value(num_val);
366 ppr.getarr(
"value_less",value,0,num_val);
367 std::string field; ppr.get(
"field_name",field);
368 ref_tags.push_back(AMRErrorTag(value,AMRErrorTag::LESS,field,info));
370 else if (ppr.countval(
"adjacent_difference_greater")) {
371 int num_val = ppr.countval(
"adjacent_difference_greater");
372 Vector<Real> value(num_val);
373 ppr.getarr(
"adjacent_difference_greater",value,0,num_val);
374 std::string field; ppr.get(
"field_name",field);
375 ref_tags.push_back(AMRErrorTag(value,AMRErrorTag::GRAD,field,info));
377 else if (realbox.ok())
379 ref_tags.push_back(AMRErrorTag(info));
381 Abort(std::string(
"Unrecognized refinement indicator for " + refinement_indicators[i]).c_str());
385 AMRErrorTagInfo info;
388 ref_tags.push_back(AMRErrorTag(value,AMRErrorTag::LESS,
"mask",info));