diff --git a/DOC/PermeabilityDamageZone.pdf b/DOC/PermeabilityDamageZone.pdf new file mode 100644 index 000000000..0929b87ea Binary files /dev/null and b/DOC/PermeabilityDamageZone.pdf differ diff --git a/FEM/CMakeLists.txt b/FEM/CMakeLists.txt index 1927b77f4..7642ccfff 100644 --- a/FEM/CMakeLists.txt +++ b/FEM/CMakeLists.txt @@ -56,7 +56,6 @@ set( HEADERS Material/Fluid/GibbsFreeEnergy/DimensionLessGibbsFreeEnergyRegion1.h Material/Fluid/Density/WaterDensityIAPWSIF97Region1.h Material/Fluid/Viscosity/WaterViscosityIAPWS.h - Material/Solid/BGRaCreep.h ) set( SOURCES @@ -116,15 +115,22 @@ set( SOURCES ShapeFunctionPool.cpp Material/Fluid/GibbsFreeEnergy/DimensionLessGibbsFreeEnergyRegion1.cpp Material/Fluid/Viscosity/WaterViscosityIAPWS.cpp - Material/Solid/BGRaCreep.cpp ) +# Get all files in the sub-directory +FILE(GLOB MAT_SOLID_H RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} Material/Solid/*.h) +FILE(GLOB MAT_SOLID_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} Material/Solid/*.cpp) + +FILE(GLOB MAT_PORO_H RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} Material/PorousMedium/*.h) +FILE(GLOB MAT_PORO_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} Material/PorousMedium/*.cpp) + +set( HEADERS ${HEADERS} ${MAT_SOLID_H} ${MAT_PORO_H}) +set( SOURCES ${SOURCES} ${MAT_SOLID_CPP} ${MAT_PORO_CPP}) + if(NOT OGS_LSOLVER STREQUAL PETSC) set( SOURCES ${SOURCES} par_ddc.h par_ddc.cpp) endif() - - if(OGS_LSOLVER STREQUAL RF) set( HEADERS ${HEADERS} solver.h matrix_routines.h) set( SOURCES ${SOURCES} solver.cpp matrix_routines.cpp) diff --git a/FEM/Material/PorousMedium/DamageZonePermeability.cpp b/FEM/Material/PorousMedium/DamageZonePermeability.cpp new file mode 100644 index 000000000..c7b30c2e2 --- /dev/null +++ b/FEM/Material/PorousMedium/DamageZonePermeability.cpp @@ -0,0 +1,39 @@ +/** + * \copyright + * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * \file DamageZonePermeability.cpp + * + * Created on February 6, 2019, 3:25 PM + * + */ + +#include "DamageZonePermeability.h" + +#include + +#include "Material/Solid/MohrCoulombFailureCriterion.h" +namespace PorousMediumProperty +{ +void DamageZonePermeability::computeDamageZonePermeability( + double* intrinsic_permeability, + SolidProp::MohrCoulombFailureCriterion const& failure_criterion, + double const* const stress, const int dim) +{ + const int n_stresses = (dim == 3) ? 6 : 4; + const double failure_index = + failure_criterion.getFailureIndex(stress, n_stresses); + + if (failure_index < 1.0) + return; + + const double extra_k = _a * std::exp(_b * failure_index); + for (int i = 0; i < dim; i++) + { + intrinsic_permeability[i * dim + i] += extra_k; + } +} +} // End of the namespace diff --git a/FEM/Material/PorousMedium/DamageZonePermeability.h b/FEM/Material/PorousMedium/DamageZonePermeability.h new file mode 100644 index 000000000..e0d03801d --- /dev/null +++ b/FEM/Material/PorousMedium/DamageZonePermeability.h @@ -0,0 +1,54 @@ +/** + * \copyright + * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * \file DamageZonePermeability.h + * + * Created on February 6, 2019, 3:25 PM + * + */ + +#pragma once + +namespace SolidProp +{ +class MohrCoulombFailureCriterion; +} +namespace PorousMediumProperty +{ +/** + * Permeability model for damage zone, which is determined by the Mohr-Coulomb + * failure index as + * \f$ k=k_0 + a \mbox{e}^{b\,f} \f$ + * where \f$k_0\f$ is the intrinsic permeability, \f$a\f$ and \f$b\f$ are + * coefficient, and \f$ f \f$ is the failure index. + */ +class DamageZonePermeability +{ +public: + DamageZonePermeability(const double a, const double b) : _a(a), _b(b) {} + /** + * + * @param intrinsic_permeability Passed in as intrinsic permeability + * tensor, and passed out the modification of + * intrinsic permeability with damage zone + * model. + * @param failure_criterion Failure criterion. + * @param stress Stress tensor. + * @param dim Dimension of the intrinsic permeability + * tensor. + */ + void computeDamageZonePermeability( + double* intrinsic_permeability, + SolidProp::MohrCoulombFailureCriterion const& failure_criterion, + double const* const stress, + const int dim); + +private: + const double _a; /// Coefficient a + const double _b; /// Coefficient a +}; +} // End of the namespace diff --git a/FEM/Material/Solid/BGRaCreep.cpp b/FEM/Material/Solid/BGRaCreep.cpp index 6d5fe4f9c..18cf409a2 100644 --- a/FEM/Material/Solid/BGRaCreep.cpp +++ b/FEM/Material/Solid/BGRaCreep.cpp @@ -16,34 +16,17 @@ #include #include -#include "PhysicalConstant.h" -#include "LinAlg/GaussAlgorithm.h" -#include "rf_msp_new.h" + #include "display.h" -namespace SolidProp -{ -void getDeviatoricStess(double const* const stress, - const int nstress_components, double* s) -{ - for (int i = 0; i < nstress_components; i++) - s[i] = stress[i]; +#include "LinAlg/GaussAlgorithm.h" +#include "PhysicalConstant.h" +#include "rf_msp_new.h" - const double mean_stress = (stress[0] + stress[1] + stress[2]) / 3.0; - for (int i = 0; i < 3; i++) - s[i] -= mean_stress; -} +#include "StressAuxiliaryFunctions.h" -double getStressNorm(double const* const s, const int nstress_components) +namespace SolidProp { - double ns = 0.0; - for (int i = 0; i < 3; i++) - ns += s[i] * s[i]; - for (int i = 3; i < nstress_components; i++) - ns += 2.0 * s[i] * s[i]; - return std::sqrt(ns); -} - double getCreepConstantCoefficient(const double A, const double n, const double sigma0) { diff --git a/FEM/Material/Solid/MohrCoulombFailureCriterion.cpp b/FEM/Material/Solid/MohrCoulombFailureCriterion.cpp new file mode 100644 index 000000000..070e73b61 --- /dev/null +++ b/FEM/Material/Solid/MohrCoulombFailureCriterion.cpp @@ -0,0 +1,51 @@ +/** + * \copyright + * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * \file MohrCoulombFailureCriterion.cpp + * + * Created on February 6, 2019, 1:40 PM + * + */ + +#include "MohrCoulombFailureCriterion.h" + +#include +#include +#include + +#include "StressAuxiliaryFunctions.h" + +namespace SolidProp +{ +MohrCoulombFailureCriterion::MohrCoulombFailureCriterion(const double c, + const double angle) + : _c(c), _angle(angle * pi / 180.0) +{ +} + +double MohrCoulombFailureCriterion::getFailureIndex( + double const* const s, const int nstress_components) const +{ + double const* const principle_stresses = + getPrincipleStresses(s, nstress_components); + + double s_min = std::numeric_limits::max(); + double s_max = -std::numeric_limits::max(); + + for (int i = 0; i < 3; i++) + { + s_max = std::max(s_max, principle_stresses[i]); + s_min = std::min(s_min, principle_stresses[i]); + } + + const double tau_max = 0.5 * std::abs(s_max - s_min); + const double s_n = -0.5 * (s_max + s_min) / std::cos(_angle); + + return tau_max / (_c + s_n * std::tan(_angle)); +} + +} // end of namespace diff --git a/FEM/Material/Solid/MohrCoulombFailureCriterion.h b/FEM/Material/Solid/MohrCoulombFailureCriterion.h new file mode 100644 index 000000000..16dd48e6a --- /dev/null +++ b/FEM/Material/Solid/MohrCoulombFailureCriterion.h @@ -0,0 +1,37 @@ +/** + * \copyright + * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * \file MohrCoulombFailureCriterion.h + * + * Created on February 6, 2019, 1:40 PM + * + */ + +#pragma once + +namespace SolidProp +{ +class MohrCoulombFailureCriterion +{ +public: + MohrCoulombFailureCriterion(const double c, const double angle); + + /** + * + * @param s Stress. + * @param nstress_components Number of stress components. + * @return + */ + double getFailureIndex(double const* const s, + const int nstress_components) const; + +private: + const double _c; /// apparent cohesion. + const double _angle; /// The angle of internal friction. +}; + +} // end of namespace diff --git a/FEM/Material/Solid/StressAuxiliaryFunctions.cpp b/FEM/Material/Solid/StressAuxiliaryFunctions.cpp new file mode 100644 index 000000000..3de26fc46 --- /dev/null +++ b/FEM/Material/Solid/StressAuxiliaryFunctions.cpp @@ -0,0 +1,88 @@ +/** + * \copyright + * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * \file StressAuxiliaryFunctions.cpp + * + * Created on February 6, 2019, 12:08 PM + * + */ + +#include "StressAuxiliaryFunctions.h" + +#include +#include +#include + +namespace SolidProp +{ +void getDeviatoricStess(double const* const stress, + const int nstress_components, double* s) +{ + for (int i = 0; i < nstress_components; i++) + s[i] = stress[i]; + + const double mean_stress = (stress[0] + stress[1] + stress[2]) / 3.0; + for (int i = 0; i < 3; i++) + s[i] -= mean_stress; +} + +double getStressNorm(double const* const s, const int nstress_components) +{ + double ns = 0.0; + for (int i = 0; i < 3; i++) + ns += s[i] * s[i]; + for (int i = 3; i < nstress_components; i++) + ns += 2.0 * s[i] * s[i]; + return std::sqrt(ns); +} + +double* getPrincipleStresses(double const* const s, + const int nstress_components) +{ + static double principle_stress[3]; + const double s11 = s[0]; + const double s22 = s[1]; + const double s33 = s[2]; + const double s12 = s[3]; + const double s13 = (nstress_components == 6) ? s[4] : 0.0; + const double s23 = (nstress_components == 6) ? s[5] : 0.0; + + const double I1 = s11 + s22 + s33; + const double I2 = s11 * s22 + s22 * s33 + s33 * s11 - s12 * s12 + - s13 * s13 - s23 * s23; + const double I3 = s11 * s22 * s33 + 2 * s12 * s23 * s13 + - s23 * s23 * s11 - s13 * s13 * s22 + - s12 * s12 * s33; + + if ((std::fabs(I1) < std::numeric_limits::epsilon() && + std::fabs(I2) < std::numeric_limits::epsilon()) || + std::fabs(I1 * I1 - 3.0 * I2) < std::numeric_limits::epsilon() + ) + { + for (int k=0; k<3; k++) + principle_stress[k] = s[k]; + return principle_stress; + } + + const double cos_a = + std::min(std::max(0.5 * (2 * I1 * I1 * I1 - 9. * I1 * I2 + 27.0 * I3) / + std::pow(I1 * I1 - 3.0 * I2, 1.5), + -1.0), + 1.0); + + const double alpha = std::acos(cos_a) / 3.0; + const double I1_d3 = I1 / 3.0; + const double fac = 2. * std::sqrt(I1 * I1 - 3 * I2) / 3.0; + + principle_stress[0] = I1_d3 + fac * std::cos(alpha); + principle_stress[1] = I1_d3 + fac * std::cos(alpha - 2.0 * pi / 3.0); + principle_stress[2] = I1_d3 + fac * std::cos(alpha - 4.0 * pi / 3.0); + + return principle_stress; +} + +} // namespace SolidProp diff --git a/FEM/Material/Solid/StressAuxiliaryFunctions.h b/FEM/Material/Solid/StressAuxiliaryFunctions.h new file mode 100644 index 000000000..7014ad872 --- /dev/null +++ b/FEM/Material/Solid/StressAuxiliaryFunctions.h @@ -0,0 +1,28 @@ +/** + * \copyright + * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * \file StressAuxiliaryFunctions.h + * + * Created on February 6, 2019, 12:08 PM + * + */ + +#pragma once + +namespace SolidProp +{ +void getDeviatoricStess(double const* const stress, + const int nstress_components, double* s); + +double getStressNorm(double const* const s, const int nstress_components); + +double* getPrincipleStresses(double const* const s, + const int nstress_components); + +const double pi = 3.14159265359; + +} // end of namespace diff --git a/FEM/fem_ele_std.cpp b/FEM/fem_ele_std.cpp index d72943b73..78b69d894 100644 --- a/FEM/fem_ele_std.cpp +++ b/FEM/fem_ele_std.cpp @@ -1789,7 +1789,7 @@ double CFiniteElementStd::CalCoefMass() 02/2007 WW Multi-phase flow 05/2008 WW Generalization **************************************************************************/ -double CFiniteElementStd::CalCoefMass2(int dof_index) +double CFiniteElementStd::CalCoefMass2(const int dof_index, const int gp) { int Index = MeshElement->GetIndex(); double val = 0.0; @@ -1805,7 +1805,7 @@ double CFiniteElementStd::CalCoefMass2(int dof_index) // // CB_merge_0513 in case of het K, store local K in permeability_tensor double* tensor = NULL; - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, gp); MediaProp->local_permeability = tensor[0]; const double Rv = SpecificGasConstant::WaterVapour; @@ -2230,7 +2230,7 @@ void CFiniteElementStd::CalCoefLaplace(bool Gravity, int ip) if (MediaProp->flowlinearity_model > 0) k_rel = MediaProp->NonlinearFlowFunction( index, gp, pcs->m_num->ls_theta, this); - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); // AS:08.2012 permeability function eff stress if (MediaProp->permeability_effstress_model > 0) { @@ -2302,7 +2302,7 @@ void CFiniteElementStd::CalCoefLaplace(bool Gravity, int ip) break; case EPT_GROUNDWATER_FLOW: // Groundwater flow - /* SB4218 - moved to ->PermeabilityTensor(Index); + /* SB4218 - moved to ->PermeabilityTensor(Index, ip); if(MediaProp->permeability_model==2){ //?efficiency for(i=0;i<(int)pcs->m_msh->mat_names_vector.size();i++){ if(pcs->m_msh->mat_names_vector[i].compare("PERMEABILITY")==0) @@ -2321,7 +2321,7 @@ void CFiniteElementStd::CalCoefLaplace(bool Gravity, int ip) k_rel = MediaProp->NonlinearFlowFunction( index, gp, pcs->m_num->ls_theta, this); // NW - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); // TK/NW 10.10.2011 if (dim > MediaProp->geo_dimension) { @@ -2383,7 +2383,7 @@ void CFiniteElementStd::CalCoefLaplace(bool Gravity, int ip) // PCH Rewriting... // PCH Laplace mat_fac is accounted for two phases here. // thought to be related to the reference pressure. - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); if (pcs->pcs_type_number == 0) { if (!Gravity) @@ -2573,7 +2573,7 @@ void CFiniteElementStd::CalCoefLaplace(bool Gravity, int ip) } //................................................................ // Friction coefficient - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); // Manning-coefficient: n manning = MediaProp->permeability_tensor[0]; // ToDo MB MMP function: m_mmp->FrictionCoefficientChezy(gp) @@ -2618,7 +2618,7 @@ void CFiniteElementStd::CalCoefLaplace(bool Gravity, int ip) fac_perm *= MediaProp->PermeabilityFunctionStrain(Index, nnodes, h_fem); - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); if (MediaProp->unconfined_flow_group == 2) // 3D unconfined GW JOD, 5.3.07 @@ -2670,7 +2670,7 @@ void CFiniteElementStd::CalCoefLaplace(bool Gravity, int ip) dens_arg[2] = Index; double vis = FluidProp->Viscosity(dens_arg); mat_fac = vis; - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); k_rel = 1.0; if (MediaProp->flowlinearity_model > 0) k_rel = MediaProp->NonlinearFlowFunction( @@ -2726,7 +2726,7 @@ void CFiniteElementStd::CalCoefLaplaceMultiphase(int phase, int ip) // PCH Rewriting... // PCH Laplace mat_fac is accounted for two phases here. // thought to be related to the reference pressure. - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); if (pcs->pcs_type_number == 0) { // PCH Laplace mat_fac is accounted for two phases here. @@ -2777,7 +2777,8 @@ void CFiniteElementStd::CalCoefLaplaceMultiphase(int phase, int ip) 02/2007 WW Implementation last modification: **************************************************************************/ -void CFiniteElementStd::CalCoefLaplace2(bool Gravity, int dof_index) +void CFiniteElementStd::CalCoefLaplace2(const bool Gravity, const int dof_index, + const int ip) { double* tensor = NULL; double mat_fac = 1.0, m_fac = 0.; @@ -2794,7 +2795,7 @@ void CFiniteElementStd::CalCoefLaplace2(bool Gravity, int dof_index) // int Index = MeshElement->GetIndex(); // CB_merge_0513 in case of het K, store local K in permeability_tensor - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); MediaProp->local_permeability = tensor[0]; // @@ -2821,7 +2822,7 @@ void CFiniteElementStd::CalCoefLaplace2(bool Gravity, int dof_index) PG = interpolate(NodalVal1); Sw = MediaProp->SaturationCapillaryPressureFunction(PG); // - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); mat_fac = MediaProp->PermeabilitySaturationFunction(Sw, 0) / FluidProp->Viscosity(); for (size_t i = 0; i < dim * dim; i++) @@ -2900,7 +2901,7 @@ void CFiniteElementStd::CalCoefLaplace2(bool Gravity, int dof_index) rho_ga = GasProp->Density(dens_arg); rho_g = rho_ga + rho_gw; } - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); mat_fac = MediaProp->PermeabilitySaturationFunction(Sw, 0) / FluidProp->Viscosity(); m_fac = 0.; @@ -2944,7 +2945,7 @@ void CFiniteElementStd::CalCoefLaplace2(bool Gravity, int dof_index) dens_arg[0] = PG2; rho_ga = GasProp->Density(dens_arg); // - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); mat_fac = rho_ga * MediaProp->PermeabilitySaturationFunction(Sw, 1) / (GasProp->Viscosity() * rhow); @@ -3030,7 +3031,9 @@ void CFiniteElementStd::CalCoefLaplaceMCF(int ip) 03/2009 PCH Implementation last modification: **************************************************************************/ -void CFiniteElementStd::CalCoefLaplacePSGLOBAL(bool Gravity, int dof_index) +void CFiniteElementStd::CalCoefLaplacePSGLOBAL(const bool Gravity, + const int dof_index, + const int ip) { double* tensor = NULL; double mat_fac = 1.0; // OK411 m_fac=0.; @@ -3046,7 +3049,7 @@ void CFiniteElementStd::CalCoefLaplacePSGLOBAL(bool Gravity, int dof_index) switch (dof_index) { case 0: - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); if (pcs->m_num->ele_upwinding == 1) { // Doing Upwind elements for saturation by divergent of @@ -3071,13 +3074,13 @@ void CFiniteElementStd::CalCoefLaplacePSGLOBAL(bool Gravity, int dof_index) mat[i] = tensor[i] * mat_fac * time_unit_factor; break; case 1: - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); mat_fac = 0.0; // Snw has no laplace term for (size_t i = 0; i < dim * dim; i++) mat[i] = tensor[i] * mat_fac * time_unit_factor; break; case 2: - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); if (pcs->m_num->ele_upwinding == 1) { // Doing Upwind elements for saturation by divergent of @@ -3108,7 +3111,7 @@ void CFiniteElementStd::CalCoefLaplacePSGLOBAL(bool Gravity, int dof_index) break; case 3: // Snw Laplace from Pc in Eqn 2 - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); if (pcs->num_type_name.find("dPcdSwGradSnw") != string::npos) { @@ -3149,7 +3152,7 @@ void CFiniteElementStd::CalCoefLaplacePSGLOBAL(bool Gravity, int dof_index) break; case 4: // For Vnw - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); // double Snw = -1.0; // if(pcs->m_num->ele_upwinding == 1) @@ -4452,7 +4455,7 @@ void CFiniteElementStd::CalcMass2() for (jn = 0; jn < dof_n; jn++) { // Material - mat_fac = CalCoefMass2(in * dof_n + jn); + mat_fac = CalCoefMass2(in * dof_n + jn, gp); mat_fac *= fkt; // Calculate mass matrix const int jsh = jn * nnodes; @@ -4691,7 +4694,7 @@ void CFiniteElementStd::CalcLumpedMass2() for (jn = 0; jn < dof_n; jn++) { // Factor - factor = CalCoefMass2(in * dof_n + jn); + factor = CalCoefMass2(in * dof_n + jn, 0); pcs->timebuffer = factor; // Tim Control "Neumann" // Volume factor *= vol / (double)nnodes; @@ -5001,9 +5004,9 @@ void CFiniteElementStd::CalcLaplace() else if (dof_n == 2) { if (PcsType == EPT_MULTIPHASE_FLOW) - CalCoefLaplace2(false, ishd + jn); + CalCoefLaplace2(false, ishd + jn, gp); else if (PcsType == EPT_PSGLOBAL) - CalCoefLaplacePSGLOBAL(false, ishd + jn); + CalCoefLaplacePSGLOBAL(false, ishd + jn, gp); } else if (PcsType == EPT_THERMAL_NONEQUILIBRIUM) CalCoefLaplaceTNEQ(ishd + jn); @@ -5143,7 +5146,7 @@ void CFiniteElementStd::Assemble_DualTransfer() fkt = GetGaussData(gp, gp_r, gp_s, gp_t); // Material getShapefunctValues(gp, 1); // Moved here by NW 25.10.2011 - mat_fac = CalcCoefDualTransfer(); + mat_fac = CalcCoefDualTransfer(gp); mat_fac *= fkt; // Calculate mass matrix for (i = 0; i < nnodes; i++) @@ -5196,7 +5199,7 @@ void CFiniteElementStd::Assemble_DualTransfer() 10/2006 YD Implementation 01/2007 WW Fundamental changes **************************************************************************/ -double CFiniteElementStd::CalcCoefDualTransfer() +double CFiniteElementStd::CalcCoefDualTransfer(const int ip) { double Sm = 0.0, Sf = 0.0, ExFac = 0.0; double pm = 0.0, pf = 0.0, matrix_conductivity, val = 0; @@ -5227,7 +5230,7 @@ double CFiniteElementStd::CalcCoefDualTransfer() Sm = m_matrix->SaturationCapillaryPressureFunction(-pm); // Fracture Sf = f_matrix->SaturationCapillaryPressureFunction(-pf); - permeability = m_matrix->PermeabilityTensor(Index); + permeability = m_matrix->PermeabilityTensor(Index, ip); ExFac = m_matrix->transfer_coefficient; // Dual by van Genuchten if (ExFac > 0.0) @@ -5940,9 +5943,9 @@ void CFiniteElementStd::Assemble_Gravity() if (dof_n == 2) { if (PcsType == EPT_MULTIPHASE_FLOW) - CalCoefLaplace2(true, ii * dof_n + 1); + CalCoefLaplace2(true, ii * dof_n + 1, gp); else if (PcsType == EPT_PSGLOBAL) - CalCoefLaplacePSGLOBAL(true, ii * dof_n); + CalCoefLaplacePSGLOBAL(true, ii * dof_n, gp); } else if (dof_n == 4) { @@ -6173,7 +6176,7 @@ void CFiniteElementStd::Assemble_Gravity_Multiphase() if (dof_n == 1) CalCoefLaplaceMultiphase(p); if (dof_n == 2) - CalCoefLaplace2(false, ii * dof_n + 1); + CalCoefLaplace2(false, ii * dof_n + 1, gp); // Calculate mass matrix for (i = 0; i < nnodes; i++) @@ -6203,7 +6206,7 @@ void CFiniteElementStd::Assemble_Gravity_Multiphase() if (dof_n == 1) CalCoefLaplace(false); if (dof_n == 2) - CalCoefLaplace2(false, ii * dof_n + 1); + CalCoefLaplace2(false, ii * dof_n + 1, gp); // Calculate mass matrix for (i = 0; i < nnodes; i++) @@ -6647,9 +6650,9 @@ void CFiniteElementStd::Cal_Velocity() else if (dof_n == 3 && PcsType == EPT_TES) CalCoefLaplaceTES(0); else if (dof_n == 2 && PcsType == EPT_MULTIPHASE_FLOW) // PCH 05.2009 - CalCoefLaplace2(true, 0); + CalCoefLaplace2(true, 0, gp); else if (dof_n == 2 && PcsType == EPT_PSGLOBAL) // PCH 05.2009 - CalCoefLaplacePSGLOBAL(true, 0); + CalCoefLaplacePSGLOBAL(true, 0, gp); // WW/CB if ((PcsType == EPT_TWOPHASE_FLOW) && (pcs->pcs_type_number == 1)) flag_cpl_pcs = false; @@ -6757,7 +6760,7 @@ void CFiniteElementStd::Cal_Velocity() // gp_ele->Velocity(i, gp) += // mat[dim*i+j]*vel[j]/time_unit_factor; } - CalCoefLaplace2(true, 3); + CalCoefLaplace2(true, 3, gp); double coef_tmp; // WX:08.2010. coef_tmp = rhow / rho_ga; for (size_t i = 0; i < dim; i++) @@ -6828,7 +6831,7 @@ void CFiniteElementStd::Cal_Velocity() if (PcsType == EPT_PSGLOBAL) // PCH 05.2009 { // Juse use the coefficient of PSGLOBAL Pressure-based velocity (4) - CalCoefLaplacePSGLOBAL(true, 4); + CalCoefLaplacePSGLOBAL(true, 4, gp); for (size_t i = 0; i < dim; i++) for (size_t j = 0; j < dim; j++) gp_ele->Velocity_g(i, gp) -= @@ -7228,9 +7231,9 @@ void CFiniteElementStd::Cal_Velocity_2() flag_cpl_pcs = true; // Material if (dof_n == 1) - CalCoefLaplace(true); + CalCoefLaplace(true, gp); else if (dof_n == 2) - CalCoefLaplace2(true, 0); + CalCoefLaplace2(true, 0, gp); if ((PcsType == EPT_TWOPHASE_FLOW) && (pcs->pcs_type_number == 1)) // WW/CB flag_cpl_pcs = false; @@ -7286,7 +7289,7 @@ void CFiniteElementStd::Cal_Velocity_2() // if (PcsType == EPT_MULTIPHASE_FLOW) { - CalCoefLaplace2(true, 3); + CalCoefLaplace2(true, 3, gp); coef = rhow / rho_ga; for (size_t i = 0; i < dim; i++) for (size_t j = 0; j < dim; j++) @@ -9989,8 +9992,6 @@ void CFiniteElementStd::CalcSaturation(MeshLib::CElem& elem) //---------------------------------------------------------------------- SetMaterial(); - // CB_merge_0513 - double* tens = MediaProp->PermeabilityTensor(Index); // int idx_cp, idx_S; idx_cp = pcs->GetNodeValueIndex("PRESSURE1") + 1; @@ -10041,6 +10042,8 @@ void CFiniteElementStd::CalcSaturation(MeshLib::CElem& elem) getShapefunctValues(gp, 1); // // CB_merge_0513 in case of het K, store local K + // CB_merge_0513 + double* tens = MediaProp->PermeabilityTensor(Index, gp); MediaProp->local_permeability = tens[0]; PG = interpolate(NodalVal0); NodalVal_Sat[i] = MediaProp->SaturationCapillaryPressureFunction(PG); @@ -10193,7 +10196,8 @@ void CFiniteElementStd::CalcNodeMatParatemer(MeshLib::CElem& elem) if ((pcs->additioanl2ndvar_print > 0) && (pcs->additioanl2ndvar_print < 3)) { - double* tensor = MediaProp->PermeabilityTensor(MeshElement->index); + double* tensor = + MediaProp->PermeabilityTensor(MeshElement->index, gp); // Modified LBNL model if (MediaProp->permeability_stress_mode == 2 || MediaProp->permeability_stress_mode == 3) @@ -10610,7 +10614,7 @@ double CFiniteElementStd::CalCoef_RHS_T_PSGlobal(int dof_index) 03/2009 PCH Implementation last modification: **************************************************************************/ -void CFiniteElementStd::CalCoef_RHS_Pc(int dof_index) +void CFiniteElementStd::CalCoef_RHS_Pc(const int dof_index, const int ip) { double* tensor = NULL; double mat_fac = 1.0; // OK411 m_fac=0.; @@ -10629,7 +10633,7 @@ void CFiniteElementStd::CalCoef_RHS_Pc(int dof_index) case 1: break; case 2: - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); Sw = 1.0 - interpolate(NodalVal_SatNW); k_rel = MediaProp->PermeabilitySaturationFunction(Sw, 1); mat_fac = k_rel / GasProp->Viscosity() * time_unit_factor; @@ -10936,7 +10940,7 @@ void CFiniteElementStd::Assemble_RHS_Pc() for (ii = 0; ii < dof_n; ii++) { // Material - CalCoef_RHS_Pc(ii + dof_n); + CalCoef_RHS_Pc(ii + dof_n, gp); // Calculate Pc #if defined(USE_PETSC) //|| defined (other parallel solver) //WW 04.2014 for (int ia = 0; ia < act_nodes; ia++) @@ -11265,7 +11269,7 @@ void CFiniteElementStd::Assemble_RHS_AIR_FLOW() dens_arg[2] = Index; fluid_density = FluidProp->Density(dens_arg); mat_fac = FluidProp->Viscosity(dens_arg); - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, gp); for (size_t i = 0; i < dim * dim; i++) mat[i] = tensor[i] / mat_fac; for (ii = 0; ii < dof_n; ii++) @@ -11372,7 +11376,8 @@ void CFiniteElementStd::Assemble_RHS_HEAT_TRANSPORT() last modification: **************************************************************************/ -double CFiniteElementStd::CalCoef_RHS_HEAT_TRANSPORT2(int dof_index) +double CFiniteElementStd::CalCoef_RHS_HEAT_TRANSPORT2(const int dof_index, + const int ip) { // TF unused variable - comment fix compile warning // ElementValue* gp_ele = ele_gp_value[Index]; @@ -11413,7 +11418,7 @@ double CFiniteElementStd::CalCoef_RHS_HEAT_TRANSPORT2(int dof_index) break; case 2: - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); mat_fac = H_vap * rhow * MediaProp->PermeabilitySaturationFunction(Sw, 0) / FluidProp->Viscosity(); @@ -11422,7 +11427,7 @@ double CFiniteElementStd::CalCoef_RHS_HEAT_TRANSPORT2(int dof_index) break; case 3: - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, ip); mat_fac = -H_vap * rhow * MediaProp->PermeabilitySaturationFunction(Sw, 0) / FluidProp->Viscosity(); @@ -11484,7 +11489,7 @@ void CFiniteElementStd::Assemble_RHS_HEAT_TRANSPORT2() for (ii = 0; ii < dof_n; ii++) { // Material - fac = fkt * CalCoef_RHS_HEAT_TRANSPORT2(ii) / dt; + fac = fkt * CalCoef_RHS_HEAT_TRANSPORT2(ii, gp) / dt; // Calculate THS for (i = 0; i < nnodes; i++) NodalVal[i] += fac * shapefct[i]; @@ -11494,7 +11499,7 @@ void CFiniteElementStd::Assemble_RHS_HEAT_TRANSPORT2() for (ii = 0; ii < dof_n - 1; ii++) { // Material - CalCoef_RHS_HEAT_TRANSPORT2(ii + dof_n); + CalCoef_RHS_HEAT_TRANSPORT2(ii + dof_n, gp); for (i = 0; i < nnodes; i++) for (j = 0; j < nnodes; j++) for (size_t k = 0; k < dim; k++) @@ -11507,7 +11512,7 @@ void CFiniteElementStd::Assemble_RHS_HEAT_TRANSPORT2() for (ii = 0; ii < dof_n - 1; ii++) { // Material - CalCoef_RHS_HEAT_TRANSPORT2(ii + dof_n + 1); + CalCoef_RHS_HEAT_TRANSPORT2(ii + dof_n + 1, gp); for (i = 0; i < nnodes; i++) for (j = 0; j < nnodes; j++) for (size_t k = 0; k < dim; k++) @@ -11519,7 +11524,7 @@ void CFiniteElementStd::Assemble_RHS_HEAT_TRANSPORT2() // gravity if (GravityOn) { - CalCoef_RHS_HEAT_TRANSPORT2(2); + CalCoef_RHS_HEAT_TRANSPORT2(2, gp); for (i = 0; i < nnodes; i++) for (size_t k = 0; k < dim; k++) NodalVal[i] -= fkt * mat[dim * k + dim - 1] * diff --git a/FEM/fem_ele_std.h b/FEM/fem_ele_std.h index 22eb4ecdc..dd37a1312 100644 --- a/FEM/fem_ele_std.h +++ b/FEM/fem_ele_std.h @@ -211,8 +211,8 @@ class CFiniteElementStd : public CElement double* swval, double* swold); void CalcOverlandCKWR(double* head, double* ckwr, int* iups); - void CalcOverlandCKWRatNodes( - int i, int j, double* head, double* ckwr, int* iups); + void CalcOverlandCKWRatNodes(int i, int j, double* head, double* ckwr, + int* iups); void CalcOverlandResidual(double* head, double* swval, double* swold, @@ -355,17 +355,18 @@ class CFiniteElementStd : public CElement // double CalCoefMass(); // 25.2.2007 WW - double CalCoefMass2(int dof_index); + double CalCoefMass2(const int dof_index, const int gp); double CalCoefMasstneq(int dof_index); // 03.3.2009 PCH double CalCoefMassPSGLOBAL(int dof_index); void CalCoefLaplace(bool Gravity, int ip = 0); // 10 2008 PCH void CalCoefLaplaceMultiphase(int phase, int ip = 0); - void CalCoefLaplace2(bool Gravity, int dof_index); + void CalCoefLaplace2(const bool Gravity, const int dof_index, const int ip); void CalCoefLaplaceTNEQ(const int dof_index); void CalCoefLaplaceTES(const int dof_index); - void CalCoefLaplacePSGLOBAL(bool Gravity, int dof_index); + void CalCoefLaplacePSGLOBAL(const bool Gravity, const int dof_index, + const int ip); double CalCoefAdvection(); // SB4200 OK/CMCD // AKS/NB double CalCoefAdvectionTNEQ(const int dof_index); @@ -385,7 +386,7 @@ class CFiniteElementStd : public CElement double CalCoefContentTES(const int dof_index); double CalCoefStrainCouping(const int phase = 0); - double CalcCoefDualTransfer(); + double CalcCoefDualTransfer(const int ip); // 27.2.2007 WW double CalCoef_RHS_T_MPhase(int dof_index); double CalCoef_RHS_TNEQ(const int dof_index); @@ -396,13 +397,13 @@ class CFiniteElementStd : public CElement // NB double CalCoef_RHS_T_PSGlobal(int dof_index); // 03.2007 PCH - void CalCoef_RHS_Pc(int dof_index); + void CalCoef_RHS_Pc(const int dof_index, const int ip); // AKS double CalCoef_RHS_AIR_FLOW(int dof_index); // AKS double CalCoef_RHS_HEAT_TRANSPORT(int dof_index); // AKS - double CalCoef_RHS_HEAT_TRANSPORT2(int dof_index); + double CalCoef_RHS_HEAT_TRANSPORT2(const int dof_index, const int ip); void CalNodalEnthalpy(); void ComputeAdditionalJacobi_H2(); // WW diff --git a/FEM/fem_ele_std1.cpp b/FEM/fem_ele_std1.cpp index d5c818b4f..3f2c60754 100644 --- a/FEM/fem_ele_std1.cpp +++ b/FEM/fem_ele_std1.cpp @@ -86,7 +86,7 @@ void CFiniteElementStd::ComputeAdditionalJacobi_H2() getGradShapefunctValues(gp, 1); // Linear interpolation function // poro = MediaProp->Porosity(Index,pcs->m_num->ls_theta); - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, gp); PG = interpolate(NodalVal1); PG2 = interpolate(p2); Sw = MediaProp->SaturationCapillaryPressureFunction(PG); @@ -281,7 +281,7 @@ void CFiniteElementStd::ComputeAdditionalJacobi_Richards() getShapefunctValues(gp, 1); // Linear interpolation function getGradShapefunctValues(gp, 1); // Linear interpolation function - tensor = MediaProp->PermeabilityTensor(Index); + tensor = MediaProp->PermeabilityTensor(Index, gp); PG = -interpolate(NodalVal1); Sw = MediaProp->SaturationCapillaryPressureFunction(PG); S1 = diff --git a/FEM/rf_mmp_new.cpp b/FEM/rf_mmp_new.cpp index 814f05242..b7f18b434 100644 --- a/FEM/rf_mmp_new.cpp +++ b/FEM/rf_mmp_new.cpp @@ -45,6 +45,7 @@ extern double gravity_constant; //#include "msh_lib.h" #include "pcs_dm.h" //WX +#include "Material/PorousMedium/DamageZonePermeability.h" #include "PhysicalConstant.h" // MAT-MP data base lists @@ -72,7 +73,10 @@ using namespace Display; last modification: **************************************************************************/ CMediumProperties::CMediumProperties() - : geo_dimension(0), _mesh(NULL), _geo_type(GEOLIB::GEODOMAIN) + : geo_dimension(0), + _mesh(NULL), + _geo_type(GEOLIB::GEODOMAIN), + _damage_zone_permeability(NULL) { name = "DEFAULT"; mode = 0; @@ -162,6 +166,9 @@ CMediumProperties::~CMediumProperties(void) { if (c_coefficient) delete[] c_coefficient; // WW + + if (_damage_zone_permeability) + delete _damage_zone_permeability; geo_name_vector.clear(); } @@ -181,7 +188,8 @@ bool MMPRead(std::string base_file_name) //---------------------------------------------------------------------- // OK MMPDelete(); //---------------------------------------------------------------------- - ScreenMessage("MMPRead ... ");; + ScreenMessage("MMPRead ... "); + ; CMediumProperties* m_mat_mp = NULL; char line[MAX_ZEILE]; std::string sub_line; @@ -207,7 +215,7 @@ bool MMPRead(std::string base_file_name) if (line_string.find("#STOP") != string::npos) { ScreenMessage("done, read %d medium properties\n", - mmp_vector.size()); + mmp_vector.size()); return true; } @@ -474,19 +482,20 @@ std::ios::pos_type CMediumProperties::Read(std::ifstream* mmp_file) break; case 10: // Chemical swelling model (constrained swelling, // constant I) - { - int m; - in >> porosity_model_values[0]; // Initial porosity - in >> m; // m - if (m > 15) - std::cout << "Maximal number of solid phases is now " - "limited to be 15!!!" - << "\n"; - for (int i = 0; i < m + 1; i++) - // molar volume [l/mol] - in >> porosity_model_values[i + 1]; - break; - } + { + int m; + in >> porosity_model_values[0]; // Initial porosity + in >> m; // m + if (m > 15) + std::cout + << "Maximal number of solid phases is now " + "limited to be 15!!!" + << "\n"; + for (int i = 0; i < m + 1; i++) + // molar volume [l/mol] + in >> porosity_model_values[i + 1]; + break; + } case 11: // MB: read from file ToDo // in >> porosity_file; // CB in >> porosity_model_values[0]; // CB some dummy default @@ -936,7 +945,28 @@ std::ios::pos_type CMediumProperties::Read(std::ifstream* mmp_file) in.clear(); continue; } + if (line_string.find("$DAMAGE_ZONE_PERMEABILITY") != std::string::npos) + { + if ((mmp_vector.size() > msp_vector.size() - 1) || + msp_vector[mmp_vector.size()] + ->getMohrCoulombFailureCriterion() == NULL) + { + ScreenMessage( + "MOHR_COULOMB_FAILURE_CRITERION is not defined in msp " + "file " + "for $DAMAGE_ZONE_PERMEABILITY in mmp file. Stop now!"); + abort(); + } + in.str(GetLineFromFile1(mmp_file)); + double a, b; + in >> a >> b; + _damage_zone_permeability = + new PorousMediumProperty::DamageZonePermeability(a, b); + in.clear(); + ScreenMessage("DAMAGE_ZONE_PERMEABILITY is used.\n"); + continue; + } //------------------------------------------------------------------------ // 12. $PERMEABILITY_FUNCTION // (i) _DEFORMATION @@ -1008,9 +1038,10 @@ std::ios::pos_type CMediumProperties::Read(std::ifstream* mmp_file) [2]; // d_fac/d_volStrain // when vol. strain // > threshold - in >> permeability_strain_model_value - [3]; // curve numer for dependenc between - // threshold and plas strain + in >> permeability_strain_model_value[3]; // curve numer + // for dependenc + // between + // threshold and plas strain // if -1, threshold is constant in >> permeability_strain_model_value[4]; // lower limit in >> permeability_strain_model_value[5]; // uper limit @@ -1107,8 +1138,9 @@ std::ios::pos_type CMediumProperties::Read(std::ifstream* mmp_file) pcs_name_vector.push_back("TEMPERATURE1"); break; case 10: // WX:05.2010 directly from curve - in >> permeability_pressure_model_values - [0]; // WX: curve number 05.2010 + in >> permeability_pressure_model_values[0]; // WX: curve + // number + // 05.2010 break; default: std::cout << "Error in MMPRead: no valid permeability model" @@ -1544,9 +1576,8 @@ std::ios::pos_type CMediumProperties::Read(std::ifstream* mmp_file) // initial values in >> permeability_porosity_model_values[0]; // initial // porosity - in >> - permeability_porosity_model_values[1]; // initial - // permeability + in >> permeability_porosity_model_values[1]; // initial + // permeability KC_permeability_initial = permeability_porosity_model_values[1]; KC_porosity_initial = permeability_porosity_model_values[0]; @@ -1561,9 +1592,8 @@ std::ios::pos_type CMediumProperties::Read(std::ifstream* mmp_file) // initial values in >> permeability_porosity_model_values[0]; // initial // porosity - in >> - permeability_porosity_model_values[1]; // initial - // permeab ility + in >> permeability_porosity_model_values[1]; // initial + // permeab ility KC_permeability_initial = permeability_porosity_model_values[1]; KC_porosity_initial = permeability_porosity_model_values[0]; @@ -1684,7 +1714,7 @@ std::ios::pos_type CMediumProperties::Read(std::ifstream* mmp_file) in >> capillary_pressure_values[2]; if (capillary_pressure_values[2] >= 0.0) { // Then a constant saturation value has been entered. - // This is model #2. + // This is model #2. ScreenMessage( "WARNING in MMPRead. Capillary pressure model 1 " "used for a constant saturation. THIS IS " @@ -1709,10 +1739,10 @@ std::ios::pos_type CMediumProperties::Read(std::ifstream* mmp_file) // [alpha_switch>0]) in >> capillary_pressure_values[1]; // Slr in >> capillary_pressure_values[2]; // Slmax - in >> capillary_pressure_values - [3]; // exponent (always <= 1.0) --> (typical is - // 0.5) i.e. n = 1 / (1 - // - exponent) == 2.0 + in >> capillary_pressure_values[3]; // exponent (always <= + // 1.0) --> (typical is + // 0.5) i.e. n = 1 / (1 + // - exponent) == 2.0 in >> capillary_pressure_values[4]; // maximum Pc in >> i; // alpha_switch (default = 0) if (i > 0) @@ -2591,7 +2621,7 @@ double CMediumProperties::PermeabilitySaturationFunction( slr = 1.0 - maximum_saturation[phase]; // slr = 1.0 - sgm slm = 1.0 - residual_saturation[phase]; // slm = 1.0 - sgr m = saturation_exponent[phase]; // always <= 1.0. Input is - // exponent = 1 / (1-lambda) + // exponent = 1 / (1-lambda) sl = MRange(slr, sl, slm); se = (sl - slr) / (slm - slr); // @@ -3026,7 +3056,8 @@ double* CMediumProperties::HeatDispersionTensorNew(int ip) if (abs(vg) > MKleinsteZahl // For the case of diffusive transport only // WW - && (alpha_l > MKleinsteZahl || alpha_t > MKleinsteZahl)) + && + (alpha_l > MKleinsteZahl || alpha_t > MKleinsteZahl)) { switch (Dim) { @@ -4334,8 +4365,9 @@ double CMediumProperties::Porosity(CElement* assem) FiniteElement::GROUNDWATER_FLOW) || (pcs_temp->getProcessType() == FiniteElement::RICHARDS_FLOW) // TF - || (pcs_temp->getProcessType() == - FiniteElement::MULTI_PHASE_FLOW)) + || + (pcs_temp->getProcessType() == + FiniteElement::MULTI_PHASE_FLOW)) { int idx = pcs_temp->GetElementValueIndex("POROSITY"); porosity = pcs_temp->GetElementValue(number, idx); @@ -4512,7 +4544,7 @@ CMediumProperties::PorosityEffectiveConstrainedSwellingConstantIonicStrength( last modification: 10/2010 TF changed access to process type **************************************************************************/ -double* CMediumProperties::PermeabilityTensor(long index) +double* CMediumProperties::PermeabilityTensor(const long index, const int gp) { static double tensor[9]; int perm_index = 0; @@ -4543,7 +4575,7 @@ double* CMediumProperties::PermeabilityTensor(long index) tensor[0] = permeability_tensor[0]; if (permeability_model == 2) { // here get the initial permeability values from material perperty - // class; + // class; // get the // index:------------------------------------------------------------------- for (perm_index = 0; @@ -4909,6 +4941,22 @@ double* CMediumProperties::PermeabilityTensor(long index) } break; } + + if (_damage_zone_permeability == NULL) + return tensor; + + FiniteElement::ElementValue_DM* element_data_DM = ele_value_dm[index]; + static double s[6]; + Math_Group::Matrix const& element_stresses = (*element_data_DM->Stress); + const int ns = static_cast(element_stresses.Rows()); + for (int i = 0; i < ns; i++) + s[i] = element_stresses(i, gp); + + const int dim = Fem_Ele_Std->Dim(); + _damage_zone_permeability->computeDamageZonePermeability( + tensor, *(Fem_Ele_Std->SolidProp->getMohrCoulombFailureCriterion()), s, + dim); + return tensor; } @@ -5003,20 +5051,21 @@ double CMediumProperties::PermeabilityFunctionStrain( } case 3: // if StrainP>0, factor=f(StrainP), else // factor=f(strain_Volume) - { - if (strainp > 0) - fac_perm_strain = GetCurveValue( - permeability_strain_model_value[1], 0, strainp, &gueltig); - else { - fac_perm_strain = - GetCurveValue(permeability_strain_model_value[0], 0, - vol_strain_temp, &gueltig); + if (strainp > 0) + fac_perm_strain = + GetCurveValue(permeability_strain_model_value[1], 0, + strainp, &gueltig); + else + { + fac_perm_strain = + GetCurveValue(permeability_strain_model_value[0], 0, + vol_strain_temp, &gueltig); + } + if (fac_perm_strain <= 0.) + fac_perm_strain = 1.; + break; } - if (fac_perm_strain <= 0.) - fac_perm_strain = 1.; - break; - } case 4: // factor = f(strainP+strain_Volume) { double tmpfkt = 1.; @@ -5044,11 +5093,13 @@ double CMediumProperties::PermeabilityFunctionStrain( threshold = GetCurveValue(permeability_strain_model_value[3], 0, vol_strain_temp, &gueltig); if (vol_strain_temp <= threshold) - fac_perm_strain = 1 - permeability_strain_model_value[1] * - (threshold - vol_strain_temp); + fac_perm_strain = 1 - + permeability_strain_model_value[1] * + (threshold - vol_strain_temp); else - fac_perm_strain = 1 + permeability_strain_model_value[2] * - (vol_strain_temp - threshold); + fac_perm_strain = 1 + + permeability_strain_model_value[2] * + (vol_strain_temp - threshold); fac_perm_strain = MRange(permeability_strain_model_value[4], fac_perm_strain, permeability_strain_model_value[5]); diff --git a/FEM/rf_mmp_new.h b/FEM/rf_mmp_new.h index 2201745e4..ceb05e92a 100644 --- a/FEM/rf_mmp_new.h +++ b/FEM/rf_mmp_new.h @@ -32,63 +32,20 @@ // PCSLib #include "rf_pcs.h" +#include "Material/PorousMedium/DamageZonePermeability.h" namespace FiniteElement { class CFiniteElementStd; } -using FiniteElement::CFiniteElementStd; -class CMediumProperties -{ -public: - CFiniteElementStd* Fem_Ele_Std; -private: - // WW - friend class FiniteElement::CFiniteElementStd; - // Data base - void SetMediumPropertiesDefaultsClay(void); // CMCD 9/2004 GeoSys 4 - void SetMediumPropertiesDefaultsSilt(void); // CMCD 9/2004 GeoSys 4 - void SetMediumPropertiesDefaultsSand(void); // CMCD 9/2004 GeoSys 4 - // CMCD 9/2004 GeoSys 4 - void SetMediumPropertiesDefaultsGravel(void); - // CMCD 9/2004 GeoSys 4 - void SetMediumPropertiesDefaultsCrystalline(void); - // CMCD 9/2004 GeoSys 4 - void SetMediumPropertiesDefaultsBordenAquifer(void); - // Porosity - // CMCD 9/2004 GeoSys 4 - double PorosityEffectiveStress(long, double); - double PorosityVolumetricFreeSwellingConstantIonicstrength(long, - double, - double); - // MX 1/2005 - double PorosityEffectiveConstrainedSwelling(long, double, double, double*); - // MX 1/2005 - double PorosityVolumetricFreeSwelling(long, double, double); - // MX 1/2005 - double PorosityEffectiveConstrainedSwellingConstantIonicStrength(long, - double, - double, - double*); - // Permeability - // Permeabilty stress corrector WW - double* c_coefficient; - unsigned geo_dimension; - unsigned geo_inclination; // inclination of domain/sub domain from - // horizontal anticloclwise: AKS - int permeability_stress_mode; - // - // CMCD 9/2004 GeoSys 4 - double PermeabilityPressureFunctionMethod1(long, double); - // CMCD 9/2004 GeoSys 4 - double PermeabilityPressureFunctionMethod2(long, double); - // CMCD 9/2004 GeoSys 4 - double PermeabilityPressureFunctionMethod3(long, double); - // CMCD 9/2004 GeoSys 4 - double PermeabilityPressureFunctionMethod4(long, double, double); - friend class CMediumPropertiesGroup; +namespace PorousMediumProperty +{ +class DamageZonePermeability; +} +class CMediumProperties +{ public: //------------------------------------------- // Methods @@ -103,7 +60,9 @@ class CMediumProperties std::ios::pos_type Read(std::ifstream*); void Write(std::fstream*); void WriteTecplot(std::string); - double* PermeabilityTensor(long index); + + double* PermeabilityTensor(const long index, const int gp = 0); + // CMCD 9/2004 GeoSys 4 double Porosity(FiniteElement::CElement* assem = NULL); // CMCD 9/2004 GeoSys 4 @@ -196,25 +155,12 @@ class CMediumProperties GEOLIB::GEOTYPE getGeoType() const { return _geo_type; } CFEMesh* getMesh(void) { return _mesh; } // Properties -private: - // PCS - std::string pcs_type_name; // YD -public: - CRFProcess* m_pcs; // OK - std::vector pcs_name_vector; -private: - std::vector porosity_pcs_name_vector; - CFEMesh* _mesh; // OK + FiniteElement::CFiniteElementStd* Fem_Ele_Std; - /** - * attribute describes the type of the geometric entity the - * material property is assigned to - */ - GEOLIB::GEOTYPE _geo_type; - FiniteElement::FrictionPhase _fric_phase; + CRFProcess* m_pcs; // OK + std::vector pcs_name_vector; -public: // GEO std::string geo_name; std::vector geo_name_vector; // OK @@ -352,6 +298,67 @@ class CMediumProperties double graindiameter; double hydraulicrad; double betaexpo; + +private: + // WW + friend class FiniteElement::CFiniteElementStd; + // Data base + void SetMediumPropertiesDefaultsClay(void); // CMCD 9/2004 GeoSys 4 + void SetMediumPropertiesDefaultsSilt(void); // CMCD 9/2004 GeoSys 4 + void SetMediumPropertiesDefaultsSand(void); // CMCD 9/2004 GeoSys 4 + // CMCD 9/2004 GeoSys 4 + void SetMediumPropertiesDefaultsGravel(void); + // CMCD 9/2004 GeoSys 4 + void SetMediumPropertiesDefaultsCrystalline(void); + // CMCD 9/2004 GeoSys 4 + void SetMediumPropertiesDefaultsBordenAquifer(void); + // Porosity + // CMCD 9/2004 GeoSys 4 + double PorosityEffectiveStress(long, double); + double PorosityVolumetricFreeSwellingConstantIonicstrength(long, + double, + double); + // MX 1/2005 + double PorosityEffectiveConstrainedSwelling(long, double, double, double*); + // MX 1/2005 + double PorosityVolumetricFreeSwelling(long, double, double); + // MX 1/2005 + double PorosityEffectiveConstrainedSwellingConstantIonicStrength(long, + double, + double, + double*); + // Permeability + // Permeabilty stress corrector WW + double* c_coefficient; + unsigned geo_dimension; + unsigned geo_inclination; // inclination of domain/sub domain from + // horizontal anticloclwise: AKS + int permeability_stress_mode; + // + // CMCD 9/2004 GeoSys 4 + double PermeabilityPressureFunctionMethod1(long, double); + // CMCD 9/2004 GeoSys 4 + double PermeabilityPressureFunctionMethod2(long, double); + // CMCD 9/2004 GeoSys 4 + double PermeabilityPressureFunctionMethod3(long, double); + // CMCD 9/2004 GeoSys 4 + double PermeabilityPressureFunctionMethod4(long, double, double); + friend class CMediumPropertiesGroup; + + // PCS + std::string pcs_type_name; // YD + + std::vector porosity_pcs_name_vector; + CFEMesh* _mesh; // OK + + /** + * attribute describes the type of the geometric entity the + * material property is assigned to + */ + GEOLIB::GEOTYPE _geo_type; + FiniteElement::FrictionPhase _fric_phase; + + PorousMediumProperty::DamageZonePermeability* _damage_zone_permeability; }; class CMediumPropertiesGroup // YD diff --git a/FEM/rf_msp_new.cpp b/FEM/rf_msp_new.cpp index 260936851..2473a1844 100644 --- a/FEM/rf_msp_new.cpp +++ b/FEM/rf_msp_new.cpp @@ -45,6 +45,7 @@ #include "PhysicalConstant.h" #include "Material/Solid/BGRaCreep.h" +#include "Material/Solid/MohrCoulombFailureCriterion.h" #include "minkley.h" #include "burgers.h" @@ -1038,6 +1039,17 @@ std::ios::pos_type CSolidProperties::Read(std::ifstream* msp_file) // TransMicroStru_TInv->Write(); // TransMicroStru->Write(); } + + if (line_string.find("$MOHR_COULOMB_FAILURE_CRITERION") != string::npos) + { + in_sd.str(GetLineFromFile1(msp_file)); + double c, angle; + in_sd >> c >> angle; + _mohrCoulomb_failure_criterion = + new MohrCoulombFailureCriterion(c, angle); + in_sd.clear(); + } + in_sd.clear(); } return position; @@ -1114,7 +1126,7 @@ CSolidProperties::CSolidProperties() data_Conductivity(NULL), data_Plasticity(NULL), data_Creep(NULL), - _bgra_creep(NULL) + _bgra_creep(NULL), _mohrCoulomb_failure_criterion(NULL) { PoissonRatio = 0.2; ThermalExpansion = 0.0; @@ -1353,6 +1365,8 @@ CSolidProperties::~CSolidProperties() if(_bgra_creep) delete _bgra_creep; + if(_mohrCoulomb_failure_criterion) + delete _mohrCoulomb_failure_criterion; } //---------------------------------------------------------------------------- diff --git a/FEM/rf_msp_new.h b/FEM/rf_msp_new.h index a0c6a1b95..10ba59ee4 100644 --- a/FEM/rf_msp_new.h +++ b/FEM/rf_msp_new.h @@ -63,6 +63,7 @@ class Invariants; namespace SolidProp { class BGRaCreep; +class MohrCoulombFailureCriterion; typedef Eigen::Matrix KVec; class CSolidProperties @@ -192,6 +193,10 @@ class CSolidProperties double getYoungsModulus(const double refence = 0.0) const; double getBulkModulus() const; double getBiotsConstant() const { return biot_const; } + MohrCoulombFailureCriterion* getMohrCoulombFailureCriterion() const + { + return _mohrCoulomb_failure_criterion; + } private: // CMCD @@ -475,6 +480,7 @@ class CSolidProperties FiniteElement::SolidReactiveSystem _reactive_system; BGRaCreep* _bgra_creep; + MohrCoulombFailureCriterion* _mohrCoulomb_failure_criterion; // Friends that can access to this data explicitly friend bool ::MSPRead(const std::string& given_file_base_name);