Implement Darcy Physics - #620
Conversation
|
@ktbolt i think the majority of these file changes have to do with adding any new physics into the current procedural framework. Unfortunate but expected at this point in my opinion. @mmegally I'll do my review in a few hours when I have some time. From my first glance id say that you should remove the sbatch slurm scripts from the commits. These shouldn't be in the testing infrastructure. I'll give a more formal review in a bit though |
|
@ktbolt I went ahead and added a new comment to issue #616 with some details on the file change split, implementation, and XML usage. Let me know if there is anything else I can clarify. To reiterate my comment from there, 31/47 of the file changes are related to the test cases. I will also go ahead and remove the SLURMs from the test folder as zack mentioned right now |
|
@mmegally Got it, thanks for adding the Issue comments ! |
|
@mmegally The Also rename the |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #620 +/- ##
==========================================
- Coverage 72.86% 72.51% -0.35%
==========================================
Files 258 259 +1
Lines 39498 39718 +220
Branches 6731 6763 +32
==========================================
+ Hits 28780 28803 +23
- Misses 10475 10671 +196
- Partials 243 244 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
zasexton
left a comment
There was a problem hiding this comment.
Suggested changes for Darcy equation initialization and fiber-flux reconstruction.
| phys_ustruct = 211, // Nonlinear elastodynamics using mixed VMS-stabilized formulation | ||
| phys_stokes = 212 | ||
| phys_stokes = 212, | ||
| phys_darcy = 213 |
There was a problem hiding this comment.
A Darcy-only problem currently sets
dFlag=true, causing the predictor to maintain a meaninglessDnstate and changing the restart record to include displacement data. The suggested changes below address this by adding the conventionalEquation_darcyalias and including Darcy in the first-order/non-displacement classification. With these changes applied, Darcy is handled consistently with the other first-order scalar equations.
Suggested code changes
Add the conventional equation alias in Code/Source/solver/consts.h at line 294:
constexpr auto Equation_CMM = EquationType::phys_CMM;
constexpr auto Equation_CEP = EquationType::phys_CEP;
+constexpr auto Equation_darcy = EquationType::phys_darcy;
constexpr auto Equation_fluid = EquationType::phys_fluid;Update the non-displacement classification in Code/Source/solver/initialize.cpp at line 443:
- if (std::set<EquationType>{Equation_fluid, Equation_heatF, Equation_heatS, Equation_CEP, Equation_stokes}.count(eq.phys) == 0) {
+ if (std::set<EquationType>{
+ Equation_CEP,
+ Equation_darcy,
+ Equation_fluid,
+ Equation_heatF,
+ Equation_heatS,
+ Equation_stokes
+ }.count(eq.phys) == 0) {
dFlag = true;
}Result of the suggested change: after equation initialization, a Darcy-only configuration leaves com_mod.dFlag == false.
There was a problem hiding this comment.
I missed this when originally writing the darcy equations since I was unsure of the dflag purpose.
| Vector<double> q(nsd); | ||
| for (int a = 0; a < eNoN; a++) { | ||
| for (int j = 0; j < nsd; j++) { | ||
| q(j) = q(j) + Nx(j, a) * yl(i, a); |
There was a problem hiding this comment.
The current reconstruction reports
MBF_fluxalong global x for a fiber mesh becausenn::gnnonly populatesNx(0,a)wheninsd=1. The suggested changes below address this by reconstructing the physical gradient as(dP/ds) * tangentand then applying the Darcy mobility. This was originally something that I overlooked when initially writing these governing equations.
Suggested code changes
Assuming one-dimensional Darcy fiber support is intentional, compute the unit physical tangent in Code/Source/solver/post.cpp beginning at line 917:
Array<double> ksix(nsd,nsd);
double Jac = 0.0;
+ Vector<double> fiber_tangent(nsd);
for (int g = 0; g < lM.nG; g++) {
if (g == 0 || !lM.lShpF) {
auto Nx_g = lM.Nx.slice(g);
nn::gnn(eNoN, nsd, insd, Nx_g, xl, Nx, Jac, ksix);
+
+ if (lM.lFib) {
+ fiber_tangent = 0.0;
+ for (int a = 0; a < eNoN; a++) {
+ for (int j = 0; j < nsd; j++) {
+ fiber_tangent(j) =
+ fiber_tangent(j) + xl(j,a) * Nx_g(0,a);
+ }
+ }
+
+ const double tangent_norm = utils::norm(fiber_tangent);
+ if (utils::is_zero(tangent_norm)) {
+ throw std::runtime_error(
+ "[post] Cannot compute Darcy flux for a degenerate fiber element.");
+ }
+ fiber_tangent = fiber_tangent / tangent_norm;
+ }
}Replace the Darcy flux block beginning at Code/Source/solver/post.cpp:1016:
} else if (outGrp == OutputNameType::outGrp_mbfFlx) {
- double kappa = eq.dmn[cDmn].prop[PhysicalProperyType::permeability];
- int i = eq.s;
- Vector<double> q(nsd);
- for (int a = 0; a < eNoN; a++) {
- for (int j = 0; j < nsd; j++) {
- q(j) = q(j) + Nx(j, a) * yl(i, a);
+ const double permeability =
+ eq.dmn[cDmn].prop[PhysicalProperyType::permeability];
+ const double viscosity =
+ eq.dmn[cDmn].prop[PhysicalProperyType::darcy_fluid_viscosity];
+ const double mobility = permeability / viscosity;
+ const int i = eq.s;
+
+ Vector<double> grad_p(nsd);
+
+ if (lM.lFib) {
+ double dp_ds = 0.0;
+ for (int a = 0; a < eNoN; a++) {
+ dp_ds = dp_ds + Nx(0,a) * yl(i,a);
+ }
+ for (int j = 0; j < nsd; j++) {
+ grad_p(j) = dp_ds * fiber_tangent(j);
+ }
+ } else {
+ for (int a = 0; a < eNoN; a++) {
+ for (int j = 0; j < nsd; j++) {
+ grad_p(j) = grad_p(j) + Nx(j,a) * yl(i,a);
+ }
}
}
+
for (int j = 0; j < nsd; j++) {
- lRes(j) = -kappa * q(j);
+ lRes(j) = -mobility * grad_p(j);
}The replacement intentionally includes the viscosity correction so the reconstructed flux implements -(K/mu) grad(P) for both fiber and volume meshes.
| double amd = eq.am / T1; | ||
| double wl = w * T1; | ||
|
|
||
| double Pd = -source; |
There was a problem hiding this comment.
Source_termis currently folded intoPdand the complete expression is multiplied byMedia_compressibility. A nonzero source therefore has no effect when the default compressibility is zero, and otherwise behaves as an offset to the pressure time derivative. The changes below separate the volumetric source from the storage term in all three kernels. With these changes applied, the residual representsrho * beta * dp/dt - rho * sourceplus the Darcy diffusion term, soSource_termremains active in the default steady/incompressible configuration.
Suggested code changes
Update the 1-D kernel beginning at Code/Source/solver/darcy.cpp:164:
- double Pd = -source;
+ double p_dot = 0.0;
double Px = 0.0;
for (int a = 0; a < eNoN; a++) {
- Pd = Pd + N(a) * al(i, a);
+ p_dot = p_dot + N(a) * al(i, a);
Px = Px + Nx(0, a) * yl(i, a);
}
for (int a = 0; a < eNoN; a++) {
- lR(0, a) = lR(0, a) + w * (rho_0 * beta_0 * N(a) * Pd +
- (((k * rho_0) / mu) * (Nx(0, a) * Px)));
+ lR(0, a) = lR(0, a) +
+ w * (rho_0 * N(a) * (beta_0 * p_dot - source) +
+ ((k * rho_0) / mu) * Nx(0, a) * Px);
for (int b = 0; b < eNoN; b++) {
lK(0, a, b) = lK(0, a, b) + wl * (rho_0 * beta_0 * N(a) * N(b) * amd +
((((rho_0 * k) / mu) * (Nx(0, a) * Nx(0, b)))));Update the 2-D kernel beginning at Code/Source/solver/darcy.cpp:219:
- double Pd = -source;
+ double p_dot = 0.0;
Vector<double> Px(nsd);
for (int a = 0; a < eNoN; a++) {
- Pd = Pd + N(a)*al(i,a);
+ p_dot = p_dot + N(a)*al(i,a);
Px(0) = Px(0) + Nx(0,a)*yl(i,a);
Px(1) = Px(1) + Nx(1,a)*yl(i,a);
}
for (int a = 0; a < eNoN; a++) {
- lR(0,a) = lR(0,a) + w*(rho_0*beta_0*N(a)*Pd + (((k*rho_0)/mu)*(Nx(0,a)*Px(0)
- + Nx(1,a)*Px(1))));
+ lR(0,a) = lR(0,a) +
+ w * (rho_0 * N(a) * (beta_0 * p_dot - source) +
+ ((k * rho_0) / mu) *
+ (Nx(0,a) * Px(0) + Nx(1,a) * Px(1)));
for (int b = 0; b < eNoN; b++) {
lK(0,a,b) = lK(0,a,b) + wl*(rho_0*beta_0*N(a)*N(b)*amd +
((((rho_0*k)/mu)*(Nx(0,a)*Nx(0,b) +Update the 3-D kernel beginning at Code/Source/solver/darcy.cpp:276:
- double Pd = -source;
+ double p_dot = 0.0;
Vector<double> Px(nsd);
for (int a = 0; a < eNoN; a++) {
- Pd = Pd + N(a) * al(i,a);
+ p_dot = p_dot + N(a) * al(i,a);
Px(0) = Px(0) + Nx(0,a) * yl(i,a);
Px(1) = Px(1) + Nx(1,a) * yl(i,a);
Px(2) = Px(2) + Nx(2,a) * yl(i,a);
}
for (int a = 0; a < eNoN; a++) {
- lR(0,a) = lR(0, a) + w*(rho_0*beta_0*N(a)*Pd +
- ((k*rho_0)/mu)*(Nx(0,a)*Px(0) + Nx(1,a)*Px(1) + Nx(2,a)*Px(2)));
+ lR(0,a) = lR(0, a) +
+ w * (rho_0 * N(a) * (beta_0 * p_dot - source) +
+ ((k * rho_0) / mu) *
+ (Nx(0,a) * Px(0) + Nx(1,a) * Px(1) +
+ Nx(2,a) * Px(2)));
for (int b = 0; b < eNoN; b++) {
lK(0,a,b) = lK(0,a,b) + wl*(rho_0*beta_0*N(a)*N(b)*amd +For Media_compressibility == 0, the source contribution at test-function node a becomes -w * rho_0 * N(a) * source instead of zero. The source remains independent of compressibility, while the existing tangent matrix remains correct because Source_term is prescribed data rather than an unknown.
| propL[1][0] = PhysicalProperyType::source_term; | ||
| propL[2][0] = PhysicalProperyType::solid_density; | ||
| propL[3][0] = PhysicalProperyType::porosity; | ||
| propL[4][0] = PhysicalProperyType::fluid_density; |
There was a problem hiding this comment.
Darcy registers
PhysicalProperyType::fluid_density, but this branch currently reads the generic<Density>value for every equation except CMM. The added Darcy inputs set<Fluid_density>1</Fluid_density>, so their requested value is silently replaced by the default<Density>value of0.5. The change below routes Darcy through the explicitfluid_densityparameter alongside CMM. With it applied, the documented Darcy input populatesdmn.prop[PhysicalProperyType::fluid_density]as intended.
Suggested code change
Update Code/Source/solver/read_files.cpp:1552:
case PhysicalProperyType::fluid_density:
- if (lEq.phys == EquationType::phys_CMM) {
+ if (lEq.phys == EquationType::phys_CMM ||
+ lEq.phys == EquationType::phys_darcy) {
rtmp = domain_params->fluid_density.value();
} else {
rtmp = domain_params->density.value();
}
break;For the four added Darcy XML inputs, <Fluid_density>1</Fluid_density> produces a stored Darcy fluid density of 1.0 rather than the unrelated default <Density> value of 0.5.
| propL[6][0] = PhysicalProperyType::media_compressibility; | ||
| propL[7][0] = PhysicalProperyType::fluid_compressibility; | ||
| propL[8][0] = PhysicalProperyType::darcy_fluid_viscosity; | ||
| propL[9][0] = PhysicalProperyType::density_pressure; |
There was a problem hiding this comment.
Darcy currently registers and parses
solid_density,porosity,porosity_pressure,fluid_compressibility, anddensity_pressure, although no Darcy kernel consumes them. The cleanup below removes the unused properties from the Darcy property list and removes the four newly introduced parser controls that have no implementation. These other parameters were holdovers from when I was trying different models; they can be removed.
Suggested code changes
Restrict the Darcy property list in Code/Source/solver/set_equation_props.h:287 to properties consumed by assembly or output:
propL[0][0] = PhysicalProperyType::permeability;
propL[1][0] = PhysicalProperyType::source_term;
- propL[2][0] = PhysicalProperyType::solid_density;
- propL[3][0] = PhysicalProperyType::porosity;
- propL[4][0] = PhysicalProperyType::fluid_density;
- propL[5][0] = PhysicalProperyType::porosity_pressure;
- propL[6][0] = PhysicalProperyType::media_compressibility;
- propL[7][0] = PhysicalProperyType::fluid_compressibility;
- propL[8][0] = PhysicalProperyType::darcy_fluid_viscosity;
- propL[9][0] = PhysicalProperyType::density_pressure;
+ propL[2][0] = PhysicalProperyType::fluid_density;
+ propL[3][0] = PhysicalProperyType::media_compressibility;
+ propL[4][0] = PhysicalProperyType::darcy_fluid_viscosity;Remove the newly added, unused XML parameter registrations from Code/Source/solver/Parameters.cpp:2049:
set_parameter("Permeability", 0.0, !required, permeability);
- set_parameter("Porosity", 0.0, !required, porosity);
- set_parameter("Porosity_pressure", 0.0, !required, porosity_pressure);
set_parameter("Media_compressibility", 0.0, !required, media_compressibility);
- set_parameter("Fluid_compressibility", 0.0, !required, fluid_compressibility);
set_parameter("Darcy_fluid_viscosity", 1.0, !required, darcy_fluid_viscosity);
- set_parameter("Density_pressure", 0.0, !required, density_pressure);Remove their storage members from Code/Source/solver/Parameters.h:1627:
Parameter<double> permeability;
- Parameter<double> porosity;
- Parameter<double> porosity_pressure;
Parameter<double> media_compressibility;
- Parameter<double> fluid_compressibility;
Parameter<double> darcy_fluid_viscosity;
- Parameter<double> density_pressure;Remove the unused physical-property identifiers and retain explicit values for the supported identifiers in Code/Source/solver/consts.h:421:
inverse_darcy_permeability = 15,
permeability = 16,
- porosity = 17,
- porosity_pressure = 18,
media_compressibility = 19,
- fluid_compressibility = 20,
- darcy_fluid_viscosity = 21,
- density_pressure = 22
+ darcy_fluid_viscosity = 21
};Remove the corresponding no-op cases from Code/Source/solver/read_files.cpp:1588:
case PhysicalProperyType::permeability:
rtmp = domain_params->permeability.value();
break;
- case PhysicalProperyType::porosity:
- rtmp = domain_params->porosity.value();
- break;
-
- case PhysicalProperyType::porosity_pressure:
- rtmp = domain_params->porosity_pressure.value();
- break;
-
case PhysicalProperyType::media_compressibility:
rtmp = domain_params->media_compressibility.value();
break;
- case PhysicalProperyType::fluid_compressibility:
- rtmp = domain_params->fluid_compressibility.value();
- break;
-
case PhysicalProperyType::darcy_fluid_viscosity:
rtmp = domain_params->darcy_fluid_viscosity.value();
break;
-
- case PhysicalProperyType::density_pressure:
- rtmp = domain_params->density_pressure.value();
- break;The implemented Darcy model retains exactly five material inputs, and each has a runtime consumer:
Permeability: Darcy assembly and flux outputSource_term: Darcy residualFluid_density: Darcy residual and tangentMedia_compressibility: transient storage termDarcy_fluid_viscosity: Darcy mobility in assembly and flux output
The removed names are no longer presented as supported Darcy controls.
…k's suggested changes)
Current situation
See issue #616 on introducing darcy physics.
Release Notes
Code of Conduct & Contributing Guidelines