17#include <EcritureLectureSpecial.h>
18#include <Probleme_FT_Disc_gen.h>
22#include <Collision_Model_FT_base.h>
36 p.lire_avec_accolades_depuis(is);
42 Cerr <<
"Error::printOn is not implemented." << finl;
65 if (word==
"collision_model")
68 words.add(
"hybrid_esi");
72 Cerr <<
"Reading collision_model attributes: " << secondword << finl;
73 const int r = words.
search(secondword);
83 Cerr <<
"Error " << words <<
"was expected whereas " << secondword <<
84 " has been found."<< finl;
89 else if (word==
"detection_method")
96 if (secondword==openbrace)
101 words.add(
"check_all");
103 words.add(
"lc_verlet");
104 const int r = words.
search(secondword);
117 Cerr <<
"Error " << words <<
"was expected whereas "
118 << secondword <<
" has been found."<< finl;
123 while (secondword != closedbrace)
126 otherwords.add(
"detection_thickness_Verlet");
127 otherwords.add(
"nb_pas_dt_max_Verlet");
128 int rang2 = otherwords.
search(secondword);
138 Cerr <<
"Collision_Model_FT_base::lire_motcle_non_standard\n"
139 <<
" options of collision_detection are:\n"
150 Cerr << word <<
" is not a keyword understood by " <<
que_suis_je() <<
151 " in lire_motcle_non_standard"<< finl;
163 Cerr <<
"WARNING: Collision_Model_FT_base::reset of F_old_, F_now_, "
164 "lagrangian_contact_forces_ and e_eff_." << finl;
175 Cerr <<
"Error in Collision_Model_FT_base::reprendre\n";
177 Cerr <<
"\n We found " << readword << finl;
185 for (
int i=0; i<
F_old_.dimension(0); i++)
186 for (
int j=0; j<
F_old_.dimension(1); j++)
188 for (
int i=0; i<
e_eff_.dimension(0); i++)
189 for (
int j=0; j<
e_eff_.dimension(1); j++)
211 for (
int i=0; i<
F_old_.dimension(0); i++)
212 for (
int j=0; j<
F_old_.dimension(1); j++)
214 for (
int i=0; i<
e_eff_.dimension(0); i++)
215 for (
int j=0; j<
e_eff_.dimension(1); j++)
225 bytes += 8 *
F_old_.size_array();
227 bytes += 8 *
e_eff_.size_array();
233 const int nb_particles_tot,
257 if ((
F_old_.dimension(0)!=nb_particles_tot) ||
258 (
F_now_.dimension(0)!=nb_particles_tot) )
275 const double mass_sphere = solid_particle.
get_mass();
276 const double e_dry = solid_particle.
get_e_dry();
277 const double mass_eff_part_part = mass_sphere/2;
278 const double mass_eff_wall_part = mass_sphere;
294 refequation_transport_ = eq;
310 Cerr <<
"Collision_Model_FT_base::compute_fictive_wall_coordinates error" <<finl;
333 const Domaine& domain = domaine_vdf.
domaine();
341 for (
int i=0; i<bords.
nb_bords(); i++)
344 int nb_boundary_faces_local=ref_cast(Frontiere,bords(i)).nb_faces();
345 if (nb_boundary_faces_local>0)
347 int face1=ref_cast(Frontiere,bords(i)).num_premiere_face();
348 int orientation_face1=domaine_vdf.
orientation(face1);
349 NiNj(orientation_face1)=nb_boundary_faces;
352 long long NxNy=
static_cast<int>(
mp_max(NiNj(2))) ;
353 long long NxNz=
static_cast<int>(
mp_max(NiNj(1)));
354 long long NyNz=
static_cast<int>(
mp_max(NiNj(0)));
358 Ny= NxNz>0 ?
static_cast<int>(sqrt(NxNy*NyNz/NxNz)) : 0;
359 Nz= NxNy>0 ?
static_cast<int>((NxNz*Ny/NxNy)) : 0;
360 Nx= Ny>0 ?
static_cast<int>(NxNy/Ny) : 0;
370 Domain_dimensions=0.;
374 double min_ =
mp_min(BB(j,0));
375 double max_ =
mp_max(BB(j,1));
378 Domain_dimensions(j)=max_-min_;
384 Cerr <<
"Origin " << Origin << finl;
385 Cerr <<
"Domain length" << Domain_dimensions << finl;
386 Cerr <<
"Nx Ny Nz " <<
nb_nodes_ << finl;
396 ArrOfInt copy_vector(vector);
399 for (
int i = 0; i < size-1; i++)
401 if (copy_vector(i)==copy_vector(i+1))
404 Cerr << copy_vector(i) <<
" is duplicate !!" << finl ;
413ArrOfInt send_receive_list_id_particles(ArrOfInt& list_id_real_particles_to_send,
414 const ArrOfInt& list_lower_zone,
417 ArrOfInt list_id_particle_recv;
420 const int nb_real_particles_to_send=list_id_real_particles_to_send.
size_array();
424 for (
int ind_pe_dest=0; ind_pe_dest<list_lower_zone.
size_array(); ind_pe_dest++)
426 int PE_dest=list_lower_zone(ind_pe_dest);
427 for(
int ind_particle=0; ind_particle<nb_real_particles_to_send; ind_particle++)
429 const int id_particle=list_id_real_particles_to_send(ind_particle);
438 const int nb_recv_pe = recv_pe_list.
size_array();
439 for (
int i=0; i<nb_recv_pe; i++)
441 const int pe_source = recv_pe_list[i];
445 int id_particle_recv=-1;
446 buffer >> id_particle_recv;
449 if (id_particle_recv<0)
457 return list_id_particle_recv;
464 ArrOfInt list_particles_to_check_LC;
467 const int& nb_elem=domain_vf.
nb_elem();
475 const double& radius=solid_particle.get_equivalent_radius();
479 Cerr <<
"Update of Verlet tables - " ;
490 if (gravity_center_elem(particle)>-1 && gravity_center_elem(particle)<nb_elem)
499 ArrOfInt list_virtual_particles;
507 Cerr <<
"list_virtual_particles " << list_virtual_particles<< finl;
515 else list_particles_to_check_LC(k)=
518 Cerr <<
"list_particles_to_check_LC " << list_particles_to_check_LC<< finl;
528 double max_vi_glob=0;
539 list_particles_to_check_LC);
541 max_vi_glob=
mp_max(max_vi);
546 int deltat_compute_min = (max_vi_glob>0) ?
559 Cerr <<
"Verlet_tables_["<<ind_part_i<<
"].size() " <<
Verlet_tables_[ind_part_i].size() <<
" -- ";
560 for (
int ind_part_j=0; ind_part_j<
Verlet_tables_[ind_part_i].size(); ind_part_j++)
570 Process::exit(
"Collision_Model_FT_base::get_last_id Should not be in here!");
574 return(list_particles_to_check_LC.
size_array());
582 Process::exit(
"Collision_Model_FT_base::get_id Should not be in here!");
584 return(ind_id_particle);
586 return(list_particle(ind_id_particle));
588 Process::exit(
"Collision_Model_FT_base::get_id unkwnown detection_method_!");
595 return(ind_particle_j);
621 (ind_particle_i+1) : 0);
626 const DoubleTab& particles_velocity,
628 const double& radius,
629 const ArrOfInt& list_particles_to_check_LC)
631 int last_id =
get_last_id(list_particles_to_check_LC);
632 for (
int ind_id_particle_i=0; ind_id_particle_i<
nb_real_particles_; ind_id_particle_i++)
634 int id_particle_i=
get_id(list_particles_to_check_LC,ind_id_particle_i);
635 const double vi=fabs(sqrt(
636 pow(particles_velocity(id_particle_i,0),2) +
637 pow(particles_velocity(id_particle_i,1),2) +
638 pow(particles_velocity(id_particle_i,2),2)));
642 for (
int ind_id_particle_j=ind_id_particle_i+1; ind_id_particle_j< last_id; ind_id_particle_j++)
644 int id_particle_j=
get_id(list_particles_to_check_LC, ind_id_particle_j);
646 pow(particles_position(id_particle_j,0)-particles_position(id_particle_i,0),2) +
647 pow(particles_position(id_particle_j,1)-particles_position(id_particle_i,1),2) +
648 pow(particles_position(id_particle_j,2)-particles_position(id_particle_i,2),2));
656 for (
int ind_wall=0; ind_wall<2*
dimension; ind_wall++)
660 particles_position(id_particle_i,ori));
673 const DoubleTab& particles_position,
674 const DoubleTab& particles_velocity,
675 const bool is_particle_particle_collision)
677 if (is_particle_particle_collision)
681 dX(d) = particles_position(particle, d) - particles_position(neighbor, d);
682 dU(d) = particles_velocity(particle, d) - particles_velocity(neighbor, d);
691 dU(d) = particles_velocity(particle, d);
696 const double& next_dist_int,
697 const DoubleTab& norm,
698 const DoubleTab& dUn,
699 const int& particle_i,
700 const int& particle_j,
701 const int& is_compression_step,
702 const double& is_collision_part_part)
708 const double e_eff_particle = is_compression_step ? 1 :
e_eff_(particle_i, particle_j);
712 force_contact(d)= -pow(e_eff_particle,2) * stiffness * next_dist_int * norm(d);
721 force_contact(d)= -stiffness*next_dist_int*norm(d) -damper*dUn(d);
724 Process::exit(
"Collision_Model_FT_base::compute_contact_force unknown collision_model_");
726 return force_contact;
730 const DoubleTab& volumic_phase_indicator_function,
732 const IntTab& particles_eulerian_id_number,
733 DoubleTab& contact_force_source_term)
735 Process::exit(
"Collision_Model_FT_base::discretize_contact_forces_eulerian_field "
736 "not coded for particles of arbitrary shape");
760 double x0 = domain_vf.
xp(0,0);
761 double y0 = domain_vf.
xp(0,1);
762 double z0 = domain_vf.
xp(0,2);
763 double epsilon=1e-10;
764 const int nb_elems=domain_vf.
nb_elem();
767 Cerr <<
"number or reals elements " << nb_elems << finl;
768 Cerr <<
"total number of elements " << nb_elems_tot << finl;
769 Cerr <<
"(x0 y0 z0) = (" << x0 <<
" " << y0 <<
" " << z0 <<
")" << finl;
770 Cerr <<
"joints number " << nb_joints << finl;
773 DoubleTabFT list_coord_recv(0,
dimension);
774 IntTabFT list_pe_recv(0);
775 Cerr <<
"list_coord_recv.dimensions " << list_coord_recv.
dimension(0) <<
" "
781 for (
int ind_pe_dest=0; ind_pe_dest<nb_joints; ind_pe_dest++)
783 const Joint& joint_temp = domain_vf.
joint(ind_pe_dest);
784 const int pe_dest = joint_temp.
PEvoisin();
792 const int nb_recv_pe = recv_pe_list.
size_array();
793 for (
int i=0; i<nb_recv_pe; i++)
795 const int pe_source = recv_pe_list[i];
799 double x0_rcv=-1, y0_rcv=-1, z0_rcv=-1;
800 buffer >> x0_rcv >> y0_rcv >> z0_rcv;
812 list_pe_recv.
resize(nb_elem_recv);
814 if (nb_joints != nb_elem_recv)
Process::exit(
"EB : Collision_Model_FT_base::"
815 "set_LC_zones -- erreur identification du 1er element"
816 " des procs de la zone de joint.");
817 for(
int ind_pe=0; ind_pe<nb_elem_recv; ind_pe++)
819 const int pe_voisin = list_pe_recv(ind_pe);
820 double x0_joint = list_coord_recv(ind_pe,0);
821 double y0_joint = list_coord_recv(ind_pe,1);
822 double z0_joint = list_coord_recv(ind_pe,2);
824 if ( y0_joint>y0 || (fabs(y0_joint-y0)<epsilon && x0_joint>x0) ||
825 ( fabs(x0_joint-x0) < epsilon && fabs(y0_joint-y0)<epsilon && (z0_joint>z0)) )
827 if ( y0_joint<=y0 && (fabs(y0_joint-y0)>=epsilon || x0_joint<=x0)
828 && ( fabs(x0_joint-x0) >= epsilon || fabs(y0_joint-y0)>=epsilon
839 Cerr <<
"max number of upper zone = " <<
mp_max(nsup) << finl;
840 Cerr <<
"max number of lower zone = " <<
mp_max(ninf) << finl;
845 const double contrib=is_part_part_collision? 1 : .2;
: class Collision_Model_FT
void compute_fictive_wall_coordinates(const double &radius)
double stiffness_breugem_part_part_
void set_activation_distance(const double &diameter)
double compute_damper_breugem(const double &mass_eff, const double &e_dry)
DoubleVect fictive_wall_coordinates_
int sauvegarder(Sortie &os) const override
Sauvegarde d'un Objet_U sur un flot de sortie Methode a surcharger.
void associate_transport_equation(const Equation_base &equation)
void set_origin(DoubleVect &Origin)
Collision_Model_FT_base()
double activation_distance_
ArrOfInt list_lower_zone_
void resize_lagrangian_contact_force()
void set_geometric_parameters(const Domaine_VDF &domaine_vdf)
Recover the geometric parameters of the domain: number of nodes in each direction origin of the domai...
void resize_particles_collision_number()
int nb_dt_compute_Verlet_
DoubleVect domain_dimensions_
double detection_thickness_Verlet_
void resize_geometric_parameters()
virtual void discretize_contact_forces_eulerian_field(const DoubleTab &volumic_phase_indicator_function, const Domaine_VF &domain_vf, const IntTab &particles_eulerian_id_number, DoubleTab &contact_force_source_term)=0
Collision_model collision_model_
int get_particle_i(const int ind_particle_i)
int check_for_duplicates(ArrOfInt &vector)
Check if two particles have the same ID Very important function to stop computation if two particles ...
int get_ind_start_particles_j(const int ind_particle_i) const
int get_nb_particles_j(const int ind_particle_i) const
void add_collision(const int part_i, const int part_j, const bool is_part_part_collision)
double stiffness_breugem_wall_part_
double compute_stiffness_breugem(const double &mass_eff, const double &e_dry)
double collision_duration_
double activation_distance_percentage_diameter_
int is_collision_activated_before_impact_
DoubleTab particles_collision_number_
int preparer_calcul(const Domaine_VDF &domain_vdf, const int nb_particles_tot, const Navier_Stokes_FT_Disc &ns, const Transport_Interfaces_FT_Disc &eq_transport, const Schema_Comm &schema_comm_FT)
int is_force_on_two_phase_elem_
void set_domain_dimensions(DoubleVect &Longueurs)
void research_collision_pairs_Verlet(const Navier_Stokes_FT_Disc &eq_ns, const Transport_Interfaces_FT_Disc &eq_transport)
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
int get_id(const ArrOfInt &list_particle, const int ind_id_particle)
ArrOfInt list_real_particles_
const ArrOfInt & get_list_lower_zone() const
double damper_breugem_wall_part_
int get_particle_j(const int ind_particle_i, const int ind_particle_j)
void set_nb_particles_tot(int nb_particles_tot)
void set_spring_properties(const Solid_Particle_base &solid_particle)
double damper_breugem_part_part_
int get_last_id(const ArrOfInt &list_particles_to_check_LC)
Detection_method detection_method_
void set_LC_zones(const Domaine_VF &domaine_vf, const Schema_Comm &schema_com)
int reprendre(Entree &is) override
Reprise d'un Objet_U sur un flot d'entree Methode a surcharger.
DoubleTab compute_contact_force(const double &next_dist_int, const DoubleTab &norm, const DoubleTab &dUn, const int &particle_i, const int &particle_j, const int &is_compression_step, const double &is_collision_part_part)
void compute_dX_dU(DoubleTab &dX, DoubleTab &dU, const int &particle, const int &neighbor, const DoubleTab &particles_position, const DoubleTab &particles_velocity, const bool is_particle_particle_collision)
void set_nb_real_particles(int nb_real_particles)
void set_param(Param &p) const override
ArrOfInt list_upper_zone_
bool is_Verlet_activated()
void compute_Verlet_tables(const DoubleTab &particles_position, const DoubleTab &particles_velocity, double &max_vi, const double &radius, const ArrOfInt &list_particles_to_check_LC)
DoubleTab getBoundingBox() const
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
const Joint & joint(int i) const
double xp(int num_elem, int k) const
const Domaine & domaine() const
static int is_ecriture_special(int &special, int &a_faire)
indique si le format special a ete demande en lecture active par sauvegarde xyz .
static int is_lecture_special()
indique si le format special a ete demande en lecture active par reprise xyz .
Class defining operators and methods for all reading operation in an input flow (file,...
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
const Fluide_Incompressible & fluide_phase(int la_phase) const
const int & get_id_fluid_phase() const
: class Maillage_FT_Disc Cette classe decrit un maillage:
const Schema_Comm & get_schema_comm_FT() const
Une chaine de caractere (Nom) en majuscules.
Un tableau d'objets de la classe Motcle.
int search(const Motcle &t) const
virtual const Fluide_Diphasique & fluide_diphasique() const
class Nom Une chaine de caractere pour nommer les objets de TRUST
classe Objet_U Cette classe est la classe de base des 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.
Helper class to factorize the readOn method of Objet_U classes.
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
static double mp_min(double)
static int check_int_overflow(trustIdType)
static double mp_max(double)
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.
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
void echange_taille_et_messages() const
Cette methode lance l'echange de donnees entre tous les processeurs.
Sortie & send_buffer(int num_PE) const
renvoie le buffer correspondant au processeur num_PE pour y entasser des donnees a envoyer.
void end_comm() const
Vide les buffers et libere les ressources: on a fini de lire les donnees recues dans les buffers.
Entree & recv_buffer(int num_PE) const
renvoie le buffer correspondant au processeur num_PE pour y lire les donnees recues.
const ArrOfInt & get_recv_pe_list() const
void begin_comm() const
Reserve les buffers de comm pour une nouvelle communication.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
const double & get_e_dry() const
const double & get_mass() const
const double & get_equivalent_diameter() const
Classe de base des flux de sortie.
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const
const Maillage_FT_Disc & maillage_interface() const
const ArrOfInt & get_gravity_center_elem() const
const DoubleTab & get_particles_velocity() const
const DoubleTab & get_particles_position() const