Skip to content

Commit

Permalink
Geo/convergence criteria (#12950)
Browse files Browse the repository at this point in the history
Streamlining and clearer writing for convergence criteria in python layer of GeoMechanics application
  • Loading branch information
WPK4FEM authored Dec 19, 2024
1 parent cab78c8 commit 333dd4b
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

# Import applications
import KratosMultiphysics.GeoMechanicsApplication as KratosGeo
import KratosMultiphysics.StructuralMechanicsApplication as KratosStructure

# Import base class file
from KratosMultiphysics.GeoMechanicsApplication.geomechanics_solver import GeoMechanicalSolver as GeoSolver
Expand All @@ -12,7 +11,7 @@ def CreateSolver(model, custom_settings):
return PwSolver(model, custom_settings)

class PwSolver(GeoSolver):
'''Solver for the solution of displacement-pore pressure coupled problems.'''
'''Solver for the solution of pore pressure problems.'''

def __init__(self, model, custom_settings):
super().__init__(model, custom_settings)
Expand Down Expand Up @@ -100,7 +99,7 @@ def PrepareModelPart(self):
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver", "Model reading finished.")

def AddDofs(self):
## Fluid dofs
## Fluid D.o.F.
KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.WATER_PRESSURE, KratosMultiphysics.REACTION_WATER_PRESSURE,self.main_model_part)
KratosMultiphysics.VariableUtils().AddDof(KratosGeo.DT_WATER_PRESSURE, self.main_model_part)

Expand All @@ -118,66 +117,40 @@ def Initialize(self):

KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver", "Solver initialization finished.")

#### Specific internal functions ####


def _ConstructScheme(self, scheme_type, solution_type):

self.main_model_part.ProcessInfo.SetValue(KratosGeo.VELOCITY_COEFFICIENT, 1.0)
self.main_model_part.ProcessInfo.SetValue(KratosGeo.DT_PRESSURE_COEFFICIENT, 1.0)

if (scheme_type.lower() == "newmark" or scheme_type.lower() == "newmark_flow"):
theta = self.settings["newmark_theta"].GetDouble()
rayleigh_m = self.settings["rayleigh_m"].GetDouble()
rayleigh_k = self.settings["rayleigh_k"].GetDouble()
self.main_model_part.ProcessInfo.SetValue(KratosStructure.RAYLEIGH_ALPHA, rayleigh_m)
self.main_model_part.ProcessInfo.SetValue(KratosStructure.RAYLEIGH_BETA, rayleigh_k)
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver, solution_type", solution_type)
if (solution_type.lower() == "transient-groundwater-flow" or solution_type.lower() == "transient_groundwater_flow"):
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver, scheme", "Newmark Transient groundwater flow.")
scheme = KratosGeo.NewmarkQuasistaticPwScheme(theta)
elif (solution_type.lower() == "steady-state-groundwater-flow" or solution_type.lower() == "steady_state_groundwater_flow"):
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver, scheme", "Newmark Steady-state groundwater flow.")
scheme = KratosGeo.NewmarkQuasistaticPwScheme(theta)

else:
raise Exception("Undefined solution type", solution_type)
elif (scheme_type.lower() == "backward_euler"):
if (solution_type.lower() == "transient-groundwater-flow" or solution_type.lower() == "transient_groundwater_flow"):
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver, scheme", "Backward Euler Transient groundwater flow.")
scheme = KratosGeo.BackwardEulerQuasistaticPwScheme()
elif (solution_type.lower() == "steady-state-groundwater-flow" or solution_type.lower() == "steady_state_groundwater_flow"):
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver, scheme", "Backward Euler Steady-state groundwater flow.")
scheme = KratosGeo.BackwardEulerQuasistaticPwScheme()
else:
raise Exception("Apart from Newmark, other scheme_type are not available.")

