Skip to content

Commit

Permalink
Merge pull request #12570 from KratosMultiphysics/optapp/responses/un…
Browse files Browse the repository at this point in the history
…ify_model_parts

[OptApp] Introduce GetInfluencingModelPart
  • Loading branch information
sunethwarna authored Jul 28, 2024
2 parents c1c64c7 + 3edf623 commit df161c3
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters
for response_params in parameters["combining_responses"].values():
response_params.ValidateAndAssignDefaults(default_settings["combining_responses"].values()[0])
response_name = response_params["response_name"].GetString()

if response_name not in [response.GetName() for response in optimization_problem.GetListOfResponses()]:
raise RuntimeError(f"\"{response_name}\" not found in the optimization problem. Please check whether this reponse is defined before the \"{self.GetName()}\".")

Expand All @@ -66,24 +66,10 @@ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFie
variables_list.extend(response.GetImplementedPhysicalKratosVariables())
return list(set(variables_list))

def GetEvaluatedModelPart(self) -> Kratos.ModelPart:
if all([response.GetEvaluatedModelPart() != None for response, _ in self.list_of_responses]):
raise RuntimeError(f"Mixing of adjoint and direct responses are prohibited.")

if self.model_part == None:
evaluated_model_part_names = [response.GetEvaluatedModelPart().FullName() for response, _ in self.list_of_responses]
model_part_operation = ModelPartOperation(self.model, ModelPartOperation.OperationType.UNION, f"response_{self.GetName()}", evaluated_model_part_names, False)
self.model_part = model_part_operation.GetModelPart()
return self.model_part

def GetAnalysisModelPart(self) -> Kratos.ModelPart:
if all([response.GetAnalysisModelPart() != None for response, _ in self.list_of_responses]):
raise RuntimeError(f"Mixing of adjoint and direct responses are prohibited.")

if self.model_part == None:
evaluated_model_part_names = [response.GetAnalysisModelPart().FullName() for response, _ in self.list_of_responses]
model_part_operation = ModelPartOperation(self.model, ModelPartOperation.OperationType.UNION, f"response_{self.GetName()}", evaluated_model_part_names, False)
self.model_part = model_part_operation.GetModelPart()
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
influencing_model_part_names = [response.GetInfluencingModelPart().FullName() for response, _ in self.list_of_responses]
model_part_operation = ModelPartOperation(self.model, ModelPartOperation.OperationType.UNION, f"response_{self.GetName()}", influencing_model_part_names, False)
self.model_part = model_part_operation.GetModelPart()
return self.model_part

def Initialize(self) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,11 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters
def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
return [self.variable]

def GetEvaluatedModelPart(self) -> Kratos.ModelPart:
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
if self.model_part is None:
raise RuntimeError("Please call DiscreteValueResidualResponseFunction::Initialize first.")
return self.model_part

def GetAnalysisModelPart(self) -> None:
return None

def Initialize(self) -> None:
self.model_part = self.model_part_operation.GetModelPart()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,11 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters
def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
return [KratosOA.SHAPE]

def GetEvaluatedModelPart(self) -> Kratos.ModelPart:
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
if self.model_part is None:
raise RuntimeError("Please call GeometricCentroidDeviationResponseFunction::Initialize first.")
return self.model_part

def GetAnalysisModelPart(self) -> None:
return None

def Initialize(self) -> None:
self.model_part = self.model_part_operation.GetModelPart()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,7 @@ def Check(self) -> None:
def Finalize(self) -> None:
pass

def GetEvaluatedModelPart(self) -> Kratos.ModelPart:
if self.model_part is None:
raise RuntimeError("Please call LinearStrainEnergyResponseFunction::Initialize first.")
return self.model_part

def GetAnalysisModelPart(self) -> Kratos.ModelPart:
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
return self.primal_analysis_execution_policy_decorator.GetAnalysisModelPart()

def CalculateValue(self) -> float:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,11 @@ def Check(self) -> None:
def Finalize(self) -> None:
pass

def GetEvaluatedModelPart(self) -> Kratos.ModelPart:
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
if self.model_part is None:
raise RuntimeError("Please call MassResponseFunction::Initialize first.")
return self.model_part

def GetAnalysisModelPart(self) -> None:
return None

def CalculateValue(self) -> float:
return KratosOA.ResponseUtils.MassResponseUtils.CalculateValue(self.model_part)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,22 +94,20 @@ def CalculateGradient(self, physical_variable_collective_expressions: 'dict[Supp
pass

@abstractmethod
def GetEvaluatedModelPart(self) -> Kratos.ModelPart:
"""Returns the model part for which this response is computed on.
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
"""Returns the model part which influences the computation of the response value.
Following two cases are considered:
1. Responses without adjoint system solve: The value of the response can only be influenced by
changing the quantities in the evaluated model part (evaluated model part is the one which the
response value is computed.) Therefore, in this case, this method should return the
evaluated model part.
2. Responses with adjoint system solve: The value of the response can be influenced by
changing quantities in the adjoint/primal model part (Evaluated model part needs to have
intersection with the adjoint/primal model part). Therefore, in this case, this method should return the
adjoint analysis model part.
Returns:
Kratos.ModelPart: Response function model part.
Kratos.ModelPart: Response function model part which influences the response value.
"""
pass

@abstractmethod
def GetAnalysisModelPart(self) -> 'Union[Kratos.ModelPart, None]':
"""Returns the analysis model part if exists. Otherwise returns None.
This method returns the analysis model part if an analysis is used (as in Adjoint case)
to compute the gradients. If it is not the case, then None should be returned.
Returns:
Union[Kratos.ModelPart, None]: Analysis model part if used, otherwise None
"""
pass
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,8 @@ def Initialize(self):
for control in self.__master_control.GetListOfControls():
# check whether control has keys given by required gradients
if set(control.GetPhysicalKratosVariables()).intersection(self.__required_physical_gradients.keys()):
# check whether there is an intersection of model parts between respones domain and control domain.
# 1. in the case where response does not require an analysis, then intersection between evaluated and control domain is checked.
# 2. in the case where response require an analysis, then intersection between analysis and control domain is checked.
if self.__response.GetAnalysisModelPart() is None:
checked_model_part: Kratos.ModelPart = self.__response.GetEvaluatedModelPart()
else:
checked_model_part: Kratos.ModelPart = self.__response.GetAnalysisModelPart()
# check whether there is an intersection of model parts between response influencial domain and control domain.
checked_model_part: Kratos.ModelPart = self.__response.GetInfluencingModelPart()

if Kratos.ModelPartOperationUtilities.HasIntersection([checked_model_part, control.GetEmptyField().GetModelPart()]):
self.__contributing_controls_list.append(control)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ def Initialize(self) -> None:
pass
def Finalize(self) -> None:
pass
def GetAnalysisModelPart(self) -> Kratos.ModelPart:
return None
def GetEvaluatedModelPart(self) -> Kratos.ModelPart:
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
return None
def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
return []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ def Initialize(self) -> None:
pass
def Finalize(self) -> None:
pass
def GetAnalysisModelPart(self) -> Kratos.ModelPart:
return None
def GetEvaluatedModelPart(self) -> Kratos.ModelPart:
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
return None
def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
return []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ def Finalize(self) -> None:
pass
def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
return None
def GetAnalysisModelPart(self) -> Kratos.ModelPart:
return None
def GetEvaluatedModelPart(self) -> Kratos.ModelPart:
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
return None
def CalculateValue(self) -> float:
return 0.0
Expand Down

0 comments on commit df161c3

Please sign in to comment.