Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into optapp/windows_comp…
Browse files Browse the repository at this point in the history
…ilation
  • Loading branch information
sunethwarna committed Aug 4, 2023
2 parents 847c6ee + 2a7e8f2 commit 90aa5e3
Show file tree
Hide file tree
Showing 11 changed files with 825 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "custom_utilities/linear_to_quadratic_tetrahedra_mesh_converter_utility.h"
#include "custom_utilities/local_refine_tetrahedra_mesh_parallel_to_boundaries.hpp"
#include "custom_utilities/local_refine_tetrahedra_mesh_only_on_boundaries.hpp"
#include "custom_utilities/gradual_variable_interpolation_utility.h"

#ifdef USE_TETGEN_NONFREE_TPL
#include "custom_utilities/tetgen_volume_mesher.h"
Expand Down Expand Up @@ -139,6 +140,11 @@ void AddCustomUtilitiesToPython(pybind11::module& m)
.def("LocalRefineMesh", &LocalRefineTetrahedraMeshOnlyOnBoundaries::LocalRefineMesh)
;

py::class_<GradualVariableInterpolationUtility, std::shared_ptr<GradualVariableInterpolationUtility>>(m, "GradualVariableInterpolationUtility")
.def("InitializeInterpolationAndConstraints", &GradualVariableInterpolationUtility::InitializeInterpolationAndConstraints)
.def("UpdateSolutionStepVariables", &GradualVariableInterpolationUtility::UpdateSolutionStepVariables)
;

#ifdef USE_TETGEN_NONFREE_TPL
py::class_<TetgenVolumeMesher >
(m,"TetgenVolumeMesher")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// KRATOS __ __ _____ ____ _ _ ___ _ _ ____
// | \/ | ____/ ___|| | | |_ _| \ | |/ ___|
// | |\/| | _| \___ \| |_| || || \| | | _
// | | | | |___ ___) | _ || || |\ | |_| |
// |_| |_|_____|____/|_| |_|___|_| \_|\____| APPLICATION
//
// License: BSD License
// license: MeshingApplication/license.txt
//
// Main authors: Sebastian Ares de Parga Regalado

// System includes
#include <string>
#include <iostream>
#include <algorithm>

// External includes

// Project includes
#include "custom_utilities/gradual_variable_interpolation_utility.h"
#include "includes/kratos_components.h"

