Skip to content

Commit aff335a

Browse files
committed
o More missed conversions
1 parent 1efbe0f commit aff335a

File tree

3 files changed

+415
-187
lines changed

3 files changed

+415
-187
lines changed

test/test_exodus.py

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,39 @@
77

88
current_path = Path(os.path.dirname(os.path.realpath(__file__)))
99

10-
class TestExodus:
11-
exo_filename = current_path / "meshfiles" / "exodus" / "outCSne8" / "outCSne8.g"
12-
exo2_filename = current_path / "meshfiles" / "exodus" / "mixed" / "mixed.exo"
13-
14-
def test_read_exodus(self):
15-
"""Read an exodus file and writes a exodus file."""
16-
uxgrid = ux.open_grid(self.exo_filename)
17-
# Add assertions or checks as needed
18-
assert uxgrid is not None # Example assertion
19-
20-
def test_init_verts(self):
21-
"""Create a uxarray grid from vertices and saves a 1 face exodus file."""
22-
verts = [[[0, 0], [2, 0], [0, 2], [2, 2]]]
23-
uxgrid = ux.open_grid(verts)
24-
# Add assertions or checks as needed
25-
assert uxgrid is not None # Example assertion
26-
27-
def test_encode_exodus(self):
28-
"""Read a UGRID dataset and encode that as an Exodus format."""
29-
uxgrid = ux.open_grid(self.exo_filename)
30-
# Add encoding logic and assertions as needed
31-
pass # Placeholder for actual implementation
32-
33-
def test_mixed_exodus(self):
34-
"""Read/write an exodus file with two types of faces (triangle and quadrilaterals) and writes a ugrid file."""
35-
uxgrid = ux.open_grid(self.exo2_filename)
36-
37-
uxgrid.encode_as("UGRID")
38-
uxgrid.encode_as("Exodus")
39-
# Add assertions or checks as needed
40-
41-
def test_standardized_dtype_and_fill(self):
42-
"""Test to see if Mesh2_Face_Nodes uses the expected integer datatype and expected fill value as set in constants.py."""
43-
uxgrid = ux.open_grid(self.exo2_filename)
44-
45-
assert uxgrid.face_node_connectivity.dtype == INT_DTYPE
46-
assert uxgrid.face_node_connectivity._FillValue == INT_FILL_VALUE
10+
exo_filename = current_path / "meshfiles" / "exodus" / "outCSne8" / "outCSne8.g"
11+
exo2_filename = current_path / "meshfiles" / "exodus" / "mixed" / "mixed.exo"
12+
13+
def test_read_exodus():
14+
"""Read an exodus file and writes a exodus file."""
15+
uxgrid = ux.open_grid(exo_filename)
16+
# Add assertions or checks as needed
17+
assert uxgrid is not None # Example assertion
18+
19+
def test_init_verts():
20+
"""Create a uxarray grid from vertices and saves a 1 face exodus file."""
21+
verts = [[[0, 0], [2, 0], [0, 2], [2, 2]]]
22+
uxgrid = ux.open_grid(verts)
23+
# Add assertions or checks as needed
24+
assert uxgrid is not None # Example assertion
25+
26+
def test_encode_exodus():
27+
"""Read a UGRID dataset and encode that as an Exodus format."""
28+
uxgrid = ux.open_grid(exo_filename)
29+
# Add encoding logic and assertions as needed
30+
pass # Placeholder for actual implementation
31+
32+
def test_mixed_exodus():
33+
"""Read/write an exodus file with two types of faces (triangle and quadrilaterals) and writes a ugrid file."""
34+
uxgrid = ux.open_grid(exo2_filename)
35+
36+
uxgrid.encode_as("UGRID")
37+
uxgrid.encode_as("Exodus")
38+
# Add assertions or checks as needed
39+
40+
def test_standardized_dtype_and_fill():
41+
"""Test to see if Mesh2_Face_Nodes uses the expected integer datatype and expected fill value as set in constants.py."""
42+
uxgrid = ux.open_grid(exo2_filename)
43+
44+
assert uxgrid.face_node_connectivity.dtype == INT_DTYPE
45+
assert uxgrid.face_node_connectivity._FillValue == INT_FILL_VALUE

test/test_integrate.py

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,238 @@ def test_get_zonal_faces_weight_at_constLat_equator():
470470

471471

472472

