Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Soret isothermal wall fix #391

Open
wants to merge 38 commits into
base: development
Choose a base branch
from

Conversation

ThomasHowarth
Copy link
Contributor

This PR addresses #389 . Happy to discuss any of the implementation, and let me know if you can see spots for improvement/clarity. Currently, I've not implemented the necessary changes required for EB.

@drummerdoc
Copy link

Is it possible to check in the test case?

@@ -917,7 +993,7 @@ PeleLM::differentialDiffusionUpdate(
GetVecOfConstPtrs(
getDensityVect(AmrNewTime)), // this triggers proper scaling by density
GetVecOfConstPtrs(getDiffusivityVect(AmrNewTime)), 0, bcRecSpec,
NUM_SPECIES - NUM_IONS, 0, m_dt);
NUM_SPECIES - NUM_IONS, 0, m_dt, GetVecOfConstPtrs(spec_boundary));
Copy link
Contributor Author

@ThomasHowarth ThomasHowarth Jun 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably isn't correct for the boundary MF to be compatible with EFIELD, any suggestions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having looked at the mechanisms with ions, the E species has a non-zero Soret coefficient (probably unsurprising), so this probably needs a little bit of thought

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to the idea of just putting an abort for the combination of Efield+Soret+Isothermal and punting on this until someone needs that particular corner case.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on the punt. :)

@baperry2 baperry2 self-requested a review June 24, 2024 22:26
Copy link
Collaborator

@baperry2 baperry2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ThomasHowarth thanks for figuring this out and adding the test case. After this PR gets merged, I can submit a separate PR to have the case run in testing suite including a check on species balance.

I've been trying out the test case. I got rid of dt_shrink to take larger timesteps and make errors more visible. This fix does drastically reduce, but not quite eliminate, species imbalance errors tracked through temporals/tempSpecies. The remaining imbalance is small enough that I'm not very concerned, but I also don't get why conservation isn't quite exact (it doesn't seem to improve by tightening the diffusion solve tolerances).

A couple comments:

  • Can the same fix be applied to the EB version of diffuse_scalar? That wouldn't eliminate the issue of isothermal EBs, but would at least allow EB simulations with isothermal domain boundaries and Soret.
  • It appears that the updated BCs are not applied when diffusion fluxes are computed to compute divu. This should not affect species conservation and with the chi correction on divu, it should not affect the results in the limit of converged SDC iterations.

auto eos = pele::physics::PhysicsType::eos();
amrex::Real Xt[NUM_SPECIES] = {0.0};
amrex::Real a = 0.0;
amrex::Print() << prob_parm.fuelID << std::endl;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove print statements

amrex::ParmParse pp_pele("peleLM");
std::string fuelName = "";
pp_pele.get("fuel_name", fuelName);
amrex::Print() << "H2_ID 1 " << H2_ID << std::endl;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove print statement

@ThomasHowarth
Copy link
Contributor Author

Sorry for the delay, busy month or so...

I've added in the changes so it is computed when computing divu, I've added in the same boundary input to the diffuse_scalar call when running with EB. Code also aborts on Isothermal+Soret+Efield. I am also still seeing some species flux in the species balance files, on the order of 3e-7 or so - any thoughts on this?

@baperry2
Copy link
Collaborator

baperry2 commented Sep 4, 2024

Sorry @ThomasHowarth, I know you've got a few big PRs in the queue waiting for review. I'm going to try to get to them this week.

I've dug into this one a bit and think I figured out the where the remaining conservation error is coming from. With the lagged correction approach, I was only thinking of the implicitly solved $\tilde{D}^{n+1,k+1}$ term in the update equation below, but, as you've now implemented the corrections must also be applied when computing $D^n$ and ${D}^{n+1,k}$, but those are explicitly computed and can't be lagged. Basically, the Soret and Wbar fluxes should be computed first in computeDifferentialDiffusionFluxes and those values should be used to set the inhomogeneous neumann conditions for the diffusive fluxes. For the Soret fluxes that should be easy with some code rearrangement. For the Wbar fluxes it's a little tricky because the Wbar fluxes at the isothermal boundary depend on the species gradients at the boundary, but also affect what the boundary condition needs to be for the species gradients, leading to an implicit definition of the boundary condition. I think it should be okay to compute the Soret terms first, use the boundary species gradients from the Soret terms in computing Wbar fluxes, then use the combined boundary gradients from both Soret and Wbar for the diffusive fluxes. Iterating around the Wbar flux computation would be the fully correct thing though.

Screenshot 2024-09-04 at 10 14 21 AM

Let me know if this makes sense. This is definitely a tricky problem and I'm not sure if I fully understand it. But I did hack a test for the Soret part of the fix (while turning Wbar fluxes off) and that did lead to correct mass conservation.

BTW, I also submitted #410 to make using temporals to track conservation a bit more user friendly.

@@ -675,36 +784,14 @@ PeleLM::addSoretTerm(
#pragma omp parallel if (Gpu::notInLaunchRegion())
#endif
{
FArrayBox rhoY_ed;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was an unnecessary rhoY_ed calculation in the Soret fluxes, which I've now removed

wbarfluxes[lev][idim].setVal(0.0);
}
}
int iter_max = 10;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently 10 iterations hardcoded - we could do some sort of residual check instead

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10 seems a bit excessive, no?

Copy link
Contributor Author

@ThomasHowarth ThomasHowarth Sep 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably - based on the test case it converged in 2 or 3 iterations. EDIT: things are blowing up, will keep testing

@ThomasHowarth
Copy link
Contributor Author

Without the Wbar correction, I have also managed to eliminate the conservation error (Up to 10^-23). However, iterating around the wbar fluxes seems to blow up the gradients, and I'm not entirely sure why. I'll keep working on it, but I've also pushed the latest version so you can take a look if you like.

@baperry2
Copy link
Collaborator

Nice progress a @ThomasHowarth. This has turned out to be much more involved than expected!

If a solution doesn't jump right out at you for the exploding wbar iterations, do you think we can merge this without the wbar iterations (or maybe hardcoding to 1 "iteration") and then have a separate PR for the final correction? There's a lot here that I don't want to risk falling out of date and even without the last bit it's more correct than what's in there now.

eos.inv_molecular_weight(imw);
gradMwmix(i, j, k) = 0.0;
for (int n = 0; n < NUM_SPECIES; n++) {
imw[n] *= 1000.0; // CGS -> MKS
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this was correct, but if I comment out, everything converges nice and quickly - thoughts?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reflects me being away from things for a while, but the MKS version of mw could be kg/kmole (depending on how it is used elsewhere) so that there is no conversion factor necessary. :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is weird because I do think multiplying by 1000 is correct here. When computing MWmix we divide by 1000. Perhaps there's some error cancellation going on?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Wall boundary conditions (e.g. NoSlipWallIsothermal) do lead to wrong behaviour using the soret effect.
3 participants