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.