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

[ConvDiff] Upgrade CHT solver #12920

Merged
merged 3 commits into from
Dec 13, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sys
import copy

# Importing the Kratos Library
import KratosMultiphysics
Expand All @@ -12,6 +13,9 @@
# Importing the base class
from KratosMultiphysics.python_solver import PythonSolver

# Importing Kratos utilities
from KratosMultiphysics.kratos_utilities import IssueDeprecationWarning

def CreateSolver(main_model_part, custom_settings):
return ConjugateHeatTransferSolver(main_model_part, custom_settings)

Expand Down Expand Up @@ -150,42 +154,34 @@ def AddVariables(self):
self.solid_thermal_solver.main_model_part.AddNodalSolutionStepVariable(KratosConvDiff.AUX_TEMPERATURE)
self.solid_thermal_solver.main_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.SCALAR_INTERFACE_RESIDUAL)

def ImportModelPart(self):
# Check that both thermal solvers have a different model part name. If
# both model part names coincide the solver will fail to acces them. This
# is the case if the default one in the convection diffusion is taken.
fluid_thermal_model_part_name = self.settings["fluid_domain_solver_settings"]["thermal_solver_settings"]["model_part_name"].GetString()
solid_thermal_model_part_name = self.settings["solid_domain_solver_settings"]["thermal_solver_settings"]["model_part_name"].GetString()
if fluid_thermal_model_part_name == solid_thermal_model_part_name:
err_msg = "\nFluid thermal solver settings model_part_name and solid thermal solver settings model_part_name can not coincide.\n"
err_msg += "- fluid model_part_name: " + fluid_thermal_model_part_name + "\n"
err_msg += "- solid model_part_name: " + solid_thermal_model_part_name + "\n"
err_msg += "Provide different model_part_names in the JSON settings file."
raise Exception(err_msg)
# In order to consider the buoyancy effects, the nodes in the fluid model part must
# be shared with the nodes in the fluid thermal model part. To do that, we use the modeler
# Save the convection diffusion settings
self.fluid_convection_diffusion_settings_aux_copy = self.fluid_thermal_solver.main_model_part.ProcessInfo.GetValue(KratosMultiphysics.CONVECTION_DIFFUSION_SETTINGS)

def ImportModelPart(self):
# Import the fluid domain in the fluid dynamics solver
self.fluid_solver.ImportModelPart()

# In order to consider the buoyancy effects, the nodes in the fluid model part must
# be shared with the nodes in the fluid thermal model part. To do that, we use the modeler
# Save the convection diffusion settings
convection_diffusion_settings = self.fluid_thermal_solver.main_model_part.ProcessInfo.GetValue(KratosMultiphysics.CONVECTION_DIFFUSION_SETTINGS)

# Here the fluid model part is cloned to be thermal model part so that the nodes are shared
modeler = KratosMultiphysics.ConnectivityPreserveModeler()
if(self.domain_size == 2):
modeler.GenerateModelPart(self.fluid_solver.main_model_part,
self.fluid_thermal_solver.main_model_part,
"Element2D3N",
"LineCondition2D2N")
else:
modeler.GenerateModelPart(self.fluid_solver.main_model_part,
self.fluid_thermal_solver.main_model_part,
"Element3D4N",
"SurfaceCondition3D3N")
#TODO: Remove this after the deprecation period
# Keep this for a while for retrocompatibility (ConnectivityPreserveModeler must be called at the stage modelers section)
if not self.settings["fluid_domain_solver_settings"]["fluid_solver_settings"]["model_import_settings"]["input_type"].GetString() == "use_input_model_part":
IssueDeprecationWarning("ConjugateHeatTransferSolver", "Using the old I/O at the solver level. Please use the geometry-based one with modelers.")
modeler = KratosMultiphysics.ConnectivityPreserveModeler()
if(self.domain_size == 2):
modeler.GenerateModelPart(self.fluid_solver.main_model_part,
self.fluid_thermal_solver.main_model_part,
"Element2D3N",
"LineCondition2D2N")
else:
modeler.GenerateModelPart(self.fluid_solver.main_model_part,
self.fluid_thermal_solver.main_model_part,
"Element3D4N",
"SurfaceCondition3D3N")

# Set the saved convection diffusion settings to the new thermal model part
self.fluid_thermal_solver.main_model_part.ProcessInfo.SetValue(KratosMultiphysics.CONVECTION_DIFFUSION_SETTINGS, convection_diffusion_settings)
self.fluid_thermal_solver.main_model_part.ProcessInfo.SetValue(KratosMultiphysics.CONVECTION_DIFFUSION_SETTINGS, self.fluid_convection_diffusion_settings_aux_copy)
self.fluid_convection_diffusion_settings_aux_copy = None

# Confirm that the buffer size in the shared nodes is the maximum required one
fluid_solver_buffer = self.fluid_solver.GetMinimumBufferSize()
Expand Down Expand Up @@ -249,6 +245,18 @@ def Clear(self):
(self.solid_thermal_solver).Clear()

def Check(self):
# Check that both thermal solvers have a different model part name. If
# both model part names coincide the solver will fail to acces them. This
# is the case if the default one in the convection diffusion is taken.
fluid_thermal_model_part_name = self.settings["fluid_domain_solver_settings"]["thermal_solver_settings"]["model_part_name"].GetString()
solid_thermal_model_part_name = self.settings["solid_domain_solver_settings"]["thermal_solver_settings"]["model_part_name"].GetString()
if fluid_thermal_model_part_name == solid_thermal_model_part_name:
err_msg = "\nFluid thermal solver settings model_part_name and solid thermal solver settings model_part_name can not coincide.\n"
err_msg += "- fluid model_part_name: " + fluid_thermal_model_part_name + "\n"
err_msg += "- solid model_part_name: " + solid_thermal_model_part_name + "\n"
err_msg += "Provide different model_part_names in the JSON settings file."
raise Exception(err_msg)

(self.fluid_solver).Check()
(self.fluid_thermal_solver).Check()
(self.solid_thermal_solver).Check()
Expand Down Expand Up @@ -297,7 +305,7 @@ def SolveSolutionStep(self):
redistribution_max_iterations = self.settings["coupling_settings"]["variable_redistribution_settings"]["max_iterations"].GetInt()

# Solve the buoyancy solver
self.fluid_solver.SolveSolutionStep()
fluid_is_converged = self.fluid_solver.SolveSolutionStep()

# Interface temperature prediction
self._temperature_coupling_prediction()
Expand All @@ -307,6 +315,7 @@ def SolveSolutionStep(self):

# Couple the solid and fluid thermal problems
iteration = 0
coupling_is_converged = False
KratosMultiphysics.Logger.PrintInfo("::[ConjugateHeatTransferSolver]::", "Starting non-linear temperature coupling")
while iteration < max_iteration:
# Initialize non-linear iteration
Expand All @@ -322,6 +331,7 @@ def SolveSolutionStep(self):
# Map reactions to the solid interface. Note that we first call the redistribution utility to convert the point values to distributed ones
KratosMultiphysics.VariableRedistributionUtility.DistributePointValues(
self._get_dirichlet_coupling_interface(),
self._get_dirichlet_coupling_interface().Conditions,
KratosMultiphysics.REACTION_FLUX,
KratosConvDiff.AUX_FLUX,
redistribution_tolerance,
Expand Down Expand Up @@ -365,11 +375,14 @@ def SolveSolutionStep(self):

# Check convergence
if rel_res_norm <= temp_rel_tol:
coupling_is_converged = True
KratosMultiphysics.Logger.PrintInfo("::[ConjugateHeatTransferSolver]::", "Converged in " + str(iteration) + " iterations.")
break
elif iteration == max_iteration:
KratosMultiphysics.Logger.PrintInfo("::[ConjugateHeatTransferSolver]::", "Did not converge in " + str(iteration) + " iterations.")

return fluid_is_converged and coupling_is_converged

def FinalizeSolutionStep(self):
if self._time_buffer_is_initialized():
self.fluid_solver.FinalizeSolutionStep()
Expand All @@ -382,6 +395,7 @@ def _set_up_dirichlet_coupling_boundary(self):
for node in self._get_dirichlet_coupling_interface().Nodes:
node.Fix(KratosMultiphysics.TEMPERATURE)

#TODO: Use MappingApplication in here
def _set_up_mappers(self):
# Set mappers settings
mappers_settings = self.settings["coupling_settings"]["mappers_settings"]
Expand Down
Loading