Sierra Toolkit Version of the Day
UnitTestCrackMesh.cpp
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::ParallelMachine pm = MPI_COMM_WORLD ;
00024   const unsigned p_rank = stk::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::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::mesh::Entity * elem = fixture.elem( ix , iy );
00037 
00038     if ( elem && p_rank == elem->owner_rank() ) {
00039       stk::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::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::ParallelMachine pm = MPI_COMM_WORLD ;
00058   const unsigned p_rank = stk::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::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::mesh::Entity * elem = fixture.elem( ix , iy , iz );
00072 
00073     if ( elem && p_rank == elem->owner_rank() ) {
00074       stk::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::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::mesh::fixtures::HexFixture fixture( MPI_COMM_WORLD, 2,2,2 );
00098   fixture.m_fem_meta.commit();
00099   fixture.generate_mesh();
00100 
00101   stk::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::mesh::Entity * const old_node = fixture.node(0,1,1);
00107 
00108   stk::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::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::mesh::PartVector no_parts;
00135 
00136     // create a new node
00137     stk::mesh::Entity & new_node = mesh.declare_entity(stk::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::mesh::PairIterRelation rel = right_element->relations();
00152     stk::mesh::Entity & new_node = * (rel.first[right_ordinal].entity());
00153 
00154     STKUNIT_EXPECT_TRUE ( new_node.identifier() == new_node_id );
00155   }
00156 }
00157 
00158 //----------------------------------------------------------------------------
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines