-
I'm struggling to get my boundary conditions implemented on domain boundaries and am looking for some advice on how to get it to work. Our code is cell centered and when I create a new refinement level at the domain boundaries, I want to set the ghost cell center of the new level such that the cell face on the domain boundary has a value interpolated from the coarser level. I am using the Fortran interface and have tried something like this in my function to remake a level:
If I then look at the solution value in Is there some way to get this to work the way I expected to, so the Alternatively, I'm open to frame-challenges -- am I going about this the wrong way? My boundary condition ghost cell needs to be set based on the face value and the first interior cell, but I can't figure out how to get the face value in a straightforward way. Thanks, Tim |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 4 replies
-
The ext_dir type of boundary condition treats the Dirichlet values as
living on faces.
…On Tue, Nov 9, 2021 at 9:32 AM tpg2114 ***@***.***> wrote:
I'm struggling to get my boundary conditions implemented on domain
boundaries and am looking for some advice on how to get it to work. Our
code is cell centered and when I create a new refinement level at the
domain boundaries, I want to set the ghost cell center of the new level
such that the cell face on the domain boundary has a value interpolated
from the coarser level. I am using the Fortran interface and have tried
something like this in my function to remake a level:
`
! All my lo_bc and hi_bc are set to amrex_bc_ext_dir
! Build my cell centered new level -- the ghost cells on domain boundaries
will be unset because my physical BC routine doesn't do anything at this
stage.
CALL amrex_fillpatch(new_vars, )
! Create a multifab for the I-face-centered values, ultimately I only want
the I-face coincident with the domain boundary
CALL amrex_multifab_build(new_vars_Ifaces, boxarray, distromap, nvars,
nghosts, (/ .TRUE., .FALSE., .FALSE. /))
CALL amrex_fillpatch(new_vars_Ifaces, )
`
If I then look at the solution value in new_vars_Ifaces on the face
coincident with the domain boundary, it looks like it just took the value
from the first interior cell center and copied it to the face value. What I
wanted is that face value to include both sides of the face, something like 0.5*(ghost_cell
+ first interior cell). However, it looks like the amrex_fillpatch
routines ignore ghost cells when setting the face values.
Is there some way to get this to work the way I expected to, so the
amrex_fillpatch will do the interpolation to the cell faces for *all*
cells, regardless of where the domain boundary is?
Alternatively, I'm open to frame-challenges -- am I going about this the
wrong way? My boundary condition ghost cell needs to be set based on the
face value and the first interior cell, but I can't figure out how to get
the face value in a straightforward way.
Thanks,
Tim
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#2468>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACRE6YR46WFVOGKBMS263O3ULFLLZANCNFSM5HV3S3FQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
--
Ann Almgren
Senior Scientist; CCSE Group Lead
Pronouns: she/her/hers
|
Beta Was this translation helpful? Give feedback.
-
Hmmm, interesting on several counts. I wonder though if instead of bastardizing the BC stuff for your purposes, if you instead created the BoxArray that defines the valid region to include the bits grown over the physical boundary. Then you could simply treat the AMReX data structure as a data structure and not as something more complicated using fill-patch stuff where you have to side-step the BCs. You could copy into it and from it and not worry about masking out or cleverly undoing what was done. Does this make sense? As for the NSCBC, a separate and uncalled for question that comes from the fact that I also need to tackle these kinds of boundaries...do you have the problem that accumulating stuff since the IC can accumulate too many errors? I'm curious to learn more about that part, if you have a paper or something...again, unrelated to your actual question here, but I'm an opportunist :) |
Beta Was this translation helpful? Give feedback.
-
Sure! Thanks. [email protected] |
Beta Was this translation helpful? Give feedback.
-
Alright, I appreciate the tips and suggestions @drummerdoc and @asalmgren -- I managed to get it to work the way I wanted! On the off chance anybody else has a similar desire, here's a summary for what I worked out:
If there are other/better ways to accomplish the same, I'm all ears! Of course, proof is in the pudding -- the test case is a left-ward traveling acoustic pulse with a quiescent background with a perfectly-reflective, Navier-Stokes Characteristic Boundary Condition inflow. The image is the flow rate at multiple snapshots in time, with the AMReX-powered AMR result and our traditional, structured multiblock result plotted together. The AMR has 3 levels and dynamically tracks the pulse, with the finest level resolution equal to the structured multiblock resolution (which is uniform). It may not look like it, but each of the pulses is actually 2 lines -- one for AMR, one for structured multiblock, but it's impossible to tell them apart. I consider that a win! Lastly, since it is tangential but was asked -- the NSCBC are very very sensitive to error accumulation. In fact, I discovered that if the initial velocity in the inflow ghost cell is -1e-11 instead of 0.0, the green lines in the image (flow rate when the pulse has bounced off the inflow) peaks at -0.05 instead of -0.01. In other words, there is a 500% error at that point in time due to a 1e-11 difference in one cell at initialization. We also discovered about 5 years ago that floating point truncation errors can make or break the BC. If we do not compile the boundary condition routines with strict IEEE 754 compliance with double precision ( If it is as I suspect, there are probably ways to re-write the code such that the individual terms are not computed directly but their sum or difference is -- however, given that developer and SME time is far far more expensive than CPU time, we opted for code clarity/fidelity to the equations as written and eat the performance penalty of strict IEEE 754 compliance. |
Beta Was this translation helpful? Give feedback.
Alright, I appreciate the tips and suggestions @drummerdoc and @asalmgren -- I managed to get it to work the way I wanted! On the off chance anybody else has a similar desire, here's a summary for what I worked out:
amrex_bc_int_dir
andamrex_bc_ext_dir
, so I don't quite appreciate what those really do I suppose. But it probably works because myfillphys_bc
is basically a no-op and I set my domain ghost cells other ways.amrex_average_cellcenter_to_face
and traced it through to the implementation where it does the $U_F = 0.5(U_L + U_R)$ that I was looking for. I saw it also ignores the geometry passed in, so I suspected it wouldn't care …