Example codes
and tutorials
The (Not-so) Quick Guide
List of tutorials/demo codes
Single-Physics Problems
Poisson
Adaptivity illustrated for Poisson
Advection-Diffusion
Unsteady heat equation
Linear wave equation
The Young-Laplace equation
Navier-Stokes
Free-surface Navier-Stokes
Axisymmetric Navier-Stokes
Solid mechanics
Beam structures
Shell structures
Multi-physics Problems
Fluid-structure interaction
Boussinesq convection
Steady thermoelasticity
Methods-based example codes and tutorials
Mesh generation
Linear solvers and preconditioners
Visualisation of the results
Parallel processing
How to write a new element
How to write a new refineable element
Default nonlinear solvers -- the sequence of action functions
...
Documentation
FE theory and top-down discussion of the data structure
The (Not-so) Quick Guide
Comprehensive bottom-up discussion of the data structure
List of available structured and unstructured meshes
Linear solvers and preconditioners
Visualisation of the results
Parallel processing
Coding conventions and C++ style
Creating documentation
Optimisation - robustness vs. "raw speed"
Linear vs. nonlinear problems
Storing shape functions
Changing the default "full" integration scheme
Disabling the ALE formulation of unsteady equations
C vs. C++ output
Different sparse assembly techniques and the STL memory pool
Publications
Publications
Talks
Journal publications
Theses
Picture show
Download
Copyright
Download/installation instructions
Download page
FAQ & Contact
FAQ
Change log
Bugs and other known problems
Completeness of the library & our "To-Do List"
Contact the developers
Get involved

 


Beta release!

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

oomph-lib AT maths DOT man DOT ac DOT uk

if you wish to be informed of the library's "official" release.

geompack_scaffold_mesh.cc

Go to the documentation of this file.
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 }

Generated on Mon Aug 10 11:23:46 2009 by  doxygen 1.4.7