# Relative between FLAC3D zone indexes and zonearray index

**URL:** <https://forum.itascainternational.com/t/relative-between-flac3d-zone-indexes-and-zonearray-index/2281>\
**Category:** FLAC3D\
**Tags:** python\
**Created:** [November 19, 2025, 10:47am UTC](https://forum.itascainternational.com/t/relative-between-flac3d-zone-indexes-and-zonearray-index/2281 "2025-11-19T10:47:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![stephaneBeaussier](https://avatars.discourse-cdn.com/v4/letter/s/73ab20/32.png) [@stephaneBeaussier](https://forum.itascainternational.com/u/stephaneBeaussier)\
**Post date:** [November 19, 2025, 10:47am UTC](https://forum.itascainternational.com/t/relative-between-flac3d-zone-indexes-and-zonearray-index/2281/1 "2025-11-19T10:47:25Z")

</div>

Hi,

I have questions about the relation between the ids of zones and faces within FLAC and the indexing in the python numpy interface:

- What is the relation between the index of zones and the indexing within zonearray?

- What is the relation between a zone face ordering and the ordering when accesses through zonearray?

If I am asking these questions it is because I want to select faces by their face group but the interface is not accessible in zonearray. Therefore, I plan to find the face group by loop through the zones and using Zone.face\_in\_group(). But to perform my calculations using python loop is very inefficient so I would to be able to access the face informations through the numpy interface zonearray and therefore I need to make sure that the indexing between the two interface is consistent.

Thank you in advance

---

<div class="post-metadata">

**Author:** ![Theophile](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.itascainternational.com/theophile/32/299_2.png) [@Theophile](https://forum.itascainternational.com/u/Theophile)\
**Post date:** [November 19, 2025, 3:03pm UTC](https://forum.itascainternational.com/t/relative-between-flac3d-zone-indexes-and-zonearray-index/2281/2 "2025-11-19T15:03:45Z")

</div>

Hi!

Not an Itasca employee, so I cannot answer all of your questions.  
However, from my experience :

* * *

> For instance is the ordering of it.zonearray.ids() the same as the ordering of the array that is accessible through the numpy interface outside of the fact that FLAC is 1 indexed and numpy is 0 indexed?

Yes, ordering is consistant between Fish `zone.list` and both Python `it.zonearray.ids()` and `it.zone.list()`.

If you want to be sure, you can run the script below in a Flac3D session (feel free to test on other geometries).

```python
import itasca as it
# Create geometry
it.command("zone create tetrahedron size 1 2 3")
# Getting the ID list from Fish
it.command("""fish define get_zone_ids
    global zone_ids=zone.id(::zone.list)
end
""")
it.fish.call_function('get_zone_ids')
zone_ids_fish = it.fish.get('zone_ids')
# ID list from Python API
zone_ids_py = np.array([zone.id() for zone in it.zone.list()])
zone_ids_py_array = it.zonearray.ids()
assert (zone_ids_py ==zone_ids_py_array ).all()
assert (zone_ids_py ==zone_ids_fish ).all()

```

* * *

> It seems the case to me but I would like to know under which condition this relation is broken.

Unfortunately, I cannot help on this one.

* * *

> For example if I access the faces of a zone individually using Zone.faces() while it be in the same order as when access through it.zonearray.faces()

Yes!  
However, you have to take care that `it.zonearray.faces()` contains ghost point indices to be able to fit all faces in a single fixed shape array.  
In the example geometry I used, we have a mix of bricks and wedges:

 ![image](https://canada1.discourse-cdn.com/flex031/uploads/itasca/original/2X/1/1e2cbe3e0f2eee28ab4001917c51c1b021b9b407.png)

Some zones will thus have both rectangle and triangle faces.  
`it.zonearray.ids()` returns a harmonized (Nzones, Nfaces, Npoints)-shaped array and will fill in the missing points for the triangle faces with a `-1` index:

To illustrate this point, we can detail the geometry of the two lower zones (gridpoint marked with their indices in NumPy, for simplicity):

 ![image](https://canada1.discourse-cdn.com/flex031/uploads/itasca/original/2X/c/c39d733d64cac265aaa9f3d602f8297754282e9e.png)

The `it.zonarray.faces()` contains several types of zones: regular 6-sided ones with rectangular faces (in yellow below), and degenerated ones with triangular faces (in green) and with “missing” faces (in blue).

 ![image](https://canada1.discourse-cdn.com/flex031/uploads/itasca/original/2X/8/80a73d8bbb6072c7506be1b415a838760deca34a.png)

On the other side, `zone.faces()` will give strictly the gridpoints forming the zone faces.  
Running this Python code, we keep the exact same structure for 6-sided zones (yellow), but `-1` ghost points are not present anymore (green), neither are the “missing” faces (no blue).

```python
for zone in it.zone.list():
    for face in zone.faces():
        print([gp.id()-1 for gp in face])
    print()

```

 ![image](https://canada1.discourse-cdn.com/flex031/uploads/itasca/original/2X/6/66cb6137744d375c2b5c6643884a500bb98368a6.png)

* * *

> Is the ordering of faces defined in the documentation ([Zone — Itasca Software 9.0 documentation](https://docs.itascacg.com/itasca900/flac3d/docproject/source/elements/zones/zones.html?node3673#zone-field-data-names)) respected in the python zonearray interface?

Yes !  
You can see in the example above that the gridpoint ordering is preserved (see references for [bricks](https://docs.itascacg.com/itasca900/_images/brick.png) and [wedges](https://docs.itascacg.com/itasca900/_images/wwedge.png)).

> the documentation say say that “the ordering is relative to the ordering of the itasca.gridpointarray return values." and frankly I don’t understand what that means.

From my understanding, this specifies that faces are not identified as such (i.e., no `Face` object) but through the gridpoints they are made of. A face can be seen as a set of ordered points. In Flac3D, a face is identified by its gridpoints ordered clockwise when looking at the face from outside its zone.

Hope it helped, cheers!

Theophile

---

<div class="post-metadata">

**Author:** ![stephaneBeaussier](https://avatars.discourse-cdn.com/v4/letter/s/73ab20/32.png) [@stephaneBeaussier](https://forum.itascainternational.com/u/stephaneBeaussier)\
**Post date:** [November 19, 2025, 5:44pm UTC](https://forum.itascainternational.com/t/relative-between-flac3d-zone-indexes-and-zonearray-index/2281/3 "2025-11-19T17:44:09Z")

</div>

Thank you for the reply Theophile, that clarify a lot of things!

To add to your extensive explanation, I did some check with by comparing the face normales with ones I calculated using a cross product which is depending of ordering.

if you get the gridpoints from Zone.faces() the increasing index correspond to an anticlockwise ordering to be consistent with the FLAC face orientation (i.e. faces normal are pointing outward).

For example assuming a tetrahedral face, the indexes of the gridpoint that are given by Zone.faces() should be considered like this:

```bash
3---<--2
| | -> normal pointing toward the inside of the zone
| |
0--->--1

1--->--2
| | -> normal pointing toward the outside of the zone (FLAC convention)
| |
0---<--3

```

---

<div class="post-metadata">

**Author:** ![Theophile](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.itascainternational.com/theophile/32/299_2.png) [@Theophile](https://forum.itascainternational.com/u/Theophile)\
**Post date:** [November 20, 2025, 10:27am UTC](https://forum.itascainternational.com/t/relative-between-flac3d-zone-indexes-and-zonearray-index/2281/4 "2025-11-20T10:27:23Z")

</div>

Glad it helped!

I agree with you: gridpoints are indeed ordered clockwise, giving normal vectors pointing outwards.

Cheers

Theophile

---

<div class="post-metadata">

**Author:** ![stephaneBeaussier](https://avatars.discourse-cdn.com/v4/letter/s/73ab20/32.png) [@stephaneBeaussier](https://forum.itascainternational.com/u/stephaneBeaussier)\
**Post date:** [November 21, 2025, 11:19am UTC](https://forum.itascainternational.com/t/relative-between-flac3d-zone-indexes-and-zonearray-index/2281/5 "2025-11-21T11:19:54Z")

</div>

After some check I can complement the answer of Theophile one of my question:

> For instance is the ordering of it.zonearray.ids() the same as the ordering of the array that is accessible through the numpy interface outside of the fact that FLAC is 1 indexed and numpy is 0 indexed?

This remains true as long as you don’t start deleting zones from example with zone delete command. In this case the counter of id for zone does not get reset and new zone will have in id that following still the counter as if the zone were not delete and therefore deviate from the indexing in numpy array.

Gridpoints follows the same rules.

---

<div class="post-metadata">

**Author:** ![Theophile](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.itascainternational.com/theophile/32/299_2.png) [@Theophile](https://forum.itascainternational.com/u/Theophile)\
**Post date:** [November 21, 2025, 11:57am UTC](https://forum.itascainternational.com/t/relative-between-flac3d-zone-indexes-and-zonearray-index/2281/6 "2025-11-21T11:57:48Z")

</div>

Thanks for the feedback, @stephaneBeaussier !

Theophile
