MeshKit  1.0
MeshOp.cpp
Go to the documentation of this file.
00001 #include <assert.h>
00002 
00003 #include "meshkit/MeshOp.hpp"
00004 #include "meshkit/MKCore.hpp"
00005 #include "meshkit/ModelEnt.hpp"
00006 
00007 #include "lemon/adaptors.h"
00008 
00009 #include <set>
00010 
00011 namespace MeshKit 
00012 {
00013     
00014 MeshOp::MeshOp(const MeshOp &mesh_op) 
00015         : GraphNode(mesh_op)
00016 {
00017   debugLevel=0;
00018 }
00019   
00020 MeshOp::MeshOp(MKCore *mkcore, const MEntVector &me_vec) 
00021         : GraphNode(mkcore)
00022 {
00023   debugLevel=0;
00024   if (!me_vec.empty()) {
00025     for (MEntVector::const_iterator vit = me_vec.begin(); vit != me_vec.end(); vit++)
00026       mentSelection[*vit];
00027   }
00028 }
00029 
00030 void MeshOp::setup_boundary() 
00031 {
00032     // generic setup code; make sure there are MeshOp's for each of my bounding entities, and create
00033     // ones where necessary (based on default MeshOp for that dimension registered with MOF)
00034 
00035     // use separate MeshOps by dimension, since there may be multiple dimension entities in mentSelection
00036   MeshOp *this_op[] = {NULL, NULL, NULL, NULL};
00037 
00038   for (MEntSelection::iterator mit = mentSelection.begin(); mit != mentSelection.end(); mit++) {
00039     ModelEnt *this_ent = (*mit).first;
00040     int dim = this_ent->dimension();
00041     if (0 == dim) continue;
00042     if (this_ent->get_meshed_state()>=COMPLETE_MESH)
00043       continue;
00044 
00045     MEntVector children;
00046     this_ent->get_adjacencies(dim-1, children);
00047     for (MEntVector::iterator chit = children.begin(); chit != children.end(); chit++) {
00048       if ((*chit)->is_meshops_list_empty()) {
00049           // no meshop, need to get one associated with this
00050         if (!this_op[dim-1]) {
00051           this_op[dim-1] = mk_core()->construct_meshop(dim-1);
00052           if (!this_op[dim-1]) throw Error(MK_MESHOP_NOT_FOUND, "No default meshop for this dimension.");
00053         }
00054         this_op[dim-1]->add_modelent(*chit);
00055       }
00056     }
00057   }
00058 
00059   // VertexMesher should be inserted after root node to be done before other meshops
00060   // It is because the VertexMesher instance is only one
00061   if (this_op[0]) {
00062     mk_core()->insert_node(this_op[0], this, mk_core()->root_node());
00063   }
00064 
00065   for (int dim = 1; dim <= 3; dim++) {
00066     if (this_op[dim])
00067       mk_core()->insert_node(this_op[dim], this);
00068   }
00069 }
00070 
00071 // TODO: Split this into separate functions, one for ensuring dependence
00072 // on a list of meshops, and the other for doing it with boundary
00073 void MeshOp::ensure_facet_dependencies(bool recurse_to_facets)
00074 {
00075   std::set<MeshOp*> allFacetMOps;
00076 
00077   for (MEntSelection::iterator mit = mentSelection.begin();
00078       mit != mentSelection.end(); ++mit)
00079   {
00080     ModelEnt *aSelEnt = (*mit).first;
00081     int dim = aSelEnt->dimension();
00082     if (dim == 0 || aSelEnt->get_meshed_state() >= COMPLETE_MESH)
00083     {
00084       continue;
00085     }
00086 
00087     MEntVector facets;
00088     aSelEnt->get_adjacencies(dim - 1, facets);
00089     for (MEntVector::iterator facetItr = facets.begin();
00090         facetItr != facets.end(); ++facetItr)
00091     {
00092       std::vector<MeshOp*> facetMOps;
00093       (*facetItr)->get_meshops(facetMOps);
00094       allFacetMOps.insert(facetMOps.begin(), facetMOps.end());
00095     }
00096   }
00097 
00098 
00099   // if recursing, keep track of mops found so we can recurse on them
00100   std::vector<MeshOp*> mopsFound;
00101 
00102   lemon::ReverseDigraph<lemon::ListDigraph>
00103       revGraph(this->get_graph()->get_graph());
00104   lemon::Bfs<lemon::ReverseDigraph<lemon::ListDigraph> > rbfs(revGraph);
00105   rbfs.init();
00106   rbfs.addSource(this->get_node());
00107   while (!rbfs.emptyQueue() && !allFacetMOps.empty())
00108   {
00109     lemon::ListDigraph::Node lemNode = rbfs.processNextNode();
00110     MeshOp* mkMOp = this->get_graph()->get_meshop(lemNode);
00111     std::set<MeshOp*>::iterator opFoundItr = allFacetMOps.find(mkMOp);
00112     if (opFoundItr != allFacetMOps.end())
00113     {
00114       if (recurse_to_facets)
00115       {
00116         mopsFound.push_back(mkMOp);
00117       }
00118       allFacetMOps.erase(opFoundItr);
00119     }
00120   }
00121 
00122   // insert direct dependencies on MeshOps not found in the graph
00123   for (std::set<MeshOp*>::iterator mOpItr = allFacetMOps.begin();
00124       mOpItr != allFacetMOps.end(); ++mOpItr)
00125   {
00126     this->get_graph()->add_arc(*mOpItr, this);
00127   }
00128 
00129   if (recurse_to_facets)
00130   {
00131     // recurse to facets that this did not previously depend on
00132     for (std::set<MeshOp*>::iterator mOpItr = allFacetMOps.begin();
00133         mOpItr != allFacetMOps.end(); ++mOpItr)
00134     {
00135       (*mOpItr)->ensure_facet_dependencies(true);
00136     }
00137     // recurse to facets that this already depended on
00138     for (std::vector<MeshOp*>::iterator mOpItr = mopsFound.begin();
00139         mOpItr != mopsFound.end(); ++mOpItr)
00140     {
00141       (*mOpItr)->ensure_facet_dependencies(true);
00142     }
00143   }
00144 
00145   return;
00146 }
00147 
00148 bool MeshOp::canmesh_vertex(ModelEnt *model_ent) 
00149 {
00150   return (model_ent->dimension() == 0);
00151 }
00152 
00153 bool MeshOp::canmesh_edge(ModelEnt *model_ent)
00154 {
00155   return (model_ent->dimension() == 1);
00156 }
00157 
00158 bool MeshOp::canmesh_face(ModelEnt *model_ent)
00159 {
00160   return (model_ent->dimension() == 2);
00161 }
00162 
00163 bool MeshOp::canmesh_region(ModelEnt *model_ent)
00164 {
00165   return (model_ent->dimension() == 3);
00166 }
00167 
00168 bool MeshOp::add_modelent(ModelEnt *model_ent) 
00169 {
00170   MEntSelection::iterator sit = mentSelection.find(model_ent);
00171   if (sit != mentSelection.end()) return false;
00172   
00173   mentSelection[model_ent];
00174 
00175   // add meshop back to model ent
00176   model_ent->add_meshop(this);
00177   
00178   return true;
00179 }
00180 
00181 bool MeshOp::remove_modelent(ModelEnt *model_ent) 
00182 {
00183   MEntSelection::iterator sit = mentSelection.find(model_ent);
00184   if (sit != mentSelection.end()) {
00185     mentSelection.erase(sit);
00186     return true;
00187   }
00188   else return false;
00189 }
00190 
00191 MeshOp::~MeshOp()
00192 {
00193 }
00194 
00195 void MeshOp::mesh_types(std::vector<moab::EntityType> &mesh_types) 
00196 {
00197   const moab::EntityType* types = mesh_types_arr();
00198   for (int i = 0; types[i] != moab::MBMAXTYPE; ++i)
00199     mesh_types.push_back(types[i]);
00200 }
00201 
00202 #ifdef HAVE_FBIGEOM
00203 void MeshOp::create_model_ents_from_previous_ops()
00204 {
00205   // model ents are empty so far...
00206   GraphNode * prevNode = other_node(in_arcs());// assumes one incoming edge!!
00207 
00208   MeshOp * prevOp = reinterpret_cast<MeshOp*> (prevNode);
00209   std::string nameOp = prevNode->get_name();
00210 
00211   if (NULL==prevOp)
00212     return;
00213   // if the previous op is MBSplitOp or MBGeomOp, we know what to do
00214   if ( !(nameOp == "MBGeomOp" || nameOp == "MBSplitOp"))
00215   {
00216     return; // do not process yet other OPs
00217   }
00218 
00219 
00220   MEntSelection & mentsel = prevOp->me_selection();
00221   if (mentsel.empty())
00222     return;
00223   ModelEnt * firstMe = (*(mentsel.begin()) ).first;
00224   moab::Range prevModelSet = mentsel[firstMe];
00225 
00226   if (prevModelSet.size()!=1)
00227    return;
00228 
00229   // this range has one set that can serve as basis for
00230   // mesh based geometry
00231   // the model ents have no model tag on the sets!!
00232   iGeom::EntitySetHandle rootSet = (iGeom::EntitySetHandle) prevModelSet[0];
00233 
00234   int latestGeomIndex = mk_core()->initialize_mesh_based_geometry(rootSet);
00235 
00236   MEntVector model_ents;
00237   // get the model entities of dimension 2, created with the latest FBiGeom!!!
00238   mk_core()->get_entities_by_dimension(2, model_ents, latestGeomIndex);
00239 
00240   // add it to the mentSelection!!
00241   if (model_ents.size()==0)
00242     return; // nothing to mesh .... could be an infinite loop maybe we should abort
00243   for (unsigned int i = 0; i<model_ents.size(); i++)
00244   {
00245     moab::Range rr = mentSelection[model_ents[i]];
00246     rr.clear(); // just to use it , to avoid some warnings
00247   }
00248 
00249   /*// redo the setup for the op, as we added more entities
00250   setup_this();
00251   // we will have to also execute operations before this ...
00252   mk_core()->setup_and_execute();// will relaunch the whole execute// some are marked as
00253   // executed, so no worries*/
00254 
00255 }
00256 #endif
00257 
00258 }
00259 
00260   
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines