1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
|
/**************************************************************************
* *
* Regina - A Normal Surface Theory Calculator *
* Computational Engine *
* *
* Copyright (c) 1999-2025, Ben Burton *
* For further details contact Ben Burton (bab@debian.org). *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* As an exception, when this program is distributed through (i) the *
* App Store by Apple Inc.; (ii) the Mac App Store by Apple Inc.; or *
* (iii) Google Play by Google Inc., then that store may impose any *
* digital rights management, device limits and/or redistribution *
* restrictions that are required by its terms of service. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
**************************************************************************/
/*! \file triangulation/example4.h
* \brief Offers some example 4-dimensional triangulations as starting
* points for testing code or getting used to Regina.
*/
#ifndef __REGINA_EXAMPLE4_H
#ifndef __DOXYGEN
#define __REGINA_EXAMPLE4_H
#endif
#include "regina-core.h"
#include "link/link.h"
#include "triangulation/dim4.h"
#include "triangulation/detail/example.h"
namespace regina {
/**
* Offers routines for constructing a variety of sample 4-dimensional
* triangulations.
*
* This is a specialisation of the generic Example class template; see the
* generic Example template documentation for a general overview of how the
* example triangulation classes work. In Python, you can read this generic
* documentation by looking at a higher dimension: try `help(Example5)`.
*
* This 4-dimensional specialisation offers significant extra functionality,
* by providing several more hard-coded and parameterised constructions.
*
* \ingroup triangulation
*/
template <>
class Example<4> : public detail::ExampleBase<4> {
public:
/**
* \name Closed Triangulations
*/
/*@{*/
/**
* Returns a two-pentachoron triangulation of the 4-sphere.
* This is identical to calling the generic routine sphere().
*
* \return a two-pentachoron 4-sphere.
*/
static Triangulation<4> fourSphere();
/**
* Returns the standard six-pentachoron triangulation of the 4-sphere
* as the boundary of a 5-simplex.
* This is identical to calling the generic routine simplicialSphere().
*
* \return the standard simplicial 4-sphere.
*/
static Triangulation<4> simplicialFourSphere();
/**
* Returns a four-pentachoron triangulation of real projective
* 4-space.
*
* \return real projective 4-space.
*/
static Triangulation<4> rp4();
/**
* Returns a four-pentachoron triangulation of the standard
* complex projective plane. This triangulation is minimal.
*
* Under the orientation convention that we use for intersection
* forms, this triangulation gives the "plain" `CP²` with
* intersection form [1], not the reflected `CP²` with
* intersection form [-1].
*
* \return the standard complex projective plane.
*/
static Triangulation<4> cp2();
/**
* Returns a six-pentachoron triangulation of the standard product
* `S² × S²`. This triangulation is minimal.
*
* \return the standard product of two 2-spheres.
*/
static Triangulation<4> s2xs2();
/**
* Returns a six-pentachoron triangulation of the twisted product
* `S² x~ S²`.
* This manifold is diffeomorphic to `CP² # -CP²`, where
* `-CP²` denotes `CP²` with its orientation reversed.
* This triangulation is minimal.
*
* \return the twisted product of two 2-spheres.
*/
static Triangulation<4> s2xs2Twisted();
/**
* Returns a two-pentachoron triangulation of the product space
* `S³ × S¹`. This is identical to calling the
* generic routine sphereBundle().
*
* \return the product `S³ × S¹`.
*/
static Triangulation<4> s3xs1();
/**
* Returns a two-pentachoron triangulation of the twisted product
* space `S³ x~ S¹`. This is identical to calling the
* generic routine twistedSphereBundle().
*
* \return the twisted product `S³ x~ S¹`.
*/
static Triangulation<4> s3xs1Twisted();
/**
* Returns a triangulation of the standard 4-torus; that is, the
* product space `T² × T²`.
*
* \return the product space `T² × T²`.
*/
static Triangulation<4> fourTorus();
/**
* Returns a triangulation of the standard K3 surface.
*
* Be warned: this triangulation is fairly large.
*
* \return the K3 surface.
*/
static Triangulation<4> k3();
/*@}*/
/**
* (end: Closed Triangulations)
*/
/**
* \name Ideal Triangulations
*/
/*@{*/
/**
* Returns a two-pentachoron triangulation of a Cappell-Shaneson 2-knot
* complement in the 4-sphere. This triangulation is described and
* analysed in "Triangulating a Cappell-Shaneson knot complement",
* Budney, Burton and Hillman, Mathematical Research Letters 19 (2012),
* no. 5, 1117-1126.
*
* \return a Cappell-Shaneson 2-knot complement.
*/
static Triangulation<4> cappellShaneson();
/*@}*/
/**
* (end: Ideal Triangulations)
*/
/**
* \name Constructions from 3-Manifold Triangulations and Links
*/
/*@{*/
/**
* Returns a triangulation of the product `M × I`,
* where \a M is the given 3-manifold triangulation.
*
* The boundary of this product will consist of two copies of \a M,
* both combinatorially isomorphic to the original triangulation.
* If \a n is the number of tetrahedra in \a M, then the first copy of
* \a M on the boundary is obtained by mapping vertices 0,1,2,3 of
* tetrahedron \a i of \a M to vertices 0,1,2,3 of pentachoron \a i,
* and the second copy is obtained by mapping vertices 0,1,2,3 of
* tetrahedron \a i of \a M to vertices 0,1,2,3 of pentachoron \a n+i.
*
* The product is created as follows: for each original tetrahedron of
* \a M we build a tetrahedral prism containing 82 pentachora, and we
* then glue these prisms together in a manner that follows the
* gluings of the original tetrahedra. It is highly recommended that
* you call Triangulation<4>::simplify() afterwards if you do not need
* to preserve the combinatorial structure.
*
* For any simplex in \a base that is locked, all of the pentachora
* and internal facets of the corresponding prism will also be locked.
* For any triangular facet of \a base that is locked, all of the
* tetrahedral facets on the corresponding prism wall(s) will likewise
* be locked.
*
* Note that the current construction does _not_ give an oriented
* triangulation (due to the specific choice of labelling); this may
* change in a future version of Regina.
*
* \warning If the given 3-manifold triangulation has ideal boundary,
* then you will obtain an invalid 4-manifold triangulation as a result.
*
* \param base the 3-manifold triangulation \a M, as described above.
* \return the product `M × I`.
*/
static Triangulation<4> iBundle(const Triangulation<3>& base);
/**
* Returns a triangulation of the product `M × S1`,
* where \a M is the given 3-manifold triangulation.
* This simply calls iBundle() and then glues together the
* two copies of \a M on the boundary.
*
* The product is created as follows. For each original tetrahedron of
* \a M, we build a tetrahedral prism containing 82 pentachora. We then
* glue these prisms together in a manner that follows the gluings of
* the original tetrahedra, and we also glue together the two
* tetrahedra at each end of every prism. It is highly recommended
* that you call Triangulation<4>::simplify() afterwards if you do not
* need to preserve the combinatorial structure.
*
* For any simplex in \a base that is locked, all of the pentachora
* and internal facets of the corresponding prism will also be locked,
* as well as the two tetrahedra at each end of the prism (which will
* be glued together, as explained above). For any triangular facet of
* \a base that is locked, all of the tetrahedral facets on the
* corresponding prism wall(s) will likewise be locked.
*
* Note that the current construction does _not_ give an oriented
* triangulation (due to the specific choice of labelling); this may
* change in a future version of Regina.
*
* \warning If the given 3-manifold triangulation has ideal boundary,
* then you will obtain an invalid 4-manifold triangulation as a result.
*
* \param base the 3-manifold triangulation \a M, as described above.
* \return the product `M × S1`.
*/
static Triangulation<4> s1Bundle(const Triangulation<3>& base);
/**
* Returns a triangulation of the given 3-manifold spun around its
* boundary.
*
* Let `M` be the given 3-manifold, with real boundary `∂M`. This
* constructs a 4-manifold from `M` as follows:
*
* - First we build the product `M × S1` in a similar way to s1Bundle().
* That is: we build a tetrahedral prism for each original tetrahedron
* of \a M, glue the top and bottom tetrahedra of each prism together,
* and glue the walls of the prisms together according to the gluings
* between the original tetrahedra of \a M.
*
* - Then, for each point `b` on the real boundary `∂M`, we collapse
* the fibre `b × S1` to a single point. (Equivalently, we attach a
* copy of `∂M × D2` to the product `M × S1` so that, for each point
* `b` on the boundary `∂M`, the fibre `b × S1` becomes the boundary
* of the corresponding disc `b × D2`.) We implement this as follows:
* for each boundary facet of \a M, we fold the corresponding prism
* wall in half, so that the top half folds onto the bottom.
*
* - If one or more of boundary facets of \a M are locked, then the
* corresponding prism walls will _not_ folded onto themselves;
* that is, the fibres over those parts of the boundary will _not_ be
* collapsed. See the section below on locks for further details.
*
* Regarding real versus ideal boundary:
*
* - The second step (collapsing fibres) only acts on _real_ boundary;
* that is, points `b` that lie on boundary triangles of `M`. It
* ignores ideal boundary, in the sense that ideal vertices will just
* be transformed as part of the product `M × S1` (the first step),
* without the subsequent collapse/filling operation.
*
* - As a result, any ideal vertices of `M` will produce invalid edges
* in the resulting 4-maifold triangulation (i.e., edges whose links
* are the same surfaces as the links of the original ideal vertices
* of `M`).
*
* Like s1Bundle(), the resulting triangulation will be very large:
* it creates 82 pentachora for each original tetrahedron of \a M.
* It is highly recommended that you call Triangulation<4>::simplify()
* afterwards if you do not need to preserve the combinatorial
* structure.
*
* This routine handles locks as follows:
*
* - For any simplex in \a base that is locked, all of the pentachora
* and internal facets of the corresponding prism will also be locked,
* as well as the two tetrahedra at each end of the prism (which will
* be glued together, as explained above).
*
* - For any internal triangular facet of \a base that is locked, all
* of the tetrahedral facets on the corresponding prism wall(s) will
* be locked.
*
* - For any boundary facet of \a base that is locked, the corresponding
* prism wall will _not_ be folded onto itself (i.e, the corresponding
* fibres will _not_ be collapsed). Instead, all of the tetrahedral
* facets on that prism wall will be locked, and will remain as
* boundary facets of the final 4-dimensional triangulation.
*
* - If \a base has a mix of locked and unlocked boundary facets, you
* should aim to ensure that the locked and unlocked regions are
* separated by embedded curves in the boundary of \a M (i.e., there
* are no "pinch points" where the local picture has two or more
* locked regions meeting two or more unlocked regions). Otherwise
* you may find that these pinch points create invalid edges in the
* resulting 4-manifold triangulation (specifically, edges whose
* links are 2-spheres with two or more punctures).
*
* Note that the current construction does _not_ give an oriented
* triangulation (due to the specific choice of labelling); this may
* change in a future version of Regina.
*
* \param base the 3-manifold triangulation \a M, as described above.
* \return the 4-manifold obtained by spinning \a M around its boundary,
* as described above.
*/
static Triangulation<4> boundarySpin(const Triangulation<3>& base);
/**
* Returns a bundle formed from a given 3-manifold and a given
* monodromy.
*
* Specifically, let \a M be the given 3-manifold triangulation.
* This routine builds the bundle `M × I`, and then
* identifies the two copies of \a M on the boundary according
* to the given homeomorphism from \a M to itself.
* The homeomorphism must be expressed as a combinatorial
* automorphism, which means that for a non-trivial monodromy you
* may need to do some work to find a sufficiently symmetric
* 3-manifold triangulation to begin with.
*
* The product is created as follows. For each original tetrahedron of
* \a M, we build a tetrahedral prism containing 82 pentachora. We then
* glue these prisms together in a manner that follows the gluings of
* the original tetrahedra. Moreover, we take the two copies of \a M
* that are formed from the tetrahedra at the two ends of these prisms,
* and glue these together according to the given monodromy. It is
* highly recommended that you call Triangulation<4>::simplify()
* afterwards if you do not need to preserve the combinatorial
* structure.
*
* For any simplex in \a base that is locked, all of the pentachora
* and internal facets of the corresponding prism will also be locked.
* For any triangular facet of \a base that is locked, all of the
* tetrahedral facets on the corresponding prism wall(s) will likewise
* be locked. The two tetrahedra at the ends of each prism will _not_
* be locked (these are the tetrahedra along which the two copies of
* \a M are identified using the given monodromy).
*
* Note that the current construction does _not_ give an oriented
* triangulation (due to the specific choice of labelling); this may
* change in a future version of Regina.
*
* \pre The given monodromy must be an isomorphism from \a M to
* itself; that is, a combinatorial automorphism.
*
* \warning If the given 3-manifold triangulation has ideal boundary,
* then you will obtain an invalid 4-manifold triangulation as a result.
*
* \param base the 3-manifold triangulation \a M, as described above.
* \param monodromy the homeomorphism from \a M to itself, as
* described above.
* \return the requested bundle.
*/
static Triangulation<4> bundleWithMonodromy(
const Triangulation<3>& base,
const Isomorphism<3>& monodromy);
/**
* Returns an ideal triangulation of the complement of the 2-knot
* obtained by spinning the given 1-knot (without twisting). The knot
* to be spun is passed as the first argument; the second (optional)
* argument allows you to specify where the knot should be broken open
* when carrying out the spinning construction.
*
* The spinning construction is described by Artin in "Zur Isotopie
* zweidimensionaler Flächen im R_4", Abh. Math. Sem. Univ. Hamburg
* 4 (1925), no. 1, 174-177.
*
* The final triangulation might (or might not) still contain internal
* vertices, in addition to the one ideal vertex that represents the
* 2-knot itself.
*
* \warning This routine could be slow, even when \a knot has very few
* crossings. This is because it typically goes via intermediate
* triangulations with thousands or even tens of thousands of
* pentachora, and simplifying such triangulations takes time.
*
* \pre The argument \a knot is a classical knot diagram. That is, the
* link diagram is not virtual, and has exactly one link component.
*
* \exception FailedPrecondition The given link diagram is empty, has
* multiple components, and/or is virtual (as opposed to classical).
*
* \param knot the knot to be spun.
* \param breakOpen indicates where to break open the given knot diagram
* when performing the spinning construction. See the StrandRef
* documentation for the convention on how arcs are represented using
* StrandRef objects. This may be a null reference (the default), in
* which case this routine will choose an arbitrary location to break
* the knot open.
* \return an ideal triangulation of the resulting 2-knot.
*/
static Triangulation<4> spun(const Link& knot,
StrandRef breakOpen = {});
/*@}*/
/**
* (end: Constructions from 3-Manifold Triangulations and Links)
*/
};
inline Triangulation<4> Example<4>::fourSphere() {
return sphere();
}
inline Triangulation<4> Example<4>::simplicialFourSphere() {
return simplicialSphere();
}
inline Triangulation<4> Example<4>::s3xs1() {
return sphereBundle();
}
inline Triangulation<4> Example<4>::s3xs1Twisted() {
return twistedSphereBundle();
}
} // namespace regina
#endif
|