1 /* ***************************************************************** 2 MESQUITE -- The Mesh Quality Improvement Toolkit 3 4 Copyright 2004 Sandia Corporation and Argonne National 5 Laboratory. Under the terms of Contract DE-AC04-94AL85000 6 with Sandia Corporation, the U.S. Government retains certain 7 rights in this software. 8 9 This library is free software; you can redistribute it and/or 10 modify it under the terms of the GNU Lesser General Public 11 License as published by the Free Software Foundation; either 12 version 2.1 of the License, or (at your option) any later version. 13 14 This library is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 Lesser General Public License for more details. 18 19 You should have received a copy of the GNU Lesser General Public License 20 (lgpl.txt) along with this library; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 23 diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov, 24 pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov 25 26 ***************************************************************** */ 27 // 28 // AUTHOR: Thomas Leurent <tleurent@mcs.anl.gov> 29 // ORG: Argonne National Laboratory 30 // E-MAIL: tleurent@mcs.anl.gov 31 // 32 // ORIG-DATE: 12-Nov-02 at 18:05:56 33 // LAST-MOD: 9-Jun-04 at 14:43:39 by Thomas Leurent 34 // 35 // DESCRIPTION: 36 // ============ 37 /*! \file PatchDataInstances.hpp 38 39 This header file contains some functions to instantiates particular PatchData Objects. 40 Those objects can be used in unit tests. 41 Patches must be allocated and dealocated by the caller. 42 43 \author Thomas Leurent 44 \author Michael Brewer 45 46 */ 47 // DESCRIP-END. 48 // 49 50 #ifndef PatchDataInstances_hpp 51 #define PatchDataInstances_hpp 52 53 #include "MsqVertex.hpp" 54 #include "PatchData.hpp" 55 #include "PlanarDomain.hpp" 56 #include "IdealElements.hpp" 57 #include "TopologyInfo.hpp" 58 59 #include <math.h> 60 #include <iostream> 61 62 #include "cppunit/extensions/HelperMacros.h" 63 64 namespace MBMesquite 65 { 66 //! must be called in sync with create_...._patch_with_domain destroy_patch_with_domain(PatchData & pd)67 inline void destroy_patch_with_domain(PatchData &pd) 68 { 69 MeshDomain* domain = pd.get_domain(); 70 pd.set_domain( 0 ); 71 delete domain; 72 73 //Mesh* mesh = pd.get_mesh(); 74 //pd.set_mesh( 0 ); 75 //delete mesh; 76 } 77 move_vertex(PatchData & pd,const Vector3D & position,const Vector3D & delta,MsqError & err)78 inline void move_vertex( PatchData& pd, 79 const Vector3D& position, 80 const Vector3D& delta, 81 MsqError& err ) 82 { 83 const MsqVertex* array = pd.get_vertex_array( err ); 84 if (err) return; 85 86 int idx = 0, cnt = 0; 87 for (size_t i = 0; i < pd.num_nodes(); ++i) 88 if ((array[i] - position).length_squared() < DBL_EPSILON) 89 { idx = i; ++cnt; } 90 91 CPPUNIT_ASSERT_EQUAL( cnt, 1 ); 92 93 pd.move_vertex( delta, idx, err ); 94 } 95 96 97 /*! creates a patch containing one ideal hexahedra 98 */ create_one_hex_patch(PatchData & one_hex_patch,MsqError & err)99 inline void create_one_hex_patch(PatchData &one_hex_patch, MsqError &err) 100 { 101 double coords[] = { 1.0, 1.0, 1.0, 102 2.0, 1.0, 1.0, 103 2.0, 2.0, 1.0, 104 1.0, 2.0, 1.0, 105 1.0, 1.0, 2.0, 106 2.0, 1.0, 2.0, 107 2.0, 2.0, 2.0, 108 1.0, 2.0, 2.0 }; 109 110 size_t indices[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; 111 112 one_hex_patch.fill( 8, coords, 1, HEXAHEDRON, indices, 0, err ); 113 } 114 115 116 //! creates a Patch containing an ideal tetrahedra create_one_tet_patch(PatchData & one_tet_patch,MsqError & err)117 inline void create_one_tet_patch(PatchData &one_tet_patch, MsqError &err) 118 { 119 double coords[] = { 1.0, 1.0, 1.0, 120 2.0, 1.0, 1.0, 121 1.5, 1+sqrt(3.0)/2.0, 1.0, 122 1.5, 1+sqrt(3.0)/6.0, 1+sqrt(2.0)/sqrt(3.0) }; 123 124 size_t indices[4] = { 0, 1, 2, 3 }; 125 126 one_tet_patch.fill( 4, coords, 1, TETRAHEDRON, indices, 0, err ); 127 } 128 129 //! create patch containing one ideal pyramid create_one_pyr_patch(PatchData & one_pyr_patch,MsqError & err)130 inline void create_one_pyr_patch( PatchData& one_pyr_patch, MsqError& err ) 131 { 132 /* Equilateral triangles 133 double coords[] = { 1, -1, 0, 134 1, 1, 0, 135 -1, 1, 0, 136 -1, -1, 0, 137 0, 0, sqrt(2) }; 138 */ 139 /* Unit height */ 140 double coords[] = { 1, -1, 0, 141 1, 1, 0, 142 -1, 1, 0, 143 -1, -1, 0, 144 0, 0, 2 }; 145 146 size_t indices[5] = { 0, 1, 2, 3, 4 }; 147 148 one_pyr_patch.fill( 5, coords, 1, PYRAMID, indices, 0, err ); 149 } 150 151 //! create patch containing one ideal wedge create_one_wdg_patch(PatchData & one_wdg_patch,MsqError & err)152 inline void create_one_wdg_patch( PatchData& one_wdg_patch, MsqError& err ) 153 { 154 double hgt = 0.5 * MSQ_SQRT_THREE; 155 double coords[] = { 0.0, 0.0, 0.0, 156 1.0, 0.0, 0.0, 157 0.5, hgt, 0.0, 158 0.0, 0.0, 1.0, 159 1.0, 0.0, 1.0, 160 0.5, hgt, 1.0 }; 161 162 size_t indices[6] = { 0, 1, 2, 3, 4, 5 }; 163 164 one_wdg_patch.fill( 6, coords, 1, PRISM, indices, 0, err ); 165 } 166 167 //! creates a Patch containing an ideal tetrahedra, inverted create_one_inverted_tet_patch(PatchData & one_tet_patch,MsqError & err)168 inline void create_one_inverted_tet_patch(PatchData &one_tet_patch, 169 MsqError &err) 170 { 171 double coords[] = { 1, 1, 1, 172 2, 1, 1, 173 1.5, 1+sqrt(3.0)/2.0, 1, 174 1.5, 1+sqrt(3.0)/6.0, 1-sqrt(2.0)/sqrt(3.0), }; 175 176 size_t indices[4] = { 0, 1, 2, 3 }; 177 178 one_tet_patch.fill( 4, coords, 1, TETRAHEDRON, indices, 0, err ); 179 } 180 181 //! creates a Patch containing an ideal quadrilateral create_one_quad_patch(PatchData & one_qua_patch,MsqError & err)182 inline void create_one_quad_patch(PatchData &one_qua_patch, MsqError &err) 183 { 184 double coords[] = { 1, 1, 1, 185 2, 1, 1, 186 2, 2, 1, 187 1, 2 , 1 }; 188 189 size_t indices[4] = { 0, 1, 2, 3 }; 190 191 one_qua_patch.fill( 4, coords, 1, QUADRILATERAL, indices, 0, err ); 192 } 193 194 195 /*! \fn create_one_tri_patch(PatchData &one_tri_patch, MsqError &err) 196 2 197 / \ creates a Patch containing an ideal triangle 198 / \ 199 0-----1 200 This Patch also has the normal information. 201 */ create_one_tri_patch(PatchData & one_tri_patch,MsqError & err)202 inline void create_one_tri_patch(PatchData &one_tri_patch, MsqError &err) 203 { 204 /* ************** Creates normal info ******************* */ 205 Vector3D pnt(0,0,0); 206 Vector3D s_norm(0,0,3); 207 one_tri_patch.set_domain( new PlanarDomain( s_norm, pnt ) ); 208 209 /* *********************FILL tri************************* */ 210 double coords[] = { 1, 1, 1, 211 2, 1, 1, 212 1.5, 1+sqrt(3.0)/2.0, 1 }; 213 214 size_t indices[3] = { 0, 1, 2 }; 215 one_tri_patch.fill( 3, coords, 1, TRIANGLE, indices, 0, err ); 216 } 217 218 219 /*! \fn create_two_tri_patch(PatchData &one_tri_patch, MsqError &err) 220 2 221 / \ creates a Patch containing two ideal triangles 222 / 0 \ 223 0-----1 224 \ 1 / 225 \ / 226 3 227 This Patch also has the normal information. 228 */ create_two_tri_patch(PatchData & pd,MsqError & err)229 inline void create_two_tri_patch(PatchData &pd, MsqError &err) 230 { 231 /* ************** Creates normal info ******************* */ 232 Vector3D pnt(0,0,1); 233 Vector3D s_norm(0,0,3); 234 pd.set_domain( new PlanarDomain(s_norm, pnt) ); 235 236 // **********************FILL tri************************* 237 238 double coords[] = { 1, 1, 1, 239 2, 1, 1, 240 1.5, 1+sqrt(3.0)/2.0, 1, 241 1.5, 1-sqrt(3.0)/2.0, 1 }; 242 243 size_t indices[] = { 0, 1, 2, 0, 3, 1 }; 244 245 pd.fill( 4, coords, 2, TRIANGLE, indices, 0, err ); 246 } 247 248 249 /*! \fn create_four_quads_patch(PatchData &four_quads, MsqError &err) 250 our 2D set up: 4 quads, center vertex outcentered by (0,-0.5) 251 7____6____5 252 | | | 253 | 2 | 3 | 254 8-_ | _-4 vertex 1 is at (0,0) 255 | -_0_- | vertex 5 is at (2,2) 256 | 0 | 1 | 257 1----2----3 258 */ create_four_quads_patch(PatchData & four_quads,MsqError & err)259 inline void create_four_quads_patch(PatchData &four_quads, MsqError &err) 260 { 261 double coords[] = { 1, .5, 0, 262 0, 0, 0, 263 1, 0, 0, 264 2, 0, 0, 265 2, 1, 0, 266 2, 2, 0, 267 1, 2, 0, 268 0, 2, 0, 269 0, 1, 0 }; 270 271 size_t indices[] = { 1, 2, 0, 8, 272 2, 3, 4, 0, 273 8, 0, 6, 7, 274 0, 4, 5, 6 }; 275 276 277 four_quads.fill( 9, coords, 4, QUADRILATERAL, indices, 0, err ); 278 } 279 280 281 /*! \fn create_six_quads_patch(PatchData &four_quads, MsqError &err) 282 our 2D set up: 6 quads, 1 center vertex outcentered by (0,-0.5), the other centered 283 7____6____5___11 284 | | | | 285 | 2 | 3 | 5 | 286 8-_ | _-4---10 vertex 1 is at (0,0) 287 | -_0_- | | vertex 11 is at (3,2) 288 | 0 | 1 | 4 | 289 1----2----3----9 290 291 use destroy_patch_with_domain() in sync. 292 */ create_six_quads_patch_with_domain(PatchData & pd,MsqError & err)293 inline void create_six_quads_patch_with_domain(PatchData &pd, MsqError &err) 294 { 295 // associates domain 296 Vector3D pnt(0,0,0); 297 Vector3D s_norm(0,0,3); 298 pd.set_domain( new PlanarDomain(s_norm, pnt) ); 299 300 double coords[] = { 1,.5, 0, 301 0, 0, 0, 302 1, 0, 0, 303 2, 0, 0, 304 2, 1, 0, 305 2, 2, 0, 306 1, 2, 0, 307 0, 2, 0, 308 0, 1, 0, 309 3, 0, 0, 310 3, 1, 0, 311 3, 2, 0 }; 312 313 size_t indices[] = { 1, 2, 0, 8, 314 2, 3, 4, 0, 315 8, 0, 6, 7, 316 0, 4, 5, 6, 317 3, 9, 10, 4, 318 4, 10, 11, 5 }; 319 320 bool fixed[] = { false, true, true, true, 321 false, true, true, true, 322 true, true, true, true }; 323 324 pd.fill( 12, coords, 6, QUADRILATERAL, indices, fixed, err ); 325 } 326 327 328 /*! \fn create_six_quads_patch_inverted_with_domain(PatchData &four_quads, MsqError &err) 329 our 2D set up: 6 quads, 1 center vertex outcentered by (0,-0.5), the other centered 330 7____6____5___11 331 | | | | 332 | 2 | 3 | 5 | 333 8 | 4---10 vertex 1 is at (0,0) 334 |\ /| | vertex 11 is at (3,2) 335 | | | 4 | 336 1----2----3----9 337 \ / 338 0 339 use destroy_patch_with_domain() in sync. 340 */ create_six_quads_patch_inverted_with_domain(PatchData & pd,MsqError & err)341 inline void create_six_quads_patch_inverted_with_domain(PatchData &pd, MsqError &err) 342 { 343 create_six_quads_patch_with_domain(pd,err); MSQ_CHKERR(err); 344 345 Vector3D displacement(0,-1.5,0); 346 347 pd.move_vertex( displacement, 0, err ); 348 } 349 350 351 /*! \fn create_twelve_hex_patch(PatchData &pd, MsqError &err) 352 3D set up: 12 quads, one center vertex outcentered by (0,-0.5), 353 the other centered. Vertex 1 is at (0,0,-1). Vertex 35 is at (3,2,1). 354 355 7____6____5___11 19___18____17__23 31___30___29___35 356 | | | | | | | | | | | | 357 | 2 | 3 | 5 | | | | | | 8 | 9 | 11 | 358 8----0----4---10 20-_ | _16---22 32---24---28---34 359 | | | | | -12_- | | | | | | 360 | 0 | 1 | 4 | | | | | | 6 | 7 | 10 | 361 1----2----3----9 13---14---15---21 25---26---27---33 362 */ create_twelve_hex_patch(PatchData & pd,MsqError & err)363 inline void create_twelve_hex_patch(PatchData &pd, MsqError &err) 364 { 365 double coords[] = { 1, 1, -1, 366 0, 0, -1, 367 1, 0, -1, 368 2, 0, -1, 369 2, 1, -1, 370 2, 2, -1, 371 1, 2, -1, 372 0, 2, -1, 373 0, 1, -1, 374 3, 0, -1, 375 3, 1, -1, 376 3, 2, -1, 377 378 1,.5, 0, 379 0, 0, 0, 380 1, 0, 0, 381 2, 0, 0, 382 2, 1, 0, 383 2, 2, 0, 384 1, 2, 0, 385 0, 2, 0, 386 0, 1, 0, 387 3, 0, 0, 388 3, 1, 0, 389 3, 2, 0, 390 391 1, 1, 1, 392 0, 0, 1, 393 1, 0, 1, 394 2, 0, 1, 395 2, 1, 1, 396 2, 2, 1, 397 1, 2, 1, 398 0, 2, 1, 399 0, 1, 1, 400 3, 0, 1, 401 3, 1, 1, 402 3, 2, 1 }; 403 404 size_t connectivity[] = { 1, 2, 0, 8, 13, 14, 12, 20, // 0 405 2, 3, 4, 0, 14, 15, 16, 12, // 1 406 8, 0, 6, 7, 20, 12, 18, 19, // 2 407 0, 4, 5, 6, 12, 16, 17, 18, // 3 408 3, 9, 10, 4, 15, 21, 22, 16, // 4 409 4, 10, 11, 5, 16, 22, 23, 17, // 5 410 13, 14, 12, 20, 25, 26, 24, 32, // 6 411 14, 15, 16, 12, 26, 27, 28, 24, // 7 412 20, 12, 18, 19, 32, 24, 30, 31, // 8 413 12, 16, 17, 18, 24, 28, 29, 30, // 9 414 15, 21, 22, 16, 27, 33, 34, 28, // 10 415 16, 22, 23, 17, 28, 34, 35, 29 }; // 11 416 417 bool fixed[] = { true, true, true, true, true, true, true, true, 418 true, true, true, true, false, true, true, true, 419 false, true, true, true, true, true, true, true, 420 true, true, true, true, true, true, true, true, 421 true, true, true, true }; 422 423 424 pd.fill( 36, coords, 12, HEXAHEDRON, connectivity, fixed, err ); 425 } 426 create_twelve_hex_patch_inverted(PatchData & pd,MsqError & err)427 inline void create_twelve_hex_patch_inverted(PatchData &pd, MsqError &err) 428 { 429 create_twelve_hex_patch(pd,err); MSQ_CHKERR(err); 430 move_vertex( pd, Vector3D(2,1,0), Vector3D(0,0,1.5), err ); MSQ_CHKERR(err); 431 } 432 433 434 /* Patch used in several quality metric tests. 435 Our triangular patch is made of two tris. tri_1 is a perfect 436 equilateral (the ideal for most metrics). tri_2 is an arbitrary 437 triangle. 438 Memory allocated in this function must be deallocated with 439 destroy_patch_with_domain(). 440 */ create_qm_two_tri_patch_with_domain(PatchData & triPatch,MsqError & err)441 inline void create_qm_two_tri_patch_with_domain(PatchData &triPatch, MsqError &err) 442 { 443 Vector3D pnt(0,0,0); 444 Vector3D s_norm(0,0,3); 445 triPatch.set_domain( new PlanarDomain(s_norm, pnt) ); 446 447 double coords[] = { 0.0, 0.0, 0.0, 448 1.0, 0.0, 0.0, 449 0.5, sqrt(3.0)/2.0, 0.0, 450 2.0, -4.0, 2.0 }; 451 452 453 const size_t conn[] = { 0, 1, 2, 0, 3, 1 }; 454 455 triPatch.fill( 4, coords, 2, TRIANGLE, conn, 0, err ); 456 } 457 458 /* Patch used in several quality metric tests. 459 Our quad patch is made of two quads. quad_1 is a perfect 460 square (the ideal for most metrics). quad_2 is an arbitrary 461 quad. 462 Memory allocated in this function must be deallocated with 463 destroy_patch_with_domain(). 464 */ create_qm_two_quad_patch_with_domain(PatchData & quadPatch,MsqError & err)465 inline void create_qm_two_quad_patch_with_domain(PatchData &quadPatch, MsqError &err) 466 { 467 Vector3D pnt(0,0,0); 468 Vector3D s_norm(0,0,3); 469 quadPatch.set_domain( new PlanarDomain(s_norm, pnt) ); 470 471 double coords[] = { 0.0, 0.0, 0.0, 472 1.0, 0.0, 0.0, 473 1.0, 1.0, 0.0, 474 0.0, 1.0, 0.0, 475 2.0, -1.0, .5, 476 1.5, 1.0, 1.0 }; 477 478 const size_t conn[] = { 0, 1, 2, 3, 1, 4, 5, 2 }; 479 480 quadPatch.fill( 6, coords, 2, QUADRILATERAL, conn, 0, err ); 481 } 482 483 /* Patch used in several quality metric tests. 484 Our tet patch is made of two tets. tet_1 is a perfect 485 equilateral (the ideal for most metrics). tet_2 is an arbitrary 486 tet. 487 */ create_qm_two_tet_patch(PatchData & tetPatch,MsqError & err)488 inline void create_qm_two_tet_patch(PatchData &tetPatch, MsqError &err) 489 { 490 double coords[] = { 0.0, 0.0, 0.0, 491 1.0, 0.0, 0.0, 492 0.5, sqrt(3.0)/2.0, 0.0, 493 0.5, sqrt(3.0)/6.0, sqrt(2.0)/sqrt(3.0), 494 2.0, 3.0, -.5 }; 495 496 497 const size_t conn[] = { 0, 1, 2, 3, 1, 4, 2, 3 }; 498 499 tetPatch.fill( 5, coords, 2, TETRAHEDRON, conn, 0, err ); 500 } 501 502 /* Patch used in several quality metric tests. 503 Our pyr patch is made of two pyramids. The first is a perfect 504 pyramid (the ideal for most metrics). The second is an arbitrary 505 pyramid. 506 */ create_qm_two_pyr_patch(PatchData & pyrPatch,MsqError & err)507 inline void create_qm_two_pyr_patch(PatchData &pyrPatch, MsqError &err) 508 { 509 /* Equilateral triangles 510 double coords[] = { 1, -1, 0, 511 1, 1, 0, 512 -1, 1, 0, 513 -1, -1, 0, 514 0, 0, sqrt(2) }; 515 */ 516 /* Unit height */ 517 double coords[] = { 518 /* Equilateral triangles */ 519 /* 1, -1, 0, 520 1, 1, 0, 521 -1, 1, 0, 522 -1, -1, 0, 523 0, 0, sqrt(2) */ 524 /* Unit height */ 525 1, -1, 0, 526 1, 1, 0, 527 -1, 1, 0, 528 -1, -1, 0, 529 0, 0, 2, 530 /* Apex for a squashed pyramid */ 531 0, 0, -1 532 }; 533 534 535 const size_t conn[] = { 0, 1, 2, 3, 4, 536 3, 2, 1, 0, 5 }; 537 538 pyrPatch.fill( 6, coords, 2, PYRAMID, conn, 0, err ); 539 } 540 541 /* Patch used in several quality metric tests. 542 Our prism patch is made of two prisms. The first is a perfect 543 prism (the ideal for most metrics). The second is an arbitrary 544 wedge. 545 */ create_qm_two_wdg_patch(PatchData & wdgPatch,MsqError & err)546 inline void create_qm_two_wdg_patch(PatchData &wdgPatch, MsqError &err) 547 { 548 double hgt = 0.5 * MSQ_SQRT_THREE; 549 double coords[] = { // ideal prism vertices 550 0.0, 0.0, 0.0, 551 1.0, 0.0, 0.0, 552 0.5, hgt, 0.0, 553 0.0, 0.0, 1.0, 554 1.0, 0.0, 1.0, 555 0.5, hgt, 1.0, 556 // top vertices for stretched wedge 557 0.5,-3.0, 0.0, 558 0.5,-4.0, 1.0 }; 559 560 const size_t conn[] = { 0, 1, 2, 3, 4, 5, 561 1, 0, 6, 4, 3, 7 }; 562 563 wdgPatch.fill( 8, coords, 2, PRISM, conn, 0, err ); 564 } 565 566 /* Patch used in seveal quality metric tests. 567 Our hex patch is made of two hexes. hex_1 is a perfect 568 unit cube (the ideal for most metrics). hex_2 is an arbitrary 569 hex. 570 */ create_qm_two_hex_patch(PatchData & hexPatch,MsqError & err)571 inline void create_qm_two_hex_patch(PatchData &hexPatch, MsqError &err) 572 { 573 double coords[] = { 0.0, 0.0, 0.0, 574 1.0, 0.0, 0.0, 575 1.0, 1.0, 0.0, 576 0.0, 1.0, 0.0, 577 0.0, 0.0, 1.0, 578 1.0, 0.0, 1.0, 579 1.0, 1.0, 1.0, 580 0.0, 1.0, 1.0, 581 2.0, 0.0, 0.0, 582 2.0, 1.0, 0.0, 583 2.0,-1.0, 1.0, 584 3.0, 2.0, 1.0 }; 585 586 const size_t conn[] = { 0, 1, 2, 3, 4, 5, 6, 7, 587 1, 8, 9, 2, 5, 10, 11, 6 }; 588 589 hexPatch.fill( 12, coords, 2, HEXAHEDRON, conn, 0, err ); 590 } 591 592 // Create patch containing one ideal element, optionally higher-order. 593 // For 2D elements, will attach appropriate planar domain. create_ideal_element_patch(PatchData & pd,EntityTopology type,size_t num_nodes,MsqError & err)594 inline void create_ideal_element_patch( PatchData& pd, 595 EntityTopology type, 596 size_t num_nodes, 597 MsqError& err ) 598 { 599 static PlanarDomain zplane(PlanarDomain::XY); 600 static Settings settings; 601 settings.set_slaved_ho_node_mode( Settings::SLAVE_NONE ); 602 pd.attach_settings( &settings ); 603 604 605 // build list of vertex coordinates 606 const Vector3D* corners = unit_edge_element( type ); 607 std::vector<Vector3D> coords( corners, corners+TopologyInfo::corners(type) ); 608 bool mids[4] = {false}; 609 TopologyInfo::higher_order( type, num_nodes, mids[1], mids[2], mids[3], err ); 610 MSQ_ERRRTN(err); 611 std::vector<size_t> conn(coords.size()); 612 for (unsigned i = 0; i < coords.size(); ++i) 613 conn[i] = i; 614 615 for (unsigned dim = 1; dim <= TopologyInfo::dimension(type); ++dim) { 616 if (!mids[dim]) 617 continue; 618 619 int num_side; 620 if (dim == TopologyInfo::dimension(type)) 621 num_side = 1; 622 else 623 num_side = TopologyInfo::adjacent( type, dim ); 624 625 for (int s = 0; s < num_side; ++s) { 626 unsigned idx = TopologyInfo::higher_order_from_side( type, num_nodes, dim, s, err ); 627 MSQ_ERRRTN(err); 628 conn.push_back(idx); 629 630 unsigned n; 631 const unsigned* side = TopologyInfo::side_vertices( type, dim, s, n, err ); 632 MSQ_ERRRTN(err); 633 Vector3D avg = coords[side[0]]; 634 for (unsigned v = 1; v < n; ++v) 635 avg += coords[side[v]]; 636 avg *= 1.0/n; 637 coords.push_back(avg); 638 } 639 } 640 641 bool* fixed = new bool[coords.size()]; 642 std::fill( fixed, fixed+coords.size(), false ); 643 pd.fill( coords.size(), coords[0].to_array(), 1, &type, 644 &num_nodes, &conn[0], fixed, err ); 645 delete [] fixed; 646 MSQ_ERRRTN(err); 647 648 if (TopologyInfo::dimension(type) == 2) 649 pd.set_domain( &zplane ); 650 } 651 652 } // namespace 653 654 #endif // PatchDataInstances_hpp 655