Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding tests #8

Merged
merged 45 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
febedd2
Create tests folder and add some mocks
RaulPPelaez Apr 29, 2024
d4fa280
Merge remote-tracking branch 'origin/main' into tests
RaulPPelaez Apr 29, 2024
86ca725
Update ci
RaulPPelaez Apr 29, 2024
ec5ff93
Change the name of setParameter[Solver] to just setParameters in the …
RaulPPelaez Apr 29, 2024
584b157
Add pytest to environment.yml
RaulPPelaez Apr 29, 2024
d57b161
Check dtype in the inputs to the solvers
RaulPPelaez Apr 30, 2024
aec74a3
added tests to check functionality based on the compiled libmobility …
rykerfish Apr 30, 2024
9b0934c
Merge branch 'tests' of github.com:stochasticHydroTools/libMobility i…
rykerfish Apr 30, 2024
bb909ad
removed double-initialization from SelfMobility
rykerfish Apr 30, 2024
52d6cde
added tests to check nbody batch parameters
rykerfish Apr 30, 2024
d680f86
Merge remote-tracking branch 'origin/main' into tests
RaulPPelaez Apr 30, 2024
c1c6652
Add fluctuation dissipation balance KS test.
RaulPPelaez Apr 30, 2024
bec854f
Make precision test more complete
RaulPPelaez Apr 30, 2024
d30ae3e
Fix precision detection
RaulPPelaez Apr 30, 2024
91d996f
Add precision test to CI
RaulPPelaez Apr 30, 2024
d77b32a
Ensure the input arrays are contiguous
RaulPPelaez Apr 30, 2024
c2d7bdb
fluctation dissapation test checking M times random samples
rykerfish Apr 30, 2024
2c69c36
fluctuating test working for nbody and pse
rykerfish Apr 30, 2024
182ee5d
Remove Donev solved comment
RaulPPelaez Apr 30, 2024
c0967ad
Update DPStokes
RaulPPelaez Apr 30, 2024
b425d3a
Add DPStokes to test_fluctuation_dissipation_balance
RaulPPelaez Apr 30, 2024
800f279
Add DPStokes to test_fluctuation_dissipation_balance
RaulPPelaez Apr 30, 2024
2ca921a
Merge remote-tracking branch 'origin/tests' into tests
RaulPPelaez Apr 30, 2024
b3e5d8f
Merge remote-tracking branch 'origin/main' into tests
RaulPPelaez Apr 30, 2024
8e5cb8e
Fix DPStokes
RaulPPelaez Apr 30, 2024
1a956a0
Fix DPStokes
RaulPPelaez May 1, 2024
aabc36b
Update DPstokes params
RaulPPelaez May 1, 2024
94cc809
Add message to test
RaulPPelaez May 1, 2024
fe9bbb6
Update DPStokes parameters
RaulPPelaez May 1, 2024
b7a067d
Move compute_M and sane_parameters to utils.py
RaulPPelaez May 1, 2024
a5b1d89
Add test for checking if the mobility matrix is symmetric
RaulPPelaez May 1, 2024
7d15d97
Fix DPStokes parameters
RaulPPelaez May 1, 2024
0e45cf2
Small change to test
RaulPPelaez May 1, 2024
31ecf44
Small change to test
RaulPPelaez May 1, 2024
694c520
Update docstring
RaulPPelaez May 1, 2024
9a2d145
Clean up tests a bit
RaulPPelaez May 1, 2024
2766faf
Fix docstring
RaulPPelaez May 1, 2024
faae4ec
Fix position precision
RaulPPelaez May 1, 2024
4e855ec
Simplify DPStokes
RaulPPelaez May 1, 2024
c9fd310
Update tolerance
RaulPPelaez May 1, 2024
274cfca
Remove old Donev comment
RaulPPelaez May 1, 2024
b6a65f0
Add tolerance to initialize
RaulPPelaez May 1, 2024
e4c96b6
Typo
RaulPPelaez May 1, 2024
ff23b4e
Fix FCM parameters, add self mobility test
RaulPPelaez May 3, 2024
45d966f
Update ci
RaulPPelaez May 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ jobs:
python -c "import libMobility"
python -c "from libMobility import DPStokes, PSE, NBody, SelfMobility"

- name: Run pytest
run: |
micromamba activate libmobility
pytest -sv tests/test_initialization.py tests/test_precision.py
#Only SelfMobility tests can run in the CPU
pytest -sv -k SelfMobility tests/test*py