return scheme
if not(solution_type.lower() == "transient-groundwater-flow" or solution_type.lower() == "transient_groundwater_flow" or
solution_type.lower() == "steady-state-groundwater-flow" or solution_type.lower() == "steady_state_groundwater_flow" ):
err_msg = "Undefined solution type:" + solution_type + " , only Transient groundwater flow and Steady state groundwater flow are available."
raise RuntimeError(err_msg)
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver, solution_type", solution_type)

if scheme_type.lower() == "newmark":
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver, scheme", "Newmark.")
return KratosGeo.NewmarkQuasistaticPwScheme(self.settings["newmark_theta"].GetDouble())

if scheme_type.lower() == "backward_euler":
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_Pw_Solver, scheme", "Backward Euler.")
return KratosGeo.BackwardEulerQuasistaticPwScheme()

raise RuntimeError("Apart from Newmark and Backward Euler, other scheme_type are not available.")

def _ConstructConvergenceCriterion(self, convergence_criterion):
if convergence_criterion.lower() == "water_pressure_criterion":
return self._MakeWaterPressureCriterion()

if convergence_criterion.lower() == "residual_criterion":
return self._MakeResidualCriterion()

if convergence_criterion.lower() == "and_criterion":
return KratosMultiphysics.AndCriteria(self._MakeResidualCriterion(), self._MakeWaterPressureCriterion())

if convergence_criterion.lower() == "or_criterion":
return KratosMultiphysics.OrCriteria(self._MakeResidualCriterion(), self._MakeWaterPressureCriterion())

D_RT = self.settings["water_pressure_relative_tolerance"].GetDouble()
D_AT = self.settings["water_pressure_absolute_tolerance"].GetDouble()
echo_level = self.settings["echo_level"].GetInt()

if (convergence_criterion.lower() == "water_pressure_criterion"):
convergence_criterion = KratosMultiphysics.MixedGenericCriteria([(KratosMultiphysics.WATER_PRESSURE, D_RT, D_AT)])
convergence_criterion.SetEchoLevel(echo_level)
elif (convergence_criterion.lower() == "residual_criterion"):
convergence_criterion = self._MakeResidualCriterion()
elif (convergence_criterion.lower() == "and_criterion"):
WaterPressure = KratosMultiphysics.MixedGenericCriteria([(KratosMultiphysics.WATER_PRESSURE, D_RT, D_AT)])
WaterPressure.SetEchoLevel(echo_level)
residual = self._MakeResidualCriterion()
convergence_criterion = KratosMultiphysics.AndCriteria(residual, WaterPressure)
elif (convergence_criterion.lower() == "or_criterion"):
WaterPressure = KratosMultiphysics.MixedGenericCriteria([(KratosMultiphysics.WATER_PRESSURE, D_RT, D_AT)])
WaterPressure.SetEchoLevel(echo_level)
residual = self._MakeResidualCriterion()
convergence_criterion = KratosMultiphysics.OrCriteria(residual, WaterPressure)
else:
err_msg = "The requested convergence criterion \"" + convergence_criterion + "\" is not available!\n"
err_msg += "Available options are: \"water_pressure_criterion\", \"residual_criterion\", \"and_criterion\", \"or_criterion\""
raise Exception(err_msg)

return convergence_criterion
err_msg = "The requested convergence criterion \"" + convergence_criterion + "\" is not available!\n"
err_msg += "Available options are: \"water_pressure_criterion\", \"residual_criterion\", \"and_criterion\", \"or_criterion\""
raise RuntimeError(err_msg)
Original file line number Diff line number Diff line change
Expand Up @@ -107,47 +107,42 @@ def _ConstructScheme(self, scheme_type, solution_type):
self.main_model_part.ProcessInfo.SetValue(KratosGeo.DT_TEMPERATURE_COEFFICIENT, 1.0)

