Skip to content

add function to read from a csv to test helper#14486

Open
Sabine-van-Dijk wants to merge 12 commits into
masterfrom
14470-geomechanicsapplication-function-to-read-from-a-csv
Open

add function to read from a csv to test helper#14486
Sabine-van-Dijk wants to merge 12 commits into
masterfrom
14470-geomechanicsapplication-function-to-read-from-a-csv

Conversation

@Sabine-van-Dijk

Copy link
Copy Markdown
Contributor

I added a function to read values from a csv to the test helper.

The function 'get_values_from_csv' gets the float values corresponding to the keys. This is a general use and can be also used for the CROW case script.

The function 'get_values_from_csv_as_vectors' gets the values corresponding to the keys as a vector. This way it is possible to assert entire cauchy stress tensors or strain tensors at once.

The last function 'get_values_from_csv_grouped' allows to get values grouped. This is used for example if you have multiple phases and want to store all the data from different phases in the same csv file. The function now returns an array, but maybe we would like to have it also available to return a float value like 'get_values_from_csv'.

I implemented the new functions on the test_element_lab.py to test their functionality.

@Sabine-van-Dijk Sabine-van-Dijk requested a review from a team as a code owner June 8, 2026 09:04
@Sabine-van-Dijk Sabine-van-Dijk requested a review from avdg81 June 8, 2026 09:04
@Sabine-van-Dijk Sabine-van-Dijk deleted the 14470-geomechanicsapplication-function-to-read-from-a-csv branch June 8, 2026 09:06
@Sabine-van-Dijk Sabine-van-Dijk restored the 14470-geomechanicsapplication-function-to-read-from-a-csv branch June 8, 2026 09:06
Comment thread applications/GeoMechanicsApplication/tests/test_element_lab.py Outdated
@Sabine-van-Dijk Sabine-van-Dijk requested a review from WPK4FEM June 11, 2026 15:12

@WPK4FEM WPK4FEM left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Sabine,
Thank you for the correction of the order of the labels. For me this is good to go, but I'm by no means a python expert. Please await also Anne's approval.
Regards, Wijtze Pieter

@avdg81 avdg81 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Sabine,
Thanks for generalizing the functionality to read expected results from CSV files. As I said before, this is even nicer than the code that you started from. 👍
I have a few minor suggestions, but overall, this PR is (almost) ready to go.

Comment on lines +50 to +61
def get_values_from_csv(csv_filepath, keys, values):
result = {}
with open(csv_filepath, newline = "") as csv_file:
reader = csv.DictReader(csv_file)
for row in reader:
if len(keys) == 1:
key = int(row[keys[0]])
else:
key = tuple(int(row[key]) for key in keys)
expected_values = {value: float(row[value]) for value in values}
result[key] = expected_values
return result

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the generality of this function. Perhaps with a little bit of renaming and extracting one helper function, it becomes even easier for me to read. My suggestion makes the code a little longer, but hopefully that is worth it. What do you think?

Suggested change
def get_values_from_csv(csv_filepath, keys, values):
result = {}
with open(csv_filepath, newline = "") as csv_file:
reader = csv.DictReader(csv_file)
for row in reader:
if len(keys) == 1:
key = int(row[keys[0]])
else:
key = tuple(int(row[key]) for key in keys)
expected_values = {value: float(row[value]) for value in values}
result[key] = expected_values
return result
def _make_key(key_field_names, row):
if len(key_field_names) == 1:
return int(row[key_field_names[0]])
return tuple(int(row[field_name]) for field_name in key_field_names)
def get_values_from_csv(csv_filepath, key_field_names, value_field_names):
with open(csv_filepath, newline = "") as csv_file:
reader = csv.DictReader(csv_file)
return {
_make_key(key_field_names, row): {
field_name: float(row[field_name]) for field_name in value_field_names
}
for row in reader
}

FYI, I wrote this from the top of my head, and I didn't test it. Please, have a close look and check for any mistakes from my side. Thank you.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works and I think it is nice. Thank you for the suggestion :)

result[key] = expected_values
return result

def get_values_from_csv_as_vectors(csv_filepath, keys, values):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice function to easily construct a vector. I like it. 👍

Perhaps also here, we can rename the arguments to key_field_names and value_field_names. What do you think?

self.assert_integration_point_tensors(result, "ENGINEERING_STRAIN_TENSOR",
self._make_integration_point_tensor_entries(expected_strain, num_elements=2, num_integration_points_per_element=1),
time, precision_places)
node_ids = sorted(expected_displacement)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, I'm getting a bit confused. Why would the node IDs be equal to the sorted expected displacements? I would have expected something like (since the node IDs are the keys in the map with the expected displacements, right?):

Suggested change
node_ids = sorted(expected_displacement)
node_ids = sorted(expected_displacement.keys())

I can guess why the code works, but I'm not 100% sure. Perhaps iterating over a map yields the keys? If yes, then I would prefer the more explicit expression, i.e. by adding .keys(). Thank you.

I'm also wondering whether the node IDs need to be sorted or not. It seems to me that the code would also work if the node IDs are not sorted. Or am I overlooking something?

@Sabine-van-Dijk Sabine-van-Dijk Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the python sorting techniques it works like the following example:
sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
[1, 2, 3, 4, 5]
They do not need to be sorted necessarily, but it was just a way to get the keys. I will add the .keys() for clarity. I can also do just expected_displacement.keys() without sorted. that returns a dict object then instead of a list but it also works here. Please let me know if that is even more clear.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay maybe not a real dict object but I don't know what to call it.
Just expected_displacement.keys()
returns: dict_keys([1, 2, 3, 4, 5, 6, 7, 8, 9])

return {key: [row[value] for value in values]
for key, row in get_values_from_csv(csv_filepath, keys, values).items()}

def get_values_from_csv_grouped(csv_filepath, grouping_keys, entry_keys, values):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this function a bit difficult to read. But I don't have a better suggestion yet. Perhaps the only thing I can think of is to rename the last three arguments as suggested before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[GeoMechanicsApplication] Add a function to read test expectations from a file (.json or .csv)

3 participants