473+
# A error will be raise if we don't set is_latlonface=True since the face_2 will be concave if
474+
# It's edges are all GCA
475+
with pytest.raises(ValueError):
476+
_get_zonal_faces_weight_at_constLat(np.array([
477+
face_0_edge_nodes, face_1_edge_nodes, face_2_edge_nodes
478+
]), np.deg2rad(20), latlon_bounds)
479+
480+
481+
def test_get_zonal_faces_weight_at_constLat_regular():
482+
face_0 = [[1.7 * np.pi, 0.25 * np.pi], [1.7 * np.pi, 0.0],
483+
[0.3 * np.pi, 0.0], [0.3 * np.pi, 0.25 * np.pi]]
484+
face_1 = [[0.4 * np.pi, 0.3 * np.pi], [0.4 * np.pi, 0.0],
485+
[0.5 * np.pi, 0.0], [0.5 * np.pi, 0.3 * np.pi]]
486+
face_2 = [[0.5 * np.pi, 0.25 * np.pi], [0.5 * np.pi, 0.0], [np.pi, 0.0],
487+
[np.pi, 0.25 * np.pi]]
488+
face_3 = [[1.2 * np.pi, 0.25 * np.pi], [1.2 * np.pi, 0.0],
489+
[1.6 * np.pi, -0.01 * np.pi], [1.6 * np.pi, 0.25 * np.pi]]
490+
491+
# Convert the face vertices to xyz coordinates
492+
face_0 = [_lonlat_rad_to_xyz(*v) for v in face_0]
493+
face_1 = [_lonlat_rad_to_xyz(*v) for v in face_1]
494+
face_2 = [_lonlat_rad_to_xyz(*v) for v in face_2]
495+
face_3 = [_lonlat_rad_to_xyz(*v) for v in face_3]
496+
497+
face_0_edge_nodes = np.array([[face_0[0], face_0[1]],
498+
[face_0[1], face_0[2]],
499+
[face_0[2], face_0[3]],
500+
[face_0[3], face_0[0]]])
501+
face_1_edge_nodes = np.array([[face_1[0], face_1[1]],
502+
[face_1[1], face_1[2]],
503+
[face_1[2], face_1[3]],
504+
[face_1[3], face_1[0]]])
505+
face_2_edge_nodes = np.array([[face_2[0], face_2[1]],
506+
[face_2[1], face_2[2]],
507+
[face_2[2], face_2[3]],
508+
[face_2[3], face_2[0]]])
509+
face_3_edge_nodes = np.array([[face_3[0], face_3[1]],
510+
[face_3[1], face_3[2]],
511+
[face_3[2], face_3[3]],
512+
[face_3[3], face_3[0]]])
513+
514+
face_0_latlon_bound = np.array([[0.0, 0.25 * np.pi],
515+
[1.7 * np.pi, 0.3 * np.pi]])
516+
face_1_latlon_bound = np.array([[0, 0.3 * np.pi],
517+
[0.4 * np.pi, 0.5 * np.pi]])
518+
face_2_latlon_bound = np.array([[0.0, 0.25 * np.pi],
519+
[0.5 * np.pi, np.pi]])
520+
face_3_latlon_bound = np.array([[-0.01 * np.pi, 0.25 * np.pi],
521+
[1.2 * np.pi, 1.6 * np.pi]])
522+
523+
latlon_bounds = np.array([
524+
face_0_latlon_bound, face_1_latlon_bound, face_2_latlon_bound,
525+
face_3_latlon_bound
526+
])
527+
528+
expected_weight_df = pd.DataFrame({
529+
'face_index': [0, 1, 2, 3],
530+
'weight': [0.375, 0.0625, 0.3125, 0.25]
531+
})
532+
533+
# Assert the results is the same to the 3 decimal places
534+
weight_df = _get_zonal_faces_weight_at_constLat(np.array([
535+
face_0_edge_nodes, face_1_edge_nodes, face_2_edge_nodes,
536+
face_3_edge_nodes
537+
]), np.sin(0.1 * np.pi), latlon_bounds)
538+
539+
nt.assert_array_almost_equal(weight_df, expected_weight_df, decimal=3)
540+
541+
def test_get_zonal_faces_weight_at_constLat_on_pole_one_face():
542+
#The face is touching the pole, so the weight should be 1.0 since there's only 1 face
543+
face_edges_cart = np.array([[
544+
[[-5.22644277e-02, -5.22644277e-02, -9.97264689e-01],
545+
[-5.23359562e-02, -6.40930613e-18, -9.98629535e-01]],
546+
547+
[[-5.23359562e-02, -6.40930613e-18, -9.98629535e-01],
548+
[6.12323400e-17, 0.00000000e+00, -1.00000000e+00]],
549+
550+
[[6.12323400e-17, 0.00000000e+00, -1.00000000e+00],
551+
[3.20465306e-18, -5.23359562e-02, -9.98629535e-01]],
552+
553+
[[3.20465306e-18, -5.23359562e-02, -9.98629535e-01],
554+
[-5.22644277e-02, -5.22644277e-02, -9.97264689e-01]]
555+
]])
556+
557+
# Corrected face_bounds
558+
face_bounds = np.array([
559+
[-1.57079633, -1.4968158],
560+
[3.14159265, 0.]
561+
])
562+
constLat_cart = -1
563+
564+
weight_df = _get_zonal_faces_weight_at_constLat(face_edges_cart, constLat_cart, face_bounds)
565+
# Define the expected DataFrame
566+
expected_weight_df = pd.DataFrame({"face_index": [0], "weight": [1.0]})
567+
568+
# Assert that the resulting should have weight is 1.0
569+
pd.testing.assert_frame_equal(weight_df, expected_weight_df)
570+
571+
572+
def test_get_zonal_faces_weight_at_constLat_on_pole_faces():
573+
#there will be 4 faces touching the pole, so the weight should be 0.25 for each face
574+
face_edges_cart = np.array([
575+
[
576+
[[5.22644277e-02, -5.22644277e-02, 9.97264689e-01], [5.23359562e-02, 0.00000000e+00, 9.98629535e-01]],
577+
[[5.23359562e-02, 0.00000000e+00, 9.98629535e-01], [6.12323400e-17, 0.00000000e+00, 1.00000000e+00]],
578+
[[6.12323400e-17, 0.00000000e+00, 1.00000000e+00], [3.20465306e-18, -5.23359562e-02, 9.98629535e-01]],
579+
[[3.20465306e-18, -5.23359562e-02, 9.98629535e-01], [5.22644277e-02, -5.22644277e-02, 9.97264689e-01]]
580+
],
581+
[
582+
[[5.23359562e-02, 0.00000000e+00, 9.98629535e-01], [5.22644277e-02, 5.22644277e-02, 9.97264689e-01]],
583+
[[5.22644277e-02, 5.22644277e-02, 9.97264689e-01], [3.20465306e-18, 5.23359562e-02, 9.98629535e-01]],
584+
[[3.20465306e-18, 5.23359562e-02, 9.98629535e-01], [6.12323400e-17, 0.00000000e+00, 1.00000000e+00]],
585+
[[6.12323400e-17, 0.00000000e+00, 1.00000000e+00], [5.23359562e-02, 0.00000000e+00, 9.98629535e-01]]
586+
],
587+
[
588+
[[3.20465306e-18, -5.23359562e-02, 9.98629535e-01], [6.12323400e-17, 0.00000000e+00, 1.00000000e+00]],
589+
[[6.12323400e-17, 0.00000000e+00, 1.00000000e+00], [-5.23359562e-02, -6.40930613e-18, 9.98629535e-01]],
590+
[[-5.23359562e-02, -6.40930613e-18, 9.98629535e-01],
591+
[-5.22644277e-02, -5.22644277e-02, 9.97264689e-01]],
592+
[[-5.22644277e-02, -5.22644277e-02, 9.97264689e-01], [3.20465306e-18, -5.23359562e-02, 9.98629535e-01]]
593+
],
594+
[
595+
[[6.12323400e-17, 0.00000000e+00, 1.00000000e+00], [3.20465306e-18, 5.23359562e-02, 9.98629535e-01]],
596+
[[3.20465306e-18, 5.23359562e-02, 9.98629535e-01], [-5.22644277e-02, 5.22644277e-02, 9.97264689e-01]],
597+
[[-5.22644277e-02, 5.22644277e-02, 9.97264689e-01], [-5.23359562e-02, -6.40930613e-18, 9.98629535e-01]],
598+
[[-5.23359562e-02, -6.40930613e-18, 9.98629535e-01], [6.12323400e-17, 0.00000000e+00, 1.00000000e+00]]
599+
]
600+
])
601+
602+
face_bounds = np.array([
603+
[[1.4968158, 1.57079633], [4.71238898, 0.0]],
604+
[[1.4968158, 1.57079633], [0.0, 1.57079633]],
605+
[[1.4968158, 1.57079633], [3.14159265, 0.0]],
606+
[[1.4968158, 1.57079633], [0.0, 3.14159265]]
607+
])
608+
609+
constLat_cart = 1.0
610+
611+
weight_df = _get_zonal_faces_weight_at_constLat(face_edges_cart, constLat_cart, face_bounds)
612+
# Define the expected DataFrame
613+
expected_weight_df = pd.DataFrame({
614+
'face_index': [0, 1, 2, 3],
615+
'weight': [0.25, 0.25, 0.25, 0.25]
616+
})
617+
618+
# Assert that the DataFrame matches the expected DataFrame
619+
pd.testing.assert_frame_equal(weight_df, expected_weight_df)
620+
621+
622+
def test_get_zonal_face_interval_pole():
623+
#The face is touching the pole
624+
face_edges_cart = np.array([
625+
[[-5.22644277e-02, -5.22644277e-02, -9.97264689e-01],
626+
[-5.23359562e-02, -6.40930613e-18, -9.98629535e-01]],
627+
628+
[[-5.23359562e-02, -6.40930613e-18, -9.98629535e-01],
629+
[6.12323400e-17, 0.00000000e+00, -1.00000000e+00]],
630+
631+
[[6.12323400e-17, 0.00000000e+00, -1.00000000e+00],
632+
[3.20465306e-18, -5.23359562e-02, -9.98629535e-01]],
633+
634+
[[3.20465306e-18, -5.23359562e-02, -9.98629535e-01],
635+
[-5.22644277e-02, -5.22644277e-02, -9.97264689e-01]]
636+
])
637+
638+
# Corrected face_bounds
639+
face_bounds = np.array([
640+
[-1.57079633, -1.4968158],
641+
[3.14159265, 0.]
642+
])
643+
constLat_cart = -0.9986295347545738
644+
645+
weight_df = _get_zonal_face_interval(face_edges_cart, constLat_cart, face_bounds)
646+
# No Nan values should be present in the weight_df
647+
assert (not weight_df.isnull().values.any())
648+
649+
650+
def test_get_zonal_faces_weight_at_constLat_latlonface():
651+
face_0 = [[np.deg2rad(350), np.deg2rad(40)], [np.deg2rad(350), np.deg2rad(20)],
652+
[np.deg2rad(10), np.deg2rad(20)], [np.deg2rad(10), np.deg2rad(40)]]
653+
face_1 = [[np.deg2rad(5), np.deg2rad(20)], [np.deg2rad(5), np.deg2rad(10)],
654+
[np.deg2rad(25), np.deg2rad(10)], [np.deg2rad(25), np.deg2rad(20)]]
655+
face_2 = [[np.deg2rad(30), np.deg2rad(40)], [np.deg2rad(30), np.deg2rad(20)],
656+
[np.deg2rad(40), np.deg2rad(20)], [np.deg2rad(40), np.deg2rad(40)]]
657+
658+
# Convert the face vertices to xyz coordinates
659+
face_0 = [_lonlat_rad_to_xyz(*v) for v in face_0]
660+
face_1 = [_lonlat_rad_to_xyz(*v) for v in face_1]
661+
face_2 = [_lonlat_rad_to_xyz(*v) for v in face_2]
662+
663+
664+
face_0_edge_nodes = np.array([[face_0[0], face_0[1]],
665+
[face_0[1], face_0[2]],
666+
[face_0[2], face_0[3]],
667+
[face_0[3], face_0[0]]])
668+
face_1_edge_nodes = np.array([[face_1[0], face_1[1]],
669+
[face_1[1], face_1[2]],
670+
[face_1[2], face_1[3]],
671+
[face_1[3], face_1[0]]])
672+
face_2_edge_nodes = np.array([[face_2[0], face_2[1]],
673+
[face_2[1], face_2[2]],
674+
[face_2[2], face_2[3]],
675+
[face_2[3], face_2[0]]])
676+
677+
face_0_latlon_bound = np.array([[np.deg2rad(20), np.deg2rad(40)],
678+
[np.deg2rad(350), np.deg2rad(10)]])
679+
face_1_latlon_bound = np.array([[np.deg2rad(10), np.deg2rad(20)],
680+
[np.deg2rad(5), np.deg2rad(25)]])
681+
face_2_latlon_bound = np.array([[np.deg2rad(20), np.deg2rad(40)],
682+
[np.deg2rad(30), np.deg2rad(40)]])
683+
684+
685+
latlon_bounds = np.array([
686+
face_0_latlon_bound, face_1_latlon_bound, face_2_latlon_bound
687+
])
688+
689+
sum = 17.5 + 17.5 + 10
690+
expected_weight_df = pd.DataFrame({
691+
'face_index': [0, 1, 2],
692+
'weight': [17.5 / sum, 17.5/sum, 10/sum]
693+
})
694+
695+
# Assert the results is the same to the 3 decimal places
696+
weight_df = _get_zonal_faces_weight_at_constLat(np.array([
697+
face_0_edge_nodes, face_1_edge_nodes, face_2_edge_nodes
698+
]), np.sin(np.deg2rad(20)), latlon_bounds, is_latlonface=True)
699+
700+
701+
nt.assert_array_almost_equal(weight_df, expected_weight_df, decimal=3)
702+
703+
704+
473705
# A error will be raise if we don't set is_latlonface=True since the face_2 will be concave if
474706
# It's edges are all GCA
475707
with pytest.raises(ValueError):

0 commit comments

Comments
 (0)