26 std::ostream&
operator<<(std::ostream& o,
const stored_mesh_slice& m) {
27 o <<
"stored_mesh_slice, containing " << m.nb_convex() <<
" convexes\n";
28 for (
size_type ic = 0; ic < m.nb_convex(); ++ic) {
29 o <<
"slice convex #" << ic <<
" (original = " << m.convex_num(ic)
31 for (
size_type i = 0; i < m.nodes(ic).size(); ++i) {
32 o <<
"node " << i <<
": " << m.nodes(ic)[i].pt <<
", ref="
33 << m.nodes(ic)[i].pt_ref <<
" flist=" << m.nodes(ic)[i].faces
36 for (
size_type i = 0; i < m.simplexes(ic).size(); ++i) {
37 o <<
"simplex " << i <<
", inodes=";
38 for (
size_type j=0;j< m.simplexes(ic)[i].dim()+1;++j)
39 o << m.simplexes(ic)[i].inodes[j] <<
" ";
48 bool with_mesh)
const {
49 std::ofstream o(name.c_str());
50 GMM_ASSERT1(o,
"impossible to open file '" << name <<
"'");
51 o <<
"% GETFEM SLICE FILE " <<
'\n';
52 o <<
"% GETFEM VERSION " << GETFEM_VERSION <<
'\n' <<
'\n' <<
'\n';
58 os <<
"\nBEGIN MESH_SLICE\n";
59 os <<
" DIM " << int(
dim()) <<
"\n";
60 for (
unsigned i=0; i < cvlst.size(); ++i) {
61 const convex_slice &cs = cvlst[i];
62 os <<
" CONVEX " << cs.cv_num
63 <<
" " << int(cs.fcnt)
64 <<
" " << int(cs.discont) <<
"\n"
65 <<
" " << cs.nodes.size() <<
" " << cs.simplexes.size() <<
"\n";
66 for (
unsigned j=0; j < cs.nodes.size(); ++j) {
68 for (
unsigned k=0; k < cs.nodes[j].pt.size(); ++k) {
70 os << cs.nodes[j].pt[k];
73 for (
unsigned k=0; k < cs.nodes[j].pt_ref.size(); ++k)
74 os <<
" " << cs.nodes[j].pt_ref[k];
75 os <<
"; "; os << cs.nodes[j].faces.to_ulong();;
78 for (
unsigned j=0; j < cs.simplexes.size(); ++j) {
79 os <<
"\t" << cs.simplexes[j].inodes.size() <<
":";
80 for (
unsigned k=0; k < cs.simplexes[j].inodes.size(); ++k) {
81 os <<
" " << cs.simplexes[j].inodes[k];
86 os <<
"END MESH_SLICE\n";
91 std::ifstream o(name.c_str());
92 GMM_ASSERT1(o,
"slice file '" << name <<
"' does not exist");
98 if (!poriginal_mesh) {
100 }
else GMM_ASSERT1(poriginal_mesh == &m,
"wrong mesh..");
108 ist.seekg(0);ist.clear();
109 bgeot::read_until(ist,
"BEGIN MESH_SLICE");
111 mesh_slicer::cs_nodes_ct nod;
112 mesh_slicer::cs_simplexes_ct sim;
117 if (bgeot::casecmp(tmp,
"END")==0) {
119 }
else if (bgeot::casecmp(tmp,
"DIM")==0) {
122 }
else if (bgeot::casecmp(tmp,
"CONVEX")==0) {
125 GMM_ASSERT1(m.
convex_index().is_in(ic),
"Convex " << ic <<
126 " does not exist, are you sure "
127 "that the mesh attached to this object is right one ?");
128 bgeot::pconvex_ref cvr = m.trans_of_convex(ic)->convex_ref();
129 unsigned fcnt, discont, nbn, nbs;
130 ist >> fcnt >> discont >> nbn >> nbs;
133 for (
unsigned i=0; i < nbn; ++i) {
134 nod[i].pt.resize(
dim());
135 nod[i].pt_ref.resize(cvr->structure()->dim());
136 for (
unsigned j=0; j <
dim(); ++j)
138 ist >> bgeot::skip(
";");
139 for (
unsigned j=0; j < cvr->structure()->
dim(); ++j)
140 ist >> nod[i].pt_ref[j];
141 ist >> bgeot::skip(
";");
142 unsigned long ul; ist >> ul;
143 nod[i].faces = slice_node::faces_ct(
int(ul));
145 for (
unsigned i=0; i < nbs; ++i) {
147 ist >> np >> bgeot::skip(
":");
148 GMM_ASSERT1(np <=
dim()+1,
"invalid simplex..");
149 sim[i].inodes.resize(np);
150 for (
unsigned j=0; j < np; ++j)
151 ist >> sim[i].inodes[j];
153 dal::bit_vector bv; bv.add(0, nbs);
154 set_convex(ic, cvr, nod, sim, dim_type(fcnt), bv, discont);
155 }
else if (tmp.size()) {
156 GMM_ASSERT1(
false,
"Unexpected token '" << tmp <<
157 "' [pos=" << std::streamoff(ist.tellg()) <<
"]");
158 }
else if (ist.eof()) {
159 GMM_ASSERT1(
false,
"Unexpected end of stream "
160 <<
"(missing BEGIN MESH_SLICE/END MESH_SLICE ?)");
165 void slicer_build_stored_mesh_slice::exec(
mesh_slicer &ms) {
166 if (!sl.poriginal_mesh) {
167 sl.poriginal_mesh = &ms.m;
171 }
else if (sl.poriginal_mesh != &ms.m) GMM_ASSERT1(
false,
"wrong mesh..");
172 sl.set_convex(ms.cv, ms.cvr, ms.nodes, ms.simplexes, dim_type(ms.fcnt),
173 ms.splx_in, ms.discont);
176 void stored_mesh_slice::set_convex(
size_type cv, bgeot::pconvex_ref cvr,
177 mesh_slicer::cs_nodes_ct cv_nodes,
178 mesh_slicer::cs_simplexes_ct cv_simplexes,
180 const dal::bit_vector& splx_in,
183 if (splx_in.card() == 0)
return;
184 merged_nodes_available =
false;
185 std::vector<size_type> nused(cv_nodes.size(),
size_type(-1));
186 convex_slice *sc = 0;
187 GMM_ASSERT1(cv < cv2pos.size(),
"internal error");
189 cv2pos[cv] = cvlst.size();
190 cvlst.push_back(convex_slice());
193 sc->cv_dim = cvr->structure()->dim();
194 sc->cv_nbfaces = dim_type(cvr->structure()->nb_faces());
196 sc->global_points_count = points_cnt;
197 sc->discont = discont;
199 sc = &cvlst[cv2pos[cv]];
200 assert(sc->cv_num == cv);
202 for (dal::bv_visitor snum(splx_in); !snum.finished(); ++snum) {
203 slice_simplex& s = cv_simplexes[snum];
204 for (
size_type i=0; i < s.dim()+1; ++i) {
207 nused[lnum] = sc->nodes.size(); sc->nodes.push_back(cv_nodes[lnum]);
208 dim_ = std::max(
int(dim_),
int(cv_nodes[lnum].pt.size()));
211 s.inodes[i] = nused[lnum];
213 simplex_cnt.resize(dim_+1, 0);
214 simplex_cnt[cv_simplexes[snum].dim()]++;
215 sc->simplexes.push_back(cv_simplexes[snum]);
219 struct get_edges_aux {
221 mutable bool slice_edge;
223 iA(std::min(a,b)), iB(std::max(a,b)), slice_edge(slice_edge_) {}
224 bool operator<(
const get_edges_aux& other)
const {
226 return (iA < other.iA || (iA == other.iA && iB < other.iB));
231 dal::bit_vector &slice_edges,
232 bool from_merged_nodes)
const {
233 if (from_merged_nodes && !merged_nodes_available)
merge_nodes();
234 std::set<get_edges_aux> e;
235 for (cvlst_ct::const_iterator it=cvlst.begin(); it != cvlst.end(); ++it) {
236 for (
size_type is=0; is < it->simplexes.size(); ++is) {
237 const slice_simplex &s = it->simplexes[is];
239 for (
size_type j=i+1; j <= s.dim(); ++j) {
240 const slice_node& A = it->nodes[s.inodes[i]];
241 const slice_node& B = it->nodes[s.inodes[j]];
244 if ((A.faces & B.faces).count() >=
unsigned(it->cv_dim-1)) {
245 slice_node::faces_ct fmask((1 << it->cv_nbfaces)-1);
248 iA = it->global_points_count + s.inodes[i];
249 iB = it->global_points_count + s.inodes[j];
250 if (from_merged_nodes) {
251 iA = to_merged_index[iA]; iB = to_merged_index[iB];
253 get_edges_aux a(iA,iB,((A.faces & B.faces) & fmask).any());
254 std::set<get_edges_aux>::iterator p=e.find(a);
256 if (p->slice_edge && !a.slice_edge) p->slice_edge =
false;
263 slice_edges.clear(); slice_edges.sup(0, e.size());
264 edges.clear(); edges.reserve(2*e.size());
265 for (std::set<get_edges_aux>::const_iterator p=e.begin();
267 if (p->slice_edge) slice_edges.add(edges.size()/2);
268 edges.push_back(p->iA);edges.push_back(p->iB);
280 if (b) slicer.push_back_action(*
const_cast<slicer_action*
>(b));
281 if (c) slicer.push_back_action(*
const_cast<slicer_action*
>(c));
283 slicer.push_back_action(sbuild);
284 slicer.exec(nrefine);
288 slicer_action *c)
const {
290 slicer.push_back_action(*a);
291 if (b) slicer.push_back_action(*b);
292 if (c) slicer.push_back_action(*c);
299 for (mesh_slicer::cs_nodes_ct::iterator it=
nodes(ic).begin();
300 it !=
nodes(ic).end(); ++it) {
301 it->pt.resize(newdim);
307 GMM_ASSERT1(
dim()==sl.
dim(),
"inconsistent dimensions for slice merging");
308 clear_merged_nodes();
309 cv2pos.resize(std::max(cv2pos.size(), sl.cv2pos.size()),
size_type(-1));
312 cvlst[cv2pos[sl.
convex_num(i)]].cv_dim == sl.cvlst[i].cv_num,
313 "inconsistent dimensions for convex " << sl.cvlst[i].cv_num
314 <<
" on the slices");
318 cv2pos[cv] = cvlst.size();
319 cvlst.push_back(convex_slice());
321 const stored_mesh_slice::convex_slice *src = &sl.cvlst[i];
322 stored_mesh_slice::convex_slice *dst = &cvlst[cv2pos[cv]];
324 dst->nodes.insert(dst->nodes.end(), src->nodes.begin(),
326 for (mesh_slicer::cs_simplexes_ct::const_iterator
327 it = src->simplexes.begin(); it != src->simplexes.end(); ++it) {
328 dst->simplexes.push_back(*it);
329 for (
size_type j = 0; j < (*it).dim()+1; ++j)
330 dst->simplexes.back().inodes[j] += n;
331 simplex_cnt[dst->simplexes.back().dim()]++;
333 points_cnt += src->nodes.size();
337 cvlst[ic].global_points_count = count; count +=
nodes(ic).size();
339 assert(count == points_cnt);
342 void stored_mesh_slice::clear_merged_nodes()
const {
343 merged_nodes_idx.clear(); merged_nodes.clear();
344 to_merged_index.clear();
345 merged_nodes_available =
false;
351 clear_merged_nodes();
352 std::vector<size_type> iv;
353 std::vector<const slice_node*> nv(
nb_points());
355 for (cvlst_ct::const_iterator it = cvlst.begin(); it != cvlst.end(); ++it) {
356 for (
size_type i=0; i < it->nodes.size(); ++i) {
357 nv[count] = &it->nodes[i];
358 to_merged_index[count++] = mp.add_point(it->nodes[i].pt);
363 gmm::sorted_indexes(to_merged_index,iv);
368 merged_nodes_idx.push_back(0);
370 merged_nodes[i].P = nv[iv[i]];
371 merged_nodes[i].pos = unsigned(iv[i]);
375 to_merged_index[iv[i+1]] != to_merged_index[iv[i]])
376 merged_nodes_idx.push_back(i+1);
379 merged_nodes_available =
true;
382 size_type stored_mesh_slice::memsize()
const {
384 for (cvlst_ct::const_iterator it = cvlst.begin();
385 it != cvlst.end(); ++it) {
390 for (
size_type i=0; i < it->nodes.size(); ++i) {
395 sz +=
sizeof(slice_node) +
396 (it->nodes[i].pt.memsize()+it->nodes[i].pt_ref.memsize())
397 -
sizeof(it->nodes[i].pt)*2;
399 for (
size_type i=0; i < it->simplexes.size(); ++i) {
403 sz +=
sizeof(slice_simplex) +
404 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.