TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Collision_Model_FT_sphere.cpp
1/****************************************************************************
2* Copyright (c) 2025, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Collision_Model_FT_sphere.h>
17#include <Probleme_FT_Disc_gen.h>
18#include <Solid_Particle_sphere.h>
19
20
21Implemente_instanciable_sans_constructeur(Collision_Model_FT_sphere,"Collision_Model_FT_sphere",Collision_Model_FT_base);
22
26
28{
30 return is;
31}
32
34{
35 Cerr << "Error::printOn is not implemented." << finl;
37 return os;
38}
39
41 const DoubleTab& particles_position,
42 const DoubleTab& particles_velocity,
43 const double& deltat_simu)
44{
45 const int& id_fluid_phase= two_phase_fluid.get_id_fluid_phase();
46 const int& id_solid_phase=1-id_fluid_phase;
47 const auto& solid_particle=ref_cast(Solid_Particle_sphere,two_phase_fluid.fluide_phase(id_solid_phase));
48 const auto& incompressible_fluid=ref_cast(Fluide_Incompressible,
49 two_phase_fluid.fluide_phase(id_fluid_phase));
50 const double& solid_density = solid_particle.masse_volumique().valeurs()(0, 0);
51 const double& fluid_density = incompressible_fluid.masse_volumique().valeurs()(0, 0);
52 const double& fluid_viscosity = fluid_density
53 * incompressible_fluid.viscosite_cinematique().valeurs()(0, 0);
54 const double& radius_sphere=solid_particle.get_radius();
55 const double& volume_sphere=solid_particle.get_volume();
56 const double& e_dry=solid_particle.get_e_dry();
57 const double min_threshold=1e-10;
58 DoubleTab dX(dimension), dU(dimension);
62
63 for (int ind_particle_i = 0; ind_particle_i < nb_real_particles_; ind_particle_i++)
64 {
65 int particle_i=get_particle_i(ind_particle_i);
66 int nb_particles_j=get_nb_particles_j(ind_particle_i);
67 int ind_start_part_j=get_ind_start_particles_j(ind_particle_i);
68 for (int ind_particle_j =ind_start_part_j; ind_particle_j < nb_particles_j; ind_particle_j++)
69 {
70 dX = 0;
71 dU = 0;
72 int particle_j=get_particle_j(ind_particle_i,ind_particle_j);
73 int is_particle_particle_collision = particle_j < nb_particles_tot_;
74 compute_dX_dU(dX, dU, particle_i, particle_j, particles_position,
75 particles_velocity, is_particle_particle_collision);
76 double dist_gravity_center = sqrt(local_carre_norme_vect(dX));
77 double dist_between_particles = dist_gravity_center - 2 * radius_sphere;
78
79 F_now_(particle_i, particle_j) = 0;
80 if (dist_between_particles <= 0) // contact
81 {
82 add_collision(particle_i,particle_j,is_particle_particle_collision);
83 DoubleTab norm(dimension);
84 for (int d = 0; d < dimension; d++)
85 norm(d) = dX(d) / dist_gravity_center;
86
87 double dX_scal_dU = local_prodscal(dX,dU);
88 DoubleTab dUn(dimension);
89 for (int d = 0; d < dimension; d++)
90 dUn(d) = (dX_scal_dU / dist_gravity_center) * norm(d);
91
92 const double impact_velocity = sqrt(local_carre_norme_vect(dUn));
93
94 F_now_(particle_i, particle_j) = 1;
95 int is_start_of_collision = F_now_(particle_i, particle_j) >
96 F_old_(particle_i, particle_j); // We need to know
97 // if this is the first time step of the collision to compute the impact velocity
98
99 DoubleTab next_dX(dimension);
100 for (int d = 0; d < dimension; d++)
101 next_dX(d) = dX(d) + deltat_simu * dU(d);
102 const double next_dist_gravity_center = sqrt(local_carre_norme_vect(next_dX));
103 const double next_dist_between_particles = next_dist_gravity_center - 2 * radius_sphere;
104 const double effective_radius = is_particle_particle_collision ? radius_sphere/2 :
105 radius_sphere;
106 const double impact_Stokes = solid_density * 2 * effective_radius * impact_velocity /
107 (9 * fluid_viscosity);
108 if (is_start_of_collision)
109 e_eff_(particle_i,particle_j)=e_dry*compute_ewet_legendre(impact_Stokes);
110 DoubleTab force_contact=compute_contact_force(
111 next_dist_between_particles,
112 norm,
113 dUn,
114 particle_i,
115 particle_j,
116 dX_scal_dU<=0,
117 is_particle_particle_collision);
118 for (int d = 0; d < dimension; d++)
119 {
120 lagrangian_contact_forces_(particle_i, d) += fabs(force_contact(d)) <=
121 min_threshold ? 0 : force_contact(d) / volume_sphere;
122 if (!is_particle_particle_collision)
123 continue; // wall collision, no force to apply on the wall
124 lagrangian_contact_forces_(particle_j, d) -= fabs(force_contact(d)) <=
125 min_threshold ? 0 : force_contact(d) / volume_sphere;
126 }
127 }
128 F_old_(particle_i, particle_j) = F_now_(particle_i, particle_j);
129 }
130 }
131
133 {
140 }
141}
142
144 const DoubleTab& volumic_phase_indicator_function,
145 const Domaine_VF& domain_vf,
146 const IntTab& particles_eulerian_id_number,
147 DoubleTab& contact_force_source_term)
148{
149 const DoubleVect& interlaced_volumes=domain_vf.volumes_entrelaces();
150 const int nb_faces=interlaced_volumes.size_array();
151 const IntVect& orientation = domain_vf.orientation();
152 const IntTab& face_voisins=domain_vf.face_voisins();
153 for (int face=0; face<nb_faces; face++)
154 {
155 const int left_elem=face_voisins(face,0);
156 const int right_elem=face_voisins(face,1);
157 int id_left = left_elem != -1 ? particles_eulerian_id_number(left_elem) : -1;
158 int id_right = right_elem != -1 ? particles_eulerian_id_number(right_elem) : -1;
159 const int id_number=std::max(id_left,id_right);
160 if (id_number!=-1)
161 {
162 const int ori=orientation(face);
163 contact_force_source_term(face)=(1-volumic_phase_indicator_function(face))
164 *interlaced_volumes(face)*lagrangian_contact_forces_(id_number,ori);
165 }
166 }
167}
: class Collision_Model_FT
int get_particle_i(const int ind_particle_i)
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 compute_ewet_legendre(const double &St)
int get_particle_j(const int ind_particle_i, const int ind_particle_j)
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)
: class Collision_Model_FT
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) override
void compute_lagrangian_contact_forces(const Fluide_Diphasique &two_phase_fluid, const DoubleTab &particles_position, const DoubleTab &particles_velocity, const double &deltat_simu) override
class Domaine_VF
Definition Domaine_VF.h:44
DoubleVect & volumes_entrelaces()
Definition Domaine_VF.h:99
virtual const IntVect & orientation() const
Definition Domaine_VF.h:646
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
const Fluide_Incompressible & fluide_phase(int la_phase) const
const int & get_id_fluid_phase() const
classe Fluide_Incompressible Cette classe represente un d'un fluide incompressible ainsi que
static int dimension
Definition Objet_U.h:99
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
static void mp_max_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:196
static int check_int_overflow(trustIdType)
Definition Process.cpp:428
static void mp_sum_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:193
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size_array() const