KratosShallowWaterApplication 10.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- KratosMultiphysics/.libs/KratosShallowWaterApplication.so +0 -0
- KratosMultiphysics/.libs/libKratosShallowWaterCore.dylib +0 -0
- KratosMultiphysics/ShallowWaterApplication/__init__.py +7 -0
- KratosMultiphysics/ShallowWaterApplication/apply_absorbing_boundary_process.py +63 -0
- KratosMultiphysics/ShallowWaterApplication/apply_slip_process.py +40 -0
- KratosMultiphysics/ShallowWaterApplication/automatic_dirichlet_conditions_process.py +117 -0
- KratosMultiphysics/ShallowWaterApplication/benchmarks/base_benchmark_process.py +119 -0
- KratosMultiphysics/ShallowWaterApplication/benchmarks/dam_break_benchmark.py +128 -0
- KratosMultiphysics/ShallowWaterApplication/benchmarks/mac_donald_shock_benchmark.py +210 -0
- KratosMultiphysics/ShallowWaterApplication/benchmarks/mac_donald_transition_benchmark.py +79 -0
- KratosMultiphysics/ShallowWaterApplication/benchmarks/planar_surface_in_parabola_benchmark.py +116 -0
- KratosMultiphysics/ShallowWaterApplication/benchmarks/solitary_wave_benchmark.py +84 -0
- KratosMultiphysics/ShallowWaterApplication/boussinesq_solver.py +69 -0
- KratosMultiphysics/ShallowWaterApplication/coupling/compute_boundary_force_process.py +119 -0
- KratosMultiphysics/ShallowWaterApplication/coupling/depth_integration_input_process.py +245 -0
- KratosMultiphysics/ShallowWaterApplication/coupling/depth_integration_output_process.py +152 -0
- KratosMultiphysics/ShallowWaterApplication/coupling/read_from_sw_interface_process.py +363 -0
- KratosMultiphysics/ShallowWaterApplication/coupling/write_from_sw_at_interface_process.py +77 -0
- KratosMultiphysics/ShallowWaterApplication/derivatives_recovery_process.py +142 -0
- KratosMultiphysics/ShallowWaterApplication/lagrangian_shallow_water_solver.py +84 -0
- KratosMultiphysics/ShallowWaterApplication/modelers/dam_break_modeler.py +17 -0
- KratosMultiphysics/ShallowWaterApplication/modelers/planar_surface_in_parabola_modeler.py +17 -0
- KratosMultiphysics/ShallowWaterApplication/postprocess/auxiliary_nodes_visualization_process.py +93 -0
- KratosMultiphysics/ShallowWaterApplication/postprocess/compute_froude_process.py +36 -0
- KratosMultiphysics/ShallowWaterApplication/postprocess/convergence_output_process.py +152 -0
- KratosMultiphysics/ShallowWaterApplication/postprocess/generate_gid_list_file.py +38 -0
- KratosMultiphysics/ShallowWaterApplication/postprocess/line_envelope_output_process.py +61 -0
- KratosMultiphysics/ShallowWaterApplication/postprocess/line_graph_output_process.py +304 -0
- KratosMultiphysics/ShallowWaterApplication/postprocess/offset_ids_process.py +66 -0
- KratosMultiphysics/ShallowWaterApplication/postprocess/swap_coordinates_process.py +55 -0
- KratosMultiphysics/ShallowWaterApplication/postprocess/visualization_mesh_process.py +211 -0
- KratosMultiphysics/ShallowWaterApplication/primitive_solver.py +18 -0
- KratosMultiphysics/ShallowWaterApplication/set_initial_perturbation_process.py +64 -0
- KratosMultiphysics/ShallowWaterApplication/set_initial_water_level_process.py +53 -0
- KratosMultiphysics/ShallowWaterApplication/set_topography_process.py +53 -0
- KratosMultiphysics/ShallowWaterApplication/shallow_water_analysis.py +37 -0
- KratosMultiphysics/ShallowWaterApplication/shallow_water_base_solver.py +294 -0
- KratosMultiphysics/ShallowWaterApplication/stabilized_shallow_water_solver.py +111 -0
- KratosMultiphysics/ShallowWaterApplication/testing/empty_output_process.py +17 -0
- KratosMultiphysics/ShallowWaterApplication/testing/empty_solver_for_testing.py +78 -0
- KratosMultiphysics/ShallowWaterApplication/utilities/benchmarking_utilities.py +21 -0
- KratosMultiphysics/ShallowWaterApplication/utilities/solitary_wave_utilities.py +124 -0
- KratosMultiphysics/ShallowWaterApplication/utilities/wave_factory.py +65 -0
- KratosMultiphysics/ShallowWaterApplication/utilities/wave_theory_utilities.py +136 -0
- KratosMultiphysics/ShallowWaterApplication/wave_generator_process.py +119 -0
- KratosMultiphysics/ShallowWaterApplication/wave_solver.py +68 -0
- kratosshallowwaterapplication-10.4.4.dist-info/METADATA +43 -0
- kratosshallowwaterapplication-10.4.4.dist-info/RECORD +53 -0
- kratosshallowwaterapplication-10.4.4.dist-info/WHEEL +6 -0
- kratosshallowwaterapplication.dylibs/libKratosCore.dylib +4 -0
- kratosshallowwaterapplication.dylibs/libgcc_s.1.1.dylib +0 -0
- kratosshallowwaterapplication.dylibs/libgomp.1.dylib +0 -0
- kratosshallowwaterapplication.dylibs/libstdc++.6.dylib +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Application dependent names and paths
|
|
2
|
+
from KratosMultiphysics import _ImportApplication
|
|
3
|
+
from KratosShallowWaterApplication import *
|
|
4
|
+
application = KratosShallowWaterApplication()
|
|
5
|
+
application_name = "KratosShallowWaterApplication"
|
|
6
|
+
|
|
7
|
+
_ImportApplication(application, application_name)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import KratosMultiphysics as KM
|
|
2
|
+
import KratosMultiphysics.ShallowWaterApplication as SW
|
|
3
|
+
from KratosMultiphysics.ShallowWaterApplication.utilities.wave_factory import WaveTheoryFactory
|
|
4
|
+
|
|
5
|
+
def Factory(settings, model):
|
|
6
|
+
if not isinstance(settings, KM.Parameters):
|
|
7
|
+
raise Exception("expected input shall be a Parameters object, encapsulating a json string")
|
|
8
|
+
return ApplyAbsorbingBoundaryProcess(model, settings["Parameters"])
|
|
9
|
+
|
|
10
|
+
class ApplyAbsorbingBoundaryProcess(KM.Process):
|
|
11
|
+
"""ApplyAbsorbingBoundaryProcess
|
|
12
|
+
|
|
13
|
+
This process sets the DISTANCE variable from every
|
|
14
|
+
node to the nearest boundary condition
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def GetDefaultParameters():
|
|
19
|
+
return KM.Parameters("""{
|
|
20
|
+
"computing_model_part_name" : "",
|
|
21
|
+
"absorbing_boundary_name" : "",
|
|
22
|
+
"r_squared_threshold" : 0.99,
|
|
23
|
+
"relative_distance" : 2.0,
|
|
24
|
+
"relative_damping" : 2.0,
|
|
25
|
+
"wave_specifications" : {}
|
|
26
|
+
}""")
|
|
27
|
+
|
|
28
|
+
def __init__(self, model, settings):
|
|
29
|
+
"""The constructor of the ApplyAbsorbingBoundaryProcess"""
|
|
30
|
+
|
|
31
|
+
KM.Process.__init__(self)
|
|
32
|
+
|
|
33
|
+
self.settings = settings
|
|
34
|
+
self.settings.ValidateAndAssignDefaults(self.GetDefaultParameters())
|
|
35
|
+
|
|
36
|
+
self.model_part = model.GetModelPart(self.settings["computing_model_part_name"].GetString())
|
|
37
|
+
self.boundary_part = model.GetModelPart(self.settings["absorbing_boundary_name"].GetString())
|
|
38
|
+
self.distance_process = SW.CalculateDistanceToBoundaryProcess(self.model_part, self.boundary_part, self.settings["r_squared_threshold"].GetDouble())
|
|
39
|
+
|
|
40
|
+
variables_names = KM.SpecificationsUtilities.GetDofsListFromConditionsSpecifications(self.boundary_part)
|
|
41
|
+
self.variables_to_fix = []
|
|
42
|
+
for variable_name in variables_names:
|
|
43
|
+
if variable_name.startswith("VELOCITY") or variable_name.startswith("MOMENTUM"):
|
|
44
|
+
variable = KM.KratosGlobals.GetVariable(variable_name)
|
|
45
|
+
self.variables_to_fix.append(variable)
|
|
46
|
+
|
|
47
|
+
def Check(self):
|
|
48
|
+
"""Check the correctness of the input."""
|
|
49
|
+
self.distance_process.Check()
|
|
50
|
+
|
|
51
|
+
def ExecuteBeforeSolutionLoop(self):
|
|
52
|
+
"""Calculate the distances and the damping parameters."""
|
|
53
|
+
self.distance_process.ExecuteBeforeSolutionLoop()
|
|
54
|
+
|
|
55
|
+
wave = WaveTheoryFactory(self.boundary_part, self.settings["wave_specifications"])
|
|
56
|
+
absorbing_distance = wave.wavelength * self.settings["relative_distance"].GetDouble()
|
|
57
|
+
dissipation_factor = wave.frequency * self.settings["relative_damping"].GetDouble()
|
|
58
|
+
|
|
59
|
+
self.model_part.ProcessInfo.SetValue(SW.ABSORBING_DISTANCE, absorbing_distance)
|
|
60
|
+
self.model_part.ProcessInfo.SetValue(SW.DISSIPATION, dissipation_factor)
|
|
61
|
+
|
|
62
|
+
for variable in self.variables_to_fix:
|
|
63
|
+
KM.VariableUtils().ApplyFixity(variable, True, self.boundary_part.Nodes)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import KratosMultiphysics as KM
|
|
2
|
+
|
|
3
|
+
def Factory(settings, model):
|
|
4
|
+
if not isinstance(settings, KM.Parameters):
|
|
5
|
+
raise Exception("expected input shall be a Parameters object, encapsulating a json string")
|
|
6
|
+
return ApplySlipProcess(model, settings["Parameters"])
|
|
7
|
+
|
|
8
|
+
class ApplySlipProcess(KM.Process):
|
|
9
|
+
"""ApplySlipProcess
|
|
10
|
+
|
|
11
|
+
This process sets the SLIP flag and computes the
|
|
12
|
+
NORMAL variable on the selected model part
|
|
13
|
+
"""
|
|
14
|
+
def __init__(self, model, settings):
|
|
15
|
+
"""The constructor of the ApplySlipProcess
|
|
16
|
+
|
|
17
|
+
Keyword arguments:
|
|
18
|
+
self -- It signifies an instance of a class.
|
|
19
|
+
model -- The model to be used
|
|
20
|
+
settings -- The ProjectParameters used
|
|
21
|
+
"""
|
|
22
|
+
KM.Process.__init__(self)
|
|
23
|
+
|
|
24
|
+
default_parameters = KM.Parameters("""{
|
|
25
|
+
"model_part_name" : "PLEASE_CHOOSE_MODEL_PART_NAME",
|
|
26
|
+
"recompute_normals" : false
|
|
27
|
+
}""")
|
|
28
|
+
settings.ValidateAndAssignDefaults(default_parameters)
|
|
29
|
+
|
|
30
|
+
self.model_part = model[settings["model_part_name"].GetString()]
|
|
31
|
+
self.recompute_normals = settings["recompute_normals"].GetBool()
|
|
32
|
+
|
|
33
|
+
def ExecuteInitialize(self):
|
|
34
|
+
domain_size = self.model_part.ProcessInfo[KM.DOMAIN_SIZE]
|
|
35
|
+
KM.NormalCalculationUtils().CalculateOnSimplex(self.model_part, domain_size)
|
|
36
|
+
KM.VariableUtils().SetFlag(KM.SLIP, True, self.model_part.Nodes)
|
|
37
|
+
|
|
38
|
+
def ExecuteInitializeSolutionStep(self):
|
|
39
|
+
if self.recompute_normals:
|
|
40
|
+
self.ExecuteInitialize()
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import KratosMultiphysics as KM
|
|
2
|
+
import KratosMultiphysics.ShallowWaterApplication as SW
|
|
3
|
+
|
|
4
|
+
def Factory(settings, model):
|
|
5
|
+
if not isinstance(settings, KM.Parameters):
|
|
6
|
+
raise Exception("expected input shall be a Parameters object, encapsulating a json string")
|
|
7
|
+
return AutomaticDirichletConditionsProcess(model, settings["Parameters"])
|
|
8
|
+
|
|
9
|
+
## This process fix the variables at the skin
|
|
10
|
+
class AutomaticDirichletConditionsProcess(KM.Process):
|
|
11
|
+
|
|
12
|
+
def __init__(self, model, settings):
|
|
13
|
+
|
|
14
|
+
KM.Process.__init__(self)
|
|
15
|
+
|
|
16
|
+
default_settings = KM.Parameters("""
|
|
17
|
+
{
|
|
18
|
+
"model_part_name" : "main_model_part",
|
|
19
|
+
"scalar_variables_list" : [],
|
|
20
|
+
"scalar_value" : 0.0,
|
|
21
|
+
"scalar_constraint" : true,
|
|
22
|
+
"vector_variables_list" : [],
|
|
23
|
+
"vector_value" : [0.0, 0.0, 0.0],
|
|
24
|
+
"vector_constraint" : [true, true, true],
|
|
25
|
+
"auxiliary_model_part_name" : "skin_model_part",
|
|
26
|
+
"auxiliary_condition_name" : "Condition",
|
|
27
|
+
"skin_parts_to_exclude" : [],
|
|
28
|
+
"allow_outwards_flow_on_land" : true,
|
|
29
|
+
"sea_water_level" : 0.0
|
|
30
|
+
}
|
|
31
|
+
"""
|
|
32
|
+
)
|
|
33
|
+
settings.ValidateAndAssignDefaults(default_settings)
|
|
34
|
+
self.settings = settings
|
|
35
|
+
self.model = model
|
|
36
|
+
|
|
37
|
+
self._CheckIfParameterIsRelativeSubModelPartName(self.settings["auxiliary_model_part_name"])
|
|
38
|
+
for item in self.settings["skin_parts_to_exclude"]:
|
|
39
|
+
self._CheckIfParameterIsRelativeSubModelPartName(item)
|
|
40
|
+
|
|
41
|
+
def ExecuteInitialize(self):
|
|
42
|
+
model_part_name = self.settings["model_part_name"].GetString()
|
|
43
|
+
model_part = self.model[model_part_name]
|
|
44
|
+
|
|
45
|
+
skin_detection_settings = KM.Parameters()
|
|
46
|
+
skin_detection_settings.AddValue("name_auxiliar_model_part", self.settings["auxiliary_model_part_name"])
|
|
47
|
+
skin_detection_settings.AddValue("name_auxiliar_condition", self.settings["auxiliary_condition_name"])
|
|
48
|
+
skin_detection_settings.AddValue("list_model_parts_to_assign_conditions", self.settings["skin_parts_to_exclude"])
|
|
49
|
+
KM.SkinDetectionProcess2D(model_part, skin_detection_settings).Execute()
|
|
50
|
+
|
|
51
|
+
skin_model_part_name = model_part_name + '.' + self.settings["auxiliary_model_part_name"].GetString()
|
|
52
|
+
skin_model_part = self.model[skin_model_part_name]
|
|
53
|
+
|
|
54
|
+
# We remove the new interface condition from the bondaries with other conditions
|
|
55
|
+
for name in self.settings["skin_parts_to_exclude"].GetStringArray():
|
|
56
|
+
skin_to_exclude = model_part_name + '.' + name
|
|
57
|
+
self.model[skin_to_exclude].RemoveConditionsFromAllLevels(KM.INTERFACE)
|
|
58
|
+
KM.VariableUtils().SetFlag(KM.INTERFACE, False, self.model[skin_to_exclude].Nodes)
|
|
59
|
+
skin_model_part.RemoveNodes((KM.INTERFACE).AsFalse())
|
|
60
|
+
|
|
61
|
+
# Here we exclude the interface which will has an outward flow
|
|
62
|
+
if self.settings["allow_outwards_flow_on_land"].GetBool():
|
|
63
|
+
dimension = 2
|
|
64
|
+
KM.NormalCalculationUtils().CalculateOnSimplex(skin_model_part, dimension)
|
|
65
|
+
KM.ComputeNonHistoricalNodalGradientProcess(model_part, SW.TOPOGRAPHY, SW.TOPOGRAPHY_GRADIENT, KM.NODAL_AREA).Execute()
|
|
66
|
+
SW.ShallowWaterUtilities().IdentifySolidBoundary(skin_model_part, self.settings["sea_water_level"].GetDouble(), KM.SOLID)
|
|
67
|
+
skin_model_part.RemoveNodes((KM.SOLID).AsFalse())
|
|
68
|
+
skin_model_part.RemoveConditionsFromAllLevels((KM.SOLID).AsFalse())
|
|
69
|
+
else:
|
|
70
|
+
KM.VariableUtils().SetFlag(KM.SOLID, True, skin_model_part.Nodes)
|
|
71
|
+
KM.VariableUtils().SetFlag(KM.SOLID, True, skin_model_part.Conditions)
|
|
72
|
+
|
|
73
|
+
self.processes = []
|
|
74
|
+
|
|
75
|
+
from KratosMultiphysics.assign_scalar_variable_process import AssignScalarVariableProcess
|
|
76
|
+
for variable in self.settings["scalar_variables_list"].GetStringArray():
|
|
77
|
+
scalar_settings = KM.Parameters()
|
|
78
|
+
scalar_settings.AddEmptyValue("model_part_name").SetString(skin_model_part_name)
|
|
79
|
+
scalar_settings.AddEmptyValue("variable_name").SetString(variable)
|
|
80
|
+
scalar_settings.AddValue("value", self.settings["scalar_value"])
|
|
81
|
+
scalar_settings.AddValue("constrained", self.settings["scalar_constraint"])
|
|
82
|
+
self.processes.append(AssignScalarVariableProcess(self.model, scalar_settings))
|
|
83
|
+
|
|
84
|
+
from KratosMultiphysics.assign_vector_variable_process import AssignVectorVariableProcess
|
|
85
|
+
for variable in self.settings["vector_variables_list"].GetStringArray():
|
|
86
|
+
vector_settings = KM.Parameters()
|
|
87
|
+
vector_settings.AddEmptyValue("model_part_name").SetString(skin_model_part_name)
|
|
88
|
+
vector_settings.AddEmptyValue("variable_name").SetString(variable)
|
|
89
|
+
vector_settings.AddValue("value", self.settings["vector_value"])
|
|
90
|
+
vector_settings.AddValue("constrained", self.settings["vector_constraint"])
|
|
91
|
+
self.processes.append(AssignVectorVariableProcess(self.model, vector_settings))
|
|
92
|
+
|
|
93
|
+
def ExecuteBeforeSolutionLoop(self):
|
|
94
|
+
for process in self.processes:
|
|
95
|
+
process.ExecuteBeforeSolutionLoop()
|
|
96
|
+
|
|
97
|
+
def ExecuteInitializeSolutionStep(self):
|
|
98
|
+
for process in self.processes:
|
|
99
|
+
process.ExecuteInitializeSolutionStep()
|
|
100
|
+
|
|
101
|
+
def ExecuteFinalizeSolutionStep(self):
|
|
102
|
+
for process in self.processes:
|
|
103
|
+
process.ExecuteFinalizeSolutionStep()
|
|
104
|
+
|
|
105
|
+
@staticmethod
|
|
106
|
+
def _CheckIfParameterIsRelativeSubModelPartName(param):
|
|
107
|
+
name = param.GetString()
|
|
108
|
+
search = name.find('.')
|
|
109
|
+
if search != -1:
|
|
110
|
+
items = name.split('.')
|
|
111
|
+
msg = "AutomaticDirichletConditionsProcess"
|
|
112
|
+
msg += 'Please, specify the sub model part with the relative name\n'
|
|
113
|
+
msg += '\tWrite : \"' + items[-1] + '\"\n'
|
|
114
|
+
msg += '\tinstead of : \"' + name + '\"\n'
|
|
115
|
+
param.SetString(name)
|
|
116
|
+
# The parameters are passed by value, we shall throw an error
|
|
117
|
+
raise Exception(msg)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics as KM
|
|
3
|
+
import KratosMultiphysics.ShallowWaterApplication as SW
|
|
4
|
+
|
|
5
|
+
from KratosMultiphysics.kratos_utilities import GenerateVariableListFromInput
|
|
6
|
+
|
|
7
|
+
def Factory(settings, model):
|
|
8
|
+
if not isinstance(settings, KM.Parameters):
|
|
9
|
+
raise Exception("expected input shall be a Parameters object, encapsulating a json string")
|
|
10
|
+
return BaseBenchmarkProcess(model, settings["Parameters"])
|
|
11
|
+
|
|
12
|
+
class BaseBenchmarkProcess(KM.Process):
|
|
13
|
+
"""The base class for the benchmarks."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, model, settings ):
|
|
16
|
+
"""The constructor of the BaseBenchmarkProcess.
|
|
17
|
+
|
|
18
|
+
It is intended to be called from the constructor of deriving classes.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
super().__init__()
|
|
22
|
+
|
|
23
|
+
self.model = model
|
|
24
|
+
self.settings = settings
|
|
25
|
+
|
|
26
|
+
default_settings = KM.Parameters("""
|
|
27
|
+
{
|
|
28
|
+
"model_part_name" : "model_part",
|
|
29
|
+
"variables_list" : [],
|
|
30
|
+
"exact_variables_list" : [],
|
|
31
|
+
"error_variables_list" : [],
|
|
32
|
+
"benchmark_settings" : {}
|
|
33
|
+
}
|
|
34
|
+
"""
|
|
35
|
+
)
|
|
36
|
+
default_settings["benchmark_settings"] = self._GetBenchmarkDefaultSettings()
|
|
37
|
+
self.settings.RecursivelyValidateAndAssignDefaults(default_settings)
|
|
38
|
+
|
|
39
|
+
self.model_part = self.model[self.settings["model_part_name"].GetString()]
|
|
40
|
+
self.variables = GenerateVariableListFromInput(self.settings["variables_list"])
|
|
41
|
+
self.exact_variables = GenerateVariableListFromInput(self.settings["exact_variables_list"])
|
|
42
|
+
self.error_variables = GenerateVariableListFromInput(self.settings["error_variables_list"])
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def ExecuteInitialize(self):
|
|
46
|
+
"""Set the topography and the initial conditions."""
|
|
47
|
+
KM.Timer.Start("Benchmark/Initial state")
|
|
48
|
+
time = self.model_part.ProcessInfo[KM.TIME]
|
|
49
|
+
for node in self.model_part.Nodes:
|
|
50
|
+
if self._Topography(node):
|
|
51
|
+
node.SetSolutionStepValue(SW.TOPOGRAPHY, self._Topography(node))
|
|
52
|
+
node.SetSolutionStepValue(SW.HEIGHT, self._Height(node, time))
|
|
53
|
+
node.SetSolutionStepValue(KM.VELOCITY, self._Velocity(node, time))
|
|
54
|
+
node.SetSolutionStepValue(KM.MOMENTUM, self._Momentum(node, time))
|
|
55
|
+
node.SetSolutionStepValue(SW.FREE_SURFACE_ELEVATION, self._FreeSurfaceElevation(node, time))
|
|
56
|
+
KM.Timer.Stop("Benchmark/Initial state")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def ExecuteBeforeOutputStep(self):
|
|
60
|
+
"""Compute the exact values of the benchmark and the error of the simulation."""
|
|
61
|
+
KM.Timer.Start("Benchmark/Exact values")
|
|
62
|
+
time = self.model_part.ProcessInfo[KM.TIME]
|
|
63
|
+
for (variable, exact_variable, error_variable) in zip(self.variables, self.exact_variables, self.error_variables):
|
|
64
|
+
|
|
65
|
+
if variable == SW.HEIGHT:
|
|
66
|
+
exact_value_function = self._Height
|
|
67
|
+
elif variable == KM.VELOCITY:
|
|
68
|
+
exact_value_function = self._Velocity
|
|
69
|
+
elif variable == KM.MOMENTUM:
|
|
70
|
+
exact_value_function = self._Momentum
|
|
71
|
+
elif variable == SW.FREE_SURFACE_ELEVATION:
|
|
72
|
+
exact_value_function = self._FreeSurfaceElevation
|
|
73
|
+
|
|
74
|
+
for node in self.model_part.Nodes:
|
|
75
|
+
exact_value = exact_value_function(node, time)
|
|
76
|
+
fem_value = node.GetSolutionStepValue(variable)
|
|
77
|
+
|
|
78
|
+
node.SetValue(exact_variable, exact_value)
|
|
79
|
+
node.SetValue(error_variable, fem_value - exact_value)
|
|
80
|
+
KM.Timer.Stop("Benchmark/Exact values")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def Check(self):
|
|
84
|
+
"""Check if the input values have physical sense."""
|
|
85
|
+
|
|
86
|
+
if len(self.variables) != len(self.exact_variables):
|
|
87
|
+
raise Exception("The input variables list does not match the input exact variables list")
|
|
88
|
+
|
|
89
|
+
if len(self.variables) != len(self.error_variables):
|
|
90
|
+
raise Exception("The input variables list does not match the input error variables list")
|
|
91
|
+
|
|
92
|
+
for (var, exact, error) in zip(self.variables, self.exact_variables, self.error_variables):
|
|
93
|
+
if KM.KratosGlobals.GetVariableType(var.Name()) != KM.KratosGlobals.GetVariableType(exact.Name()):
|
|
94
|
+
msg = var.Name() + " variable type does not match the " + exact.Name() + " variable type"
|
|
95
|
+
raise Exception(msg)
|
|
96
|
+
|
|
97
|
+
if KM.KratosGlobals.GetVariableType(var.Name()) != KM.KratosGlobals.GetVariableType(error.Name()):
|
|
98
|
+
msg = var.Name() + " variable type does not match the " + error.Name() + " variable type"
|
|
99
|
+
raise Exception(msg)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@classmethod
|
|
103
|
+
def _GetBenchmarkDefaultSettings(cls):
|
|
104
|
+
raise Exception("Calling the base class of the benchmark. Please, implement the custom benchmark settings")
|
|
105
|
+
|
|
106
|
+
def _Topography(self, coordinates):
|
|
107
|
+
return 0
|
|
108
|
+
|
|
109
|
+
def _Height(self, coordinates, time):
|
|
110
|
+
raise Exception("Calling the base class of the benchmark. Please, implement the custom benchmark")
|
|
111
|
+
|
|
112
|
+
def _Velocity(self, coordinates, time):
|
|
113
|
+
raise Exception("Calling the base class of the benchmark. Please, implement the custom benchmark")
|
|
114
|
+
|
|
115
|
+
def _Momentum(self, coordinates, time):
|
|
116
|
+
return [self._Height(coordinates, time)*v for v in self._Velocity(coordinates, time)]
|
|
117
|
+
|
|
118
|
+
def _FreeSurfaceElevation(self, coordinates, time):
|
|
119
|
+
return self._Topography(coordinates) + self._Height(coordinates, time)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import KratosMultiphysics as KM
|
|
2
|
+
|
|
3
|
+
from KratosMultiphysics.ShallowWaterApplication.benchmarks.base_benchmark_process import BaseBenchmarkProcess
|
|
4
|
+
|
|
5
|
+
# Other imports
|
|
6
|
+
from math import sqrt
|
|
7
|
+
import scipy.optimize as opt
|
|
8
|
+
|
|
9
|
+
def Factory(settings, model):
|
|
10
|
+
if not isinstance(settings, KM.Parameters):
|
|
11
|
+
raise Exception("expected input shall be a Parameters object, encapsulating a json string")
|
|
12
|
+
return DamBreakBenchmark(model, settings["Parameters"])
|
|
13
|
+
|
|
14
|
+
class DamBreakBenchmark(BaseBenchmarkProcess):
|
|
15
|
+
"""Dam break benchark.
|
|
16
|
+
|
|
17
|
+
O. Delestre, C. Lucas, P.-A. Ksinant, F. Darboux, C. Laguerre, T.N.T. Vo, F. James, S. Cordier
|
|
18
|
+
SWASHES: a compilation of Shallow Water Analytic Solutions for Hydraulic and Environmental Studies
|
|
19
|
+
International Journal for Numerical Methods in Fluids, Wiley, 2013, 72 (3), pp.269-300
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, model, settings ):
|
|
23
|
+
"""Constructor of the benchmark.
|
|
24
|
+
|
|
25
|
+
The base class validates the settings and sets the model_part, the variables and the benchmark_settings
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
super().__init__(model, settings)
|
|
29
|
+
|
|
30
|
+
self.dam = self.settings["benchmark_settings"]["dam_position"].GetDouble()
|
|
31
|
+
self.hl = self.settings["benchmark_settings"]["left_height"].GetDouble()
|
|
32
|
+
self.hr = self.settings["benchmark_settings"]["right_height"].GetDouble()
|
|
33
|
+
self.g = self.model_part.ProcessInfo[KM.GRAVITY_Z]
|
|
34
|
+
|
|
35
|
+
self.cm = self.__cm()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def Check(self):
|
|
39
|
+
"""This method checks if the input values have physical sense."""
|
|
40
|
+
|
|
41
|
+
super().Check()
|
|
42
|
+
label = "DamBreakBenchmark. "
|
|
43
|
+
if self.g <= 0:
|
|
44
|
+
msg = label + "Gravity must be a positive value. Please, check the definition of GRAVITY_Z component in the ProcessInfo."
|
|
45
|
+
raise Exception(msg)
|
|
46
|
+
elif self.hr < 0:
|
|
47
|
+
msg = label + "Right height must be non-negative. Please, check the Parameters."
|
|
48
|
+
raise Exception(msg)
|
|
49
|
+
elif self.hl < 0:
|
|
50
|
+
msg = label + "Left height must be non-negative. Please, check the Parameters."
|
|
51
|
+
raise Exception(msg)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@classmethod
|
|
55
|
+
def _GetBenchmarkDefaultSettings(cls):
|
|
56
|
+
return KM.Parameters("""
|
|
57
|
+
{
|
|
58
|
+
"dam_position" : 5.0,
|
|
59
|
+
"left_height" : 2.0,
|
|
60
|
+
"right_height" : 1.0
|
|
61
|
+
}
|
|
62
|
+
"""
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _Height(self, coordinates, time):
|
|
67
|
+
x = coordinates.X
|
|
68
|
+
|
|
69
|
+
xa = self.__xa(time)
|
|
70
|
+
xb = self.__xb(time)
|
|
71
|
+
xc = self.__xc(time)
|
|
72
|
+
|
|
73
|
+
if x < xa:
|
|
74
|
+
return self.hl
|
|
75
|
+
elif x < xb:
|
|
76
|
+
return 4 / 9 / self.g * (sqrt(self.g * self.hl) - 0.5*(x - self.dam) / time)**2
|
|
77
|
+
elif x < xc:
|
|
78
|
+
return self.cm**2 / self.g
|
|
79
|
+
else:
|
|
80
|
+
return self.hr
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _Velocity(self, coordinates, time):
|
|
84
|
+
x = coordinates.X
|
|
85
|
+
|
|
86
|
+
xa = self.__xa(time)
|
|
87
|
+
xb = self.__xb(time)
|
|
88
|
+
xc = self.__xc(time)
|
|
89
|
+
|
|
90
|
+
if x < xa:
|
|
91
|
+
return [0.0, 0.0, 0.0]
|
|
92
|
+
elif x < xb:
|
|
93
|
+
return [2 / 3 * ((x - self.dam) / time + sqrt(self.g * self.hl)), 0.0, 0.0]
|
|
94
|
+
elif x < xc:
|
|
95
|
+
return [2 * (sqrt(self.g * self.hl) - self.cm), 0.0, 0.0]
|
|
96
|
+
else:
|
|
97
|
+
return [0.0, 0.0, 0.0]
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def __xa(self, t):
|
|
101
|
+
return self.dam - t * sqrt(self.g * self.hl)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def __xb(self, t):
|
|
105
|
+
return self.dam + t * (2*sqrt(self.g * self.hl) - 3 * self.cm)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def __xc(self, t):
|
|
109
|
+
if self.hr > 0:
|
|
110
|
+
return self.dam + t * 2 * self.cm**2 * (sqrt(self.g*self.hl) - self.cm) / (self.cm**2 - self.g * self.hr)
|
|
111
|
+
else:
|
|
112
|
+
return self.__xb(t)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def __cm(self):
|
|
116
|
+
if self.hr > 0:
|
|
117
|
+
cm0 = sqrt(self.g * 0.5 * (self.hl + self.hr))
|
|
118
|
+
cm = opt.newton(self.__cm_residual, cm0)
|
|
119
|
+
return cm
|
|
120
|
+
else:
|
|
121
|
+
return 0.0
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def __cm_residual(self,cm):
|
|
125
|
+
hl = self.hl
|
|
126
|
+
hr = self.hr
|
|
127
|
+
g = self.g
|
|
128
|
+
return -8*g*hr*cm**2*(sqrt(g*hl)-cm)**2 + (cm**2-g*hr)**2 * (cm**2+g*hr)
|