OpenFPM  5.2.0
Project that contain the implementation of distributed structures
SphBench.cpp
1 // ------------------------------------------------------------------------------------------
2 // Copyright (C) 2021 ---- absingh
3 //
4 // This file is part of the Surface DCPSE Paper.
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 // ------------------------------------------------------------------------------------------
19 
20 //#define SE_CLASS1
21 
22 #include "Vector/vector_dist_subset.hpp"
23 #include "DCPSE/DCPSE_op/DCPSE_surface_op.hpp"
24 //#include "DCPSE/DCPSE_op/DCPSE_Solver.hpp"
25 #include "util/SphericalHarmonics.hpp"
26 #include <util/PathsAndFiles.hpp>
27 
28 std::string p_output;
29 
30 constexpr int DF=0;
31 constexpr int F=1;
32 constexpr int ANADF=2;
33 constexpr int ERR=3;
34 constexpr int NORMAL=4;
35 constexpr int PCOORD=5;
36 
38 openfpm::vector<std::string> propNames{{"Df","f","AnaDf","error","Normal","PCOORD"}};
40 
41 int main(int argc, char * argv[]) {
42  openfpm_init(&argc,&argv);
43  auto & v_cl = create_vcluster();
44  timer tt,tt2,tt3,tt4;
45  tt4.start();
46  size_t n;
47  double spL;
48  double grid_spacing_surf;
49  double rCut;
50  constexpr int K = 4;
51 
52  // Get command line arguments
53  if (argc > 3) {
54  if(v_cl.rank()==0)
55  std::cout << "Warning: The executable requires the following arguments: number_grid_points orderOfConv" << std::endl;
56  }
57 
58  n = std::stoi(argv[1]);
59  unsigned int ord=std::stoi(argv[2]);
60  //spL=std::stof(argv[2]);
61  //grid_spacing_surf=std::stof(argv[3]);
62  //rCut=std::stof(argv[4]);
63 
64  p_output = "particles";
65  size_t n_sp=n;
66  // Domain
67  double boxP1{-1.5}, boxP2{1.5};
68  double boxSize{boxP2 - boxP1};
69  size_t sz[3] = {n,n,n};
70  double grid_spacing{0.8/((std::pow(sz[0],1/3.0)-1))};
71  double Golden_angle=M_PI * (3.0 - sqrt(5.0));
72  grid_spacing_surf=grid_spacing;
73  rCut=2.9 * grid_spacing_surf;
74 
75  Box<3,double> domain{{boxP1,boxP1,boxP1},{boxP2,boxP2,boxP2}};
76  size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
77  Ghost<3,double> ghost{rCut + grid_spacing/8.0};
78 
79  // particles
80  vector_type particles{0,domain,bc,ghost};
81  particles.setPropNames(propNames);
82 
83  Point<3,double> coord;
84  // 1. particles on the Circular surface
85  double theta{0.0};
86  if (v_cl.rank() == 0) {
87  for(int i=1;i<n_sp;i++)
88  {
89  double y = 1.0 - (i /double(n_sp - 1.0)) * 2.0;
90  double radius = sqrt(1 - y * y);
91  double Golden_theta = Golden_angle * i;
92  double x = cos(Golden_theta) * radius;
93  double z = sin(Golden_theta) * radius;
94  particles.add();
95  particles.getLastPos()[0] = x;
96  particles.getLastPos()[1] = y;
97  particles.getLastPos()[2] = z;
98  double rm=sqrt(x*x+y*y+z*z);
99  particles.getLastProp<NORMAL>()[0] = x/rm;
100  particles.getLastProp<NORMAL>()[1] = y/rm;
101  particles.getLastProp<NORMAL>()[2] = z/rm;
102  particles.getLastProp<PCOORD>()[0] = 1.0 ;
103  particles.getLastProp<PCOORD>()[1] = std::atan2(sqrt(x*x+y*y),z);
104  particles.getLastProp<PCOORD>()[2] = std::atan2(y,x);
105  }
106  particles.getLastSubset(1);
107  std::cout << "n: " << n <<" - rCut: " << rCut << " nSpacing" << grid_spacing_surf<<std::endl;
108  }
109 
110  particles.map();
111  particles.ghost_get<F>();
112 
114  vector_dist_subset<3,double,prop> particles_boundary(particles,1);
115  auto &bulkIds=particles_bulk.getIds();
116  auto &bdrIds=particles_boundary.getIds();
117  std::unordered_map<const lm,double,key_hash,key_equal> Alm;
118  //Setting max mode l_max
119  //Setting amplitudes to 1
120  for(int l=0;l<=K;l++){
121  for(int m=-l;m<=l;m++){
122  Alm[std::make_tuple(l,m)]=0;
123  }
124  }
125  //2Alm[std::make_tuple(1,0)]=1;
126  Alm[std::make_tuple(K,0)]=1;
127  //Alm[std::make_tuple(3,2)]=1;
128 
129  spL=K;
130  auto it2 = particles.getDomainIterator();
131  while (it2.isNext()) {
132  auto p = it2.get();
133  Point<3, double> xP = particles.getProp<PCOORD>(p);
134  particles.getProp<ANADF>(p)=openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Alm);
135  particles.getProp<DF>(p)=-(K)*(K+1)*openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Alm);
136  ++it2;
137  }
138  particles.ghost_get<ANADF>();
139  auto DErr=getV<ERR>(particles);
140  auto Af=getV<ANADF>(particles);
141  auto Df=getV<DF>(particles);
142  auto f=getV<F>(particles);
143  tt.start();
144  tt3.start();
145 
146  auto verletList = particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
147  SurfaceDerivative_xx<NORMAL,decltype(verletList)> Sdxx{particles,verletList,ord,rCut,grid_spacing_surf,rCut/grid_spacing_surf};
148  SurfaceDerivative_yy<NORMAL,decltype(verletList)> Sdyy{particles,verletList,ord,rCut,grid_spacing_surf,rCut/grid_spacing_surf};
149  SurfaceDerivative_zz<NORMAL,decltype(verletList)> Sdzz{particles,verletList,ord,rCut,grid_spacing_surf,rCut/grid_spacing_surf};
150  tt3.stop();
151  tt2.start();
152  particles.ghost_get<F>();
153  f=(Sdxx(Af)+Sdyy(Af)+Sdzz(Af));
154  tt2.stop();
155  tt.stop();
157  particles.write_frame(p_output,0,BINARY);
158  // Error
159  double MaxError=0,L2=0;
160  for (int j = 0; j < bulkIds.size(); j++) {
161  auto p = bulkIds.get<0>(j);
162  particles.getProp<ERR>(p) = fabs(particles.getProp<F>(p)-particles.getProp<DF>(p));
163  if (particles.getProp<ERR>(p)>MaxError){
164  MaxError=particles.getProp<ERR>(p);
165  }
166  L2+=particles.getProp<ERR>(p)*particles.getProp<ERR>(p);
167  }
168  double tcpu=tt.getcputime(),twall=tt.getwct(),
169  Dtcpu=tt2.getcputime(),Dtwall=tt2.getwct(),
170  DCtcpu=tt3.getcputime(),DCtwall=tt3.getwct();
171  v_cl.sum(DCtcpu);
172  v_cl.sum(DCtwall);
173  v_cl.sum(Dtcpu);
174  v_cl.sum(Dtwall);
175  v_cl.sum(tcpu);
176  v_cl.sum(twall);
177  v_cl.sum(L2);
178  v_cl.max(MaxError);
179  v_cl.execute();
180  L2=sqrt(L2);
181  std::cout.precision(16);
182  if (v_cl.rank()==0){
183  std::cout<<"L2:"<<L2/double(sqrt(n_sp))<<std::endl;
184  std::cout<<"L_inf:"<<MaxError<<std::endl;
185  }
186 
188  particles.write(p_output,BINARY);
189  Sdxx.deallocate(particles);
190  Sdyy.deallocate(particles);
191  Sdzz.deallocate(particles);
192  tt4.stop();
193  double Ftcpu=tt4.getcputime(),Ftwall=tt.getwct();
194  v_cl.sum(Ftcpu);
195  v_cl.sum(Ftwall);
196  v_cl.execute();
197  if (v_cl.rank() == 0){
198  std::cout << "DCPSE Construction took: " << DCtcpu/v_cl.size() << " s (CPU) - " << DCtwall/v_cl.size() << " s (wall)\n";
199  std::cout << "DCPSE Evaluation took: " << Dtcpu/v_cl.size() << " s (CPU) - " << Dtwall/v_cl.size() << " s (wall)\n";
200  std::cout << "Total DCPSE time: " << tcpu/v_cl.size() << " s (CPU) - " << twall/v_cl.size() << " s (wall)\n";
201  std::cout << "Entire Simulation took: " << Ftcpu/v_cl.size() << " s (CPU) - " << Ftwall/v_cl.size() << " s (wall)\n";
202  }
203  openfpm_finalize();
204  return 0;
205 
206 }
Header file containing functions for creating files and folders.
This class represent an N-dimensional box.
Definition: Box.hpp:60
Definition: Ghost.hpp:40
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
Class for cpu time benchmarking.
Definition: timer.hpp:28
void stop()
Stop the timer.
Definition: timer.hpp:119
double getcputime()
Return the cpu time.
Definition: timer.hpp:142
void start()
Start the timer.
Definition: timer.hpp:90
double getwct()
Return the elapsed real time.
Definition: timer.hpp:130
Distributed vector.
bool write_frame(std::string out, size_t iteration, int opt=VTK_WRITER)
Output particle position and properties.
auto getProp(vect_dist_key_dx vec_key) -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
void setPropNames(const openfpm::vector< std::string > &names)
Set the properties names.
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
void ghost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
bool write(std::string out, int opt=VTK_WRITER)
Output particle position and properties.
auto getLastProp() -> decltype(vPrp.template get< id >(0))
Get the property of the last element.
void add()
Add local particle.
void deleteGhost()
Delete the particles on the ghost.
auto getLastPos() -> decltype(vPos.template get< 0 >(0))
Get the position of the last element.
[v_transform metafunction]
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:221