Skip to content

Add BET solver JSON translator #319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion flow360/component/simulation/framework/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,13 @@ def _convert_dimensions_to_solver(
)
# pylint: disable=no-member
value.units.registry = flow360_conv_system.registry
print(">>> value.dtype = ", value.dtype)
solver_values[property_name] = value.in_base(unit_system="flow360")
print(
f">>> property_name = {property_name} value.dtype = ",
value.dtype,
"solver_values[property_name] is ",
solver_values[property_name].value.dtype,
)
log.debug(f" converted to: {solver_values[property_name]}")
else:
solver_values[property_name] = value
Expand Down
35 changes: 29 additions & 6 deletions flow360/component/simulation/unit_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def _unit_object_parser(value, unyt_types: List[type]):
if "value" in value:
for unyt_type in unyt_types:
try:
return unyt_type(value["value"], value["units"])
return unyt_type(value["value"], value["units"], dtype=np.float64)
except u.exceptions.UnitParseError:
pass
else:
Expand Down Expand Up @@ -219,9 +219,10 @@ def _unit_inference_validator(value, dim_name, is_array=False):
unit = unit_system_manager.current[dim_name]
if is_array:
if all(isinstance(item, Number) for item in value):
return value * unit
float64_tuple = tuple(np.float64(item) for item in value)
return float64_tuple * unit
if isinstance(value, Number):
return value * unit
return np.float64(value) * unit
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are these float64 needed when we are calling _enforce_float64 anyways?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because we cannot guarantee that _enforce_flaot64 is always called after these functions. What if this function is used as standalone somewhere?

return value


Expand Down Expand Up @@ -259,6 +260,27 @@ def _has_dimensions_validator(value, dim):
return value


def _enforce_float64(unyt_obj):
"""
This make sure all the values are float64 to minimize floating point errors
"""
if isinstance(unyt_obj, (u.Unit, _Flow360BaseUnit)):
return unyt_obj

# Determine if the object is a scalar or an array and cast to float64
if isinstance(unyt_obj, u.unyt_array):
# For unyt_array, ensure all elements are float64
new_values = np.asarray(unyt_obj, dtype=np.float64)
return new_values * unyt_obj.units

if isinstance(unyt_obj, u.unyt_quantity):
# For unyt_quantity, ensure the value is float64
new_value = np.float64(unyt_obj)
return u.unyt_quantity(new_value, unyt_obj.units)

raise TypeError(f"arg '{unyt_obj}' is not a valid unyt object")


class _DimensionedType(metaclass=ABCMeta):
"""
:class: Base class for dimensioned values
Expand All @@ -280,12 +302,13 @@ def validate(cls, value):
if cls.has_defaults:
value = _unit_inference_validator(value, cls.dim_name)
value = _has_dimensions_validator(value, cls.dim)
value = _enforce_float64(value)
except TypeError as err:
details = InitErrorDetails(type="value_error", ctx={"error": err})
raise pd.ValidationError.from_exception_data("validation error", [details])

if isinstance(value, u.Unit):
return 1.0 * value
return np.float64(1.0) * value

return value

Expand Down Expand Up @@ -826,7 +849,7 @@ def __init__(self, val=None) -> None:
self.val = val

@classmethod
def factory(cls, value, unit_name):
def factory(cls, value, unit_name, dtype=np.float64):
"""Returns specialised class object based on unit name

Parameters
Expand All @@ -848,7 +871,7 @@ def factory(cls, value, unit_name):
"""
for sub_classes in _Flow360BaseUnit.__subclasses__():
if sub_classes.unit_name == unit_name:
return sub_classes(value)
return sub_classes(dtype(value))
raise ValueError(f"No class found for unit_name: {unit_name}")

def __eq__(self, other):
Expand Down
Loading