- name: Install docs dependencies
run: |
pip install -r docs/requirements.txt
Expand Down
2 changes: 2 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ dependencies:
- pybind11
- numpy
- python 3.11.*
- pytest
- scipy
1 change: 0 additions & 1 deletion include/MobilityInterface/MobilityInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ namespace libmobility{
}

//Equivalent to calling Mdot and then stochasticDisplacements, can be faster in some solvers
// Donev: The README says there is a torque parameter here but I do not see it (I asked that it be removed but maybe this README never got updated)?
virtual void hydrodynamicVelocities(const real* forces, real* result, real prefactor = 1){
Mdot(forces, result);
sqrtMdotW(result, prefactor);
Expand Down
48 changes: 36 additions & 12 deletions include/MobilityInterface/pythonify.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The MOBILITY_PYTHONIFY(className, description) macro creates a pybind11 module f
#include<pybind11/numpy.h>
namespace py = pybind11;
using namespace pybind11::literals;
using pyarray = py::array_t<libmobility::real>;
using pyarray = py::array;

#define MOBILITYSTR(s) xMOBILITYSTR(s)
#define xMOBILITYSTR(s) #s
Expand All @@ -31,6 +31,26 @@ inline auto createConfiguration(std::string perx, std::string pery, std::string
return conf;
}

template<typename T>
void check_dtype(pyarray &arr){
if(not py::isinstance<py::array_t<T>>(arr)){
throw std::runtime_error("Input array must have the correct data type.");
}
if(not py::isinstance<py::array_t<T, py::array::c_style | py::array::forcecast>>(arr)){
throw std::runtime_error("The input array is not contiguous and cannot be used as a buffer.");
}

}

libmobility::real* cast_to_real(pyarray &arr){
check_dtype<libmobility::real>(arr);
return static_cast<libmobility::real*>(arr.mutable_data());
}

const libmobility::real* cast_to_const_real(pyarray &arr){
check_dtype<const libmobility::real>(arr);
return static_cast<const libmobility::real*>(arr.data());
}
const char *constructor_docstring = R"pbdoc(
Initialize the module with a given set of periodicity conditions.

Expand Down Expand Up @@ -64,6 +84,8 @@ hydrodynamicRadius : float
Hydrodynamic radius of the particles.
numberParticles : int
Number of particles in the system.
tolerance : float, optional
Tolerance, used for approximate methods and also for Lanczos (default fluctuation computation). Default is 1e-4.
)pbdoc";

