Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
pymatlib
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Rahil Doshi
pymatlib
Commits
1f716b64
Commit
1f716b64
authored
2 months ago
by
Rahil Doshi
Browse files
Options
Downloads
Patches
Plain Diff
Improve interpolation code
parent
60a6f9fe
Branches
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#76704
passed
2 months ago
Stage: test
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/pymatlib/core/codegen/interpolation_array_container.py
+33
-17
33 additions, 17 deletions
src/pymatlib/core/codegen/interpolation_array_container.py
src/pymatlib/core/interpolators.py
+50
-21
50 additions, 21 deletions
src/pymatlib/core/interpolators.py
with
83 additions
and
38 deletions
src/pymatlib/core/codegen/interpolation_array_container.py
+
33
−
17
View file @
1f716b64
import
re
import
numpy
as
np
import
numpy
as
np
from
pystencils.types
import
PsCustomType
from
pystencils.types
import
PsCustomType
from
pystencilssfg
import
SfgComposer
from
pystencilssfg
import
SfgComposer
...
@@ -53,30 +54,45 @@ class InterpolationArrayContainer(CustomGenerator):
...
@@ -53,30 +54,45 @@ class InterpolationArrayContainer(CustomGenerator):
corresponding to temperature_array.
corresponding to temperature_array.
Raises:
Raises:
ValueError: If arrays are empty, have different lengths, or are not monotonic.
ValueError: If arrays are empty, have different lengths, or are not monotonic.
TypeError: If name is not a string or arrays are not numpy arrays.
"""
"""
super
().
__init__
()
super
().
__init__
()
# Validate inputs
if
not
isinstance
(
name
,
str
)
or
not
name
:
raise
TypeError
(
"
Name must be a non-empty string
"
)
if
not
re
.
match
(
r
'
^[a-zA-Z_][a-zA-Z0-9_]*$
'
,
name
):
raise
ValueError
(
f
"'
{
name
}
'
is not a valid C++ class name
"
)
if
not
isinstance
(
temperature_array
,
np
.
ndarray
)
or
not
isinstance
(
energy_density_array
,
np
.
ndarray
):
raise
TypeError
(
"
Temperature and energy arrays must be numpy arrays
"
)
self
.
name
=
name
self
.
name
=
name
self
.
T_array
=
temperature_array
self
.
T_array
=
temperature_array
self
.
E_array
=
energy_density_array
self
.
E_array
=
energy_density_array
# Prepare arrays and determine best method
# Prepare arrays and determine best method
self
.
data
=
prepare_interpolation_arrays
(
self
.
T_array
,
self
.
E_array
)
try
:
self
.
method
=
self
.
data
[
"
method
"
]
self
.
data
=
prepare_interpolation_arrays
(
T_array
=
self
.
T_array
,
E_array
=
self
.
E_array
,
verbose
=
False
)
self
.
method
=
self
.
data
[
"
method
"
]
# Store arrays for binary search (always available)
self
.
T_bs
=
self
.
data
[
"
T_bs
"
]
# Store arrays for binary search (always available)
self
.
E_bs
=
self
.
data
[
"
E_bs
"
]
self
.
T_bs
=
self
.
data
[
"
T_bs
"
]
self
.
E_bs
=
self
.
data
[
"
E_bs
"
]
# Store arrays for double lookup if available
if
self
.
method
==
"
double_lookup
"
:
# Store arrays for double lookup if available
self
.
T_eq
=
self
.
data
[
"
T_eq
"
]
if
self
.
method
==
"
double_lookup
"
:
self
.
E_neq
=
self
.
data
[
"
E_neq
"
]
self
.
T_eq
=
self
.
data
[
"
T_eq
"
]
self
.
E_eq
=
self
.
data
[
"
E_eq
"
]
self
.
E_neq
=
self
.
data
[
"
E_neq
"
]
self
.
inv_delta_E_eq
=
self
.
data
[
"
inv_delta_E_eq
"
]
self
.
E_eq
=
self
.
data
[
"
E_eq
"
]
self
.
idx_map
=
self
.
data
[
"
idx_map
"
]
self
.
inv_delta_E_eq
=
self
.
data
[
"
inv_delta_E_eq
"
]
self
.
has_double_lookup
=
True
self
.
idx_map
=
self
.
data
[
"
idx_map
"
]
else
:
self
.
has_double_lookup
=
True
self
.
has_double_lookup
=
False
else
:
self
.
has_double_lookup
=
False
except
Exception
as
e
:
raise
ValueError
(
f
"
Failed to prepare interpolation arrays:
{
e
}
"
)
from
e
@classmethod
@classmethod
def
from_material
(
cls
,
name
:
str
,
material
):
def
from_material
(
cls
,
name
:
str
,
material
):
...
...
This diff is collapsed.
Click to expand it.
src/pymatlib/core/interpolators.py
+
50
−
21
View file @
1f716b64
...
@@ -323,10 +323,23 @@ def create_idx_mapping(E_neq: np.ndarray, E_eq: np.ndarray) -> np.ndarray:
...
@@ -323,10 +323,23 @@ def create_idx_mapping(E_neq: np.ndarray, E_eq: np.ndarray) -> np.ndarray:
return
idx_map
.
astype
(
np
.
int32
)
return
idx_map
.
astype
(
np
.
int32
)
def
prepare_interpolation_arrays
(
T_array
:
np
.
ndarray
,
E_array
:
np
.
ndarray
)
->
dict
:
def
prepare_interpolation_arrays
(
T_array
:
np
.
ndarray
,
E_array
:
np
.
ndarray
,
verbose
=
False
)
->
dict
:
"""
"""
Validates input arrays and prepares data for interpolation.
Validates input arrays and prepares data for interpolation.
Returns a dictionary with arrays and metadata for the appropriate method.
Args:
T_array: Array of temperature values
E_array: Array of energy density values corresponding to temperatures
verbose: If True, prints diagnostic information during processing
Returns:
A dictionary with arrays and metadata for the appropriate interpolation method:
- Common keys:
'
T_bs
'
,
'
E_bs
'
,
'
method
'
,
'
is_equidistant
'
,
'
increment
'
- Additional keys for double_lookup method:
'
T_eq
'
,
'
E_neq
'
,
'
E_eq
'
,
'
inv_delta_E_eq
'
,
'
idx_map
'
Raises:
ValueError: If arrays don
'
t meet requirements for interpolation
"""
"""
# Convert to numpy arrays if not already
# Convert to numpy arrays if not already
T_array
=
np
.
asarray
(
T_array
)
T_array
=
np
.
asarray
(
T_array
)
...
@@ -364,43 +377,59 @@ def prepare_interpolation_arrays(T_array: np.ndarray, E_array: np.ndarray) -> di
...
@@ -364,43 +377,59 @@ def prepare_interpolation_arrays(T_array: np.ndarray, E_array: np.ndarray) -> di
# Flip arrays if temperature is in descending order
# Flip arrays if temperature is in descending order
if
T_decreasing
:
if
T_decreasing
:
print
(
"
Temperature array is descending, flipping arrays for processing
"
)
if
verbose
:
print
(
"
Temperature array is descending, flipping arrays for processing
"
)
T_bs
=
np
.
flip
(
T_bs
)
T_bs
=
np
.
flip
(
T_bs
)
E_bs
=
np
.
flip
(
E_bs
)
E_bs
=
np
.
flip
(
E_bs
)
# Check for strictly increasing values
has_warnings
=
False
try
:
try
:
check_strictly_increasing
(
T_bs
,
"
Temperature array
"
)
check_strictly_increasing
(
T_bs
,
"
Temperature array
"
)
check_strictly_increasing
(
E_bs
,
"
Energy density array
"
)
check_strictly_increasing
(
E_bs
,
"
Energy density array
"
)
except
ValueError
as
e
:
except
ValueError
as
e
:
print
(
f
"
Warning:
{
e
}
"
)
has_warnings
=
True
print
(
"
Continuing with interpolation, but results may be less accurate
"
)
if
verbose
:
print
(
f
"
Warning:
{
e
}
"
)
print
(
"
Continuing with interpolation, but results may be less accurate
"
)
# Use
your
existing check_equidistant function to determine if suitable for double lookup
# Use
the
existing check_equidistant function to determine if suitable for double lookup
T_incr
=
check_equidistant
(
T_bs
)
T_incr
=
check_equidistant
(
T_bs
)
is_equidistant
=
T_incr
!=
0.0
is_equidistant
=
T_incr
!=
0.0
# Initialize result with common fields
result
=
{
result
=
{
"
T_bs
"
:
T_bs
,
"
T_bs
"
:
T_bs
,
"
E_bs
"
:
E_bs
,
"
E_bs
"
:
E_bs
,
"
method
"
:
"
binary_search
"
"
method
"
:
"
binary_search
"
,
"
is_equidistant
"
:
is_equidistant
,
"
increment
"
:
T_incr
if
is_equidistant
else
0.0
,
"
has_warnings
"
:
has_warnings
}
}
# If temperature is equidistant, prepare for double lookup
# If temperature is equidistant, prepare for double lookup
if
is_equidistant
:
if
is_equidistant
:
print
(
f
"
Temperature array is equidistant with increment
{
T_incr
}
, using double lookup
"
)
if
verbose
:
# Create equidistant energy array and mapping
print
(
f
"
Temperature array is equidistant with increment
{
T_incr
}
, using double lookup
"
)
E_eq
,
inv_delta_E_eq
=
E_eq_from_E_neq
(
E_bs
)
idx_mapping
=
create_idx_mapping
(
E_bs
,
E_eq
)
try
:
# Create equidistant energy array and mapping
result
.
update
({
E_eq
,
inv_delta_E_eq
=
E_eq_from_E_neq
(
E_bs
)
"
T_eq
"
:
T_bs
,
idx_mapping
=
create_idx_mapping
(
E_bs
,
E_eq
)
"
E_neq
"
:
E_bs
,
"
E_eq
"
:
E_eq
,
result
.
update
({
"
inv_delta_E_eq
"
:
inv_delta_E_eq
,
"
T_eq
"
:
T_bs
,
"
idx_map
"
:
idx_mapping
,
"
E_neq
"
:
E_bs
,
"
method
"
:
"
double_lookup
"
"
E_eq
"
:
E_eq
,
})
"
inv_delta_E_eq
"
:
inv_delta_E_eq
,
else
:
"
idx_map
"
:
idx_mapping
,
"
method
"
:
"
double_lookup
"
})
except
Exception
as
e
:
if
verbose
:
print
(
f
"
Warning: Failed to create double lookup tables:
{
e
}
"
)
print
(
"
Falling back to binary search method
"
)
elif
verbose
:
print
(
"
Temperature array is not equidistant, using binary search
"
)
print
(
"
Temperature array is not equidistant, using binary search
"
)
return
result
return
result
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment