Commit 23cb8afc authored by Cristian Lalescu's avatar Cristian Lalescu
Browse files

[WIP] add Stokes drag particles

`NSVE_Stokes_particles` currently hangs on my computer, with no
error output at all.
I will debug later
parent dea79bc3
......@@ -300,6 +300,7 @@ set(cpp_for_lib
${PROJECT_SOURCE_DIR}/cpp/full_code/test_interpolation.cpp
${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEparticles.cpp
${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEcomplex_particles.cpp
${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_Stokes_particles.cpp
${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEp_extra_sampling.cpp
${PROJECT_SOURCE_DIR}/cpp/particles/particles_inner_computer.cpp
${PROJECT_SOURCE_DIR}/cpp/full_code/ornstein_uhlenbeck_process.cpp
......@@ -348,6 +349,7 @@ set(hpp_for_lib
${PROJECT_SOURCE_DIR}/cpp/full_code/test_interpolation.hpp
${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEparticles.hpp
${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEcomplex_particles.hpp
${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_Stokes_particles.hpp
${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEp_extra_sampling.hpp
${PROJECT_SOURCE_DIR}/cpp/particles/particles_inner_computer.hpp
${PROJECT_SOURCE_DIR}/cpp/particles/particles_inner_computer_2nd_order.hpp
......@@ -430,41 +432,56 @@ enable_testing()
if (BUILD_TESTING)
file(MAKE_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
### basic functionality
add_test(NAME test_fftw
COMMAND turtle.test_fftw
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(NAME test_Parseval
COMMAND turtle.test_Parseval
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_fftw
COMMAND turtle.test_fftw
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_Parseval
COMMAND turtle.test_Parseval
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
### compare DNS output to stored results
add_test(NAME test_NSVEparticles
COMMAND turtle.test_NSVEparticles
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_NSVEparticles
COMMAND turtle.test_NSVEparticles
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
### simple runs of post-processing tools
add_test(NAME test_pp_single_to_double
COMMAND turtle PP field_single_to_double --simname dns_nsveparticles --iter0 32 --iter1 32
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(NAME test_pp_get_rfields
COMMAND turtle PP get_rfields --simname dns_nsveparticles --iter0 0 --iter1 64
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(NAME test_pp_joint_acc_vel_stats
COMMAND turtle PP joint_acc_vel_stats --simname dns_nsveparticles --iter0 0 --iter1 64
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(NAME test_pp_resize
COMMAND turtle PP resize --simname dns_nsveparticles --new_nx 96 --new_ny 96 --new_nz 96 --new_simname dns_nsveparticles_resized
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_pp_single_to_double
COMMAND turtle PP field_single_to_double --simname dns_nsveparticles --iter0 32 --iter1 32
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_pp_get_rfields
COMMAND turtle PP get_rfields --simname dns_nsveparticles --iter0 0 --iter1 64
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_pp_joint_acc_vel_stats
COMMAND turtle PP joint_acc_vel_stats --simname dns_nsveparticles --iter0 0 --iter1 64
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_pp_resize
COMMAND turtle PP resize --simname dns_nsveparticles --new_nx 96 --new_ny 96 --new_nz 96 --new_simname dns_nsveparticles_resized
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
### simple runs of different DNS
add_test(NAME test_NSVEp_extra_sampling
COMMAND turtle DNS NSVEp_extra_sampling -n 32 --src-simname dns_nsveparticles --src-iteration 32 --simname dns_nsvep_extra_sampling --nparticles 1000
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(NAME test_NSVEcomplex_particles
COMMAND turtle DNS NSVEcomplex_particles -n 32 --src-simname dns_nsveparticles --src-iteration 32 --simname dns_nsvecomplex_particles --nparticles 1000
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(NAME test_static_field
COMMAND turtle DNS static_field --simname dns_static_field --nparticles 10000
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(NAME test_kraichnan_field
COMMAND turtle DNS kraichnan_field --simname dns_kraichnan_field --nparticles 10000
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_NSVEp_extra_sampling
COMMAND turtle DNS NSVEp_extra_sampling -n 32 --src-simname dns_nsveparticles --src-iteration 32 --simname dns_nsvep_extra_sampling --nparticles 1000
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_NSVEcomplex_particles
COMMAND turtle DNS NSVEcomplex_particles -n 32 --src-simname dns_nsveparticles --src-iteration 32 --simname dns_nsvecomplex_particles --nparticles 1000
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_static_field
COMMAND turtle DNS static_field --simname dns_static_field --nparticles 10000
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_kraichnan_field
COMMAND turtle DNS kraichnan_field --simname dns_kraichnan_field --nparticles 10000
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
add_test(
NAME test_NSVE_Stokes_particles
COMMAND turtle DNS NSVE_Stokes_particles -n 32 --src-simname dns_nsveparticles --src-iteration 32 --simname dns_nsve_tokes_particles --nparticles 10000
WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
endif(BUILD_TESTING)
......@@ -439,7 +439,13 @@ class DNS(_code):
assert (self.parameters['niter_todo'] % self.parameters['niter_stat'] == 0)
assert (self.parameters['niter_todo'] % self.parameters['niter_out'] == 0)
assert (self.parameters['niter_out'] % self.parameters['niter_stat'] == 0)
if self.dns_type in ['NSVEparticles_no_output', 'NSVEcomplex_particles', 'NSVEparticles', 'static_field', 'kraichnan_field']:
if self.dns_type in [
'NSVEparticles_no_output',
'NSVEcomplex_particles',
'NSVE_Stokes_particles',
'NSVEparticles',
'static_field',
'kraichnan_field']:
assert (self.parameters['niter_todo'] % self.parameters['niter_part'] == 0)
assert (self.parameters['niter_out'] % self.parameters['niter_part'] == 0)
_code.write_par(self, iter0 = iter0)
......@@ -648,6 +654,10 @@ class DNS(_code):
'NSVEparticles',
help = 'plain Navier-Stokes vorticity formulation, with basic fluid tracers')
parser_NSVE_Stokes_particles = subparsers.add_parser(
'NSVE_Stokes_particles',
help = 'plain Navier-Stokes vorticity formulation, with passive Stokes drag particles')
parser_NSVEp2p = subparsers.add_parser(
'NSVEcomplex_particles',
help = 'plain Navier-Stokes vorticity formulation, with oriented active particles')
......@@ -660,6 +670,7 @@ class DNS(_code):
'NSVEparticles_no_output',
'NSVEp2',
'NSVEp2p',
'NSVE_Stokes_particles',
'NSVEp_extra',
'static_field',
'kraichnan_field']:
......@@ -673,6 +684,7 @@ class DNS(_code):
'NSVEparticles_no_output',
'NSVEp2',
'NSVEp2p',
'NSVE_Stokes_particles',
'NSVEp_extra',
'static_field',
'kraichnan_field']:
......@@ -726,7 +738,14 @@ class DNS(_code):
self.dns_type = opt.DNS_class
self.name = self.dns_type + '-' + self.fluid_precision + '-v' + TurTLE.__version__
# merge parameters if needed
if self.dns_type in ['NSVEparticles', 'NSVEcomplex_particles', 'NSVEparticles_no_output', 'NSVEp_extra_sampling', 'static_field', 'kraichnan_field']:
if self.dns_type in [
'NSVEparticles',
'NSVEcomplex_particles',
'NSVE_Stokes_particles',
'NSVEparticles_no_output',
'NSVEp_extra_sampling',
'static_field',
'kraichnan_field']:
for k in self.NSVEp_extra_parameters.keys():
self.parameters[k] = self.NSVEp_extra_parameters[k]
if type(extra_parameters) != type(None):
......@@ -797,7 +816,14 @@ class DNS(_code):
# hardcoded FFTW complex representation size
field_size = 3*(opt.nx+2)*opt.ny*opt.nz*self.fluid_dtype.itemsize
checkpoint_size = field_size
if self.dns_type in ['kraichnan_field', 'static_field', 'NSVEparticles', 'NSVEcomplex_particles', 'NSVEparticles_no_output', 'NSVEp_extra_sampling']:
if self.dns_type in [
'kraichnan_field',
'static_field',
'NSVEparticles',
'NSVEcomplex_particles',
'NSVE_Stokes_particles',
'NSVEparticles_no_output',
'NSVEp_extra_sampling']:
rhs_size = self.parameters['tracers0_integration_steps']
if type(opt.tracers0_integration_steps) != type(None):
rhs_size = opt.tracers0_integration_steps
......@@ -837,7 +863,9 @@ class DNS(_code):
integration_steps = self.NSVEp_extra_parameters['tracers0_integration_steps']
if 'tracers{0}_integration_steps'.format(species) in self.parameters.keys():
integration_steps = self.parameters['tracers{0}_integration_steps'.format(species)]
if self.dns_type == 'NSVEcomplex_particles' and species == 0:
if self.dns_type in [
'NSVEcomplex_particles',
'NSVE_Stokes_particles'] and species == 0:
ncomponents = 6
with h5py.File(self.get_checkpoint_0_fname(), 'a') as data_file:
nn = self.parameters['nparticles']
......@@ -1021,6 +1049,8 @@ class DNS(_code):
if self.dns_type in ['NSVEcomplex_particles']:
particle_file.create_group('tracers0/orientation')
particle_file.create_group('tracers0/velocity_gradient')
if self.dns_type in ['NSVE_Stokes_particles']:
particle_file.create_group('tracers0/momentum')
if self.dns_type in ['NSVEp_extra_sampling']:
particle_file.create_group('tracers0/velocity_gradient')
particle_file.create_group('tracers0/pressure')
......@@ -1041,6 +1071,7 @@ class DNS(_code):
'static_field',
'NSVEparticles',
'NSVEcomplex_particles',
'NSVE_Stokes_particles',
'NSVEparticles_no_output',
'NSVEp_extra_sampling']:
if not os.path.exists(self.get_checkpoint_0_fname()):
......@@ -1093,6 +1124,7 @@ class DNS(_code):
'static_field',
'NSVEparticles',
'NSVEcomplex_particles',
'NSVE_Stokes_particles',
'NSVEparticles_no_output',
'NSVEp_extra_sampling']:
self.generate_particle_data(opt = opt)
......
/**********************************************************************
* *
* Copyright 2019 Max Planck Institute *
* for Dynamics and Self-Organization *
* *
* This file is part of bfps. *
* *
* bfps is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* bfps is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with bfps. If not, see <http://www.gnu.org/licenses/> *
* *
* Contact: Cristian.Lalescu@ds.mpg.de *
* *
**********************************************************************/
#include <string>
#include <cmath>
#include "NSVE_Stokes_particles.hpp"
#include "scope_timer.hpp"
#include "particles/particles_sampling.hpp"
#include "particles/p2p_ghost_collisions.hpp"
#include "particles/particles_inner_computer_2nd_order.hpp"
template <typename rnumber>
int NSVE_Stokes_particles<rnumber>::initialize(void)
{
TIMEZONE("NSVE_Stokes_particles::intialize");
this->NSVE<rnumber>::initialize();
this->pressure = new field<rnumber, FFTW, ONE>(
this->fs->cvelocity->rlayout->sizes[2],
this->fs->cvelocity->rlayout->sizes[1],
this->fs->cvelocity->rlayout->sizes[0],
this->fs->cvelocity->rlayout->comm,
this->fs->cvelocity->fftw_plan_rigor);
particles_inner_computer_2nd_order_Stokes<double, long long int> current_particles_inner_computer;
current_particles_inner_computer.set_drag_coefficient(0.1);
DEBUG_MSG_WAIT(MPI_COMM_WORLD, "before call to particles_system_builder\n");
this->ps = particles_system_builder_with_p2p(
this->fs->cvelocity, // (field object)
this->fs->kk, // (kspace object, contains dkx, dky, dkz)
tracers0_integration_steps, // to check coherency between parameters and hdf input file (nb rhs)
(long long int)nparticles, // to check coherency between parameters and hdf input file
this->fs->get_current_fname(), // particles input filename
std::string("/tracers0/state/") + std::to_string(this->fs->iteration), // dataset name for initial input
std::string("/tracers0/rhs/") + std::to_string(this->fs->iteration), // dataset name for initial input
tracers0_neighbours, // parameter (interpolation no neighbours)
tracers0_smoothness, // parameter
this->comm,
this->fs->iteration+1,
std::move(p2p_ghost_collisions<double, long long int>()),
std::move(particles_inner_computer_2nd_order_Stokes<double, long long int>()),
this->tracers0_cutoff);
DEBUG_MSG_WAIT(MPI_COMM_WORLD, "after call to particles_system_builder\n");
this->particles_output_writer_mpi = new particles_output_hdf5<
long long int, double, 6>(
MPI_COMM_WORLD,
"tracers0",
nparticles,
tracers0_integration_steps);
this->particles_output_writer_mpi->setParticleFileLayout(this->ps->getParticleFileLayout());
this->particles_sample_writer_mpi = new particles_output_sampling_hdf5<
long long int, double, 3>(
MPI_COMM_WORLD,
this->ps->getGlobalNbParticles(),
(this->simname + "_particles.h5"),
"tracers0",
"position/0");
this->particles_sample_writer_mpi->setParticleFileLayout(this->ps->getParticleFileLayout());
return EXIT_SUCCESS;
}
template <typename rnumber>
int NSVE_Stokes_particles<rnumber>::step(void)
{
TIMEZONE("NSVE_Stokes_particles::step");
this->fs->compute_velocity(this->fs->cvorticity);
this->fs->cvelocity->ift();
this->ps->completeLoop(this->dt);
this->NSVE<rnumber>::step();
return EXIT_SUCCESS;
}
template <typename rnumber>
int NSVE_Stokes_particles<rnumber>::write_checkpoint(void)
{
TIMEZONE("NSVE_Stokes_particles::write_checkpoint");
this->NSVE<rnumber>::write_checkpoint();
this->particles_output_writer_mpi->open_file(this->fs->get_current_fname());
this->particles_output_writer_mpi->template save<6>(
this->ps->getParticlesState(),
this->ps->getParticlesRhs(),
this->ps->getParticlesIndexes(),
this->ps->getLocalNbParticles(),
this->fs->iteration);
this->particles_output_writer_mpi->close_file();
return EXIT_SUCCESS;
}
template <typename rnumber>
int NSVE_Stokes_particles<rnumber>::finalize(void)
{
TIMEZONE("NSVE_Stokes_particles::finalize");
delete this->pressure;
delete this->ps.release();
delete this->particles_output_writer_mpi;
delete this->particles_sample_writer_mpi;
this->NSVE<rnumber>::finalize();
return EXIT_SUCCESS;
}
/** \brief Compute fluid stats and sample fields at particle locations.
*/
template <typename rnumber>
int NSVE_Stokes_particles<rnumber>::do_stats()
{
TIMEZONE("NSVE_Stokes_particles::do_stats");
/// fluid stats go here
this->NSVE<rnumber>::do_stats();
/// either one of two conditions suffices to compute statistics:
/// 1) current iteration is a multiple of niter_part
/// 2) we are within niter_part_fine_duration/2 of a multiple of niter_part_fine_period
if (!(this->iteration % this->niter_part == 0 ||
((this->iteration + this->niter_part_fine_duration/2) % this->niter_part_fine_period <=
this->niter_part_fine_duration)))
return EXIT_SUCCESS;
/// allocate temporary data array
/// initialize pdata0 with the positions, and pdata1 with the orientations
std::unique_ptr<double[]> pdata0 = this->ps->extractParticlesState(0, 3);
std::unique_ptr<double[]> pdata1 = this->ps->extractParticlesState(3, 6);
std::unique_ptr<double[]> pdata2(new double[9*this->ps->getLocalNbParticles()]);
/// sample position
this->particles_sample_writer_mpi->template save_dataset<3>(
"tracers0",
"position",
pdata0.get(), // we need to use pdata0.get() here, because it's 3D, whereas getParticlesState may give something else
&pdata0,
this->ps->getParticlesIndexes(),
this->ps->getLocalNbParticles(),
this->ps->get_step_idx()-1);
/// sample particle momentum
this->particles_sample_writer_mpi->template save_dataset<3>(
"tracers0",
"momentum",
pdata0.get(),
&pdata1,
this->ps->getParticlesIndexes(),
this->ps->getLocalNbParticles(),
this->ps->get_step_idx()-1);
/// sample velocity
std::fill_n(pdata1.get(), 3*this->ps->getLocalNbParticles(), 0);
if (!(this->iteration % this->niter_stat == 0))
{
// we need to compute velocity field manually, because it didn't happen in NSVE::do_stats()
this->fs->compute_velocity(this->fs->cvorticity);
*this->tmp_vec_field = this->fs->cvelocity->get_cdata();
this->tmp_vec_field->ift();
}
this->ps->sample_compute_field(*this->tmp_vec_field, pdata1.get());
this->particles_sample_writer_mpi->template save_dataset<3>(
"tracers0",
"velocity",
pdata0.get(),
&pdata1,
this->ps->getParticlesIndexes(),
this->ps->getLocalNbParticles(),
this->ps->get_step_idx()-1);
// deallocate temporary data array
delete[] pdata0.release();
delete[] pdata1.release();
return EXIT_SUCCESS;
}
template <typename rnumber>
int NSVE_Stokes_particles<rnumber>::read_parameters(void)
{
TIMEZONE("NSVE_Stokes_particles::read_parameters");
this->NSVE<rnumber>::read_parameters();
hid_t parameter_file = H5Fopen((this->simname + ".h5").c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
this->niter_part = hdf5_tools::read_value<int>(parameter_file, "parameters/niter_part");
this->niter_part_fine_period = hdf5_tools::read_value<int>(parameter_file, "parameters/niter_part_fine_period");
this->niter_part_fine_duration = hdf5_tools::read_value<int>(parameter_file, "parameters/niter_part_fine_duration");
this->nparticles = hdf5_tools::read_value<int>(parameter_file, "parameters/nparticles");
this->tracers0_integration_steps = hdf5_tools::read_value<int>(parameter_file, "parameters/tracers0_integration_steps");
this->tracers0_neighbours = hdf5_tools::read_value<int>(parameter_file, "parameters/tracers0_neighbours");
this->tracers0_smoothness = hdf5_tools::read_value<int>(parameter_file, "parameters/tracers0_smoothness");
this->tracers0_cutoff = hdf5_tools::read_value<double>(parameter_file, "parameters/tracers0_cutoff");
H5Fclose(parameter_file);
return EXIT_SUCCESS;
}
template class NSVE_Stokes_particles<float>;
template class NSVE_Stokes_particles<double>;
/**********************************************************************
* *
* Copyright 2017 Max Planck Institute *
* for Dynamics and Self-Organization *
* *
* This file is part of bfps. *
* *
* bfps is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* bfps is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with bfps. If not, see <http://www.gnu.org/licenses/> *
* *
* Contact: Cristian.Lalescu@ds.mpg.de *
* *
**********************************************************************/
#ifndef NSVE_STOKES_PARTICLES_HPP
#define NSVE_STOKES_PARTICLES_HPP
#include <cstdlib>
#include "base.hpp"
#include "vorticity_equation.hpp"
#include "full_code/NSVE.hpp"
#include "particles/particles_system_builder.hpp"
#include "particles/particles_output_hdf5.hpp"
#include "particles/particles_sampling.hpp"
/** \brief Navier-Stokes solver that includes simple Lagrangian tracers.
*
* Child of Navier Stokes vorticity equation solver, this class calls all the
* methods from `NSVE`, and in addition integrates simple Lagrangian tracers
* in the resulting velocity field.
*/
template <typename rnumber>
class NSVE_Stokes_particles: public NSVE<rnumber>
{
public:
/* parameters that are read in read_parameters */
int niter_part;
int niter_part_fine_period;
int niter_part_fine_duration;
int nparticles;
int tracers0_integration_steps;
int tracers0_neighbours;
int tracers0_smoothness;
double tracers0_cutoff;
/* other stuff */
std::unique_ptr<abstract_particles_system<long long int, double>> ps;
field<rnumber, FFTW, ONE> *pressure;
particles_output_hdf5<long long int, double,6> *particles_output_writer_mpi;
particles_output_sampling_hdf5<long long int, double, 3> *particles_sample_writer_mpi;
NSVE_Stokes_particles(
const MPI_Comm COMMUNICATOR,
const std::string &simulation_name):
NSVE<rnumber>(
COMMUNICATOR,
simulation_name){}
~NSVE_Stokes_particles(){}
int initialize(void);
int step(void);
int finalize(void);
int read_parameters(void);
int write_checkpoint(void);
int do_stats(void);
};
#endif//NSVE_STOKES_PARTICLES_HPP
......@@ -61,6 +61,7 @@ public:
virtual void shift_rhs_vectors() = 0;
virtual void completeLoop(const real_number dt) = 0;
virtual void complete2ndOrderLoop(const real_number dt) = 0;
virtual void completeLoopWithVorticity(
const real_number dt,
......
/******************************************************************************
* *
* Copyright 2019 Max Planck Institute for Dynamics and Self-Organization *
* *
* This file is part of bfps. *
* *
* bfps is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* bfps is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with bfps. If not, see <http://www.gnu.org/licenses/> *
* *
* Contact: Cristian.Lalescu@ds.mpg.de *
* *
******************************************************************************/
#ifndef PARTICLES_INNER_COMPUTER_2ND_ORDER_HPP
#define PARTICLES_INNER_COMPUTER_2ND_ORDER_HPP
#include <cstring>
#include <cassert>
template <class real_number, class partsize_t>
class particles_inner_computer_2nd_order_Stokes{
double drag_coefficient;
public:
template <int size_particle_state, int size_particle_rhs>
void compute_interaction(const partsize_t number_of_particles, real_number particle_state[], real_number particle_rhs[]) const{
}
template <int size_particle_state>
void enforce_unit_orientation(const partsize_t /*nb_particles*/, real_number /*pos_part*/[]) const{
}
template <int size_particle_state, int size_particle_rhs>
void add_Lagrange_multipliers(const partsize_t /*nb_particles*/, real_number /*pos_part*/[], real_number /*rhs_part*/[]) const{
}
template <int size_particle_state, int size_particle_rhs, int size_particle_rhs_extra>
void compute_interaction_with_extra(
const partsize_t number_of_particles,
real_number particle_state[],
real_number particle_rhs[],
const real_number sampled_velocity[]) const{
assert(size_particle_state == 6);
assert(size_particle_rhs == 6);
assert(size_particle_rhs_extra == 3);
#pragma omp parallel for
for(partsize_t idx_part = 0 ; idx_part < number_of_particles ; ++idx_part){
particle_rhs[idx_part*size_particle_rhs + IDXC_X] = particle_state[idx_part*size_particle_state + 3 + IDXC_X];
particle_rhs[idx_part*size_particle_rhs + IDXC_Y] = particle_state[idx_part*size_particle_state + 3 + IDXC_Y];
particle_rhs[idx_part*size_particle_rhs + IDXC_Z] = particle_state[idx_part*size_particle_state + 3 + IDXC_Z];
particle_rhs[idx_part*size_particle_rhs + 3 + IDXC_X] = - this->drag_coefficient * (particle_state[idx_part*size_particle_state + 3 + IDXC_X] - sampled_velocity[idx_part*size_particle_rhs_extra + IDXC_X]);
particle_rhs[idx_part*size_particle_rhs + 3 + IDXC_Y] = - this->drag_coefficient * (particle_state[idx_part*size_particle_state + 3 + IDXC_Y] - sampled_velocity[idx_part*size_particle_rhs_extra + IDXC_Y]);
particle_rhs[idx_part*size_particle_rhs + 3 + IDXC_Z] = - this->drag_coefficient * (particle_state[idx_part*size_particle_state + 3 + IDXC_Z] - sampled_velocity[idx_part*size_particle_rhs_extra + IDXC_Z]);
}
}
constexpr static bool isEnable() {
return true;
}
void set_drag_coefficient(double mu)
{
this->drag_coefficient = mu;
}
double get_drag_coefficient()
{
return this->drag_coefficient;
}