const char *mdot_docstring = R"pbdoc(
Expand Down Expand Up @@ -130,35 +152,37 @@ prefactor : float, optional
solver.def(py::init([](std::string perx, std::string pery, std::string perz){ \
return std::unique_ptr<MODULENAME>(new MODULENAME(createConfiguration(perx, pery, perz))); }), \
constructor_docstring, "periodicityX"_a, "periodicityY"_a, "periodicityZ"_a). \
def("initialize", [](MODULENAME &myself, real T, real eta, real a, int N){ \
def("initialize", [](MODULENAME &myself, real T, real eta, real a, int N, real tol){ \
Parameters par; \
par.temperature = T; \
par.viscosity = eta; \
par.hydrodynamicRadius = {a}; \
par.tolerance = tol; \
par.numberParticles = N; \
myself.initialize(par); \
}, \
initialize_docstring, \
"temperature"_a, "viscosity"_a, \
"hydrodynamicRadius"_a, \
"numberParticles"_a). \
def("setPositions", [](MODULENAME &myself, pyarray pos){myself.setPositions(pos.data());}, \
"numberParticles"_a, \
"tolerance"_a = 1e-4). \
def("setPositions", [](MODULENAME &myself, pyarray pos){myself.setPositions(cast_to_const_real(pos));}, \
"The module will compute the mobility according to this set of positions.", \
"positions"_a). \
def("Mdot", [](MODULENAME &myself, pyarray forces, pyarray result){\
auto f = forces.size()?forces.data():nullptr; \
myself.Mdot(f, result.mutable_data());}, \
mdot_docstring, \
auto f = forces.size()?cast_to_const_real(forces):nullptr; \
myself.Mdot(f, cast_to_real(result));}, \
mdot_docstring, \
"forces"_a = pyarray(), "result"_a). \
def("sqrtMdotW", [](MODULENAME &myself, pyarray result, libmobility::real prefactor){ \
myself.sqrtMdotW(result.mutable_data(), prefactor);}, \
sqrtMdotW_docstring, \
myself.sqrtMdotW(cast_to_real(result), prefactor);}, \
sqrtMdotW_docstring, \
"result"_a = pyarray(), "prefactor"_a = 1.0). \
def("hydrodynamicVelocities", [](MODULENAME &myself, pyarray forces,\
pyarray result, libmobility::real prefactor){ \
auto f = forces.size()?forces.data():nullptr; \
myself.hydrodynamicVelocities(f, result.mutable_data(), prefactor);}, \
hydrodynamicvelocities_docstring, \
auto f = forces.size()?cast_to_const_real(forces):nullptr; \
myself.hydrodynamicVelocities(f, cast_to_real(result), prefactor);}, \
hydrodynamicvelocities_docstring, \
"forces"_a = pyarray(), "result"_a = pyarray(), "prefactor"_a = 1). \
def("clean", &MODULENAME::clean, "Frees any memory allocated by the module."). \
def_property_readonly_static("precision", [](py::object){return MODULENAME::precision;}, R"pbdoc(Compilation precision, a string holding either float or double.)pbdoc"); \
Expand Down
60 changes: 23 additions & 37 deletions solvers/DPStokes/mobility.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class DPStokes: public libmobility::Mobility{
real lanczosTolerance;
std::uint64_t lanczosSeed;
std::shared_ptr<LanczosStochasticVelocities> lanczos;
std::string wallmode;
public:

DPStokes(Configuration conf){
Expand All @@ -33,31 +34,13 @@ class DPStokes: public libmobility::Mobility{
conf.periodicityZ == libmobility::periodicity_mode::two_walls)
)
throw std::runtime_error("[DPStokes] This is a doubly periodic solver");
if(conf.periodicityZ == periodicity_mode::open) wallmode = "nowall";
else if(conf.periodicityZ == periodicity_mode::single_wall) wallmode = "bottom";
else if(conf.periodicityZ == periodicity_mode::two_walls) wallmode = "slit";
}

void setParametersDPStokes(DPStokesParameters i_dppar){
this->dppar = i_dppar;
// DPStokesParameters dppar;
// int nx = -1;
// int ny = -1;
// int nz = -1;
// dppar.dt
// dppar.viscosity
// dppar.Lx
// dppar.Ly
// dppar.zmin
// dppar. zmax
// //Tolerance will be ignored in DP mode, TP will use only tolerance and nxy/nz
// dppar.tolerance = 1e-5;
// dppar.w
// dppar.w_d;
// dppar.hydrodynamicRadius = -1;
// dppar.beta = -1;
// dppar.beta_d = -1;
// dppar.alpha = -1;
// dppar.alpha_d = -1;
// //Can be either none, bottom, slit or periodic
// dppar.mode;
dpstokes = std::make_shared<uammd_dpstokes::DPStokesGlue>();
}

Expand All @@ -66,6 +49,25 @@ class DPStokes: public libmobility::Mobility{
this->dppar.viscosity = ipar.viscosity;
this->temperature = ipar.temperature;
this->lanczosTolerance = ipar.tolerance;
this->dppar.mode = this->wallmode;
this->dppar.hydrodynamicRadius = ipar.hydrodynamicRadius[0];
this->dppar.w = 6;
this->dppar.beta = 1.714*this->dppar.w;
real h = this->dppar.hydrodynamicRadius/1.554;
this->dppar.alpha = this->dppar.w/2.0;
this->dppar.tolerance = 1e-6;
this->dppar.nx = int(this->dppar.Lx/h + 0.5);
this->dppar.ny = int(this->dppar.Ly/h + 0.5);
// Add a buffer of w*h/2 when there is an open boundary
if(this->wallmode == "nowall"){
this->dppar.zmax += this->dppar.w*h/2;
this->dppar.zmin -= this->dppar.w*h/2;
}
if(this->wallmode == "bottom"){
this->dppar.zmin -= this->dppar.w*h/2;
}
real Lz = this->dppar.zmax - this->dppar.zmin;
this->dppar.nz = M_PI*Lz/(h);
dpstokes->initialize(dppar, this->numberParticles);
Mobility::initialize(ipar);
}
Expand All @@ -78,22 +80,6 @@ class DPStokes: public libmobility::Mobility{
dpstokes->Mdot(forces, nullptr, result, nullptr);
}