KratosMultiphysics.Logger.PrintInfo("GeoMechanics_T_Solver, solution_type", solution_type)
if solution_type.lower() == "transient_heat_transfer":
if scheme_type.lower() == "newmark" or scheme_type.lower() == "newmark_flow":
theta = self.settings["newmark_theta"].GetDouble()
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_T_Solver, scheme", "Newmark Transient heat transfer.")
scheme = KratosGeo.GeneralizedNewmarkTScheme(theta)
elif scheme_type.lower() == "backward_euler":
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_T_Solver, scheme", "Backward Euler Transient heat transfer.")
scheme = KratosGeo.BackwardEulerTScheme()
else:
raise RuntimeError("Apart from Newmark and Backward Euler, no other scheme_type is available for thermal calculations.")

else:
raise RuntimeError("Undefined solution type", solution_type)
if solution_type.lower() != "transient_heat_transfer":
err_msg = "Undefined solution type\"" + solution_type + "\" , only Transient heat transfer is available."
raise RuntimeError(err_msg)

return scheme
if scheme_type.lower() == "newmark":
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_T_Solver, scheme", "Newmark Transient heat transfer.")
return KratosGeo.GeneralizedNewmarkTScheme(self.settings["newmark_theta"].GetDouble())

if scheme_type.lower() == "backward_euler":
KratosMultiphysics.Logger.PrintInfo("GeoMechanics_T_Solver, scheme", "Backward Euler Transient heat transfer.")
return KratosGeo.BackwardEulerTScheme()

raise RuntimeError("Apart from Newmark and Backward Euler, no other scheme_type is available for thermal calculations.")

def _ConstructConvergenceCriterion(self, convergence_criterion):
if convergence_criterion.lower() == "temperature_criterion":
return self._MakeTemperatureCriterion()
elif convergence_criterion.lower() == "residual_criterion":

if convergence_criterion.lower() == "residual_criterion":
return self._MakeResidualCriterion()
elif convergence_criterion.lower() == "and_criterion":
temperature = self._MakeTemperatureCriterion()
residual = self._MakeResidualCriterion()
return KratosMultiphysics.AndCriteria(residual, temperature)
elif convergence_criterion.lower() == "or_criterion":
temperature = self._MakeTemperatureCriterion()
residual = self._MakeResidualCriterion()
return KratosMultiphysics.OrCriteria(residual, temperature)
else:
err_msg = "The requested convergence criterion \"" + convergence_criterion + "\" is not available!\n"
err_msg += "Available options are: \"temperature_criterion\", \"residual_criterion\", \"and_criterion\", \"or_criterion\""
raise RuntimeError(err_msg)

if convergence_criterion.lower() == "and_criterion":
return KratosMultiphysics.AndCriteria(self._MakeResidualCriterion(), self._MakeTemperatureCriterion())

if convergence_criterion.lower() == "or_criterion":
return KratosMultiphysics.OrCriteria(self._MakeResidualCriterion(), self._MakeTemperatureCriterion())

err_msg = "The requested convergence criterion \"" + convergence_criterion + "\" is not available!\n"
err_msg += "Available options are: \"temperature_criterion\", \"residual_criterion\", \"and_criterion\", \"or_criterion\""
raise RuntimeError(err_msg)

def _MakeTemperatureCriterion(self):
relative_tolerance = self.settings["temperature_relative_tolerance"].GetDouble()
absolute_tolerance = self.settings["temperature_absolute_tolerance"].GetDouble()

temperature = KratosMultiphysics.MixedGenericCriteria([(KratosMultiphysics.TEMPERATURE, relative_tolerance, absolute_tolerance)])
temperature.SetEchoLevel(self.settings["echo_level"].GetInt())
temperature_criterion = KratosMultiphysics.MixedGenericCriteria([(KratosMultiphysics.TEMPERATURE, relative_tolerance, absolute_tolerance)])
temperature_criterion.SetEchoLevel(self.settings["echo_level"].GetInt())

return temperature
return temperature_criterion
Loading

0 comments on commit 333dd4b

Please sign in to comment.