namespace Kratos {

void GradualVariableInterpolationUtility::InitializeInterpolationAndConstraints(
ModelPart& rOriginModelPart,
ModelPart& rDestinationModelPart,
std::vector<std::string>& rInterpolationVariablesList,
double AlphaRampUpIncrement,
int DomainSize,
bool ConstrainVariables)
{
{
// Set variables field to origin model part
for(auto& r_variable_name : rInterpolationVariablesList){
auto& r_variable = KratosComponents<Variable<double>>::Get(r_variable_name);
for(auto& rNode: rOriginModelPart.Nodes()) {
const double value = rNode.FastGetSolutionStepValue(r_variable);
rNode.SetValue(r_variable, AlphaRampUpIncrement * value);
}
}

// Interpolate variables to destination model part
if (DomainSize == 2) {
NodalValuesInterpolationProcess<2> interpolation(rOriginModelPart, rDestinationModelPart);
interpolation.Execute();
} else if (DomainSize == 3) {
NodalValuesInterpolationProcess<3> interpolation(rOriginModelPart, rDestinationModelPart);
interpolation.Execute();
} else {
KRATOS_ERROR << "Invalid DomainSize: " << DomainSize << ". DomainSize should be 2 or 3." << std::endl;
}

for(auto& r_variable_name : rInterpolationVariablesList){
auto& r_variable = KratosComponents<Variable<double>>::Get(r_variable_name);
for(auto& rNode: rDestinationModelPart.Nodes()) {
rNode.AddDof(r_variable);
}
}

// Using the parallel utilities
if(ConstrainVariables)
{
// Apply constraints to variables
for(auto& r_variable_name : rInterpolationVariablesList){
auto& r_variable = KratosComponents<Variable<double>>::Get(r_variable_name);
block_for_each(rDestinationModelPart.Nodes(), [&](Node& rNode){
const double value = rNode.GetValue(r_variable);
rNode.FastGetSolutionStepValue(r_variable) = value;
rNode.Fix(r_variable);
});
}
}
else
{
// Simply set the variables
for(auto& r_variable_name : rInterpolationVariablesList){
auto& r_variable = KratosComponents<Variable<double>>::Get(r_variable_name);
block_for_each(rDestinationModelPart.Nodes(), [&](Node& rNode){
const double value = rNode.GetValue(r_variable);
rNode.FastGetSolutionStepValue(r_variable) = value;
});
}
}
}
}

void GradualVariableInterpolationUtility::UpdateSolutionStepVariables(
ModelPart& rDestinationModelPart,
std::vector<std::string>& rInterpolationVariablesList,
double& rAlpha,
double& rOldAlpha,
bool ConstrainVariables)
{
{
if(ConstrainVariables)
{
for(auto& r_variable_name : rInterpolationVariablesList){
auto& r_variable = KratosComponents<Variable<double>>::Get(r_variable_name);
block_for_each(rDestinationModelPart.Nodes(), [&](Node& rNode){
const double value = rNode.FastGetSolutionStepValue(r_variable);
rNode.FastGetSolutionStepValue(r_variable) = rAlpha * value / rOldAlpha;
rNode.Fix(r_variable);
});
}
}
else
{
for(auto& r_variable_name : rInterpolationVariablesList){
auto& r_variable = KratosComponents<Variable<double>>::Get(r_variable_name);
block_for_each(rDestinationModelPart.Nodes(), [&](Node& rNode){
const double value = rNode.FastGetSolutionStepValue(r_variable);
rNode.FastGetSolutionStepValue(r_variable) = rAlpha * value / rOldAlpha;
});
}
}
}
}

} // namespace Kratos.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// KRATOS __ __ _____ ____ _ _ ___ _ _ ____
// | \/ | ____/ ___|| | | |_ _| \ | |/ ___|
// | |\/| | _| \___ \| |_| || || \| | | _
// | | | | |___ ___) | _ || || |\ | |_| |
// |_| |_|_____|____/|_| |_|___|_| \_|\____| APPLICATION
//
// License: BSD License
// license: MeshingApplication/license.txt
//
// Main authors: Sebastian Ares de Parga Regalado

#pragma once

// Project includes
#include "processes/process.h"
#include "includes/model_part.h"
#include "includes/kratos_parameters.h"
#include "custom_processes/nodal_values_interpolation_process.h"
#include "includes/parallel_environment.h"
#include "utilities/parallel_utilities.h"

namespace Kratos {

class KRATOS_API(MESHING_APPLICATION) GradualVariableInterpolationUtility {
public:
KRATOS_CLASS_POINTER_DEFINITION(GradualVariableInterpolationUtility);

/**
* @brief Initializes interpolation and applies constraints to the given variables
* @param rOriginModelPart The original model part
* @param rDestinationModelPart The destination model part
* @param rInterpolationVariablesList List of variables to be interpolated
* @param AlphaRampUpIncrement Alpha increment for the ramp-up
* @param DomainSize Size of the domain (2D or 3D)
* @param ConstrainVariables Flag to apply constraints to the variables
*/
static void InitializeInterpolationAndConstraints(
ModelPart& rOriginModelPart,
ModelPart& rDestinationModelPart,
std::vector<std::string>& rInterpolationVariablesList,
double AlphaRampUpIncrement,
int DomainSize,
bool ConstrainVariables);

/**
* @brief Updates the solution step variables
* @param rDestinationModelPart The destination model part
* @param rInterpolationVariablesList List of variables to be interpolated
* @param rAlpha Alpha value for updating the variables
* @param rOldAlpha Previous alpha value
* @param ConstrainVariables Flag to apply constraints to the variables
*/
static void UpdateSolutionStepVariables(
ModelPart& rDestinationModelPart,
std::vector<std::string>& rInterpolationVariablesList,
double& rAlpha,
double& rOldAlpha,
bool ConstrainVariables);
};

} // namespace Kratos.

Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import KratosMultiphysics
import KratosMultiphysics.MeshingApplication as KratosMA

def Factory(settings, model):
if not isinstance(settings, KratosMultiphysics.Parameters):
raise Exception("expected input shall be a Parameters object, encapsulating a json string")
return GradualVariableInterpolationProcess(model, settings["Parameters"])