void sqrtMdotW(real* result, real prefactor = 1) override{
if(this->temperature == 0) return;
if(not dpstokes)
throw std::runtime_error("[libMobility] You must initialize the base class in order to use the default stochastic displacement computation");
if(not lanczos){
if(this->lanczosSeed==0){//If a seed is not provided, get one from random device
this->lanczosSeed = std::random_device()();
}
lanczos = std::make_shared<LanczosStochasticVelocities>(this->numberParticles,
this->lanczosTolerance, this->lanczosSeed);
}
lanczos->sqrtMdotW([this](const real*f, real* mv){Mdot(f, mv);}, result, prefactor);
}

// Donev: Is there a Lanczos implementation on the GPU or that is always done on CPU? If there is a GPU version, is it possible with the current interface to make a more efficient hydrodynamicDisplacements routine that does not do the CPU<->GPU twice of say the positions. That is, there is no return back to the GPU until both Mdot and sqrtMdotW are finished? I cannot follow the UAMMD stuff so just tell me what the code does now and if it is possible to optimize further.

void clean() override{
Mobility::clean();
dpstokes->clear();
Expand Down
64 changes: 18 additions & 46 deletions solvers/DPStokes/python_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ using DPStokesParameters = uammd_dpstokes::PyParameters;
static const char *docstring = R"pbdoc(
In the Doubly periodic Stokes geometry (DPStokes), an incompressible fluid exists in a domain which is periodic in the plane and open (or walled) in the third direction.

When the periodicity is set to :code:`single_wall` a wall in the bottom of the domain is added.

Parameters
----------
dt : float
The time step.
viscosity : float
The viscosity of the fluid.
Lx : float
The box size in the x direction.
Ly : float
Expand All @@ -20,49 +20,21 @@ zmin : float
The minimum value of the z coordinate.
zmax : float
The maximum value of the z coordinate.
w : float
The support of the particle force spreading kernel.
w_d : float
The support of the dipole force spreading kernel.
hydrodynamicRadius : float
The hydrodynamic radius of the particle.
beta : float
The width of the Exponential of the Semicircle (ES) particle force spreading kernel.
beta_d : float
The width of the Exponential of the Semicircle (ES) particle dipole spreading kernel.
alpha : float
Distance normalization factor for the particle force spreading kernel.
alpha_d : float
Distance normalization factor for the dipole force spreading kernel.
mode : str
The wall mode. Options are 'slit', 'bottom' and 'nowall'.
)pbdoc";

MOBILITY_PYTHONIFY_WITH_EXTRA_CODE(
DPStokes,
solver.def(
"setParameters",
[](DPStokes &self, real dt, real viscosity, real Lx, real Ly, real zmin,
real zmax, real w, real w_d, real hydrodynamicRadius, real beta,
real beta_d, real alpha, real alpha_d, std::string mode) {
DPStokesParameters params;
params.dt = dt;
params.viscosity = viscosity;
params.Lx = Lx;
params.Ly = Ly;
params.zmin = zmin;
params.zmax = zmax;
params.w = w;
params.w_d = w_d;
params.hydrodynamicRadius = hydrodynamicRadius;
params.beta = beta;
params.beta_d = beta_d;
params.alpha = alpha;
params.alpha_d = alpha_d;
params.mode = mode;
self.setParametersDPStokes(params);
},
"dt"_a, "viscosity"_a, "Lx"_a, "Ly"_a, "zmin"_a, "zmax"_a, "w"_a,
"w_d"_a, "hydrodynamicRadius"_a, "beta"_a, "beta_d"_a, "alpha"_a,
"alpha_d"_a, "mode"_a);,
docstring);
MOBILITY_PYTHONIFY_WITH_EXTRA_CODE(DPStokes,
solver.def(
"setParameters",
[](DPStokes &self, real dt, real Lx,
real Ly, real zmin, real zmax) {
DPStokesParameters params;
params.dt = dt;
params.Lx = Lx;
params.Ly = Ly;
params.zmin = zmin;
params.zmax = zmax;
self.setParametersDPStokes(params);
},
"dt"_a, "Lx"_a, "Ly"_a, "zmin"_a,
"zmax"_a);
, docstring);
Loading
Loading