Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mbex4.cpp
Go to the documentation of this file.
1 /// \file mbex4.cpp 2 /// 3 /// \author Milad Fatenejad 4 /// 5 /// \brief beginner tutorial, example 4: Create a 2D structured mesh 6 /// and set some tag data on it 7 /// 8 /// In this example, we create a 2D structured mesh (actually a 3D 9 /// mesh made of quads) and then we will actually set data on the 10 /// mesh. Tags represent data that is attached to entities. In this 11 /// example, we will create two tags: 12 /// 13 /// -# A "temperature" tag that is a single double precision number 14 /// attached to each quad. 15 /// -# A "velocity" tag that is an array of 2 double precision numbers 16 /// attached to each vertex. 17 /// 18 /// We will write the mesh out to a file, and you can visualize the 19 /// data using your favorite tool. 20 /// 21 /// In this example, I am demonstrating these operations in the 22 /// clearest possible way - not using the most efficient method. MOAB 23 /// has been designed so that users do not need to sacrifice 24 /// performance - future examples will demonstrate how to 25 /// access/manipulate the mesh using the fastest methods possible. 26  27 // The moab/Core.hpp header file is needed for all MOAB work... 28 #include "moab/Core.hpp" 29  30 // The moab/ScdInterface.hpp contains code which defines the moab 31 // structured mesh interface 32 #include "moab/ScdInterface.hpp" 33  34 #include <iostream> 35 #include <cmath> 36  37 // **************** 38 // * * 39 // * main * 40 // * * 41 // **************** 42 int main() 43 { 44  moab::ErrorCode rval; 45  moab::Core mbint; 46  47  // *********************** 48  // * Create the Mesh * 49  // *********************** 50  51  // First, lets make the mesh. It will be a 100 by 100 uniform grid 52  // (there will be 100x100 quads, 101x101 vertexes) with dx = dy = 53  // 0.1. Unlike the previous example, we will first make the mesh, 54  // then set the coordinates one at a time. 55  56  const unsigned NI = 100; 57  const unsigned NJ = 100; 58  59  // moab::ScdInterface is the structured mesh interface class for 60  // MOAB. 61  moab::ScdInterface* scdint; 62  63  // Tell MOAB that our mesh is structured: 64  rval = mbint.query_interface( scdint );MB_CHK_SET_ERR( rval, "mbint.query_interface failed" ); 65  66  // Create the mesh: 67  moab::ScdBox* scdbox = NULL; 68  rval = scdint->construct_box( moab::HomCoord( 0, 0, 0 ), moab::HomCoord( NI, NJ, 0 ), NULL, 0, scdbox );MB_CHK_SET_ERR( rval, "scdint->construct_box failed" ); 69  70  // MOAB knows to make quads instead of hexes because the last start 71  // and end indexes are the same (0). Note that it is still a "3D" 72  // mesh because each vertex coordinate is still defined using three 73  // numbers although every element in the mesh is a quadrilateral. 74  75  // ****************************** 76  // * Set Vertex Coordinates * 77  // ****************************** 78  79  // The "NULL" and "0" arguments in the call to construct_box are 80  // where we could specify the vertex coordinates. Since we didn't 81  // give any coordinates, every vertex is given a position of 0,0,0 82  // by default. Now we will set the vertex coordinates... 83  84  const double DX = 0.1; 85  const double DY = 0.1; 86  87  for( unsigned i = 0; i < NI + 1; i++ ) 88  for( unsigned j = 0; j < NJ + 1; j++ ) 89  { 90  // First, get the entity handle: 91  moab::EntityHandle handle = scdbox->get_vertex( i, j ); 92  93  // Compute the coordinate: 94  double coord[3] = { DX * i, DY * j, 0.0 }; 95  96  // Change the coordinate of the vertex: 97  mbint.set_coords( &handle, 1, coord ); 98  } 99  100  // ******************* 101  // * Attach Tags * 102  // ******************* 103  104  // The vertex coordinates have been defined, now let's attach some 105  // data to the mesh. In MOAB this is done using "tags". Tags are 106  // little bits of information that can be attached to any mesh 107  // entity. In our example, we want to create two tags. The 108  // "temperature" tag will be attached to each quad and will be 1 109  // double. The "velocity" tag will be attached to each vertex and 110  // will be an array of two doubles. 111  112  // zero and twozeros represent the initial tag 113  114  // Create the tags: 115  moab::Tag temp_tag; 116  double temp_default_value = 0.0; 117  rval = mbint.tag_get_handle( "temperature", 1, moab::MB_TYPE_DOUBLE, temp_tag, 118  moab::MB_TAG_DENSE | moab::MB_TAG_CREAT, &temp_default_value );MB_CHK_SET_ERR( rval, "mbint.tag_get_handle(temperature) failed" ); 119  120  moab::Tag vel_tag; 121  double vel_default_value[2] = { 0.0, 0.0 }; 122  rval = mbint.tag_get_handle( "velocity", 2, moab::MB_TYPE_DOUBLE, vel_tag, moab::MB_TAG_DENSE | moab::MB_TAG_CREAT, 123  vel_default_value );MB_CHK_SET_ERR( rval, "mbint.tag_get_handle(velocity) failed" ); 124  125  // Note that when we created each tag, we specified two flags: 126  // 127  // The moab::MB_TAG_DENSE flag tells MOAB that this is a dense 128  // tag. Dense tags will get automatically assigned to entities which 129  // have continuous handles. For this example, this means that once 130  // we set a tag on one vertex, memory will be allocated for 131  // assigning the tag to all vertexes. The same is true of 132  // quads. Dense tags are much more efficient when assigning tags to 133  // lots of entities. If you only want to assign a tag to a few 134  // entities, it is more efficient to use sparse tags 135  // (moab::MB_TAG_SPARSE). 136  // 137  // The moab::MB_TAG_CREAT flag tells MOAB to create the tag if it 138  // doesn't already exist. 139  140  // The tags have now been created, now we have to attach them to 141  // entities and set their values. NOTE: I am going to do this in a 142  // manner which emphasizes clarity - this is not the most efficient 143  // approach - that will be saved for later tutorial examples. 144  145  // Loop through each quad and set the temperature: 146  for( unsigned i = 0; i < NI; i++ ) 147  for( unsigned j = 0; j < NJ; j++ ) 148  { 149  // Get the handle for this quad: 150  moab::EntityHandle handle = scdbox->get_element( i, j ); 151  152  // Compute the temperature... 153  double xc = DX * ( i + 0.5 ); 154  double yc = DY * ( j + 0.5 ); 155  double r = std::sqrt( xc * xc + yc * yc ); 156  double temperature = std::exp( -0.5 * r ); 157  158  // Set the temperature on a single quad: 159  rval = mbint.tag_set_data( temp_tag, &handle, 1, &temperature );MB_CHK_SET_ERR( rval, "mbint.tag_set_data(temp_tag) failed" ); 160  } 161  162  // Loop through each vertex and set the velocity: 163  for( unsigned i = 0; i < NI + 1; i++ ) 164  for( unsigned j = 0; j < NJ + 1; j++ ) 165  { 166  // Get the handle for this vertex: 167  moab::EntityHandle handle = scdbox->get_vertex( i, j ); 168  double velocity[2] = { i, j }; 169  170  // Set the velocity on a vertex: 171  rval = mbint.tag_set_data( vel_tag, &handle, 1, velocity );MB_CHK_SET_ERR( rval, "mbint.tag_set_data(vel_tag) failed" ); 172  } 173  174  // *************************** 175  // * Write Mesh to Files * 176  // *************************** 177  178  // NOTE: Some visualization software (such as VisIt) may not 179  // interpret the velocity tag as a vector and you may not be able to 180  // plot it. But you should be able to plot the temperature on top of 181  // the mesh. 182  183  rval = mbint.write_file( "mbex4.vtk" );MB_CHK_SET_ERR( rval, "write_file(mbex4.vtk) failed" ); 184  185  return 0; 186 }