[GeoMechanicsApplication] Integrate the functionality for UPw interfaces#14266
[GeoMechanicsApplication] Integrate the functionality for UPw interfaces#14266markelov208 merged 31 commits intomasterfrom
Conversation
Hi @markelov208, Yes I think that that is acceptable. Its what the water part of the U-Pw interface element needs. |
In principle no problem for me. However, since we use IGNORE_UNDRAINED in most of the model, I would not expect this to be necessary. I think if you'd add IGNORE_UNDRAINED: true to the material parameters of the interface (instead of the transversal permeability and dynamic viscosity), it'll also work (and that might be a bit more intuitive, since the rest of the materials also have IGNORE_UNDRAINED set to true. |
| "MINIMUM_RELATIVE_PERMEABILITY" : 0.0001, | ||
| "TRANSVERSAL_PERMEABILITY" : 5.0e-4, | ||
| "DYNAMIC_VISCOSITY" : 1.0e-3 |
There was a problem hiding this comment.
As mentioned in the other comment, I think this would also work:
| "MINIMUM_RELATIVE_PERMEABILITY" : 0.0001, | |
| "TRANSVERSAL_PERMEABILITY" : 5.0e-4, | |
| "DYNAMIC_VISCOSITY" : 1.0e-3 | |
| "IGNORE_UNDRAINED" : true, |
There was a problem hiding this comment.
Because in that case, the contributions for permeability would be ignored by the interface element
There was a problem hiding this comment.
Thank you for the suggestion! It works.
rfaasse
left a comment
There was a problem hiding this comment.
Hi Gennady, thank you for adding the integration tests for the interface! As mentioned the PR will likely change due to the fluid body flow etc, but these are my intermediate comments!
| "WATER_PRESSURE", no_pressure_time, no_pressure_output, [5] | ||
| )[0] | ||
|
|
||
| self.assertGreater(baseline_top_pressure - no_pressure_top_pressure, 900.0) |
There was a problem hiding this comment.
What is the reason we use an assertGreater instead of assertAlmostEqual here?
There was a problem hiding this comment.
The test has been generated by AI and I kept it just in case. Right now I removed it because it checks the imposed pressure. It should be somewhere for the tables/boundaries.
| Displacement and water pressure values obtained with and without the interface are compared for all nodes. The following pairs are used: | ||
|
|
||
| - `column_horizontal_interface` and `column`, | ||
| - `column_vertical_interface` and `column`, | ||
| - `column_horizontal_interface_diff_order_elements` and `column_diff_order_elements`. |
There was a problem hiding this comment.
If I understand correctly, this means we check that adding the interface does not have an effect on the results. That probably means we have high stiffnesses, such that the interfaces stay closed (correct me if I'm wrong).
I'm not sure, just asking, but would there be a benefit in having at least 1 test which does have an open interface (i.e. would it increase the covered paths within the element)?
There was a problem hiding this comment.
You are right these tests show that the solution is the same with/without an interface and the interface stays rather thin. If stiffness values are lower then the interface gets thicker and a solution changes. It is not clear what to check in this case.
There was a problem hiding this comment.
The stiffness values of the interface element will have an effect on the obtained displacement (additional deformation compared to the situation where there is no interface, assuming the normal stiffness is not nearly "infinite"). And I suspect the transverse permeability has an impact on the groundwater flow (if it is less permeable than the surrounding soil, I mean).
I think it's wise to double-check the obtained results with @WPK4FEM.
| Begin Table 2 TIME WATER_PRESSURE | ||
| 0.0000000000 0.0000000000 | ||
| 1.0000000000 1000.0000000000 | ||
| End Table |
There was a problem hiding this comment.
Since the water pressure is time dependent, does it make sense to add asserts for more time steps than just the latest ones?
There was a problem hiding this comment.
Correct, now tests check parameters for all times steps.
| "max_line_search_iterations": 5, | ||
| "first_alpha_value": 0.5, | ||
| "second_alpha_value": 1.0, | ||
| "min_alpha": 0.1, | ||
| "max_alpha": 2.0, | ||
| "line_search_tolerance": 0.5, |
There was a problem hiding this comment.
I don't think these params are needed, since we don't use line search
| "max_line_search_iterations": 5, | |
| "first_alpha_value": 0.5, | |
| "second_alpha_value": 1.0, | |
| "min_alpha": 0.1, | |
| "max_alpha": 2.0, | |
| "line_search_tolerance": 0.5, |
There was a problem hiding this comment.
It might be GitHub, but I still see these parameters here (and in the other project parameter files)
There was a problem hiding this comment.
Sorry it seems they are pop-up due to changing the folder structure. removed
| "kratos_module": "KratosMultiphysics.GeoMechanicsApplication", | ||
| "process_name": "ApplyK0ProcedureProcess", | ||
| "Parameters": { | ||
| "model_part_name": "PorousDomain.settlement_computational_model_part" |
There was a problem hiding this comment.
Just to validate my understanding, this means it's the intention that K0 is done for the interfaces as well, right?
There was a problem hiding this comment.
removed. Initially, the test was falling with Soil. Tried to find the reason.
markelov208
left a comment
There was a problem hiding this comment.
Hi Richard, many thanks for the review. It helped me to improve these tests and to learn better integration tests in general.
| "WATER_PRESSURE", no_pressure_time, no_pressure_output, [5] | ||
| )[0] | ||
|
|
||
| self.assertGreater(baseline_top_pressure - no_pressure_top_pressure, 900.0) |
There was a problem hiding this comment.
The test has been generated by AI and I kept it just in case. Right now I removed it because it checks the imposed pressure. It should be somewhere for the tables/boundaries.
| project_parameters_filenames = ( | ||
| project_parameters_filenames or self.project_parameters_filenames | ||
| ) | ||
| status = run_geo_settlement.run_stages(case_path, project_parameters_filenames) |
There was a problem hiding this comment.
Frankly speaking, I just grabbed something that I met first.
| "kratos_module": "KratosMultiphysics.GeoMechanicsApplication", | ||
| "process_name": "ApplyK0ProcedureProcess", | ||
| "Parameters": { | ||
| "model_part_name": "PorousDomain.settlement_computational_model_part" |
There was a problem hiding this comment.
removed. Initially, the test was falling with Soil. Tried to find the reason.
| def test_horizontal_interface(self): | ||
| file_path = test_helper.get_file_path(os.path.join("UPw_interface", "column")) | ||
| output_data = self._run_two_stage_soil_case(file_path) | ||
| self.assertTrue(output_data.get("results")) | ||
|
|
||
| def test_horizontal_interface_diff_order(self): | ||
| file_path = test_helper.get_file_path( | ||
| os.path.join("UPw_interface", "column_diff_order_elements") | ||
| ) | ||
| output_data = self._run_two_stage_soil_case(file_path) | ||
| self.assertTrue(output_data.get("results")) | ||
|
|
||
| def test_vertical_interface(self): | ||
| file_path = test_helper.get_file_path( | ||
| os.path.join("UPw_interface", "column_vertical_interface") | ||
| ) | ||
| output_data = self._run_two_stage_interface_case(file_path) | ||
| self.assertTrue(output_data.get("results")) |
There was a problem hiding this comment.
Yes, these tests just run. Now removed them because these computations are also done in other tests.
| if pair not in seen_pairs: | ||
| seen_pairs.add(pair) | ||
| node_id_pairs.append(pair) | ||
|
|
||
| return node_id_pairs |
There was a problem hiding this comment.
a vertical interface consists of two elements and repeated pairs of nodes exist.
| Begin Table 2 TIME WATER_PRESSURE | ||
| 0.0000000000 0.0000000000 | ||
| 1.0000000000 1000.0000000000 | ||
| End Table |
There was a problem hiding this comment.
Correct, now tests check parameters for all times steps.
| "max_line_search_iterations": 5, | ||
| "first_alpha_value": 0.5, | ||
| "second_alpha_value": 1.0, | ||
| "min_alpha": 0.1, | ||
| "max_alpha": 2.0, | ||
| "line_search_tolerance": 0.5, |
There was a problem hiding this comment.
It might be GitHub, but I still see these parameters here (and in the other project parameter files)
| project_parameters_filenames = ( | ||
| project_parameters_filenames or self.project_parameters_filenames | ||
| ) | ||
| status = run_geo_settlement.run_stages(case_path, project_parameters_filenames) |
There was a problem hiding this comment.
In that case, since run_geo_settlement is at this moment not that generic, I'd propose to use the python workflow 👍
| "kratos_module": "KratosMultiphysics.GeoMechanicsApplication", | ||
| "process_name": "ApplyK0ProcedureProcess", | ||
| "Parameters": { | ||
| "model_part_name": "PorousDomain.settlement_computational_model_part" | ||
| "model_part_name": "PorousDomain.Soil" | ||
| } | ||
| } |
There was a problem hiding this comment.
Does this mean that K0 should not be applied to the interfaces?
There was a problem hiding this comment.
There are no any effects of the model part name. Perhaps, this is a topic for the next study.
| if pair not in seen_pairs: | ||
| seen_pairs.add(pair) | ||
| node_id_pairs.append(pair) | ||
|
|
||
| return node_id_pairs |
There was a problem hiding this comment.
Okay, I still don't fully understand the code then, because seen_pairs is a set (so only contains unique items if I'm correct) and a pair is only added to node_id_pairs if it's not in the set. Could you explain this a bit more?
avdg81
left a comment
There was a problem hiding this comment.
Hi Gennady,
Thanks a lot for all the work that you've done for this PR. I like that you've set things up in a systematic way 👍 I have several suggestions and a few questions.
In addition, I have found two files that define a constitutive law for interface elements, but which don't have IGNORE_UNDRAINED set (is that intentional?):
line_interface_elements/common/MaterialParameters.jsontest_mohr_coulomb_with_tension_cutoff/interface_coulomb_2plus2/MaterialParameters.json(this one doesn't have any pore water properties defined)
One more thing: can you also please update this branch with the latest changes from master and then reformat the code (using kp format), to make sure the new JSON files are formatted correctly? Thanks.
| // Arrange | ||
| auto p_element = | ||
| CreateSmallStrainUPwDiffOrderElementWithUPwDofs(CreatePropertiesForUPwDiffOrderElementTest()); | ||
| SetSolutionStepValuesForGeneralCheck(p_element); // uniform pressure + gravity |
There was a problem hiding this comment.
When I looked at this function, I noticed that it only sets displacements at three of the six nodes. Not sure what happens at the mid-side nodes. This is not related in any way to your changes, but I was curious about what we prescribe and then I happened to see this. Perhaps just something to think about.
There was a problem hiding this comment.
this is a separate action due to replace of auto with Vector . In release mode the flux was always 0. Sorry the goal was to check the non-zero flux only.
| def _run_two_stage_case(self, case_path, project_parameters_filenames=None): | ||
| project_parameters_filenames = ( | ||
| project_parameters_filenames or self.project_parameters_filenames | ||
| ) |
There was a problem hiding this comment.
When we call _run_two_stage_case in our test cases, we always provide a value for project_parameters_filenames. That is, in our tests, the value will never be None. Therefore, I would suggest to remove the check and just use what is being passed. Then, you also no longer need to define self.project_parameters_filenames.
| def _all_times(output_data): | ||
| times = GiDOutputFileReader.get_time_steps_from_first_valid_result(output_data) | ||
| if not times: | ||
| raise RuntimeError("No valid output time steps found") | ||
| return times |
There was a problem hiding this comment.
I feel this approach is a bit tricky, since now the time steps depend on the produced output, which may be incorrect. I suspect that we know in advance which time steps will be calculated, so I would prefer to have hard-coded lists of expected time steps.
| } | ||
|
|
||
| @staticmethod | ||
| def _read_mdpa_nodes(mdpa_file_path): |
There was a problem hiding this comment.
I'm not sure, but perhaps you can use read_coordinates_from_post_msh_file from test_helper.py? If you really need to have a map from node ID to position, we could add a second helper function (e.g. extract_node_map_from_post_msh_file) that does just that (see variable node_map in the body of read_coordinates_from_post_msh_file), and then let read_coordinates_from_post_msh_file call extract_node_map_from_post_msh_file and produce the coordinates list from that.
There was a problem hiding this comment.
Thank you for the info. I tried to use read_coordinates_from_post_msh_file and met a situation that in column_vertical_interface folder .post.msh file does not include all nodes. Nodes used only in the vertical interface are missed. Perhaps, we can discuss it.
There was a problem hiding this comment.
Wow, this is a lot of test code. I see that many things have been set up in a very generic way, which is generally a good idea. For test code, however, and in particular for asserting certain results, it may be clearer to hard-code, for instance, which times or at which nodes you'd like to check something. That may help to reduce this test code a bit. For now I would suggest to keep the code "as-is", but we may want to simplify it a bit more in a separate PR. What do you think?
There was a problem hiding this comment.
That is AI. Now I reduced the code a bit.
the new tests fail when |
markelov208
left a comment
There was a problem hiding this comment.
Hi Richard and Anne, many thanks for the reviews and suggestions how to improve the tests. Unfortunately, I was not able to use all these suggestions. Hope we can discuss them.
| if pair not in seen_pairs: | ||
| seen_pairs.add(pair) | ||
| node_id_pairs.append(pair) | ||
|
|
||
| return node_id_pairs |
There was a problem hiding this comment.
As far as I understand a set is faster and a list preserves the order. The number of pairs is small in these tests so only the list can be used. Removed seen_pairs.
| "max_line_search_iterations": 5, | ||
| "first_alpha_value": 0.5, | ||
| "second_alpha_value": 1.0, | ||
| "min_alpha": 0.1, | ||
| "max_alpha": 2.0, | ||
| "line_search_tolerance": 0.5, |
There was a problem hiding this comment.
Sorry it seems they are pop-up due to changing the folder structure. removed
| project_parameters_filenames = ( | ||
| project_parameters_filenames or self.project_parameters_filenames | ||
| ) | ||
| status = run_geo_settlement.run_stages(case_path, project_parameters_filenames) |
There was a problem hiding this comment.
switched to run_multiple_stages, this required some changes in it and adding K0 parameters in material files.
| "kratos_module": "KratosMultiphysics.GeoMechanicsApplication", | ||
| "process_name": "ApplyK0ProcedureProcess", | ||
| "Parameters": { | ||
| "model_part_name": "PorousDomain.settlement_computational_model_part" | ||
| "model_part_name": "PorousDomain.Soil" | ||
| } | ||
| } |
There was a problem hiding this comment.
There are no any effects of the model part name. Perhaps, this is a topic for the next study.
| // Arrange | ||
| auto p_element = | ||
| CreateSmallStrainUPwDiffOrderElementWithUPwDofs(CreatePropertiesForUPwDiffOrderElementTest()); | ||
| SetSolutionStepValuesForGeneralCheck(p_element); // uniform pressure + gravity |
There was a problem hiding this comment.
this is a separate action due to replace of auto with Vector . In release mode the flux was always 0. Sorry the goal was to check the non-zero flux only.
| - Constitutive law: `GeoIncrementalLinearElasticInterfaceLaw` | ||
| - `INTERFACE_NORMAL_STIFFNESS = 6.4e10` | ||
| - `INTERFACE_SHEAR_STIFFNESS = 2.6000869565e10` | ||
| - `TRANSVERSAL_PERMEABILITY = 5.0e-4` |
There was a problem hiding this comment.
Are k_{\perp} and m^2 OK?
There was a problem hiding this comment.
It is just happened because a one stage calculation did not work due to my mistakes in settings and I looked at building_pit model as an example.
There was a problem hiding this comment.
That is AI. Now I reduced the code a bit.
| } | ||
|
|
||
| @staticmethod | ||
| def _read_mdpa_nodes(mdpa_file_path): |
There was a problem hiding this comment.
Thank you for the info. I tried to use read_coordinates_from_post_msh_file and met a situation that in column_vertical_interface folder .post.msh file does not include all nodes. Nodes used only in the vertical interface are missed. Perhaps, we can discuss it.
avdg81
left a comment
There was a problem hiding this comment.
I feel this PR is good to go. Thanks a lot for processing the review suggestions. 👍
WPK4FEM
left a comment
There was a problem hiding this comment.
Hi Gennady,
Lets put this in master.
Wijtze Pieter
📝 Description
A brief description of the PR.
Created integration tests that perform computations for:
The obtained solutions (displacement and pressure values) are compared with solutions obtained for
Tests are Quasi-static and displacement, pressure and fluid flux are compared for all time steps.
Added
PUCoupling,PermeabilityandFluidBodyFlowtoUPwInterfaceElementContributions.This requires allows to get proper values of pressure and fluid fluxes for these tests but it breaks two tests:
They have been fixed by adding
"IGNORE_UNDRAINED" : truefor interface material properties.A hydraulic discharge flow field is disconnected at the horizontal interface because
UPwInterfaceElementdoes not calculate the discharge now. Therefore a new issue [GeoMechanicsApplication] Add hydraulic discharge calculation in UPw interface element is created.Fixed error with
fluid_fluxcalculation inSmallStrainUPwDiffOrderElement::CalculateOnIntegrationPoints.A unit test is added.