action functions
|
Please note that the library has not been "officially" released. While we continue to work on the documentation, these web pages are likely to contain broken links and documents in draft form. Please send an email to if you wish to be informed of the library's "official" release. |
00001 //LIC// ==================================================================== 00002 //LIC// This file forms part of oomph-lib, the object-oriented, 00003 //LIC// multi-physics finite-element library, available 00004 //LIC// at http://www.oomph-lib.org. 00005 //LIC// 00006 //LIC// Version 0.90. August 3, 2009. 00007 //LIC// 00008 //LIC// Copyright (C) 2006-2009 Matthias Heil and Andrew Hazel 00009 //LIC// 00010 //LIC// This library is free software; you can redistribute it and/or 00011 //LIC// modify it under the terms of the GNU Lesser General Public 00012 //LIC// License as published by the Free Software Foundation; either 00013 //LIC// version 2.1 of the License, or (at your option) any later version. 00014 //LIC// 00015 //LIC// This library is distributed in the hope that it will be useful, 00016 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 //LIC// Lesser General Public License for more details. 00019 //LIC// 00020 //LIC// You should have received a copy of the GNU Lesser General Public 00021 //LIC// License along with this library; if not, write to the Free Software 00022 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00023 //LIC// 02110-1301 USA. 00024 //LIC// 00025 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk. 00026 //LIC// 00027 //LIC//==================================================================== 00028 #include "geompack_scaffold_mesh.h" 00029 00030 namespace oomph 00031 { 00032 00033 //===================================================================== 00034 /// \short Constructor: Pass the filename of the mesh files 00035 //===================================================================== 00036 GeompackQuadScaffoldMesh::GeompackQuadScaffoldMesh( 00037 const std::string& mesh_file_name, 00038 const std::string& curve_file_name) 00039 { 00040 00041 //Read the output mesh file to find informations about the nodes 00042 //and elements of the mesh 00043 00044 // Process mesh file 00045 //--------------------- 00046 std::ifstream mesh_file(mesh_file_name.c_str(),std::ios_base::in); 00047 00048 // Number of nodes 00049 unsigned n_node; 00050 mesh_file>>n_node; 00051 00052 // Coordinates of nodes and extra information index 00053 Vector<double> x_node(n_node); 00054 Vector<double> y_node(n_node); 00055 Vector<int> vertinfo(n_node); 00056 for(unsigned i=0;i<n_node;i++) 00057 { 00058 mesh_file>>x_node[i]; 00059 mesh_file>>y_node[i]; 00060 mesh_file>>vertinfo[i]; 00061 } 00062 00063 // Extra information (nodes lying on a curve) 00064 unsigned n_vx; 00065 mesh_file>>n_vx; 00066 00067 // Dummy storage for the node code 00068 int dummy_node_code; 00069 00070 // Storage for the curve indice 00071 Vector<int> icurv(n_vx); // it's negative if not used 00072 00073 // Dummy storage for the location of the point on the curve 00074 double dummy_ucurv; 00075 00076 for(unsigned i=0;i<n_vx;i++) 00077 { 00078 mesh_file>>dummy_node_code; 00079 mesh_file>>icurv[i]; 00080 mesh_file>>dummy_ucurv; 00081 } 00082 00083 // Number of local nodes per element 00084 unsigned n_local_node; 00085 mesh_file>>n_local_node; 00086 00087 // Number of elements 00088 unsigned n_element; 00089 mesh_file>>n_element; 00090 00091 // Storage for global node numbers for all elements 00092 Vector<unsigned> global_node(n_local_node*n_element); 00093 00094 // Storage for edge information 00095 // (needed for a possible construction of midside node 00096 // in the following build from scaffold function) 00097 Vector<int> edgeinfo(n_local_node*n_element); 00098 00099 // Initialize counter 00100 unsigned k=0; 00101 00102 // Read global node numbers for all elements 00103 for(unsigned i=0;i<n_element;i++) 00104 { 00105 for(unsigned j=0;j<n_local_node;j++) 00106 { 00107 mesh_file>>global_node[k]; 00108 k++; 00109 } 00110 } 00111 00112 // Initialize counter 00113 unsigned l=0; 00114 00115 // Read the edge information 00116 for(unsigned i=0;i<n_element;i++) 00117 { 00118 for(unsigned j=0;j<n_local_node;j++) 00119 { 00120 mesh_file>>edgeinfo[l]; 00121 l++; 00122 } 00123 } 00124 00125 mesh_file.close(); 00126 00127 // Create a vector of boolean so as not to create the same node twice 00128 std::vector<bool> done (n_node); 00129 for(unsigned i=0;i<n_node;i++) 00130 { 00131 done[i]=false; 00132 } 00133 00134 // Resize the Node vector 00135 Node_pt.resize(n_node,0); 00136 00137 // Resize the Element vector 00138 Element_pt.resize(n_element); 00139 00140 00141 // Process curve file to extract information about boundaries 00142 // ---------------------------------------------------------- 00143 00144 // Important: the input file must NOT have NURBS curve 00145 std::ifstream curve_file(curve_file_name.c_str(),std::ios_base::in); 00146 00147 // Number of curves 00148 unsigned n_curv; 00149 curve_file>>n_curv; 00150 00151 // Storage of several information for each curve 00152 Vector< Vector<int> > curv; 00153 00154 // Resize to n_curv rows 00155 curv.resize(n_curv); 00156 00157 // Curve type 00158 unsigned type; 00159 00160 // Loop over the curves to extract information 00161 for(unsigned i=0;i<n_curv;i++) 00162 { 00163 curve_file>>type; 00164 if(type==1) 00165 { 00166 curv[i].resize(4); 00167 curv[i][0]=type; 00168 for(unsigned j=1;j<4;j++) 00169 { 00170 curve_file>>curv[i][j]; 00171 } 00172 } 00173 else if(type==2) 00174 { 00175 curv[i].resize(5); 00176 curv[i][0]=type; 00177 for(unsigned j=1;j<5;j++) 00178 { 00179 curve_file>>curv[i][j]; 00180 } 00181 } 00182 else 00183 { 00184 std::ostringstream error_stream; 00185 error_stream << "Current we can only process curves of\n" 00186 << "type 1 (straight lines) and 2 (circular arcs\n" 00187 << "You've specified: type " << type << std::endl; 00188 00189 throw OomphLibError( 00190 error_stream.str(), 00191 "GeompackQuadScaffoldMesh::GeompackQuadScaffoldMesh()", 00192 OOMPH_EXCEPTION_LOCATION); 00193 } 00194 } 00195 00196 curve_file.close(); 00197 00198 // Searching the number of boundaries 00199 int d=0; 00200 for(unsigned i=0;i<n_curv;i++) 00201 { 00202 if(d<curv[i][1]) 00203 { 00204 d=curv[i][1]; // the boundary code is the 2nd value of each curve 00205 } 00206 } 00207 oomph_info<< "The number of boundaries is "<<d<<std::endl; 00208 00209 // Set number of boundaries 00210 if(d>0){ set_nboundary(d); } 00211 00212 // Search the boundary number of node located on a boundary 00213 // If after this, boundary_of_node[j][0] is -1 then node j 00214 // is not located on any boundary. 00215 // If boundary_of_node[j][0] is positive, the node is located 00216 // on the boundary indicated by that number. 00217 // If boundary_of_node[j][1] is also positive, the node is also 00218 // located on that boundary. Note: We're ignoring the (remote) 00219 // possibility that node is located on 3 or more boundaries 00220 // as one of them would have to be an internal boundary which 00221 // would be odd... 00222 Vector<Vector<int> > boundary_of_node; 00223 boundary_of_node.resize(n_node); 00224 unsigned n; 00225 for(unsigned i=0;i<n_node;i++) 00226 { 00227 n=0; 00228 boundary_of_node[i].resize(2); 00229 boundary_of_node[i][0]=-1; 00230 boundary_of_node[i][1]=-1; 00231 if(vertinfo[i]==2) // it's an endpoint 00232 { 00233 for(unsigned j=0;j<n_curv;j++) 00234 { 00235 for(unsigned m=2;m<curv[j].size();m++) 00236 { 00237 if(curv[j][m]==static_cast<int>(i+1)) // node number begins at 1 00238 { //in the mesh file !!! 00239 boundary_of_node[i][n]=curv[j][1]; 00240 n++; 00241 } 00242 } 00243 } 00244 } 00245 if(vertinfo[i]>20) 00246 { 00247 int a=0; 00248 a=(vertinfo[i])/20; 00249 int b; 00250 b=icurv[a-1]; // 1st value of vector at [0] !! 00251 boundary_of_node[i][0]=curv[b-1][1]; // 1st value of vector at [0] !! 00252 } 00253 } 00254 00255 00256 // Create the elements 00257 //-------------------- 00258 00259 unsigned count=0; 00260 unsigned c; 00261 for(unsigned e=0;e<n_element;e++) 00262 { 00263 // Build simplex four node quad in the scaffold mesh 00264 Element_pt[e]=new QElement<2,2>; 00265 00266 // Construction of the two first nodes of the element 00267 for(unsigned j=0;j<2;j++) 00268 { 00269 c=global_node[count]; 00270 if(done[c-1]==false) // c-1 because node number begins 00271 // at 1 in the mesh file 00272 { 00273 //If the node is located on a boundary construct a boundary node 00274 if((d>0) && ((boundary_of_node[c-1][0] > 0) || 00275 (boundary_of_node[c-1][1] > 0))) 00276 { 00277 //Construct a boundary node 00278 Node_pt[c-1] = finite_element_pt(e)->construct_boundary_node(j); 00279 //Add to the look=up schemes 00280 if(boundary_of_node[c-1][0] > 0) 00281 {add_boundary_node(boundary_of_node[c-1][0]-1,Node_pt[c-1]);} 00282 if(boundary_of_node[c-1][1] > 0) 00283 {add_boundary_node(boundary_of_node[c-1][1]-1,Node_pt[c-1]);} 00284 } 00285 //Otherwise construct a normal node 00286 else 00287 { 00288 Node_pt[c-1]=finite_element_pt(e)->construct_node(j); 00289 } 00290 done[c-1]=true; 00291 Node_pt[c-1]->x(0)=x_node[c-1]; 00292 Node_pt[c-1]->x(1)=y_node[c-1]; 00293 } 00294 else 00295 { 00296 finite_element_pt(e)->node_pt(j) = Node_pt[c-1]; 00297 } 00298 count++; 00299 } 00300 00301 // Construction of the third node not in anticlockwise order 00302 c=global_node[count+1]; 00303 if(done[c-1]==false) //c-1 because node number begins at 1 in the mesh file 00304 { 00305 //If the node is on a boundary, construct a boundary node 00306 if((d>0) && ((boundary_of_node[c-1][0]>0) || 00307 (boundary_of_node[c-1][1]>0))) 00308 { 00309 //Construct the node 00310 Node_pt[c-1] = finite_element_pt(e)->construct_boundary_node(2); 00311 //Add to the look-up schemes 00312 if(boundary_of_node[c-1][0]>0) 00313 {add_boundary_node(boundary_of_node[c-1][0]-1,Node_pt[c-1]);} 00314 if(boundary_of_node[c-1][1]>0) 00315 {add_boundary_node(boundary_of_node[c-1][1]-1,Node_pt[c-1]);} 00316 } 00317 //otherwise construct a normal node 00318 else 00319 { 00320 Node_pt[c-1]=finite_element_pt(e)->construct_node(2); 00321 } 00322 done[c-1]=true; 00323 Node_pt[c-1]->x(0)=x_node[c-1]; 00324 Node_pt[c-1]->x(1)=y_node[c-1]; 00325 } 00326 else 00327 { 00328 finite_element_pt(e)->node_pt(2) = Node_pt[c-1]; 00329 } 00330 00331 count++; 00332 00333 // Construction of the fourth node 00334 c=global_node[count-1]; 00335 if(done[c-1]==false) //c-1 because node number begins at 1 in the mesh file 00336 { 00337 //If the node is on a boundary, constuct a boundary node 00338 if((d>0) && ((boundary_of_node[c-1][0]>0) || 00339 (boundary_of_node[c-1][1]>0))) 00340 { 00341 //Construct the boundary node 00342 Node_pt[c-1] = finite_element_pt(e)->construct_boundary_node(3); 00343 //Add to the look-up schemes 00344 if(boundary_of_node[c-1][0]>0) 00345 {add_boundary_node(boundary_of_node[c-1][0]-1,Node_pt[c-1]);} 00346 if(boundary_of_node[c-1][1]>0) 00347 {add_boundary_node(boundary_of_node[c-1][1]-1,Node_pt[c-1]);} 00348 } 00349 //Otherwise construct a normal node 00350 else 00351 { 00352 Node_pt[c-1]=finite_element_pt(e)->construct_node(3); 00353 } 00354 done[c-1]=true; 00355 Node_pt[c-1]->x(0)=x_node[c-1]; 00356 Node_pt[c-1]->x(1)=y_node[c-1]; 00357 } 00358 else 00359 { 00360 finite_element_pt(e)->node_pt(3) = Node_pt[c-1]; 00361 } 00362 00363 count++; 00364 } 00365 00366 } 00367 00368 }
1.4.7