OpenFPM  5.2.0
Project that contain the implementation of distributed structures
CircPoisson.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 "DCPSE/DCPSE_op/DCPSE_Solver.hpp"
24 #include "OdeIntegrators/OdeIntegrators.hpp"
25 
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 THETA=5;
36 constexpr int TEMP=6;
37 
38 double dt,tf,ALPHA=0.1;
39 
41 openfpm::vector<std::string> propNames{{"Df","f","AnaDf","error","Normal","Theta","TEMP"}};
43 
44 
45 int main(int argc, char * argv[]) {
46  openfpm_init(&argc,&argv);
47  auto & v_cl = create_vcluster();
48  timer tt;
49  tt.start();
50  size_t n,k;
51  // Get command line arguments
52  if (argc > 4) {
53  std::cout << "Warning: The executable requires the following arguments: number_grid_points FrequencyMode Order" << std::endl;
54  return 1;
55  }
56  n = std::stoi(argv[1]);
57  k = std::stoi(argv[2]);
58  unsigned int ord = std::stoi(argv[3]);
59 
60  // Files and directories
61  std::string cwd{boost::filesystem::current_path().string()};
62  std::string output_dir{cwd + "/output_circle_Poisson"};
64  p_output = output_dir + "/particles";
65 
66  // Domain
67  double boxP1{-1.5}, boxP2{1.5};
68  double boxSize{boxP2 - boxP1};
69  size_t sz[2] = {n,n};
70  double grid_spacing{boxSize/(sz[0]-1)};
71  double rCut{3.9 * grid_spacing};
72 
73  Box<2,double> domain{{boxP1,boxP1},{boxP2,boxP2}};
74  size_t bc[2] = {NON_PERIODIC,NON_PERIODIC};
75  Ghost<2,double> ghost{rCut + grid_spacing/8.0};
76 
77  // Particles
78  vector_type particles{0,domain,bc,ghost};
79  particles.setPropNames(propNames);
80 
81  Point<2,double> coord;
82  // 1. Particles on the Circular surface
83  double theta{0.0};
84  double dtheta{2*M_PI/double(n)};
85  if (v_cl.rank() == 0) {
86  for (int i = 0; i < n; ++i) {
87  coord[0] = std::cos(theta);
88  coord[1] = std::sin(theta);
89 
90  particles.add();
91  particles.getLastPos()[0] = coord[0];
92  particles.getLastPos()[1] = coord[1];
93 
94  particles.getLastProp<F>() = std::sin(theta)+std::cos(theta);
95 
96  particles.getLastProp<NORMAL>()[0] = std::cos(theta);
97  particles.getLastProp<NORMAL>()[1] = std::sin(theta);
98  particles.getLastProp<ANADF>() = std::sin(k*theta);;
99  particles.getLastProp<DF>() = -openfpm::math::intpowlog(k,2)*std::sin(k*theta);
100  particles.getLastProp<THETA>() = theta;
101  particles.getLastSubset(0);
102  if(coord[0]==1. && coord[1]==0.)
103  {particles.getLastSubset(1);}
104  theta += dtheta;
105  }
106  std::cout << "n: " << n << " - grid spacing: " << grid_spacing << " - rCut: " << rCut << " - Dtheta: " << dtheta<<std::endl;
107  }
108 
109  particles.map();
110  particles.ghost_get<0>();
111  std::cout << "size: " << particles.size_local() << std::endl;
113  particles.write_frame(p_output,0,BINARY);
114 
116  vector_dist_subset<2, double,prop> particles_boundary(particles,1);
117  auto & bulk=particles_bulk.getIds();
118  auto & boundary=particles_boundary.getIds();
119 
120  auto verletList = particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
121  //SurfaceDerivative_x<NORMAL> Sdx(particles, 2, rCut,grid_spacing);
122  //SurfaceDerivative_y<NORMAL> Sdy(particles, 2, rCut,grid_spacing);
123  SurfaceDerivative_xx<NORMAL, decltype(verletList)> Sdxx(particles, verletList, ord, rCut, grid_spacing, rCut/grid_spacing);
124  SurfaceDerivative_yy<NORMAL, decltype(verletList)> Sdyy(particles, verletList, ord, rCut, grid_spacing, rCut/grid_spacing);
125  //SurfaceDerivative_xy<NORMAL> Sdxy(particles, 2, rCut,grid_spacing);
126 
127  auto f=getV<F>(particles);
128  auto df=getV<DF>(particles);
129  auto Af=getV<ANADF>(particles);
130  particles.ghost_get<F>();
131 
132  DCPSE_scheme<equations2d1,decltype(particles)> Solver(particles);
133  Solver.impose(Sdxx(f)+Sdyy(f), bulk, df);
134  Solver.impose(f, boundary, Af);
135  Solver.solve(f);
136 
137  // Error
138  double MaxError=0,L2=0;
139  auto it=particles.getDomainIterator();
140  while(it.isNext()){
141  auto p = it.get();
143  double theta=particles.getProp<THETA>(p);
144  particles.getProp<ERR>(p) = fabs(particles.getProp<F>(p)-particles.getProp<ANADF>(p));
145  if (particles.getProp<ERR>(p)>MaxError){
146  MaxError=particles.getProp<ERR>(p);
147  }
148  L2+=particles.getProp<ERR>(p)*particles.getProp<ERR>(p);
149  ++it;
150  }
151  v_cl.sum(L2);
152  v_cl.max(MaxError);
153  v_cl.execute();
154  L2=sqrt(L2);
155  std::cout.precision(30);
156  if (v_cl.rank()==0){
157  std::cout<<"dTheta:"<<dtheta<<std::endl;
158  std::cout<<"L2:"<<L2<<std::endl;
159  std::cout<<"L_inf:"<<MaxError<<std::endl;
160  }
162  particles.write(p_output,BINARY);
163  Sdxx.deallocate(particles);
164  Sdyy.deallocate(particles);
165 
166  tt.stop();
167  if (v_cl.rank() == 0)
168  std::cout << "Simulation took: " << tt.getcputime() << " s (CPU) - " << tt.getwct() << " s (wall)\n";
169 
170  openfpm_finalize();
171  return 0;
172 
173 }
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
Specify the general characteristic of system to solve.
Definition: EqnsStruct.hpp:14