Commit def6d702 authored by Rudolf Weeber's avatar Rudolf Weeber

Merge branch 'python' of git://github.com/espressomd/espresso into pr2381

parents bbfa2067 e3cf300e
......@@ -205,6 +205,16 @@ empty:
- linux
- cuda
ubuntu:wo-dependencies:
stage: build
image: gitlab.icp.uni-stuttgart.de:4567/espressomd/docker/$CI_JOB_NAME
script:
- export myconfig=maxset make_check=false
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
### Builds with ROCm
rocm-maxset:
......
......@@ -180,13 +180,14 @@ if (WITH_CUDA)
target_link_libraries(${target} ${CUFFT_LIBRARY})
endfunction()
else()
find_package(HIP QUIET MODULE)
list(APPEND CMAKE_MODULE_PATH "/opt/rocm/hip/cmake")
find_package(HIP 1.5.18494 QUIET MODULE)
if(HIP_FOUND)
set(HCC_PATH "${HIP_ROOT_DIR}")
find_package(HIP MODULE)
message(STATUS "Found HIP compiler: ${HIP_HIPCC_EXECUTABLE}")
set(CUDA 1)
list(APPEND HIP_HCC_FLAGS "-Wno-macro-redefined")
list(APPEND HIP_HCC_FLAGS "-Wno-macro-redefined -Wno-duplicate-decl-specifier")
HIP_INCLUDE_DIRECTORIES("${CMAKE_BINARY_DIR}/src/core" "${CMAKE_SOURCE_DIR}/src/core")
function(cuda_include_directories)
HIP_INCLUDE_DIRECTORIES(${ARGV})
......
This diff is collapsed.
###############################################################################
# Runs commands using HIPCC
###############################################################################
###############################################################################
# This file runs the hipcc commands to produce the desired output file
# along with the dependency file needed by CMake to compute dependencies.
#
# Input variables:
#
# verbose:BOOL=<> OFF: Be as quiet as possible (default)
# ON : Describe each step
# build_configuration:STRING=<> Build configuration. Defaults to Debug.
# generated_file:STRING=<> File to generate. Mandatory argument.
if(NOT build_configuration)
set(build_configuration Debug)
endif()
if(NOT generated_file)
message(FATAL_ERROR "You must specify generated_file on the command line")
endif()
# Set these up as variables to make reading the generated file easier
set(HIP_HIPCC_EXECUTABLE "@HIP_HIPCC_EXECUTABLE@") # path
set(HIP_HIPCONFIG_EXECUTABLE "@HIP_HIPCONFIG_EXECUTABLE@") #path
set(HIP_HOST_COMPILER "@HIP_HOST_COMPILER@") # path
set(CMAKE_COMMAND "@CMAKE_COMMAND@") # path
set(HIP_run_make2cmake "@HIP_run_make2cmake@") # path
set(HCC_HOME "@HCC_HOME@") #path
@HIP_HOST_FLAGS@
@_HIP_HIPCC_FLAGS@
@_HIP_HCC_FLAGS@
@_HIP_NVCC_FLAGS@
set(HIP_HIPCC_INCLUDE_ARGS "@HIP_HIPCC_INCLUDE_ARGS@") # list (needs to be in quotes to handle spaces properly)
set(cmake_dependency_file "@cmake_dependency_file@") # path
set(source_file "@source_file@") # path
set(host_flag "@host_flag@") # bool
# Determine compiler and compiler flags
execute_process(COMMAND ${HIP_HIPCONFIG_EXECUTABLE} --platform OUTPUT_VARIABLE HIP_PLATFORM OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT host_flag)
set(__CC ${HIP_HIPCC_EXECUTABLE})
if(HIP_PLATFORM STREQUAL "hcc")
if(NOT "x${HCC_HOME}" STREQUAL "x")
set(ENV{HCC_HOME} ${HCC_HOME})
endif()
set(__CC_FLAGS ${HIP_HIPCC_FLAGS} ${HIP_HCC_FLAGS} ${HIP_HIPCC_FLAGS_${build_configuration}} ${HIP_HCC_FLAGS_${build_configuration}})
else()
set(__CC_FLAGS ${HIP_HIPCC_FLAGS} ${HIP_NVCC_FLAGS} ${HIP_HIPCC_FLAGS_${build_configuration}} ${HIP_NVCC_FLAGS_${build_configuration}})
endif()
else()
set(__CC ${HIP_HOST_COMPILER})
set(__CC_FLAGS ${CMAKE_HOST_FLAGS} ${CMAKE_HOST_FLAGS_${build_configuration}})
endif()
set(__CC_INCLUDES ${HIP_HIPCC_INCLUDE_ARGS})
# hip_execute_process - Executes a command with optional command echo and status message.
# status - Status message to print if verbose is true
# command - COMMAND argument from the usual execute_process argument structure
# ARGN - Remaining arguments are the command with arguments
# HIP_result - Return value from running the command
macro(hip_execute_process status command)
set(_command ${command})
if(NOT "x${_command}" STREQUAL "xCOMMAND")
message(FATAL_ERROR "Malformed call to hip_execute_process. Missing COMMAND as second argument. (command = ${command})")
endif()
if(verbose)
execute_process(COMMAND "${CMAKE_COMMAND}" -E echo -- ${status})
# Build command string to print
set(hip_execute_process_string)
foreach(arg ${ARGN})
# Escape quotes if any
string(REPLACE "\"" "\\\"" arg ${arg})
# Surround args with spaces with quotes
if(arg MATCHES " ")
list(APPEND hip_execute_process_string "\"${arg}\"")
else()
list(APPEND hip_execute_process_string ${arg})
endif()
endforeach()
# Echo the command
execute_process(COMMAND ${CMAKE_COMMAND} -E echo ${hip_execute_process_string})
endif()
# Run the command
execute_process(COMMAND ${ARGN} RESULT_VARIABLE HIP_result)
endmacro()
# Delete the target file
hip_execute_process(
"Removing ${generated_file}"
COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
)
# Generate the dependency file
hip_execute_process(
"Generating dependency file: ${cmake_dependency_file}.pre"
COMMAND "${__CC}"
-M
"${source_file}"
-o "${cmake_dependency_file}.pre"
${__CC_FLAGS}
${__CC_INCLUDES}
)
if(HIP_result)
message(FATAL_ERROR "Error generating ${generated_file}")
endif()
# Generate the cmake readable dependency file to a temp file
hip_execute_process(
"Generating temporary cmake readable file: ${cmake_dependency_file}.tmp"
COMMAND "${CMAKE_COMMAND}"
-D "input_file:FILEPATH=${cmake_dependency_file}.pre"
-D "output_file:FILEPATH=${cmake_dependency_file}.tmp"
-D "verbose=${verbose}"
-P "${HIP_run_make2cmake}"
)
if(HIP_result)
message(FATAL_ERROR "Error generating ${generated_file}")
endif()
# Copy the file if it is different
hip_execute_process(
"Copy if different ${cmake_dependency_file}.tmp to ${cmake_dependency_file}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${cmake_dependency_file}.tmp" "${cmake_dependency_file}"
)
if(HIP_result)
message(FATAL_ERROR "Error generating ${generated_file}")
endif()
# Delete the temporary file
hip_execute_process(
"Removing ${cmake_dependency_file}.tmp and ${cmake_dependency_file}.pre"
COMMAND "${CMAKE_COMMAND}" -E remove "${cmake_dependency_file}.tmp" "${cmake_dependency_file}.pre"
)
if(HIP_result)
message(FATAL_ERROR "Error generating ${generated_file}")
endif()
# Generate the output file
hip_execute_process(
"Generating ${generated_file}"
COMMAND "${__CC}"
-c
"${source_file}"
-o "${generated_file}"
${__CC_FLAGS}
${__CC_INCLUDES}
)
if(HIP_result)
# Make sure that we delete the output file
hip_execute_process(
"Removing ${generated_file}"
COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
)
message(FATAL_ERROR "Error generating file ${generated_file}")
else()
if(verbose)
message("Generated ${generated_file} successfully.")
endif()
endif()
# vim: ts=4:sw=4:expandtab:smartindent
###############################################################################
# Computes dependencies using HIPCC
###############################################################################
###############################################################################
# This file converts dependency files generated using hipcc to a format that
# cmake can understand.
# Input variables:
#
# input_file:STRING=<> Dependency file to parse. Required argument
# output_file:STRING=<> Output file to generate. Required argument
if(NOT input_file OR NOT output_file)
message(FATAL_ERROR "You must specify input_file and output_file on the command line")
endif()
file(READ ${input_file} depend_text)
if (NOT "${depend_text}" STREQUAL "")
string(REPLACE " /" "\n/" depend_text ${depend_text})
string(REGEX REPLACE "^.*:" "" depend_text ${depend_text})
string(REGEX REPLACE "[ \\\\]*\n" ";" depend_text ${depend_text})
set(dependency_list "")
foreach(file ${depend_text})
string(REGEX REPLACE "^ +" "" file ${file})
if(NOT EXISTS "${file}")
message(WARNING " Removing non-existent dependency file: ${file}")
set(file "")
endif()
if(NOT IS_DIRECTORY "${file}")
get_filename_component(file_absolute "${file}" ABSOLUTE)
list(APPEND dependency_list "${file_absolute}")
endif()
endforeach()
endif()
# Remove the duplicate entries and sort them.
list(REMOVE_DUPLICATES dependency_list)
list(SORT dependency_list)
foreach(file ${dependency_list})
set(hip_hipcc_depend "${hip_hipcc_depend} \"${file}\"\n")
endforeach()
file(WRITE ${output_file} "# Generated by: FindHIP.cmake. Do not edit.\nSET(HIP_HIPCC_DEPEND\n ${hip_hipcc_depend})\n\n")
# vim: ts=4:sw=4:expandtab:smartindent
......@@ -103,7 +103,7 @@ ROCm SDK to make use of GPU computation:
wget -qO - http://repo.radeon.com/rocm/apt/debian/rocm.gpg.key | sudo apt-key add -
echo 'deb [arch=amd64] http://repo.radeon.com/rocm/apt/debian/ xenial main' | sudo tee /etc/apt/sources.list.d/rocm.list
sudo apt update
sudo apt install libnuma-dev rocm-dkms rocblas rocfft rocrand
sudo apt install libnuma-dev rocm-dkms rocblas rocfft rocrand hip-thrust
.. _Installing Requirements on Mac OS X:
......
......@@ -71,7 +71,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define SOFT_SPHERE
#define INTER_RF
#define OVERLAPPED
#ifdef P3M
#define THOLE
#endif
#define BOND_ANGLE
......
......@@ -319,7 +319,7 @@ void Mmm1dgpuForce::set_params(mmm1dgpu_real _boxz,
__global__ void forcesKernel(const mmm1dgpu_real *__restrict__ r,
const mmm1dgpu_real *__restrict__ q,
mmm1dgpu_real *__restrict__ force, int N,
int pairs, int tStart = 0, int tStop = -1) {
int pairs, int tStart, int tStop) {
if (tStop < 0)
tStop = N * N;
......@@ -406,7 +406,7 @@ __global__ void forcesKernel(const mmm1dgpu_real *__restrict__ r,
__global__ void energiesKernel(const mmm1dgpu_real *__restrict__ r,
const mmm1dgpu_real *__restrict__ q,
mmm1dgpu_real *__restrict__ energy, int N,
int pairs, int tStart = 0, int tStop = -1) {
int pairs, int tStart, int tStop) {
if (tStop < 0)
tStop = N * N;
......@@ -474,7 +474,7 @@ __global__ void energiesKernel(const mmm1dgpu_real *__restrict__ r,
}
__global__ void vectorReductionKernel(mmm1dgpu_real *src, mmm1dgpu_real *dst,
int N, int tStart = 0, int tStop = -1) {
int N, int tStart, int tStop) {
if (tStop < 0)
tStop = N * N;
......@@ -511,12 +511,12 @@ void Mmm1dgpuForce::computeForces(SystemInterface &s) {
{
int blocksRed = s.npart_gpu() / numThreads + 1;
KERNELCALL(forcesKernel, numBlocks(s), numThreads, s.rGpuBegin(),
s.qGpuBegin(), dev_forcePairs, s.npart_gpu(), pairs)
s.qGpuBegin(), dev_forcePairs, s.npart_gpu(), pairs, 0, -1)
KERNELCALL(vectorReductionKernel, blocksRed, numThreads, dev_forcePairs,
s.fGpuBegin(), s.npart_gpu())
s.fGpuBegin(), s.npart_gpu(), 0, -1)
} else {
KERNELCALL(forcesKernel, numBlocks(s), numThreads, s.rGpuBegin(),
s.qGpuBegin(), s.fGpuBegin(), s.npart_gpu(), pairs)
s.qGpuBegin(), s.fGpuBegin(), s.npart_gpu(), pairs, 0, -1)
}
}
......@@ -547,7 +547,7 @@ void Mmm1dgpuForce::computeEnergy(SystemInterface &s) {
KERNELCALL_shared(energiesKernel, numBlocks(s), numThreads, shared,
s.rGpuBegin(), s.qGpuBegin(), dev_energyBlocks,
s.npart_gpu(), 0);
s.npart_gpu(), 0, 0, -1);
KERNELCALL_shared(sumKernel, 1, numThreads, shared, dev_energyBlocks,
numBlocks(s));
KERNELCALL(scaleAndAddKernel, 1, 1, &(((CUDA_energy *)s.eGpu())->coulomb),
......@@ -567,7 +567,7 @@ float Mmm1dgpuForce::force_benchmark(SystemInterface &s) {
cuda_safe_mem(cudaEventCreate(&eventStop));
cuda_safe_mem(cudaEventRecord(eventStart, stream[0]));
KERNELCALL(forcesKernel, numBlocks(s), numThreads, s.rGpuBegin(),
s.qGpuBegin(), dev_f_benchmark, s.npart_gpu(), 0)
s.qGpuBegin(), dev_f_benchmark, s.npart_gpu(), 0, 0, -1)
cuda_safe_mem(cudaEventRecord(eventStop, stream[0]));
cuda_safe_mem(cudaEventSynchronize(eventStop));
cuda_safe_mem(cudaEventElapsedTime(&elapsedTime, eventStart, eventStop));
......
......@@ -372,6 +372,11 @@ inline bool pair_bond_exists_on(const Particle *const p,
inline bool pair_bond_enum_exists_on(const Particle *const p_bond,
const Particle *const p_partner,
BondedInteraction bond) {
#ifdef ADDITIONAL_CHECKS
extern int ghosts_have_bonds;
assert(ghosts_have_bonds);
#endif
int i = 0;
while (i < p_bond->bl.n) {
int type_num = p_bond->bl.e[i];
......
......@@ -48,25 +48,24 @@ int subt_lj_set_params(int bond_type);
@return true if bond is broken
*/
inline int calc_subt_lj_pair_force(Particle *p1, Particle *p2,
Bonded_ia_parameters *iaparams, double dx[3],
Bonded_ia_parameters *, double dx_[3],
double force[3]) {
auto ia_params = get_ia_param(p1->p.type, p2->p.type);
for (int i = 0; i < 3; i++) {
dx[i] *= -1;
}
auto const dx = -Vector3d(dx_, dx_ + 3);
add_lj_pair_force(p1, p2, ia_params, dx, normr(dx), force);
add_lj_pair_force(p1, p2, ia_params, dx.data(), dx.norm(), force);
return ES_OK;
}
inline int subt_lj_pair_energy(Particle *p1, Particle *p2,
Bonded_ia_parameters *iaparams, double dx[3],
Bonded_ia_parameters *, double dx_[3],
double *_energy) {
auto ia_params = get_ia_param(p1->p.type, p2->p.type);
auto const dx = -Vector3d(dx_, dx_ + 3);
*_energy = -lj_pair_energy(p1, p2, ia_params, dx, normr(dx));
*_energy = -lj_pair_energy(p1, p2, ia_params, dx.data(), dx.norm());
return ES_OK;
}
......
......@@ -56,14 +56,13 @@ void thermalized_bond_init();
@return true if bond is broken
*/
inline int calc_thermalized_bond_forces(Particle *p1, Particle *p2,
Bonded_ia_parameters *iaparams,
inline int calc_thermalized_bond_forces(const Particle *p1, const Particle *p2,
const Bonded_ia_parameters *iaparams,
double dx[3], double force1[3],
double force2[3]) {
// Bond broke?
double dist = normr(dx);
if (iaparams->p.thermalized_bond.r_cut > 0.0 &&
dist > iaparams->p.thermalized_bond.r_cut) {
Vector3d(dx, dx + 3).norm() > iaparams->p.thermalized_bond.r_cut) {
return 1;
}
......@@ -109,10 +108,4 @@ inline int calc_thermalized_bond_forces(Particle *p1, Particle *p2,
return 0;
}
inline int thermalized_bond_energy(const Particle *p1, const Particle *p2,
const Bonded_ia_parameters *iaparams,
double dx[3], double *_energy) {
return 0;
}
#endif
......@@ -39,7 +39,9 @@
#include "utils.hpp"
#include "utils/NoOp.hpp"
#include "utils/mpi/gather_buffer.hpp"
#include <boost/iterator/indirect_iterator.hpp>
#include <cstdio>
#include <cstdlib>
#include <cstring>
......@@ -263,16 +265,8 @@ void realloc_cells(int size) {
for (auto &c : cells) {
c.resize(0);
}
auto const old_size = cells.size();
/* resize the cell list */
cells.resize(size);
/* initialize new cells */
for (int i = old_size; i < size; i++) {
init_particlelist(&cells[i]);
}
}
/*************************************************/
......@@ -296,13 +290,68 @@ void announce_resort_particles() {
/*************************************************/
int cells_get_n_particles() {
using std::distance;
return distance(local_cells.particles().begin(),
local_cells.particles().end());
return std::accumulate(local_cells.begin(), local_cells.end(), 0,
[](int n, const Cell *c) { return n + c->n; });
}
/*************************************************/
namespace {
/**
* @brief Fold coordinates to box and reset the
* old position.
*/
void fold_and_reset(Particle &p) {
fold_position(p.r.p, p.l.i);
p.l.p_old = p.r.p;
}
} // namespace
/**
* @brief Sort and fold particles.
*
* This function folds the positions of all particles back into
* the box and puts them back into the correct cells. Particles
* that do not belong to this node are removed from the cell
* and returned.
*
* @param cs The cell system to be used.
* @param cells Cells to iterate over.
*
* @returns List of Particles that do not belong on this node.
*/
ParticleList sort_and_fold_parts(const CellStructure &cs, CellPList cells) {
ParticleList displaced_parts;
for (auto &c : cells) {
for (int i = 0; i < c->n; i++) {
auto &p = c->part[i];
fold_and_reset(p);
auto target_cell = cs.position_to_cell(p.r.p);
if (target_cell == nullptr) {
append_unindexed_particle(&displaced_parts,
extract_indexed_particle(c, i));
if (i < c->n) {
i--;
}
} else if (target_cell != c) {
move_indexed_particle(target_cell, c, i);
if (i < c->n) {
i--;
}
}
}
}
return displaced_parts;
}
void cells_resort_particles(int global_flag) {
CELL_TRACE(fprintf(stderr, "%d: entering cells_resort_particles %d\n",
this_node, global_flag));
......@@ -312,18 +361,32 @@ void cells_resort_particles(int global_flag) {
clear_particle_node();
n_verlet_updates++;
ParticleList displaced_parts =
sort_and_fold_parts(cell_structure, local_cells);
switch (cell_structure.type) {
case CELL_STRUCTURE_LAYERED:
layered_exchange_and_sort_particles(global_flag);
break;
case CELL_STRUCTURE_LAYERED: {
layered_exchange_and_sort_particles(global_flag, &displaced_parts);
} break;
case CELL_STRUCTURE_NSQUARE:
nsq_balance_particles(global_flag);
break;
case CELL_STRUCTURE_DOMDEC:
dd_exchange_and_sort_particles(global_flag);
dd_exchange_and_sort_particles(global_flag, &displaced_parts);
break;
}
if (0 != displaced_parts.n) {
for (int i = 0; i < displaced_parts.n; i++) {
auto &part = displaced_parts.part[i];
runtimeErrorMsg() << "Particle " << part.identity()
<< " moved more than"
" one local box length in one timestep.";
resort_particles = Cells::RESORT_GLOBAL;
append_indexed_particle(local_cells.cell[0], std::move(part));
}
}
#ifdef ADDITIONAL_CHECKS
/* at the end of the day, everything should be consistent again */
check_particle_consistency();
......@@ -401,13 +464,11 @@ void cells_update_ghosts() {
}
Cell *find_current_cell(const Particle &p) {
auto c = cell_structure.position_to_cell(p.r.p.data());
if (c) {
return c;
} else if (!p.l.ghost) {
// Old pos must lie within the cell system
return cell_structure.position_to_cell(p.l.p_old.data());
} else {
assert(not resort_particles);
if (p.l.ghost) {
return nullptr;
}
return cell_structure.position_to_cell(p.l.p_old);
}
......@@ -158,13 +158,13 @@ struct CellStructure {
\param pos Position of a particle.
\return number of the node where to put the particle.
*/
int (*position_to_node)(double pos[3]);
int (*position_to_node)(const Vector3d &pos);
/** Cell system dependent function to find the right cell for a
particle at position pos.
\param pos Position of a particle.
\return pointer to cell where to put the particle.
*/
Cell *(*position_to_cell)(const double pos[3]);
Cell *(*position_to_cell)(const Vector3d &pos);
};
/*@}*/
......@@ -296,18 +296,14 @@ void announce_resort_particles();
/* Checks if a particle resorting is required. */
void check_resort_particles();
/* Do a strict particle sorting, including order in the cells. */
void local_sort_particles();
/*@}*/
/* @brief Finds the cell in which a particle is stored
Uses position_to_cell on p.r.p. If this is not on the node's domain,
uses position at last Verlet list rebuild (p.l.p_old).
@return pointer to the cell or nullptr if the particle is not on the node
*/
/**
* @brief Finds the cell in which a particle is stored
*
*
* @return pointer to the cell or nullptr if the particle is not on the node
*/
Cell *find_current_cell(const Particle &p);
#endif
......@@ -228,6 +228,7 @@ bool validate_collision_parameters() {
recalc_forces = 1;
rebuild_verletlist = 1;
on_ghost_flags_change();
return true;
}
......
......@@ -644,16 +644,17 @@ void mpi_send_rotational_inertia_slave(int pnode, int part) {
#endif
}
void mpi_rotate_particle(int pnode, int part, double axis[3], double angle) {
void mpi_rotate_particle(int pnode, int part, const Vector3d &axis,
double angle) {
#ifdef ROTATION
mpi_call(mpi_rotate_particle_slave, pnode, part);
if (pnode == this_node) {
Particle *p = local_particles[part];
local_rotate_particle(p, axis, angle);
local_rotate_particle(*p, axis, angle);
} else {
MPI_Send(axis, 3, MPI_DOUBLE, pnode, SOME_TAG, comm_cart);
MPI_Send(&angle, 1, MPI_DOUBLE, pnode, SOME_TAG, comm_cart);
comm_cart.send(pnode, SOME_TAG, axis);
comm_cart.send(pnode, SOME_TAG, angle);
}
on_particle_change();
......@@ -664,10 +665,11 @@ void mpi_rotate_particle_slave(int pnode, int part) {
#ifdef ROTATION
if (pnode == this_node) {
Particle *p = local_particles[part];
double axis[3], angle;
MPI_Recv(axis, 3, MPI_DOUBLE, 0, SOME_TAG, comm_cart, MPI_STATUS_IGNORE);
MPI_Recv(&angle, 1, MPI_DOUBLE, 0, SOME_TAG, comm_cart, MPI_STATUS_IGNORE);
local_rotate_particle(p, axis, angle);
Vector3d axis;
double angle;
comm_cart.recv(0, SOME_TAG, axis);
comm_cart.recv(0, SOME_TAG, angle);
local_rotate_particle(*p, axis, angle);
}
on_particle_change();
......@@ -815,18 +817,15 @@ void mpi_send_quat_slave(int pnode, int part) {
/********************* REQ_SET_OMEGA ********/
void mpi_send_omega(int pnode, int part, double omega[3]) {
void mpi_send_omega(int pnode, int part, const Vector3d &omega) {
#ifdef ROTATION
mpi_call(mpi_send_omega_slave, pnode, part);
if (pnode == this_node) {
Particle *p = local_particles[part];
/* memmove(p->omega, omega, 3*sizeof(double));*/
p->m.omega[0] = omega[0];
p->m.omega[1] = omega[1];
p->m.omega[2] = omega[2];
p->m.omega = omega;
} else {
MPI_Send(omega, 3, MPI_DOUBLE, pnode, SOME_TAG, comm_cart);
comm_cart.send(pnode, SOME_TAG, omega);
}
on_particle_change();
......@@ -837,27 +836,23 @@ void mpi_send_omega_slave(int pnode, int part) {
#ifdef ROTATION
if (pnode == this_node) {
Particle *p = local_particles[part];
MPI_Recv(p->m.omega.data(), 3, MPI_DOUBLE, 0, SOME_TAG, comm_cart,
MPI_STATUS_IGNORE);
comm_cart.recv(0, SOME_TAG, p->m.omega);
}
on_particle_change();
#endif
}
/********************* REQ_SET_TORQUE ********/
void mpi_send_torque(int pnode, int part, double torque[3]) {
void mpi_send_torque(int pnode, int part, const Vector3d &torque) {