16#include <Linear_algebra_tools_impl.h>
17#include <Connectivite_som_elem.h>
18#include <MD_Vector_composite.h>
19#include <Domaine_Poly_base.h>
20#include <MD_Vector_tools.h>
21#include <Interface_blocs.h>
22#include <Comm_Group_MPI.h>
23#include <Quadrangle_VEF.h>
24#include <communications.h>
25#include <Matrice_Morse.h>
26#include <Segment_poly.h>
27#include <Hexaedre_VEF.h>
28#include <Matrix_tools.h>
29#include <unordered_map>
30#include <Array_tools.h>
31#include <Quadri_poly.h>
32#include <Tetra_poly.h>
33#include <TRUSTLists.h>
57bool polymac_flica5=
false;
63 os <<
"____ h_carre "<<finl;
65 os <<
"____ type_elem_ "<<finl;
66 os << type_elem_.valeur() << finl;
67 os <<
"____ nb_elem_std_ "<<finl;
69 os <<
"____ volumes_entrelaces_ "<<finl;
71 os <<
"____ face_normales_ "<<finl;
73 os <<
"____ nb_faces_std_ "<<finl;
75 os <<
"____ rang_elem_non_std_ "<<finl;
85 os << type_elem_.valeur() << finl;
105 if (type ==
"Tri_poly")
106 type_elem_ = Tri_poly();
107 else if (type ==
"Tetra_poly")
108 type_elem_ = Tetra_poly();
109 else if (type ==
"Quadri_poly")
110 type_elem_ = Quadri_poly();
111 else if (type ==
"Hexa_poly")
112 type_elem_ = Hexa_poly();
115 Cerr << type <<
" is not an Elem_poly !" << finl;
133 const Elem_geom_base& elem_geom = domaine_geom.type_elem().valeur();
135 if (sub_type(Rectangle, elem_geom))
137 domaine_geom.
typer(
"Quadrangle");
139 else if (sub_type(Hexaedre, elem_geom))
140 domaine_geom.
typer(
"Hexaedre_VEF");
142 const Nom& type_elem_geom = domaine_geom.type_elem()->
que_suis_je();
144 Cerr <<
"Elem_poly => type geometrique : " << type_elem_geom << finl;
147 if (type_elem_geom ==
"Triangle")
149 else if (type_elem_geom ==
"Tetraedre")
151 else if (type_elem_geom ==
"Quadrangle")
152 type =
"Quadri_poly";
153 else if (type_elem_geom ==
"Hexaedre_VEF")
155 else if (type_elem_geom ==
"Segment")
156 type =
"Segment_poly";
157 else if (type_elem_geom ==
"Polygone")
158 type =
"Polygone_poly";
159 else if (type_elem_geom ==
"Polyedre")
160 type =
"Polyedre_poly";
163 Cerr <<
"problem in Elem_poly::typer" << finl;
166 type_elem_.typer(type);
167 Cerr <<
"Elem_poly => type retenu : " << type_elem_->
que_suis_je() << finl;
172 const Elem_geom_base& elem_geom =
domaine().type_elem().valeur();
176 if (!sub_type(Segment,elem_geom))
178 Cerr <<
" The type of the element " << elem_geom.
que_suis_je() <<
" is incorrect" << finl;
182 else if (sub_type(
Tri_poly,type_elem_.valeur()))
184 if (!sub_type(Triangle,elem_geom))
186 Cerr <<
" The type of the element " << elem_geom.
que_suis_je() <<
" is incorrect" << finl;
187 Cerr <<
" Only the Triangle type is compatible with the PolyMAC_MPFA discretisation in dimension 2" << finl;
188 Cerr <<
" You must triangulate the domain when using the TRUST mesher" ;
189 Cerr <<
" This can be done by adding : Trianguler nom_dom" << finl;
193 else if (sub_type(
Tetra_poly,type_elem_.valeur()))
195 if (!sub_type(Tetraedre,elem_geom))
197 Cerr <<
" The type of the element " << elem_geom.
que_suis_je() <<
" is incorrect" << finl;
198 Cerr <<
" Only the Tetrahedral type is compatible with the PolyMAC_MPFA discretisation in dimension 3" << finl;
199 Cerr <<
" You must tetrahedrize the domain when using the TRUST mesher" ;
200 Cerr <<
" This can be done by adding : Tetraedriser nom_dom" << finl;
205 else if (sub_type(
Quadri_poly,type_elem_.valeur()))
208 if (!sub_type(Quadrangle_VEF,elem_geom))
210 Cerr <<
" The type of the element " << elem_geom.
que_suis_je() <<
" is incorrect" << finl;
214 else if (sub_type(
Hexa_poly,type_elem_.valeur()))
217 if (!sub_type(Hexaedre_VEF,elem_geom))
219 Cerr <<
" The type of the element " << elem_geom.
que_suis_je() <<
" is incorrect" << finl;
238 for (
int i = debut; i < fin; i++)
241 face_vois(i, 0) = face_vois(i, 1);
242 face_vois(i, 1) = -1;
266 std::map<std::array<double, 3>,
int> xv_fsa;
271 for (
auto &&c_f : xv_fsa)
elem_faces_(e, j) = c_f.second, j++;
289 for (
int f = 0; f < nf_tot; f++)
294 for (
int f = 0; f < nf_tot; f++)
303 Cerr <<
"pb in faces_normales" << finl;
310 std::swap(face_vois(f, 0), face_vois(f, 1));
317 Cerr <<
"Domaine_Poly has been filled with success" << finl;
320 Journal() <<
"Domaine_Poly_base::Modifier_pour_Cl" << finl;
321 int nb_cond_lim=conds_lim.size();
323 for (; num_cond_lim<nb_cond_lim; num_cond_lim++)
337 int num_derniere_face = num_premiere_face+nfin;
339 int nbr_faces_bord = la_front_dis.
nb_faces();
353 for (
int ind_face=ndeb; ind_face<nfin; ind_face++)
356 face = la_front_dis.
num_face(ind_face);
360 if (ind_face<nbr_faces_bord)
362 assert(faassociee>=num_premiere_face);
363 assert(faassociee<num_derniere_face);
406 IntTab face(np), elem1(np), elem2(np);
410 for (i = 0; i < f_s.dimension(1) && (s = f_s(f, i)) >= 0; i++)
411 if (fs(f) > 0 && (sin2 = std::pow(
dot(&xs(s, 0), &nf(f, 0), &
xv_(f, 0)) / fs(f), 2) /
dot(&xs(s, 0), &xs(s, 0), &
xv_(f, 0), &
xv_(f, 0))) > val[rk])
412 val[rk] = sin2, face(rk) = f, elem1(rk) = f_e(f, 0), elem2(rk) = f_e(f, 1);
413 envoyer_all_to_all(val, val), envoyer_all_to_all(face, face), envoyer_all_to_all(elem1, elem1), envoyer_all_to_all(elem2, elem2);
416 if (val[i] > sin2) sin2 = val[i], j = i;
417 double theta = asin(sqrt(sin2)) * 180 / M_PI;
418 Cerr <<
"Domaine_Poly_base : angle sommet/face max " << theta <<
" deg (proc " << j <<
" , face ";
419 Cerr << face(j) <<
" , elems " << elem1(j) <<
" / " << elem2(j) <<
" )" << finl;
422 Cerr <<
"Domaine_Poly_base : non-planar face detected ! Please fix your mesh or call 911 ..." << finl;
436 xa_.resize(0, 3),
ta_.resize(0, 3);
476 int elem = (elem0 == -1 ? elem1 : elem0);
478 int last_index = nb_edges_max-1;
481 for (
int k=0; k<nb_edges_elem_max; k++)
483 arete = elem_aretes(elem,k);
485 if (arete == -1)
break;
486 node0 = aretes_som(arete,0);
487 node1 = aretes_som(arete,1);
489 for (
int j=0; j<nb_edges_max; j++)
494 int previous = j > 0 ? j-1 : last_index;
495 int next = j < last_index ? j+1 : 0;
514 int i, j, e, f, s, np;
517 IntTrav b_f_ortho, b_e_ortho;
526 double d2min = DBL_MAX, d2max = 0, d2;
527 for (i = 0, np = 0; i < f_s.
dimension(1) && (s = f_s(f, i)) >= 0; i++, np++)
528 d2min = std::min(d2min, d2 =
dot(&xs(s, 0), &xs(s, 0), &
xv_(f, 0), &
xv_(f, 0))), d2max = std::max(d2max, d2);
529 if ((b_f_ortho(f) = (d2max / d2min - 1 < 1e-8)))
continue;
532 M.resize(np + 1, 4), S.resize(np + 1, 1);
533 for (i = 0; i < np; i++)
534 for (j = 0, S(i, 0) = 0, M(i, 3) = 1; j < 3; j++)
535 S(i, 0) += 0.5 * std::pow(M(i, j) = xs(f_s(f, i), j) -
xv_(f, j), 2);
536 for (j = 0, S(np, 0) = M(np, 3) = 0; j < 3; j++) M(np, j) = nf(f, j) / fs(f);
537 if (kersol(M, S, 1e-12,
nullptr, X, vp) > 1e-8)
continue;
540 double r2min = DBL_MAX;
541 for (i = 0; i < f_s.
dimension(1) && (s = f_s(f, i)) >= 0; i++)
543 int s2 = f_s(f, i + 1 < f_s.
dimension(1) && f_s(f, i + 1) >= 0 ? i + 1 : 0),
545 std::array<double, 3> vec =
cross(3, 3, &
xv_(f, 0), &
ta_(a, 0), &xs(s, 0));
546 r2min = std::min(r2min,
dot(&vec[0], &vec[0]));
548 if (
dot(&X(0, 0), &X(0, 0)) > 0.25 * r2min)
continue;
550 for (i = 0, b_f_ortho(f) = 1; i <
dimension; i++)
551 if (std::fabs(X(i, 0)) > 1e-8)
xv_(f, i) += X(i, 0);
553 Cerr << 100. * (double)(mp_somme_vect(b_f_ortho) /
Process::mp_sum(
nb_faces())) <<
"% orthocentered faces " << finl;
560 double d2min = DBL_MAX, d2max = 0, d2;
561 for (i = 0, np = 0; i < e_s.dimension(1) && (s = e_s(e, i)) >= 0; i++, np++)
562 d2min = std::min(d2min, d2 =
dot(&xs(s, 0), &xs(s, 0), &
xp_(e, 0), &
xp_(e, 0))), d2max = std::max(d2max, d2);
563 if ((b_e_ortho(e) = (d2max / d2min - 1 < 1e-8)))
continue;
566 for (i = 0, j = 1; i < e_f.dimension(1) && (f = e_f(e, i)) >= 0; i++) j = j && b_f_ortho(f);
571 for (i = 0; i < np; i++)
573 S(i, 0) += 0.5 * std::pow(M(i, j) = xs(e_s(e, i), j) -
xp_(e, j), 2);
574 if (kersol(M, S, 1e-12,
nullptr, X, vp) > 1e-8)
continue;
577 double rmin = DBL_MAX;
578 for (i = 0; i < e_f.dimension(1) && (f = e_f(e, i)) >= 0; i++)
579 rmin = std::min(rmin, std::fabs(
dot(&
xp_(e, 0), &nf(f, 0), &
xv_(f, 0)) / fs(f)));
580 if (
dot(&X(0, 0), &X(0, 0)) > 0.25 * rmin * rmin)
continue;
582 for (i = 0, b_e_ortho(e) = 1; i <
dimension; i++)
583 if (std::fabs(X(i, 0)) > 1e-8)
xp_(e, i) += X(i, 0);
585 Cerr << 100. * (double)(mp_somme_vect(b_e_ortho) /
Process::mp_sum(
nb_elem())) <<
"% d'elements orthocentres" << finl;
598 for (
int num_elem=0; num_elem<nbe; num_elem++)
601 for (
int i=0; i<nb_faces_elem; i++)
603 double surf = surfaces(
elem_faces(num_elem,i));
604 surf_max = (surf > surf_max)? surf : surf_max;
606 double vol =
volumes(num_elem)/surf_max;
613void disp_dt(
const DoubleTab& A)
618 for (j = 0, fprintf(stderr, i ?
"}}},{" :
"{{"); j < A.
dimension(1); j++)
619 for (k = 0, fprintf(stderr, j ?
"}},{" :
"{"); k < A.
dimension(2); k++)
620 for (l = 0, fprintf(stderr, k ?
"},{" :
"{"); l < A.
dimension(3); l++)
624 for (j = 0, fprintf(stderr, i ?
"}},{" :
"{{"); j < A.
dimension(1); j++)
625 for (k = 0, fprintf(stderr, j ?
"},{" :
"{"); k < A.
dimension(2); k++)
629 for (j = 0, fprintf(stderr, i ?
"},{" :
"{{"); j < A.
dimension(1); j++)
631 else for (i = 0, fprintf(stderr,
"{"); i < A.
dimension_tot(0); i++)
633 fprintf(stderr, A.
nb_dim() == 4 ?
"}}}}\n" : A.
nb_dim() == 3 ?
"}}}\n" : A.
nb_dim() == 2 ?
"}}\n" :
"}\n");
636void disp_da(
const ArrOfDouble& A)
639 for (i = 0, fprintf(stderr,
"{"); i < A.
size_array(); i++)
640 fprintf(stderr,
"%.10E%s ", A.
addr()[i], i + 1 < A.
size_array() ?
"," :
"");
641 fprintf(stderr,
"}\n");
644void disp_it(
const IntTab& A)
649 for (j = 0, fprintf(stderr, i ?
"}}},{" :
"{{"); j < A.
dimension(1); j++)
650 for (k = 0, fprintf(stderr, j ?
"}},{" :
"{"); k < A.
dimension(2); k++)
651 for (l = 0, fprintf(stderr, k ?
"},{" :
"{"); l < A.
dimension(3); l++)
655 for (j = 0, fprintf(stderr, i ?
"}},{" :
"{{"); j < A.
dimension(1); j++)
656 for (k = 0, fprintf(stderr, j ?
"},{" :
"{"); k < A.
dimension(2); k++)
660 for (j = 0, fprintf(stderr, i ?
"},{" :
"{{"); j < A.
dimension(1); j++)
662 else for (i = 0, fprintf(stderr,
"{"); i < A.
dimension_tot(0); i++)
663 fprintf(stderr,
"%d%s ", (
int)A.
addr()[i], i + 1 < A.
dimension_tot(0) ?
"," :
"");
664 fprintf(stderr, A.
nb_dim() == 4 ?
"}}}}\n" : A.
nb_dim() == 3 ?
"}}}\n" : A.
nb_dim() == 2 ?
"}}\n" :
"}\n");
667void disp_ia(
const ArrOfInt& A)
670 for (i = 0, fprintf(stderr,
"{"); i < A.
size_array(); i++)
671 fprintf(stderr,
"%d%s ", (
int)A.
addr()[i], i + 1 < A.
size_array() ?
"," :
"");
672 fprintf(stderr,
"}\n");
681 for (
auto k = M.
get_tab1().addr()[i] - 1; k < M.
get_tab1().addr()[i + 1] - 1; k++)
686void disp_mt(
const tabs_t& mvect)
688 for (
auto &&n_v : mvect)
689 fprintf(stderr,
"%s:\n", n_v.first.c_str()), disp_dt(n_v.second), fprintf(stderr,
"\n");
692void disp_mm(
const std::map<std::string, Matrice_Morse>& mmat)
694 for (
auto &&n_v : mmat)
695 fprintf(stderr,
"%s:\n", n_v.first.c_str()), disp_m(n_v.second), fprintf(stderr,
"\n");
698void disp_mmp(
const matrices_t& mmat)
700 for (
auto &&n_v : mmat)
701 fprintf(stderr,
"%s:\n", n_v.first.c_str()), disp_m(*n_v.second), fprintf(stderr,
"\n");
706 for (
int n_bord=0; n_bord<les_bords_.size(); n_bord++)
709 if (fr_vf.
le_nom() == nom_bord)
713 for (
int face=ndeb; face<ndeb+fr_vf.
nb_faces(); face++)
764 for (i = 0; i < e_f.dimension(1) && (f = e_f(e, i)) >= 0; i++)
765 for (j = 0; j < f_s.dimension(1) && (s = f_s(f, j)) >= 0; j++)
767 int sb = D < 3 ? -1 : f_s(f, j + 1 < f_s.dimension(1) && f_s(f, j + 1) >= 0 ? j + 1 : 0);
768 auto vec =
cross(D, D, &
xv_(f, 0), &xs(s, 0), &
xp_(e, 0), &
xp_(e, 0));
769 double x = std::abs(D < 3 ? vec[2] :
dot(&xs(sb, 0), &vec[0], &
xp_(e, 0)));
770 for (k = 0; k < D - 1; k++)
771 vol(es_d(e) + (
int)(std::find(&e_s(e, 0), &e_s(e, 0) + es_d(e + 1) - es_d(e), k ? sb : s) - &e_s(e, 0))) += x / (D < 3 ? 2 : 12);
783 for (
int i = 0, j = es_d(e); j < es_d(e + 1); i++, j++)
784 pvol_som_(e_s(e, i)) += porosite_elem(e) * v_es(j);
795 std::map<std::array<double, 3>,
int> xv_fsa;
798 for (i = 0, j = 0, xv_fsa.clear(); i < a_s.
dimension(1) && (s = a_s(a, i)) >= 0; i++) xv_fsa[ {{ xs(s, 0), xs(s, 1), xs(s, 2) }}] = s;
799 for (
auto &&c_s : xv_fsa) a_s(a, j) = c_s.second, j++;
805 for (
int j = 0; j < 2; j++)
som_arete[a_s(i, j)][a_s(i, !j)] = i;
809 int s1 = a_s(i, 0), s2 = a_s(i, 1);
811 for (k = 0; k < 3; k++)
xa_(i, k) = (xs(s1, k) + xs(s2, k)) / 2,
ta_(i, k) = (xs(s2, k) - xs(s1, k)) /
longueur_aretes_(i);
817 for (i = 0, j = 0, xv_fsa.clear(); i < e_a.dimension(1) && (a = e_a(e, i)) >= 0; i++) xv_fsa[ {{
xa_(a, 0),
xa_(a, 1),
xa_(a, 2) }}] = a;
818 for (
auto &&c_a : xv_fsa) e_a(e, j) = c_a.second, j++;
827 for (
int face = 0; face <
nb_faces(); face++)
829 double xs[3] = { 0, }, S = 0;
836 for (
int r = 0; r < 3; r++)
837 for (
int i = 0; i < 2; i++)
838 s += (i ? -1 : 1) *
face_normales_(face, r) * (coords(s2, (r + 1 + i) % 3) - coords(s0, (r + 1 + i) % 3))
839 * (coords(s1, (r + 1 + !i) % 3) - coords(s0, (r + 1 + !i) % 3));
840 for (
int r = 0; r < 3; r++) xs[r] += s * (coords(s0, r) + coords(s1, r) + coords(s2, r)) / 3;
843 if (S == 0 && sub_type(
Hexa_poly,type_elem_.valeur()))
845 Cerr <<
"===============================" << finl;
846 Cerr <<
"Error in your mesh for " <<
que_suis_je() <<
"!" << finl;
847 Cerr <<
"Add this keyword before discretization in your data file to create polyedras:" << finl;
851 for (
int r = 0; r < 3; r++)
xv_(face, r) = xs[r] / S;
853 xv_.echange_espace_virtuel();
classe Cond_lim_base Classe de base pour la hierarchie des classes qui representent les differentes c...
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
int_t nb_aretes_tot() const
renvoie le nombre d'aretes total (reelles+virtuelles).
const IntTab_t & aretes_som() const
renvoie le tableau de connectivite aretes/sommets.
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
creation d'un tableau parallele de valeurs aux elements.
IntTab_t & set_aretes_som()
IntTab_t & set_elem_aretes()
int nb_faces_elem(int=0) const
Renvoie le nombre de face de type i des elements geometriques constituants le domaine.
void typer(const Nom &)
Type les elements du domaine avec le nom passe en parametre.
const DoubleTab_t & coord_sommets() const
virtual void creer_tableau_sommets(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
Cree un tableau ayant une "ligne" par sommet du maillage.
int_t elem_aretes(int_t i, int j) const
renvoie le numero de la jeme arete du ieme element.
DoubleVect longueur_aretes_
MD_Vector mdv_faces_aretes
void detecter_faces_non_planes() const
const DoubleTab & vol_elem_som() const
virtual void calculer_volumes_entrelaces()
MD_Vector mdv_elems_faces
void modifier_pour_Cl(const Conds_lim &) override
void verifier_type_elem() const
void discretiser_aretes()
const Static_Int_Lists & som_elem() const
const IntTab & elem_som_d() const
virtual void init_equiv() const =0
const IntTab & equiv() const
std::vector< std::map< int, int > > som_arete
void discretiser() override
const DoubleTab & pvol_som(const DoubleVect &poro) const
virtual void calculer_h_carre()
Static_Int_Lists som_elem_
double dist_norm_bord(int num_face) const override
void calculer_infos_aretes()
void corriger_face_voisins_sur_les_faces_virtuelles()
const IntTab & elem_arete_d() const
Sortie & ecrit(Sortie &os) const
void typer_elem(Domaine &domaine_geom) override
IntVect rang_elem_non_std_
void creer_tableau_aretes(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
virtual const DoubleVect & face_surfaces() const
int nb_faces() const
renvoie le nombre global de faces.
IntTab & face_sommets() override
renvoie le tableau de connectivite faces/sommets.
DoubleVect volumes_entrelaces_
const MD_Vector & md_vector_faces() const
const MD_Vector & md_vector_aretes() const
int nb_faces_tot() const
renvoie le nombre total de faces.
double dot(const double *a, const double *b, const double *ma=nullptr, const double *mb=nullptr) const
void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
void discretiser() override
Genere les faces construits les frontieres.
IntTab & elem_faces()
renvoie le tableau de connectivite element/faces
std::array< double, 3 > cross(int dima, int dimb, const double *a, const double *b, const double *ma=nullptr, const double *mb=nullptr) const
MD_Vector md_vector_aretes_
DoubleTab volumes_entrelaces_dir_
const Front_VF & front_VF(int i) const
IntTab & face_voisins() override
renvoie le tableaux des volumes des connectivites face elements cf au dessus.
void marquer_faces_double_contrib(const Conds_lim &)
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
int num_premiere_face() const
int num_face(const int) const
const Nom & le_nom() const override
Renvoie le nom de la frontiere geometrique.
Metadata for a distributed composite vector.
void add_part(const MD_Vector &part, int shape=0, Nom name="")
Append the "part" descriptor to the composite vector.
Classe Matrice_Base Classe de base de la hierarchie des matrices.
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
const auto & get_tab2() const
const auto & get_tab1() const
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
const auto & get_coeff() const
int nb_lignes() const override
Return local number of lines (=size on the current proc).
class Nom Une chaine de caractere pour nommer les objets de TRUST
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
classe Periodique Cette classe represente une condition aux limites periodique.
int face_associee(int i) const
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
static int me()
renvoie mon rang dans le groupe de communication courant.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Classe de base des flux de sortie.
_SIZE_ size_array() const
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension_tot(int) const override
_SIZE_ dimension(int d) const
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
virtual const MD_Vector & get_md_vector() const