OpenFPM  5.2.0
Project that contain the implementation of distributed structures
CircLap.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 #include "Vector/vector_dist_subset.hpp"
21 #include "Operators/Vector/vector_dist_operators.hpp"
22 #include "DCPSE/DCPSE_op/DCPSE_surface_op.hpp"
23 #include <util/PathsAndFiles.hpp>
24 
25 std::string p_output;
26 
27 constexpr int DF=0;
28 constexpr int F=1;
29 constexpr int ANADF=2;
30 constexpr int ERR=3;
31 constexpr int NORMAL=4;
32 
34 openfpm::vector<std::string> propNames{{"Df","f","AnaDf","error","Normal"}};
36 
37 int main(int argc, char * argv[]) {
38  openfpm_init(&argc,&argv);
39  auto & v_cl = create_vcluster();
40  timer tt;
41  tt.start();
42  size_t n;
43 
44  // Get command line arguments
45  if (argc > 4) {
46  std::cout << "Warning: The executable requires the following arguments: number_grid_points" << std::endl;
47  }
48  n = 128*std::pow(2,std::stoi(argv[1]));
49  unsigned int ord=std::stoi(argv[2]);
50  double rcfac=std::stof(argv[3]);
51  // Files and directories
52  std::string cwd{boost::filesystem::current_path().string()};
53  std::string output_dir{cwd + "/output_circle_NoProj"};
56  p_output = output_dir + "/particles_";
57 
58  // Domain
59  double boxP1{-1.5}, boxP2{1.5};
60  double boxSize{boxP2 - boxP1};
61  size_t sz[2] = {n,n};
62  double grid_spacing{boxSize/(sz[0]-1)};
63  double rCut{(rcfac) * grid_spacing};
64 
65  Box<2,double> domain{{boxP1,boxP1},{boxP2,boxP2}};
66  size_t bc[2] = {NON_PERIODIC,NON_PERIODIC};
67  Ghost<2,double> ghost{rCut + grid_spacing/8.0};
68 
69  // Particles
70  vector_type particles{0,domain,bc,ghost};
71  particles.setPropNames(propNames);
72 
73  Point<2,double> coord;
74  // 1. Particles on the Circular surface
75  double theta{0.0};
76  double dtheta{2*M_PI/double(n)};
77  if (v_cl.rank() == 0) {
78  for (int i = 0; i < n; ++i) {
79  coord[0] = std::cos(theta);
80  coord[1] = std::sin(theta);
81 
82  particles.add();
83  particles.getLastPos()[0] = coord[0];
84  particles.getLastPos()[1] = coord[1];
85 
86  particles.getLastProp<F>() = std::sin(theta)+std::cos(theta);
87 
88  particles.getLastProp<NORMAL>()[0] = std::cos(theta);
89  particles.getLastProp<NORMAL>()[1] = std::sin(theta);
90  particles.getLastProp<ANADF>() = -std::sin(theta)-std::cos(theta);
91  particles.getLastSubset(0);
92 
93  theta += dtheta;
94  }
95  std::cout << "n: " << n << " - grid spacing: " << grid_spacing << " - rCut: " << rCut << "Dtheta" << dtheta<<std::endl;
96  }
97 
98  particles.map();
99 
100  std::cout << "size: " << particles.size_local() << std::endl;
101 
103  particles.write_frame(p_output,0,BINARY);
104 
105  //SurfaceDerivative_xx<NORMAL> Sdxx{particles,2,rCut,grid_spacing};
106  //SurfaceDerivative_yy<NORMAL> Sdyy{particles,2,rCut,grid_spacing};
107  auto verletList = particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
108  SurfaceDerivative_xx<NORMAL,decltype(verletList)> Sdxx(particles, verletList, ord, rCut, grid_spacing, rCut/grid_spacing);
109  SurfaceDerivative_yy<NORMAL,decltype(verletList)> Sdyy(particles, verletList, ord, rCut, grid_spacing, rCut/grid_spacing);
110 
111  auto f=getV<F>(particles);
112  auto df=getV<DF>(particles);
113  particles.ghost_get<F>();
114 
115  df=Sdxx(f)+Sdyy(f);
116  // Error
117  double MaxError=0,L2=0;
118  auto it=particles.getDomainIterator();
119  while(it.isNext()){
120  auto p = it.get();
122  particles.getProp<ERR>(p) = fabs(particles.getProp<DF>(p)-particles.getProp<ANADF>(p));
123  if (particles.getProp<ERR>(p)>MaxError){
124  MaxError=particles.getProp<ERR>(p);
125  }
126  L2+=particles.getProp<ERR>(p)*particles.getProp<ERR>(p);
127  ++it;
128  }
129  v_cl.sum(L2);
130  v_cl.max(MaxError);
131  v_cl.execute();
132  L2=sqrt(L2);
133  std::cout.precision(16);
134  std::ofstream norms_file;
135  if (v_cl.rank()==0){
136  std::cout<<"dTheta:"<<dtheta<<std::endl;
137  std::cout<<"L2:"<<L2/sqrt(double(n))<<std::endl;
138  std::cout<<"L_inf:"<<MaxError<<std::endl;
139  norms_file.open("Errors/LBCirc_order_" + std::to_string(ord) + ".csv", std::ios_base::app);
140  if (norms_file.is_open() == false) {
141  std::cout << "ERROR: File is not open.\n";
142  return 1;
143  }
144  norms_file <<n<<","<<rcfac<<std::scientific<<","<<L2/sqrt(double(n))<<","<<MaxError<< std::endl;
145  }
147  particles.write(p_output,BINARY);
148  Sdxx.deallocate(particles);
149  Sdyy.deallocate(particles);
150 
151  tt.stop();
152  if (v_cl.rank() == 0)
153  std::cout << "Simulation took: " << tt.getcputime() << " s (CPU) - " << tt.getwct() << " s (wall)\n";
154 
155  openfpm_finalize();
156  return 0;
157 
158 }
Header file containing functions for creating files and folders.
static void create_directory_if_not_exist(std::string path, bool silent=0)
Creates a directory if not already existent.
This class represent an N-dimensional box.
Definition: Box.hpp:60
Definition: Ghost.hpp:40
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.
size_t size_local() const
return the local size of the 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.
auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
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