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;
73 if (word==
"collision_model")
76 words.add(
"hybrid_esi");
80 Cerr <<
"Reading collision_model attributes: " << secondword << finl;
81 const int r = words.
search(secondword);
91 Cerr <<
"Error " << words <<
"was expected whereas " << secondword <<
92 " has been found."<< finl;
97 else if (word==
"detection_method")
104 if (secondword==openbrace)
109 words.add(
"check_all");
111 words.add(
"lc_verlet");
112 const int r = words.
search(secondword);
125 Cerr <<
"Error " << words <<
"was expected whereas "
126 << secondword <<
" has been found."<< finl;
131 while (secondword != closedbrace)
134 otherwords.add(
"detection_thickness_Verlet");
135 otherwords.add(
"nb_pas_dt_max_Verlet");
136 int rang2 = otherwords.
search(secondword);
146 Cerr <<
"Collision_Model_FT_base::lire_motcle_non_standard\n"
147 <<
" options of collision_detection are:\n"
158 Cerr << word <<
" is not a keyword understood by " <<
que_suis_je() <<
159 " in lire_motcle_non_standard"<< finl;
171 Cerr <<
"WARNING: Collision_Model_FT_base::reset of F_old_, F_now_, "
172 "lagrangian_contact_forces_ and e_eff_." << finl;
183 Cerr <<
"Error in Collision_Model_FT_base::reprendre\n";
185 Cerr <<
"\n We found " << readword << finl;
193 for (
int i=0; i<
F_old_.dimension(0); i++)
194 for (
int j=0; j<
F_old_.dimension(1); j++)
196 for (
int i=0; i<
e_eff_.dimension(0); i++)
197 for (
int j=0; j<
e_eff_.dimension(1); j++)
219 for (
int i=0; i<
F_old_.dimension(0); i++)
220 for (
int j=0; j<
F_old_.dimension(1); j++)
222 for (
int i=0; i<
e_eff_.dimension(0); i++)
223 for (
int j=0; j<
e_eff_.dimension(1); j++)
233 bytes += 8 *
F_old_.size_array();
235 bytes += 8 *
e_eff_.size_array();
241 const int nb_particles_tot,
265 if ((
F_old_.dimension(0)!=nb_particles_tot) ||
266 (
F_now_.dimension(0)!=nb_particles_tot) )
283 const double mass_sphere = solid_particle.
get_mass();
284 const double e_dry = solid_particle.
get_e_dry();
285 const double mass_eff_part_part = mass_sphere/2;
286 const double mass_eff_wall_part = mass_sphere;
302 refequation_transport_ = eq;
318 Cerr <<
"Collision_Model_FT_base::compute_fictive_wall_coordinates error" <<finl;
341 const Domaine& domain = domaine_vdf.
domaine();
349 for (
int i=0; i<bords.
nb_bords(); i++)
352 int nb_boundary_faces_local=ref_cast(Frontiere,bords(i)).nb_faces();
353 if (nb_boundary_faces_local>0)
355 int face1=ref_cast(Frontiere,bords(i)).num_premiere_face();
356 int orientation_face1=domaine_vdf.
orientation(face1);
357 NiNj(orientation_face1)=nb_boundary_faces;
360 long long NxNy=
static_cast<int>(
mp_max(NiNj(2))) ;
361 long long NxNz=
static_cast<int>(
mp_max(NiNj(1)));
362 long long NyNz=
static_cast<int>(
mp_max(NiNj(0)));
366 Ny= NxNz>0 ?
static_cast<int>(sqrt(NxNy*NyNz/NxNz)) : 0;
367 Nz= NxNy>0 ?
static_cast<int>((NxNz*Ny/NxNy)) : 0;
368 Nx= Ny>0 ?
static_cast<int>(NxNy/Ny) : 0;
378 Domain_dimensions=0.;
382 double min_ =
mp_min(BB(j,0));
383 double max_ =
mp_max(BB(j,1));
386 Domain_dimensions(j)=max_-min_;
392 Cerr <<
"Origin " << Origin << finl;
393 Cerr <<
"Domain length" << Domain_dimensions << finl;
394 Cerr <<
"Nx Ny Nz " <<
nb_nodes_ << finl;
404 ArrOfInt copy_vector(vector);
407 for (
int i = 0; i < size-1; i++)
409 if (copy_vector(i)==copy_vector(i+1))
412 Cerr << copy_vector(i) <<
" is duplicate !!" << finl ;
421ArrOfInt send_receive_list_id_particles(ArrOfInt& list_id_real_particles_to_send,
422 const ArrOfInt& list_lower_zone,
425 ArrOfInt list_id_particle_recv;
428 const int nb_real_particles_to_send=list_id_real_particles_to_send.
size_array();
432 for (
int ind_pe_dest=0; ind_pe_dest<list_lower_zone.
size_array(); ind_pe_dest++)
434 int PE_dest=list_lower_zone(ind_pe_dest);
435 for(
int ind_particle=0; ind_particle<nb_real_particles_to_send; ind_particle++)
437 const int id_particle=list_id_real_particles_to_send(ind_particle);
446 const int nb_recv_pe = recv_pe_list.
size_array();
447 for (
int i=0; i<nb_recv_pe; i++)
449 const int pe_source = recv_pe_list[i];
453 int id_particle_recv=-1;
454 buffer >> id_particle_recv;
457 if (id_particle_recv<0)
465 return list_id_particle_recv;
472 ArrOfInt list_particles_to_check_LC;
475 const int& nb_elem=domain_vf.
nb_elem();
483 const double& radius=solid_particle.get_equivalent_radius();
487 Cerr <<
"Update of Verlet tables - " ;
498 if (gravity_center_elem(particle)>-1 && gravity_center_elem(particle)<nb_elem)
507 ArrOfInt list_virtual_particles;
515 Cerr <<
"list_virtual_particles " << list_virtual_particles<< finl;
523 else list_particles_to_check_LC(k)=
526 Cerr <<
"list_particles_to_check_LC " << list_particles_to_check_LC<< finl;
536 double max_vi_glob=0;
547 list_particles_to_check_LC);
549 max_vi_glob=
mp_max(max_vi);
554 int deltat_compute_min = (max_vi_glob>0) ?
567 Cerr <<
"Verlet_tables_["<<ind_part_i<<
"].size() " <<
Verlet_tables_[ind_part_i].size() <<
" -- ";
568 for (
int ind_part_j=0; ind_part_j<
Verlet_tables_[ind_part_i].size(); ind_part_j++)
578 Process::exit(
"Collision_Model_FT_base::get_last_id Should not be in here!");
582 return(list_particles_to_check_LC.
size_array());
590 Process::exit(
"Collision_Model_FT_base::get_id Should not be in here!");
592 return(ind_id_particle);
594 return(list_particle(ind_id_particle));
596 Process::exit(
"Collision_Model_FT_base::get_id unkwnown detection_method_!");
603 return(ind_particle_j);
629 (ind_particle_i+1) : 0);
634 const DoubleTab& particles_velocity,
636 const double& radius,
637 const ArrOfInt& list_particles_to_check_LC)
639 int last_id =
get_last_id(list_particles_to_check_LC);
640 for (
int ind_id_particle_i=0; ind_id_particle_i<
nb_real_particles_; ind_id_particle_i++)
642 int id_particle_i=
get_id(list_particles_to_check_LC,ind_id_particle_i);
643 const double vi=fabs(sqrt(
644 pow(particles_velocity(id_particle_i,0),2) +
645 pow(particles_velocity(id_particle_i,1),2) +
646 pow(particles_velocity(id_particle_i,2),2)));
650 for (
int ind_id_particle_j=ind_id_particle_i+1; ind_id_particle_j< last_id; ind_id_particle_j++)
652 int id_particle_j=
get_id(list_particles_to_check_LC, ind_id_particle_j);
654 pow(particles_position(id_particle_j,0)-particles_position(id_particle_i,0),2) +
655 pow(particles_position(id_particle_j,1)-particles_position(id_particle_i,1),2) +
656 pow(particles_position(id_particle_j,2)-particles_position(id_particle_i,2),2));
664 for (
int ind_wall=0; ind_wall<2*
dimension; ind_wall++)
668 particles_position(id_particle_i,ori));
681 const DoubleTab& particles_position,
682 const DoubleTab& particles_velocity,
683 const bool is_particle_particle_collision)
685 if (is_particle_particle_collision)
689 dX(d) = particles_position(particle, d) - particles_position(neighbor, d);
690 dU(d) = particles_velocity(particle, d) - particles_velocity(neighbor, d);
699 dU(d) = particles_velocity(particle, d);
704 const double& next_dist_int,
705 const DoubleTab& norm,
706 const DoubleTab& dUn,
707 const int& particle_i,
708 const int& particle_j,
709 const int& is_compression_step,
710 const double& is_collision_part_part)
716 const double e_eff_particle = is_compression_step ? 1 :
e_eff_(particle_i, particle_j);
720 force_contact(d)= -pow(e_eff_particle,2) * stiffness * next_dist_int * norm(d);
729 force_contact(d)= -stiffness*next_dist_int*norm(d) -damper*dUn(d);
732 Process::exit(
"Collision_Model_FT_base::compute_contact_force unknown collision_model_");
734 return force_contact;
738 const DoubleTab& volumic_phase_indicator_function,
740 const IntTab& particles_eulerian_id_number,
741 DoubleTab& contact_force_source_term)
743 Process::exit(
"Collision_Model_FT_base::discretize_contact_forces_eulerian_field "
744 "not coded for particles of arbitrary shape");
768 double x0 = domain_vf.
xp(0,0);
769 double y0 = domain_vf.
xp(0,1);
770 double z0 = domain_vf.
xp(0,2);
771 double epsilon=1e-10;
772 const int nb_elems=domain_vf.
nb_elem();
775 Cerr <<
"number or reals elements " << nb_elems << finl;
776 Cerr <<
"total number of elements " << nb_elems_tot << finl;
777 Cerr <<
"(x0 y0 z0) = (" << x0 <<
" " << y0 <<
" " << z0 <<
")" << finl;
778 Cerr <<
"joints number " << nb_joints << finl;
781 DoubleTabFT list_coord_recv(0,
dimension);
782 IntTabFT list_pe_recv(0);
783 Cerr <<
"list_coord_recv.dimensions " << list_coord_recv.
dimension(0) <<
" "
789 for (
int ind_pe_dest=0; ind_pe_dest<nb_joints; ind_pe_dest++)
791 const Joint& joint_temp = domain_vf.
joint(ind_pe_dest);
792 const int pe_dest = joint_temp.
PEvoisin();
800 const int nb_recv_pe = recv_pe_list.
size_array();
801 for (
int i=0; i<nb_recv_pe; i++)
803 const int pe_source = recv_pe_list[i];
807 double x0_rcv=-1, y0_rcv=-1, z0_rcv=-1;
808 buffer >> x0_rcv >> y0_rcv >> z0_rcv;
820 list_pe_recv.
resize(nb_elem_recv);
822 if (nb_joints != nb_elem_recv)
Process::exit(
"EB : Collision_Model_FT_base::"
823 "set_LC_zones -- erreur identification du 1er element"
824 " des procs de la zone de joint.");
825 for(
int ind_pe=0; ind_pe<nb_elem_recv; ind_pe++)
827 const int pe_voisin = list_pe_recv(ind_pe);
828 double x0_joint = list_coord_recv(ind_pe,0);
829 double y0_joint = list_coord_recv(ind_pe,1);
830 double z0_joint = list_coord_recv(ind_pe,2);
832 if ( y0_joint>y0 || (fabs(y0_joint-y0)<epsilon && x0_joint>x0) ||
833 ( fabs(x0_joint-x0) < epsilon && fabs(y0_joint-y0)<epsilon && (z0_joint>z0)) )
835 if ( y0_joint<=y0 && (fabs(y0_joint-y0)>=epsilon || x0_joint<=x0)
836 && ( fabs(x0_joint-x0) >= epsilon || fabs(y0_joint-y0)>=epsilon
847 Cerr <<
"max number of upper zone = " <<
mp_max(nsup) << finl;
848 Cerr <<
"max number of lower zone = " <<
mp_max(ninf) << finl;
853 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