|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <stdexcept> 00010 00011 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 00012 00013 #include <stk_mesh/fixtures/QuadFixture.hpp> 00014 #include <stk_mesh/fixtures/HexFixture.hpp> 00015 00016 //---------------------------------------------------------------------------- 00017 00018 STKUNIT_UNIT_TEST ( UnitTestCrackMesh , VerifyDestroy2D ) 00019 { 00020 // In 2D, build a fresh 3x3 mesh each loop iteration, destroying a different 00021 // single element each time. 00022 00023 stk_classic::ParallelMachine pm = MPI_COMM_WORLD ; 00024 const unsigned p_rank = stk_classic::parallel_machine_rank( pm ); 00025 00026 const unsigned nx = 3 , ny = 3 ; 00027 00028 for ( unsigned iy = 0 ; iy < ny ; ++iy ) { 00029 for ( unsigned ix = 0 ; ix < nx ; ++ix ) { 00030 stk_classic::mesh::fixtures::QuadFixture fixture( pm , nx , ny ); 00031 fixture.m_fem_meta.commit(); 00032 fixture.generate_mesh(); 00033 00034 fixture.m_bulk_data.modification_begin(); 00035 00036 stk_classic::mesh::Entity * elem = fixture.elem( ix , iy ); 00037 00038 if ( elem && p_rank == elem->owner_rank() ) { 00039 stk_classic::mesh::Entity * tmp = elem ; 00040 fixture.m_bulk_data.destroy_entity( tmp ); 00041 } 00042 00043 fixture.m_bulk_data.modification_end(); 00044 00045 if ( elem ) { 00046 STKUNIT_EXPECT_TRUE ( elem->log_query() == stk_classic::mesh::EntityLogDeleted ); 00047 } 00048 } 00049 } 00050 } 00051 00052 STKUNIT_UNIT_TEST ( UnitTestCrackMesh , VerifyDestroy3D ) 00053 { 00054 // In 3D, build a 3x3x3 mesh each loop iteration, destroying a different 00055 // single element each time. 00056 00057 stk_classic::ParallelMachine pm = MPI_COMM_WORLD ; 00058 const unsigned p_rank = stk_classic::parallel_machine_rank( pm ); 00059 00060 const unsigned nx = 3 , ny = 3 , nz = 3 ; 00061 00062 for ( unsigned iz = 0 ; iz < nz ; ++iz ) { 00063 for ( unsigned iy = 0 ; iy < ny ; ++iy ) { 00064 for ( unsigned ix = 0 ; ix < nx ; ++ix ) { 00065 stk_classic::mesh::fixtures::HexFixture fixture( pm , nx , ny , nz ); 00066 fixture.m_fem_meta.commit(); 00067 fixture.generate_mesh(); 00068 00069 fixture.m_bulk_data.modification_begin(); 00070 00071 stk_classic::mesh::Entity * elem = fixture.elem( ix , iy , iz ); 00072 00073 if ( elem && p_rank == elem->owner_rank() ) { 00074 stk_classic::mesh::Entity * tmp = elem ; 00075 fixture.m_bulk_data.destroy_entity( tmp ); 00076 } 00077 00078 fixture.m_bulk_data.modification_end(); 00079 00080 if ( elem ) { 00081 STKUNIT_EXPECT_TRUE ( elem->log_query() == stk_classic::mesh::EntityLogDeleted ); 00082 } 00083 } 00084 } 00085 } 00086 } 00087 00088 //---------------------------------------------------------------------------- 00089 00090 STKUNIT_UNIT_TEST ( UnitTestCrackMesh , verifyBoxGhosting ) 00091 { 00092 // Start with a normal hex fixture, then crack it, and check to see 00093 // if all (incl ghosted) copies get updated. 00094 00095 // Make the hex fixture 00096 00097 stk_classic::mesh::fixtures::HexFixture fixture( MPI_COMM_WORLD, 2,2,2 ); 00098 fixture.m_fem_meta.commit(); 00099 fixture.generate_mesh(); 00100 00101 stk_classic::mesh::BulkData & mesh = fixture.m_bulk_data; 00102 00103 // Hardwire which entities are being modified. Note that not every 00104 // process will know about these entities 00105 00106 stk_classic::mesh::Entity * const old_node = fixture.node(0,1,1); 00107 00108 stk_classic::mesh::Entity * const right_element = fixture.elem(0,0,1); 00109 00110 unsigned right_ordinal = 0; 00111 unsigned new_node_id = 28; 00112 00113 // If this process knows about both entities, compute the ordinal 00114 // of the relation from right_element to old_node 00115 00116 if ( old_node && right_element ) { 00117 stk_classic::mesh::PairIterRelation rel = old_node->relations(); 00118 00119 for (; rel.first != rel.second; ++rel) { 00120 if ( (rel.first->entity()) == right_element) { 00121 right_ordinal = rel.first->identifier(); 00122 } 00123 } 00124 } 00125 00126 // Crack the mesh 00127 00128 mesh.modification_begin(); 00129 00130 //only crack the mesh if I own the element 00131 if ( right_element && 00132 right_element->owner_rank() == mesh.parallel_rank() ) { 00133 00134 const stk_classic::mesh::PartVector no_parts; 00135 00136 // create a new node 00137 stk_classic::mesh::Entity & new_node = mesh.declare_entity(stk_classic::mesh::fem::FEMMetaData::NODE_RANK, new_node_id, no_parts); 00138 00139 // destroy right_element's relation to old_node, replace with a 00140 // relation to new node 00141 mesh.destroy_relation(*right_element, *old_node, right_ordinal); 00142 mesh.declare_relation(*right_element, new_node, right_ordinal); 00143 } 00144 00145 mesh.modification_end(); 00146 00147 // Now that modification_end has been called, all processes that know 00148 // about right_element should know about the crack. 00149 00150 if ( right_element ) { 00151 stk_classic::mesh::PairIterRelation rel = right_element->relations(); 00152 stk_classic::mesh::Entity & new_node = * (rel.first[right_ordinal].entity()); 00153 00154 STKUNIT_EXPECT_TRUE ( new_node.identifier() == new_node_id ); 00155 } 00156 } 00157 00158 //----------------------------------------------------------------------------