Arbitrary shape GridGraph

Admittedly the implementation below is not as simple or efficient as I wished. Some of the visualizations are a bit messy, but I think it works correctly.

Basically it tracks the planar graph boundary and tries to add new edges in regularity-admitting locations. Regular planar tilings are trivially present, but this code also generates Platonic graphs corresponding to regular Platonic polyhedra (these close on themselves, and don't have a "boundary"), and graphs corresponding to tilings in hyperbolic geometry.

Module[{regularGraphBoundary, takeClosestVertexGroup, 
  selectAdmissableArcs, addNewEdges, tryAddPolygon},
 regularGraphBoundary[g_Graph, nvertices_Integer] :=
  Graph[First /@
    Select[Tally[Sort /@ Flatten@FindCycle[g, {nvertices}, All]], 
     Last@# == 1 &]];

 takeClosestVertexGroup[g_Graph, groups_List] :=
  First@TakeSmallestBy[
    groups, Min[GraphDistance[g, 1, #] & /@ #] &, 1];

 selectAdmissableArcs[g_Graph, candidates_List, nvertices_Integer, 
   targetdegree_Integer] :=
  Select[
   candidates,
   VertexDegree[g, First@#] < targetdegree &&
     And @@ (VertexDegree[g, #] == targetdegree & /@ #[[2 ;; -2]]) && 
     VertexDegree[g, Last@#] < targetdegree &];

 addNewEdges[g_Graph, oldvertices_List, nvertices_Integer] :=
  GraphUnion[g,
   Graph[UndirectedEdge @@@
     Partition[{First@oldvertices,
       Sequence @@ (Unique[] & /@ 
          Range[nvertices - Length@oldvertices]),
       Last@oldvertices},
      2, 1]]];

 tryAddPolygon[g_Graph, vertices_Integer, targetdegree_Integer] :=
  Module[{graphboundary, admissablearcgroups},
   graphboundary = regularGraphBoundary[g, vertices];

   If[EmptyGraphQ@graphboundary,
    g,

    admissablearcgroups =
     Flatten[
      Table[
       selectAdmissableArcs[g, 
        Partition[First /@ First@FindCycle@graphboundary, n, 1, 1],
        vertices, targetdegree],
       {n, vertices, 2, -1}],
      1];

    addNewEdges[
     g, takeClosestVertexGroup[g, admissablearcgroups], vertices]]];

 Grid[Table[
   HighlightGraph[#, regularGraphBoundary[#, v]] &@
    Nest[tryAddPolygon[#, v, d] &, CycleGraph[v], 150], {v, 3, 7}, {d, 
    3, 7}], Frame -> All]]

enter image description here


IGraph/M now has some new lattice graph generation features that might be useful (though not every graph of the type you describe can be generated through these functions).

Here's a demo through a few examples:

IGTriangularLattice[5]

Mathematica graphics

IGTriangularLattice[{4, 5}]

Mathematica graphics

IGBetheLattice[5]

Mathematica graphics

There is IGLatticeMesh which uses (a post-processed version of) Mathematica's built-in periodic tiling data to generate various meshes. These can be converted to graphs using IGMeshGraph, or to face-face adjacency graphs (i.e. the dual) using IGMeshCellAdjacencyGraph[mesh, 2, VertexCoordinates -> Automatic].

IGLatticeMesh["Hexagonal"]

Mathematica graphics

IGLatticeMesh["Hexagonal", {3, 2}]

Mathematica graphics

IGLatticeMesh["Hexagonal", Polygon@CirclePoints[4, 6]]

Mathematica graphics

IGLatticeMesh["Trihexagonal"]

Mathematica graphics

Convert to graphs:

IGMeshGraph[%]

Mathematica graphics

IGMeshCellAdjacencyGraph[%%, 2, VertexCoordinates -> Automatic]

Mathematica graphics

In this last graph, not all non-boundary vertices have the same number of neighbours. I included it as an illustration of how to extract the dual lattice, which may be useful for some other tilings.