CylindricalHoneycombMeshGenerator.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "CylindricalHoneycombMeshGenerator.hpp"
00030 #include "RandomNumberGenerator.hpp"
00031 #include "MathsCustomFunctions.hpp"
00032
00033 CylindricalHoneycombMeshGenerator::CylindricalHoneycombMeshGenerator(unsigned numNodesAlongWidth, unsigned numNodesAlongLength, unsigned ghosts, double scaleFactor)
00034 {
00035 mpMesh = NULL;
00036 mDomainWidth = numNodesAlongWidth*scaleFactor;
00037 mNumCellWidth = numNodesAlongWidth;
00038 mNumCellLength = numNodesAlongLength;
00039
00040
00041 assert(PetscTools::IsSequential());
00042
00043
00044 std::stringstream pid;
00045 pid << getpid();
00046 mMeshFilename = "2D_temporary_honeycomb_mesh_" + pid.str();
00047
00048 mGhostNodeIndices.empty();
00049
00050 OutputFileHandler output_file_handler("");
00051 std::string output_dir = output_file_handler.GetOutputDirectoryFullPath();
00052
00053 if (PetscTools::AmMaster())
00054 {
00055 unsigned numNodesAlongWidth = mNumCellWidth;
00056 unsigned numNodesAlongLength = mNumCellLength;
00057 double horizontal_spacing = mDomainWidth / (double)numNodesAlongWidth;
00058 double vertical_spacing = (sqrt(3)/2)*horizontal_spacing;
00059
00060
00061 mDomainDepth = (double)(numNodesAlongLength) * vertical_spacing;
00062
00063
00064 numNodesAlongLength = numNodesAlongLength + 2*ghosts;
00065
00066 unsigned num_nodes = numNodesAlongWidth*numNodesAlongLength;
00067 unsigned num_elem_along_width = numNodesAlongWidth-1;
00068 unsigned num_elem_along_length = numNodesAlongLength-1;
00069 unsigned num_elem = 2*num_elem_along_width*num_elem_along_length;
00070 unsigned num_edges = 3*num_elem_along_width*num_elem_along_length + num_elem_along_width + num_elem_along_length;
00071
00072 double x0 = 0;
00073 double y0 = -vertical_spacing*ghosts;
00074
00075 mBottom = -vertical_spacing*ghosts;
00076 mTop = mBottom + vertical_spacing*(numNodesAlongLength-1);
00077
00078
00079 out_stream p_node_file = output_file_handler.OpenOutputFile(mMeshFilename+".node");
00080 (*p_node_file) << std::scientific;
00081 (*p_node_file) << num_nodes << "\t2\t0\t1" << std::endl;
00082
00083 unsigned node = 0;
00084 for (unsigned i=0; i<numNodesAlongLength; i++)
00085 {
00086 for (unsigned j=0; j<numNodesAlongWidth; j++)
00087 {
00088 if (i<ghosts || i>=(ghosts+mNumCellLength))
00089 {
00090 mGhostNodeIndices.insert(node);
00091 }
00092 unsigned boundary = 0;
00093 if ((i==0) || (i==numNodesAlongLength-1))
00094 {
00095 boundary = 1;
00096 }
00097
00098 double x = x0 + horizontal_spacing*((double)j + 0.25*(1.0+ SmallPow(-1,i+1)));
00099 double y = y0 + vertical_spacing*(double)i;
00100
00101
00102 if ( (y<0.0) && (y>-1e-12) )
00103 {
00104
00105 #define COVERAGE_IGNORE
00106 y = 0.0;
00107 #undef COVERAGE_IGNORE
00108 }
00109
00110 (*p_node_file) << node++ << "\t" << x << "\t" << y << "\t" << boundary << std::endl;
00111 }
00112 }
00113 p_node_file->close();
00114
00115
00116 out_stream p_elem_file = output_file_handler.OpenOutputFile(mMeshFilename+".ele");
00117 (*p_elem_file) << std::scientific;
00118
00119 out_stream p_edge_file = output_file_handler.OpenOutputFile(mMeshFilename+".edge");
00120 (*p_node_file) << std::scientific;
00121
00122 (*p_elem_file) << num_elem << "\t3\t0" << std::endl;
00123 (*p_edge_file) << num_edges << "\t1" << std::endl;
00124
00125 unsigned elem = 0;
00126 unsigned edge = 0;
00127 for (unsigned i=0; i<num_elem_along_length; i++)
00128 {
00129 for (unsigned j=0; j < num_elem_along_width; j++)
00130 {
00131 unsigned node0 = i*numNodesAlongWidth + j;
00132 unsigned node1 = i*numNodesAlongWidth + j+1;
00133 unsigned node2 = (i+1)*numNodesAlongWidth + j;
00134
00135 if (i%2 != 0)
00136 {
00137 node2 = node2 + 1;
00138 }
00139
00140 (*p_elem_file) << elem++ << "\t" << node0 << "\t" << node1 << "\t" << node2 << std::endl;
00141
00142 unsigned horizontal_edge_is_boundary_edge = 0;
00143 unsigned vertical_edge_is_boundary_edge = 0;
00144 if (i==0)
00145 {
00146 horizontal_edge_is_boundary_edge = 1;
00147 }
00148
00149 (*p_edge_file) << edge++ << "\t" << node0 << "\t" << node1 << "\t" << horizontal_edge_is_boundary_edge << std::endl;
00150 (*p_edge_file) << edge++ << "\t" << node1 << "\t" << node2 << "\t" << 0 << std::endl;
00151 (*p_edge_file) << edge++ << "\t" << node2 << "\t" << node0 << "\t" << vertical_edge_is_boundary_edge << std::endl;
00152
00153 node0 = i*numNodesAlongWidth + j + 1;
00154
00155 if (i%2 != 0)
00156 {
00157 node0 = node0 - 1;
00158 }
00159 node1 = (i+1)*numNodesAlongWidth + j+1;
00160 node2 = (i+1)*numNodesAlongWidth + j;
00161
00162 (*p_elem_file) << elem++ << "\t" << node0 << "\t" << node1 << "\t" << node2 << std::endl;
00163 }
00164 }
00165
00166 for (unsigned i=0; i<num_elem_along_length; i++)
00167 {
00168 unsigned node0, node1;
00169
00170 if (i%2==0)
00171 {
00172 node0 = (i+1)*numNodesAlongWidth - 1;
00173 node1 = (i+2)*numNodesAlongWidth - 1;
00174 }
00175 else
00176 {
00177 node0 = (i+1)*numNodesAlongWidth;
00178 node1 = (i)*numNodesAlongWidth;
00179 }
00180 (*p_edge_file) << edge++ << "\t" << node0 << "\t" << node1 << "\t" << 1 << std::endl;
00181 }
00182
00183 for (unsigned j=0; j<num_elem_along_width; j++)
00184 {
00185 unsigned node0 = numNodesAlongWidth*(numNodesAlongLength-1) + j;
00186 unsigned node1 = numNodesAlongWidth*(numNodesAlongLength-1) + j+1;
00187 (*p_edge_file) << edge++ << "\t" << node1 << "\t" << node0 << "\t" << 1 << std::endl;
00188 }
00189
00190 p_elem_file->close();
00191 p_edge_file->close();
00192 }
00193
00194
00195 PetscTools::Barrier();
00196
00197
00198 TrianglesMeshReader<2,2> mesh_reader(output_dir + mMeshFilename);
00199 mpMesh = new Cylindrical2dMesh(mDomainWidth);
00200 mpMesh->ConstructFromMeshReader(mesh_reader);
00201 NodeMap map(mpMesh->GetNumNodes());
00202
00203
00204 mpMesh->ReMesh(map);
00205
00206
00207 std::string command = "rm " + output_dir + mMeshFilename + ".*";
00208 int return_value = system(command.c_str());
00209 if (return_value != 0)
00210 {
00211
00212 #define COVERAGE_IGNORE
00213 EXCEPTION("HoneycombMeshGenerator cannot delete temporary files\n");
00214 #undef COVERAGE_IGNORE
00215 }
00216
00217
00218 mpMesh->SetMeshHasChangedSinceLoading();
00219 }
00220
00221 MutableMesh<2,2>* CylindricalHoneycombMeshGenerator::GetMesh()
00222 {
00223 EXCEPTION("A cylindrical mesh was created but a normal mesh is being requested.");
00224 return mpMesh;
00225 }
00226
00227 Cylindrical2dMesh* CylindricalHoneycombMeshGenerator::GetCylindricalMesh()
00228 {
00229 return (Cylindrical2dMesh*) mpMesh;
00230 }