Commit db0c2164 authored by PIACIBELLO Cyrille's avatar PIACIBELLO Cyrille

Minor changes in Api, new file FScalfmmApiInit.cpp, and test written in C, compiling fine

parent 52919eb2
......@@ -90,6 +90,8 @@ typedef void* scalfmm_handle;
scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* BoxCenter, scalfmm_kernel_type KernelType);
/////////////////////////////////////////////////////////////////////
////////////////// Tree Part //////////////
/////////////////////////////////////////////////////////////////////
......@@ -167,10 +169,10 @@ void scalfmm_get_physical_values_npart(scalfmm_handle Handle, int nbPhysicalValu
* Forces will be stored sequentially, according to the indices in the
* array. (ie fx1,fy1,fz1,fx2,fy2,fz2,fx3 ....)
*/
void scalfmm_get_forces(scalfmm_handle Handle, int nbParts, double * forcesToFill);
void scalfmm_get_forces_npart(scalfmm_handle Handle, int nbParts, int* idxOfParticles, double * forcesToFill);
void scalfmm_get_forces_xyz(scalfmm_handle Handle, int nbParts, double * fX, double* fY, double* fZ);
void scalfmm_get_forces_xyz_npart(scalfmm_handle Handle, int nbParts, int* idxOfParticles, double * fX, double* fY, double* fZ);
void scalfmm_get_forces_xyz(scalfmm_handle Handle, int nbParts, double * forcesToFill);
void scalfmm_get_forces_xyz_npart(scalfmm_handle Handle, int nbParts, int* idxOfParticles, double * forcesToFill);
void scalfmm_get_forces(scalfmm_handle Handle, int nbParts, double * fX, double* fY, double* fZ);
void scalfmm_get_forces_npart(scalfmm_handle Handle, int nbParts, int* idxOfParticles, double * fX, double* fY, double* fZ);
/**
......@@ -186,10 +188,10 @@ void scalfmm_get_forces_xyz_npart(scalfmm_handle Handle, int nbParts, int* idxOf
* forces . WARNING : User must allocate the array before call.
*
*/
void scalfmm_set_forces(scalfmm_handle Handle, int nbParts, double * forcesToFill);
void scalfmm_set_forces_npart(scalfmm_handle Handle, int nbParts, int* idxOfParticles, double * forcesToFill);
void scalfmm_set_forces_xyz(scalfmm_handle Handle, int nbParts, double * fX, double* fY, double* fZ);
void scalfmm_set_forces_xyz_npart(scalfmm_handle Handle, int nbParts, int* idxOfParticles, double * fX, double* fY, double* fZ);
void scalfmm_set_forces_xyz(scalfmm_handle Handle, int nbParts, double * forcesToFill);
void scalfmm_set_forces_xyz_npart(scalfmm_handle Handle, int nbParts, int* idxOfParticles, double * forcesToFill);
void scalfmm_set_forces(scalfmm_handle Handle, int nbParts, double * fX, double* fY, double* fZ);
void scalfmm_set_forces_npart(scalfmm_handle Handle, int nbParts, int* idxOfParticles, double * fX, double* fY, double* fZ);
/**
......@@ -218,10 +220,10 @@ void scalfmm_set_potentials_npart(scalfmm_handle Handle, int nbParts, int* idxOf
* @param updatedXYZ array of displacement (ie
* dx1,dy1,dz1,dx2,dy2,dz2,dx3 ...)
*/
void scalfmm_add_to_positions(scalfmm_handle Handle, int NbPositions, double * updatedXYZ);
void scalfmm_add_to_positions_xyz(scalfmm_handle Handle, int NbPositions, double * X, double * Y , double * Z);
void scalfmm_add_to_positions_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * updatedXYZ);
void scalfmm_add_to_positions_xyz_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * X, double * Y , double * Z);
void scalfmm_add_to_positions_xyz(scalfmm_handle Handle, int NbPositions, double * updatedXYZ);
void scalfmm_add_to_positions(scalfmm_handle Handle, int NbPositions, double * X, double * Y , double * Z);
void scalfmm_add_to_positions_xyz_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * updatedXYZ);
void scalfmm_add_to_positions_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * X, double * Y , double * Z);
/**
......@@ -239,15 +241,15 @@ void scalfmm_add_to_positions_xyz_npart(scalfmm_handle Handle, int NbPositions,
* compliant.
*
*/
void scalfmm_set_positions(scalfmm_handle Handle, int NbPositions, double * updatedXYZ);
void scalfmm_set_positions_xyz(scalfmm_handle Handle, int NbPositions, double * X, double * Y , double * Z);
void scalfmm_set_positions_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * updatedXYZ);
void scalfmm_set_positions_xyz_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * X, double * Y , double * Z);
void scalfmm_set_positions_xyz(scalfmm_handle Handle, int NbPositions, double * updatedXYZ);
void scalfmm_set_positions(scalfmm_handle Handle, int NbPositions, double * X, double * Y , double * Z);
void scalfmm_set_positions_xyz_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * updatedXYZ);
void scalfmm_set_positions_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * X, double * Y , double * Z);
void scalfmm_get_positions(scalfmm_handle Handle, int NbPositions, double * updatedXYZ);
void scalfmm_get_positions_xyz(scalfmm_handle Handle, int NbPositions, double * X, double * Y , double * Z);
void scalfmm_get_positions_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * updatedXYZ);
void scalfmm_get_positions_xyz_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * X, double * Y , double * Z);
void scalfmm_get_positions_xyz(scalfmm_handle Handle, int NbPositions, double * updatedXYZ);
void scalfmm_get_positions(scalfmm_handle Handle, int NbPositions, double * X, double * Y , double * Z);
void scalfmm_get_positions_xyz_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * updatedXYZ);
void scalfmm_get_positions_npart(scalfmm_handle Handle, int NbPositions, int* idxOfParticles, double * X, double * Y , double * Z);
......@@ -259,18 +261,6 @@ void scalfmm_get_positions_xyz_npart(scalfmm_handle Handle, int NbPositions, int
///////////////// User kernel part :
/**
* @param user_kernel Scalfmm_Kernel_Descriptor containing callbacks
* to user Fmm function. Meaningless if using one of our kernel
* (Chebyshev or Interpolation).
* @param userDatas Data that will be passed to each FMM
* function. Can be anything, but allocation/deallocation is user
* side.
*
*/
void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel_Descriptor userKernel, void * userDatas);
/**
* @brief Function to be filled by user's P2M
......@@ -346,7 +336,7 @@ typedef void (*Callback_P2PInner)(int nbParticles, int* particleIndexes, void* u
* user kernel.
*
*/
struct Scalfmm_Kernel_Descriptor {
typedef struct User_Scalfmm_Kernel_Descriptor {
Callback_P2M p2m;
Callback_M2M m2m;
Callback_M2L m2l;
......@@ -354,10 +344,43 @@ struct Scalfmm_Kernel_Descriptor {
Callback_L2P l2p;
Callback_P2P p2p;
Callback_P2PInner p2pinner;
};
}Scalfmm_Kernel_Descriptor;
/**
* @param user_kernel Scalfmm_Kernel_Descriptor containing callbacks
* to user Fmm function. Meaningless if using one of our kernel
* (Chebyshev or Interpolation).
* @param userDatas Data that will be passed to each FMM
* function. Can be anything, but allocation/deallocation is user
* side.
*
*/
void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel_Descriptor userKernel, void * userDatas);
//To fill gestion des cellules utilisateurs
/**
* @brief Function to init the cells (should be given by the user when
* calling Scalfmm_init_cell)
* @param level level of the cell.
* @param morton_index morton index of the cell to be allocated.
* @param tree_position int[3] position inside the tree (number of boxes in
* each direction)
* @param spatial_position double[3] center of the cell
*/
typedef void* (*Callback_init_cell)(int level, long long morton_index, int* tree_position, double* spatial_position);
/**
* Function to destroy what have bee initialized by the user (should
* be give in Scalfmm_dealloc_handle)
*/
typedef void (*Callback_free_cell)(void*);
///////////////// Common kernel part : /////////////////
......@@ -367,3 +390,25 @@ struct Scalfmm_Kernel_Descriptor {
* @param Handle scalfmm_handle provided by scalfmm_init
*/
void scalfmm_execute_fmm(scalfmm_handle Handle);
/////////////////////////////////////////////////////////////////////
////////////////// Dealloc Part /////////////////
/////////////////////////////////////////////////////////////////////
/**
* @brief This function dealloc the scalfmm handle.
* @param Handle scalfmm_handle provided by scalfmm_init.
* @param cellDestroyer Function to be called on the user cell to
* dealloc
*
* The last param cellDestroyer is meaningless in case the user uses
* one of the provided kernel. (i.e. Chebyshev, Lagrange)
*/
void Scalfmm_dealloc_handle(scalfmm_handle handle, Callback_free_cell cellDestroyer);
#endif
// ===================================================================================
// Copyright ScalFmm 2014 I
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// This program 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 and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
/**
* @file This file contains a class that inherits from FScalFMMEngine,
* and will implement the API functions for Interpolations kernels.
*/
#ifndef FINTERENGINE_HPP
#define FINTERENGINE_HPP
#include "FScalFMMEngine.hpp"
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#ifdef _OPENMP
#include "Core/FFmmAlgorithmThread.hpp"
#else
#include "Core/FFmmAlgorithm.hpp"
#endif
/**
* @class FInterEngine implements API for Interpolations kernels, its
* templates can be ChebCell/ChebKernel or UnifCell/UnifKernel
*/
template<class InterCell,class InterKernel,
class ContainerClass = FP2PParticleContainerIndexed<>,
class LeafClass = FSimpleLeaf<FP2PParticleContainerIndexed<>>,
class MatrixKernelClass = FInterpMatrixKernelR>
class FInterEngine : public FScalFMMEngine{
private:
//Pointer to the kernel to be executed
InterKernel * kernel;
//Link to the tree
FOctree<InterCell,ContainerClass,LeafClass> * octree;
public:
/**
* @brief Constructor : its only build the tree
* @param TreeHeight Height of the tree
* @param BoxWidth box Width
* @param BoxCenter double[3] coordinate of the center of the
* simulation box
*/
FInterEngine(int TreeHeight, double BoxWidth , double * BoxCenter) : kernel(nullptr), octree(nullptr){
octree = new FOctree<InterCell,ContainerClass,LeafClass>(TreeHeight,FMath::Min(3,TreeHeight-1),BoxWidth,FPoint(BoxCenter));
}
//TODO free kernel too
~FInterEngine(){
free(octree);
}
};
#endif
This diff is collapsed.
#ifndef CALL_HPP
#define CALL_HPP
/** It should be compiled with C export */
extern "C" {
#include "CScalfmmApi.h"
}
#include "FInterEngine.hpp"
extern "C" scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* BoxCenter, scalfmm_kernel_type KernelType){
ScalFmmCoreHandle * handle = new ScalFmmCoreHandle();
switch(KernelType){
case 0:
//handle->engine = new FUserKernelEngine(...);
std::cout<< "User Kernel type unsupported yet" << std::endl;
break;
case 1:
//TODO typedefs
typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FChebCell<7> ChebCell;
typedef FInterpMatrixKernelR MatrixKernelClass;
typedef FChebSymKernel<ChebCell,ContainerClass,MatrixKernelClass,7> ChebKernel;
handle->engine = new FInterEngine<ChebCell,ChebKernel>(TreeHeight,BoxWidth,BoxCenter);
break;
case 2:
//TODO typedefs
typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FUnifCell<7> UnifCell;
typedef FInterpMatrixKernelR MatrixKernelClass;
typedef FUnifKernel<UnifCell,ContainerClass,MatrixKernelClass,7> UnifKernel;
handle->engine = new FInterEngine<UnifCell,UnifKernel>(TreeHeight,BoxWidth,BoxCenter);
break;
default:
std::cout<< "Kernel type unsupported" << std::endl;
exit(0);
break;
}
return handle;
}
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../Src/CScalfmmApi.h"
void compute_displacement_from_forces(double * fXYZ, double* dXYZ, int nb_xyz){
//Do some things
}
int main(int argc, char ** av){
scalfmm_kernel_type myChoice = chebyshev;
//Octree configuration
int TreeHeight = 5;
double boxWidth = 1.0;
double boxCenter[3] = {0.0,0.0,0.0};
//Init our lib
scalfmm_handle handle = scalfmm_init(TreeHeight,boxWidth,boxCenter,myChoice); //The tree is built
//Creation of an array of particles
int nb_of_parts = 200;
int idxPart;
double * positionsXYZ = malloc(sizeof(double)*3*nb_of_parts);
for(idxPart = 0; idxPart<nb_of_parts ; ++idxPart){
positionsXYZ[idxPart*3+0] = (random()/(double)(RAND_MAX))*boxWidth - boxWidth/2 + boxCenter[0];
positionsXYZ[idxPart*3+1] = (random()/(double)(RAND_MAX))*boxWidth - boxWidth/2 + boxCenter[1];
positionsXYZ[idxPart*3+2] = (random()/(double)(RAND_MAX))*boxWidth - boxWidth/2 + boxCenter[2];
}
//Creation of charge for each part
double * array_of_charge = malloc(sizeof(double)*nb_of_parts);
for(idxPart = 0; idxPart<nb_of_parts ; ++idxPart){
array_of_charge[idxPart] = (random()/(double)(RAND_MAX)); //charge in [-1,1]
}
//Inserting the array in the tree
scalfmm_tree_insert_particles_xyz(handle,nb_of_parts,positionsXYZ);
//Set the charge
scalfmm_set_physical_values(handle,nb_of_parts,array_of_charge);
//Computation Part
int nb_iteration = 100;
int curr_iteration = 0;
//Array to store the forces
double * array_of_forces = malloc(sizeof(double)*3*nb_of_parts);
//Array to store the displacement
double * array_of_displacement = malloc(sizeof(double)*3*nb_of_parts);
//Start of an iteration loop
while(curr_iteration < nb_iteration){
//Execute
scalfmm_execute_fmm(handle);
//Get the resulting forces
scalfmm_get_forces_xyz(handle,nb_of_parts,array_of_forces);
//User function to compute the movement of each part
compute_displacement_from_forces(array_of_forces,array_of_displacement,nb_of_parts);
//Apply displacement computed
scalfmm_add_to_positions_xyz(handle,nb_of_parts,array_of_displacement);
curr_iteration++;
}
//End of Computation, useer get the position after a hundreds of iterations
//Free memory
free(positionsXYZ);
free(array_of_charge);
free(array_of_forces);
free(array_of_displacement);
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment