diff --git a/CHANGELOG.md b/CHANGELOG.md
index bb4a59f6..d8374f81 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,20 @@
-
-# [v0.20.9](https://github.com/gdsfactory/kfactory/releases/tag/v0.20.9) - 10 Oct 2024
+
+# [v0.21.1](https://github.com/gdsfactory/kfactory/releases/tag/v0.21.1) - 11 Oct 2024
+
+# What's Changed
+
+## New
+
+- add instance iterator which returns coord plus port [#491](https://github.com/gdsfactory/kfactory/pull/491)
+
+**Full Changelog**: https://github.com/gdsfactory/kfactory/compare/v0.21.0...v0.21.1
+
+
+[Changes][v0.21.1]
+
+
+
+# [v0.21.0](https://github.com/gdsfactory/kfactory/releases/tag/v0.21.0) - 10 Oct 2024
# What's Changed
@@ -13,10 +28,10 @@
- fix naming of cells from vinsts [#489](https://github.com/gdsfactory/kfactory/pull/489)
- fix route_bundle bbox ignore for single route (or matching opposite side) [#488](https://github.com/gdsfactory/kfactory/pull/488)
-**Full Changelog**: https://github.com/gdsfactory/kfactory/compare/v0.20.8...v0.20.9
+**Full Changelog**: https://github.com/gdsfactory/kfactory/compare/v0.20.8...v0.21.0
-[Changes][v0.20.9]
+[Changes][v0.21.0]
@@ -1168,7 +1183,8 @@
[Changes][v0.4.0]
-[v0.20.9]: https://github.com/gdsfactory/kfactory/compare/v0.20.8...v0.20.9
+[v0.21.1]: https://github.com/gdsfactory/kfactory/compare/v0.21.0...v0.21.1
+[v0.21.0]: https://github.com/gdsfactory/kfactory/compare/v0.20.8...v0.21.0
[v0.20.8]: https://github.com/gdsfactory/kfactory/compare/v0.20.7...v0.20.8
[v0.20.7]: https://github.com/gdsfactory/kfactory/compare/v0.20.6...v0.20.7
[v0.20.6]: https://github.com/gdsfactory/kfactory/compare/v0.20.5...v0.20.6
diff --git a/src/kfactory/kcell.py b/src/kfactory/kcell.py
index 423b780a..ac004371 100644
--- a/src/kfactory/kcell.py
+++ b/src/kfactory/kcell.py
@@ -1373,6 +1373,48 @@ def __iter__(self) -> Iterator[Port]:
for p in self.cell_ports
)
+ def each_by_array_coord(self) -> Iterator[tuple[int, int, Port]]:
+ if not self.instance.is_regular_array():
+ if not self.instance.is_complex():
+ yield from (
+ (0, 0, p.copy(self.instance.trans)) for p in self.cell_ports
+ )
+ else:
+ yield from (
+ (0, 0, p.copy(self.instance.dcplx_trans)) for p in self.cell_ports
+ )
+ else:
+ if not self.instance.is_complex():
+ yield from (
+ (
+ i_a,
+ i_b,
+ p.copy(
+ kdb.Trans(self.instance.a * i_a + self.instance.b * i_b)
+ * self.instance.trans
+ ),
+ )
+ for i_a in range(self.instance.na)
+ for i_b in range(self.instance.nb)
+ for p in self.cell_ports
+ )
+ else:
+ yield from (
+ (
+ i_a,
+ i_b,
+ p.copy(
+ kdb.DCplxTrans(
+ self.instance.da * i_a + self.instance.db * i_b
+ )
+ * self.instance.dcplx_trans
+ ),
+ )
+ for i_a in range(self.instance.na)
+ for i_b in range(self.instance.nb)
+ for p in self.cell_ports
+ )
+
def __repr__(self) -> str:
"""String representation.