27   std::ostream& 
operator<<(std::ostream& o, 
const stored_mesh_slice& m) {
 
   28     o << 
"stored_mesh_slice, containing " << m.nb_convex() << 
" convexes\n";
 
   29     for (
size_type ic = 0; ic < m.nb_convex(); ++ic) {
 
   30       o << 
"slice convex #" << ic << 
" (original = " << m.convex_num(ic)
 
   32       for (
size_type i = 0; i < m.nodes(ic).size(); ++i) {
 
   33         o << 
"node " << i << 
": " << m.nodes(ic)[i].pt << 
", ref=" 
   34           << m.nodes(ic)[i].pt_ref << 
" flist=" << m.nodes(ic)[i].faces
 
   37       for (
size_type i = 0; i < m.simplexes(ic).size(); ++i) {
 
   38         o << 
"simplex " << i << 
", inodes=";
 
   39         for (
size_type j=0;j< m.simplexes(ic)[i].dim()+1;++j)
 
   40           o << m.simplexes(ic)[i].inodes[j] << 
" ";
 
   49                                         bool with_mesh)
 const {
 
   50     std::ofstream o(name.c_str());
 
   51     GMM_ASSERT1(o, 
"impossible to open file '" << name << 
"'");
 
   52     o << 
"% GETFEM SLICE FILE " << 
'\n';
 
   53     o << 
"% GETFEM VERSION " << GETFEM_VERSION << 
'\n' << 
'\n' << 
'\n';
 
   59     os << 
"\nBEGIN MESH_SLICE\n";
 
   60     os << 
" DIM " << int(
dim()) << 
"\n"; 
 
   61     for (
unsigned i=0; i < cvlst.size(); ++i) {
 
   62       const convex_slice &cs = cvlst[i];
 
   63       os << 
" CONVEX " << cs.cv_num 
 
   64          << 
" " << int(cs.fcnt)
 
   65          << 
" " << int(cs.discont) << 
"\n" 
   66          << 
" " << cs.nodes.size() << 
" " << cs.simplexes.size() << 
"\n";
 
   67       for (
unsigned j=0; j < cs.nodes.size(); ++j) {
 
   69         for (
unsigned k=0; k < cs.nodes[j].pt.size(); ++k) {
 
   71           os << cs.nodes[j].pt[k];
 
   74         for (
unsigned k=0; k < cs.nodes[j].pt_ref.size(); ++k)
 
   75           os << 
" " << cs.nodes[j].pt_ref[k];
 
   76         os << 
"; "; os << cs.nodes[j].faces.to_ulong();;
 
   79       for (
unsigned j=0; j < cs.simplexes.size(); ++j) {
 
   80         os << 
"\t" << cs.simplexes[j].inodes.size() << 
":";
 
   81         for (
unsigned k=0; k < cs.simplexes[j].inodes.size(); ++k) {
 
   82           os << 
" " << cs.simplexes[j].inodes[k];
 
   87     os << 
"END MESH_SLICE\n";
 
   92     std::ifstream o(name.c_str());
 
   93     GMM_ASSERT1(o, 
"slice file '" << name << 
"' does not exist");
 
   99     if (!poriginal_mesh) {
 
  101     } 
else GMM_ASSERT1(poriginal_mesh == &m, 
"wrong mesh..");
 
  109     ist.seekg(0);ist.clear();
 
  110     bgeot::read_until(ist, 
"BEGIN MESH_SLICE");
 
  112     mesh_slicer::cs_nodes_ct nod;
 
  113     mesh_slicer::cs_simplexes_ct sim;
 
  118       if (bgeot::casecmp(tmp, 
"END")==0) {
 
  120       } 
else if (bgeot::casecmp(tmp, 
"DIM")==0) {
 
  123       } 
else if (bgeot::casecmp(tmp, 
"CONVEX")==0) {
 
  126         GMM_ASSERT1(m.
convex_index().is_in(ic), 
"Convex " << ic <<
 
  127                     " does not exist, are you sure " 
  128                     "that the mesh attached to this object is right one ?");
 
  129         bgeot::pconvex_ref cvr = m.trans_of_convex(ic)->convex_ref();
 
  130         unsigned fcnt, discont, nbn, nbs;
 
  131         ist >> fcnt >> discont >> nbn >> nbs;
 
  134         for (
unsigned i=0; i < nbn; ++i) {
 
  135           nod[i].pt.resize(
dim()); 
 
  136           nod[i].pt_ref.resize(cvr->structure()->dim());
 
  137           for (
unsigned j=0; j < 
dim(); ++j) 
 
  139           ist >> bgeot::skip(
";");
 
  140           for (
unsigned j=0; j < cvr->structure()->
dim(); ++j) 
 
  141             ist >> nod[i].pt_ref[j];
 
  142           ist >> bgeot::skip(
";");
 
  143           unsigned long ul; ist >> ul;
 
  144           nod[i].faces = slice_node::faces_ct(
int(ul));
 
  146         for (
unsigned i=0; i < nbs; ++i) {
 
  148           ist >> np >> bgeot::skip(
":");
 
  149           GMM_ASSERT1(np <= 
dim()+1, 
"invalid simplex..");
 
  150           sim[i].inodes.resize(np);
 
  151           for (
unsigned j=0; j < np; ++j) 
 
  152             ist >> sim[i].inodes[j];
 
  154         dal::bit_vector bv; bv.add(0, nbs);
 
  155         set_convex(ic, cvr, nod, sim, dim_type(fcnt), bv, discont);
 
  156       } 
else if (tmp.size()) {
 
  157         GMM_ASSERT1(
false, 
"Unexpected token '" << tmp <<
 
  158                     "' [pos=" << std::streamoff(ist.tellg()) << 
"]");
 
  159       } 
else if (ist.eof()) {
 
  160         GMM_ASSERT1(
false, 
"Unexpected end of stream " 
  161                     << 
"(missing BEGIN MESH_SLICE/END MESH_SLICE ?)");
 
  166   void slicer_build_stored_mesh_slice::exec(
mesh_slicer &ms) {
 
  167     if (!sl.poriginal_mesh) {
 
  168       sl.poriginal_mesh = &ms.m;
 
  172     } 
else if (sl.poriginal_mesh != &ms.m) GMM_ASSERT1(
false, 
"wrong mesh..");
 
  173     sl.set_convex(ms.cv, ms.cvr, ms.nodes, ms.simplexes, dim_type(ms.fcnt),
 
  174                   ms.splx_in, ms.discont);
 
  177   void stored_mesh_slice::set_convex(
size_type cv, bgeot::pconvex_ref cvr, 
 
  178                                      mesh_slicer::cs_nodes_ct cv_nodes, 
 
  179                                      mesh_slicer::cs_simplexes_ct cv_simplexes,
 
  181                                      const dal::bit_vector& splx_in,
 
  184     if (splx_in.card() == 0) 
return;
 
  185     merged_nodes_available = 
false;
 
  186     std::vector<size_type> nused(cv_nodes.size(), 
size_type(-1));
 
  187     convex_slice *sc = 0;
 
  188     GMM_ASSERT1(cv < cv2pos.size(), 
"internal error");
 
  190       cv2pos[cv] = cvlst.size();
 
  191       cvlst.push_back(convex_slice());
 
  194       sc->cv_dim = cvr->structure()->dim();
 
  195       sc->cv_nbfaces = dim_type(cvr->structure()->nb_faces());
 
  197       sc->global_points_count = points_cnt;
 
  198       sc->discont = discont;
 
  200       sc = &cvlst[cv2pos[cv]];
 
  201       assert(sc->cv_num == cv);
 
  203     for (dal::bv_visitor snum(splx_in); !snum.finished(); ++snum) {
 
  204       slice_simplex& s = cv_simplexes[snum];
 
  205       for (
size_type i=0; i < s.dim()+1; ++i) {
 
  208           nused[lnum] = sc->nodes.size(); sc->nodes.push_back(cv_nodes[lnum]);
 
  209           dim_ = std::max(
int(dim_), 
int(cv_nodes[lnum].pt.size()));
 
  212         s.inodes[i] = nused[lnum];
 
  214       simplex_cnt.resize(dim_+1, 0);
 
  215       simplex_cnt[cv_simplexes[snum].dim()]++;
 
  216       sc->simplexes.push_back(cv_simplexes[snum]);
 
  220   struct get_edges_aux {
 
  222     mutable bool slice_edge;
 
  224       iA(std::min(a,b)), iB(std::max(a,b)), slice_edge(slice_edge_) {}
 
  225     bool operator<(
const get_edges_aux& other)
 const {
 
  227       return (iA < other.iA || (iA == other.iA && iB < other.iB));
 
  232                                     dal::bit_vector &slice_edges,
 
  233                                     bool from_merged_nodes)
 const {
 
  234     if (from_merged_nodes && !merged_nodes_available) 
merge_nodes();
 
  235     std::set<get_edges_aux> e;
 
  236     for (cvlst_ct::const_iterator it=cvlst.begin(); it != cvlst.end(); ++it) {
 
  237       for (
size_type is=0; is < it->simplexes.size(); ++is) {
 
  238         const slice_simplex &s = it->simplexes[is];
 
  240           for (
size_type j=i+1; j <= s.dim(); ++j) {
 
  241             const slice_node& A = it->nodes[s.inodes[i]];
 
  242             const slice_node& B = it->nodes[s.inodes[j]];
 
  245             if ((A.faces & B.faces).count() >= 
unsigned(it->cv_dim-1)) {
 
  246               slice_node::faces_ct fmask((1 << it->cv_nbfaces)-1);
 
  249               iA = it->global_points_count + s.inodes[i];
 
  250               iB = it->global_points_count + s.inodes[j];
 
  251               if (from_merged_nodes) {
 
  252                 iA = to_merged_index[iA]; iB = to_merged_index[iB];
 
  254               get_edges_aux a(iA,iB,((A.faces & B.faces) & fmask).any());
 
  255               std::set<get_edges_aux>::iterator p=e.find(a);
 
  257                 if (p->slice_edge && !a.slice_edge) p->slice_edge = 
false;
 
  264     slice_edges.clear(); slice_edges.sup(0, e.size());
 
  265     edges.clear(); edges.reserve(2*e.size());
 
  266     for (std::set<get_edges_aux>::const_iterator p=e.begin();
 
  268       if (p->slice_edge) slice_edges.add(edges.size()/2);
 
  269       edges.push_back(p->iA);edges.push_back(p->iB);
 
  281     if (b) slicer.push_back_action(*
const_cast<slicer_action*
>(b));
 
  282     if (c) slicer.push_back_action(*
const_cast<slicer_action*
>(c));
 
  284     slicer.push_back_action(sbuild);
 
  285     slicer.exec(nrefine);
 
  289                                  slicer_action *c)
 const {
 
  291     slicer.push_back_action(*a); 
 
  292     if (b) slicer.push_back_action(*b);
 
  293     if (c) slicer.push_back_action(*c);
 
  300       for (mesh_slicer::cs_nodes_ct::iterator it=
nodes(ic).begin();
 
  301            it != 
nodes(ic).end(); ++it) {
 
  302         it->pt.resize(newdim);
 
  308     GMM_ASSERT1(
dim()==sl.
dim(), 
"inconsistent dimensions for slice merging");
 
  309     clear_merged_nodes();
 
  310     cv2pos.resize(std::max(cv2pos.size(), sl.cv2pos.size()), 
size_type(-1));
 
  313                   cvlst[cv2pos[sl.
convex_num(i)]].cv_dim == sl.cvlst[i].cv_num,
 
  314                   "inconsistent dimensions for convex " << sl.cvlst[i].cv_num
 
  315                   << 
" on the slices");
 
  319         cv2pos[cv] = cvlst.size();
 
  320         cvlst.push_back(convex_slice());
 
  322       const stored_mesh_slice::convex_slice *src = &sl.cvlst[i];
 
  323       stored_mesh_slice::convex_slice *dst = &cvlst[cv2pos[cv]];
 
  325       dst->nodes.insert(dst->nodes.end(), src->nodes.begin(),
 
  327       for (mesh_slicer::cs_simplexes_ct::const_iterator
 
  328              it = src->simplexes.begin(); it != src->simplexes.end(); ++it) {
 
  329         dst->simplexes.push_back(*it);
 
  330         for (
size_type j = 0; j < (*it).dim()+1; ++j)
 
  331           dst->simplexes.back().inodes[j] += n;        
 
  332         simplex_cnt[dst->simplexes.back().dim()]++;
 
  334       points_cnt += src->nodes.size();
 
  338       cvlst[ic].global_points_count = count; count += 
nodes(ic).size();
 
  340     assert(count == points_cnt);
 
  343   void stored_mesh_slice::clear_merged_nodes()
 const { 
 
  344     merged_nodes_idx.clear(); merged_nodes.clear(); 
 
  345     to_merged_index.clear();
 
  346     merged_nodes_available = 
false; 
 
  352     clear_merged_nodes();
 
  353     std::vector<size_type> iv;
 
  354     std::vector<const slice_node*> nv(
nb_points());
 
  356     for (cvlst_ct::const_iterator it = cvlst.begin(); it != cvlst.end(); ++it) {
 
  357       for (
size_type i=0; i < it->nodes.size(); ++i) {
 
  358         nv[count] = &it->nodes[i];
 
  359         to_merged_index[count++] = mp.add_point(it->nodes[i].pt);
 
  364     gmm::sorted_indexes(to_merged_index,iv);
 
  369     merged_nodes_idx.push_back(0);
 
  371       merged_nodes[i].P = nv[iv[i]];
 
  372       merged_nodes[i].pos = unsigned(iv[i]);
 
  376           to_merged_index[iv[i+1]] != to_merged_index[iv[i]]) 
 
  377         merged_nodes_idx.push_back(i+1);
 
  380     merged_nodes_available = 
true;
 
  383   size_type stored_mesh_slice::memsize()
 const {
 
  385     for (cvlst_ct::const_iterator it = cvlst.begin();
 
  386          it != cvlst.end(); ++it) {
 
  391       for (
size_type i=0; i < it->nodes.size(); ++i) {
 
  396         sz += 
sizeof(slice_node) + 
 
  397           (it->nodes[i].pt.memsize()+it->nodes[i].pt_ref.memsize())
 
  398           - 
sizeof(it->nodes[i].pt)*2;
 
  400       for (
size_type i=0; i < it->simplexes.size(); ++i) {
 
  404         sz += 
sizeof(slice_simplex) + 
 
  405           it->simplexes[i].inodes.size()*
sizeof(
size_type);
 
Inversion of geometric transformations.
 
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
 
size_type nb_allocated_convex() const
The number of convex indexes from 0 to the index of the last convex.
 
Apply a serie a slicing operations to a mesh.
 
Describe a mesh (collection of convexes (elements) and points).
 
void write_to_file(const std::string &name) const
Write the mesh to a file.
 
a getfem::mesh_slicer whose side effect is to build a stored_mesh_slice object.
 
The output of a getfem::mesh_slicer which has been recorded.
 
size_type dim() const
return the slice dimension
 
void replay(slicer_action &a) const
Apply the listed slicer_action(s) to the slice object.
 
void set_dim(size_type newdim)
change the slice dimension (append zeros or truncate node coordinates..)
 
const mesh_slicer::cs_nodes_ct & nodes(size_type ic) const
Return the list of nodes for the 'ic'th convex of the slice.
 
void merge(const stored_mesh_slice &sl)
merge with another mesh slice.
 
const mesh & linked_mesh() const
return a pointer to the original mesh
 
void write_to_file(std::ostream &os) const
Save a slice content to a text file.
 
size_type nb_points() const
Return the number of nodes in the slice.
 
size_type nb_convex() const
return the number of convexes of the original mesh referenced in the slice
 
void read_from_file(std::istream &ist, const getfem::mesh &m)
Read a slice from a file.
 
void merge_nodes() const
build a list of merged nodes.
 
void get_edges(std::vector< size_type > &edges, dal::bit_vector &slice_edges, bool from_merged_nodes) const
Extract the list of mesh edges.
 
size_type convex_num(size_type ic) const
return the original convex number of the 'ic'th convex referenced in the slice
 
void build(const getfem::mesh &m, const slicer_action &a, size_type nrefine=1)
Build the slice, by applying a slicer_action operation.
 
Define the class getfem::stored_mesh_slice.
 
std::ostream & operator<<(std::ostream &o, const convex_structure &cv)
Print the details of the convex structure cvs to the output stream o.
 
int get_token(std::istream &ist, std::string &st, bool ignore_cr, bool to_up, bool read_un_pm, int *linenb)
Very simple lexical analysis of general interest for reading small languages with a "MATLAB like" syn...
 
size_t size_type
used as the common size type in the library
 
GEneric Tool for Finite Element Methods.