class GradualVariableInterpolationProcess(KratosMultiphysics.Process):
"""This class defines a process for gradually interpolating nodal values from one
model part to another, called the origin and destination model parts respectively.
The rate of interpolation can be controlled through an increment parameter 'alpha_rampup_increment'
or by specifying the total number of steps for the full interpolation 'steps_for_rampup'.
The list of variables to be interpolated is also user-definable."""
def __init__(self, model, settings):
KratosMultiphysics.Process.__init__(self)

default_settings = KratosMultiphysics.Parameters("""{
"origin_model_part_file_name" : "NameOfMDPAfile",
"destination_model_part_name" : "ModelPartName",
"interpolation_variables_list": [],
"constrain_variables": false,
"alpha_rampup_increment": 0.0,
"steps_for_rampup": 0.0
}""")

settings.ValidateAndAssignDefaults(default_settings)

self.model = model
self.settings = settings
self.constrain_variables = self.settings["constrain_variables"].GetBool()
self.alpha_rampup_increment = self.settings["alpha_rampup_increment"].GetDouble()
self.steps_for_rampup = self.settings["steps_for_rampup"].GetInt()

if not self.alpha_rampup_increment and not self.steps_for_rampup:
KratosMultiphysics.Logger.PrintWarning('GradualVariableInterpolationProcess', 'Neither alpha_rampup_increment nor steps_for_rampup was specified; defaulting to alpha_rampup_increment = 1.0')
self.alpha_rampup_increment = 1.0
elif self.alpha_rampup_increment and self.steps_for_rampup:
KratosMultiphysics.Logger.PrintWarning('GradualVariableInterpolationProcess', 'Both alpha_rampup_increment and steps_for_rampup were specified; using alpha_rampup_increment and ignoring steps_for_rampup')
elif self.alpha_rampup_increment:
if self.alpha_rampup_increment < 0 or self.alpha_rampup_increment > 1:
raise Exception("'alpha_rampup_increment' must be in the interval (0, 1].")
elif self.steps_for_rampup:
if self.steps_for_rampup <= 0:
raise Exception("'steps_for_rampup' must be a positive integer.")
else:
self.alpha_rampup_increment = 1.0 / self.steps_for_rampup

self.alpha = 0.0
self.expected_alpha = 1.0
self.interpolation_variables_list = self.settings["interpolation_variables_list"].GetStringArray()

def ExecuteInitialize(self):
origin_model_part_file_name = self.settings["origin_model_part_file_name"].GetString()
destination_model_part_name = self.settings["destination_model_part_name"].GetString()
self.destination_model_part = self.model.GetModelPart(destination_model_part_name)

# Import Origin Model Part
self.origin_model_part = self.model.CreateModelPart("OriginModelPart")
for variable in self.destination_model_part.GetHistoricalVariablesNames():
if KratosMultiphysics.KratosGlobals.HasVariable(variable):
self.origin_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.KratosGlobals.GetVariable(variable))
else:
raise Exception(f"Variable '{variable}' does not exist or is not valid in KratosMultiphysics.")

model_part_io = KratosMultiphysics.ModelPartIO(origin_model_part_file_name)
model_part_io.ReadModelPart(self.origin_model_part)

self.domain_size = self.destination_model_part.ProcessInfo.GetValue(KratosMultiphysics.DOMAIN_SIZE)

KratosMA.GradualVariableInterpolationUtility.InitializeInterpolationAndConstraints(self.origin_model_part, self.destination_model_part, self.interpolation_variables_list, self.alpha_rampup_increment, self.domain_size, self.constrain_variables)

def ExecuteInitializeSolutionStep(self):
self.old_alpha = self.alpha
if self.old_alpha == 0.0:
self.old_alpha = self.alpha_rampup_increment
self.alpha += self.alpha_rampup_increment
if self.alpha <= self.expected_alpha:
KratosMA.GradualVariableInterpolationUtility.UpdateSolutionStepVariables(self.destination_model_part, self.interpolation_variables_list, self.alpha, self.old_alpha, self.constrain_variables)
Binary file not shown.
Loading

0 comments on commit 90aa5e3

Please sign in to comment.