20 #include "Vector/vector_dist_subset.hpp"
21 #include "DCPSE/DCPSE_op/DCPSE_surface_op.hpp"
23 #include "OdeIntegrators/OdeIntegrators.hpp"
25 void *PointerGlobal, *Pointer2Bulk,*Pointer2Boundary;
32 constexpr
int DCONC=1;
33 constexpr
int NORMAL=2;
37 double dt,tf,max_steady_tol;
46 const double threshold;
56 for (
int d = 0; d < dim-1; ++d)
57 arg += (coord[d]-surf.center[d])*(coord[d]-surf.center[d]);
58 arg2 = arg/(surf.radius*surf.radius);
60 if (arg2 < (1 - surf.threshold)*(1 - surf.threshold))
61 return surf.alpha * std::exp(-1.0/(1.0-arg2));
71 double x, y, dist, arg, prefactor, norm_grad;
72 const double r2{surf.radius*surf.radius};
75 for (
int d = 0; d < dim-1; ++d)
76 dist += (coord[d]-surf.center[d])*(coord[d]-surf.center[d]);
78 if (std::fabs(dist - r2) < 1e-10)
81 arg = r2 / (dist - r2);
83 x = coord[0]-surf.center[0];
84 y = coord[1]-surf.center[1];
85 prefactor = - 2.0 * f<dim>(coord,surf) * arg*arg / r2;
87 norm_grad = std::sqrt(4.0 * f<dim>(coord,surf)*f<dim>(coord,surf) * arg*arg*arg*arg * dist / (r2*r2) + 1.0);
89 normal[0] = - prefactor * x / norm_grad;
90 normal[1] = - prefactor * y / norm_grad;
91 normal[2] = 1.0 / norm_grad;
93 double mag=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
99 Point<3,double> SurfaceNormal(
double &x,
double &y,
double &z,
double alpha){
101 double dist=sqrt((x+0.5)*(x+0.5)+y*y);
108 double norm_grad = -alpha*2*dist*exp(-1./(1.-dist*dist)*1./((1.-dist*dist)*(1.-dist*dist)));
111 Normal[2]=4.0*z*norm_grad*(0.5/dist)*(2*(x+0.5)+2*y);
112 return Normal/Normal.
distance(Normal);
116 template<
typename DXX,
typename DYY,
typename DZZ>
124 RHSFunctor(DXX &SDxx,DYY &SDyy,DZZ &SDzz):SDxx(SDxx),SDyy(SDyy),SDzz(SDzz)
134 auto C = getV<CONC>(Particles);
135 auto C_bulk = getV<CONC>(Particles_bulk);
136 auto dC = getV<DCONC>(Particles);
137 auto dC_bulk = getV<DCONC>(Particles_bulk);
138 C_bulk=X.data.get<0>();
142 dC_bulk = (SDxx(C)+SDyy(C)+SDzz(C));
145 dxdt.data.get<0>()=dC;
163 auto & v_cl = create_vcluster();
166 auto &bulk=Particles_bulk.
getIds();
167 auto Concentration = getV<CONC>(Particles);
168 auto Concentration_old = getV<COLD>(Particles);
169 auto Concentration_bulk = getV<CONC>(Particles_bulk);
170 Concentration_bulk = X.data.get<0>();
171 if (v_cl.rank() == 0) {
172 std::cout <<
"Time step " << ctr <<
" : " << t <<
" over." <<
"dt is set to: "<<(t-t_old)<< std::endl;
173 std::cout <<
"----------------------------------------------------------" << std::endl;
181 double MaxRateOfChange=0;
182 for (
int j = 0; j < bulk.size(); j++) {
183 auto p = bulk.get<0>(j);
184 if(Particles.
getProp<CONC>(p)<0){
187 if(fabs(Particles.
getProp<CONC>(p)-Particles.
getProp<COLD>(p))>MaxRateOfChange)
189 MaxRateOfChange=fabs(Particles.
getProp<CONC>(p)-Particles.
getProp<COLD>(p));
192 v_cl.max(MaxRateOfChange);
195 {std::cout<<
"MaxRateOfChange: "<<MaxRateOfChange<<std::endl;
197 if(MaxRateOfChange<max_steady_tol && ctr>5)
199 std::cout<<
"Steady State Reached."<<std::endl;
203 Concentration_old=Concentration;
207 X.data.get<0>()=Concentration;
211 int main(
int argc,
char * argv[]) {
212 openfpm_init(&argc,&argv);
213 auto & v_cl = create_vcluster();
216 double grid_spacing_surf;
217 double rCut,SCF,alph;
221 std::ifstream PCfile;
223 std::cout <<
"Error: Not exact no. of args." << std::endl;
227 grid_spacing_surf=0.03125;
228 PCfile.open(argv[1]);
229 tf=std::stof(argv[2]);
230 dt=std::stof(argv[3]);
231 wr_at=std::stoi(argv[4]);
232 max_steady_tol=std::stof(argv[5]);
233 SCF=std::stof(argv[6]);
234 alph=std::stof(argv[7]);
235 DCPSE_LOAD=std::stof(argv[8]);
238 rCut=3.1*grid_spacing_surf;
241 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
243 struct bump<dim> surf = {.center=
Point<dim-1,
double>{-0.5,0.0}, .alpha=alph, .radius=0.25, .threshold=0.025};
248 double uconc,Nx,Ny,Nz,Px,Py,Pz;
251 while ( PCfile >>uconc>> Px >> Py >> Pz)
278 std::cout <<
"n: " << pctr <<
" - rCut: " << rCut <<
" - nSpacing: " << grid_spacing_surf<<
" - Final Time: "<<tf<<
" - Initial DT: "<<dt<<std::endl;
287 auto &bulk=particles_boundary.getIds();
299 opt=support_options::LOAD;
303 opt=support_options::ADAPTIVE;
305 auto verletList =
particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
306 SurfaceDerivative_xx<NORMAL,decltype(verletList)> Sdxx{
particles,verletList,2,rCut,SCF,rCut/SCF,opt};
307 SurfaceDerivative_yy<NORMAL,decltype(verletList)> Sdyy{
particles,verletList,2,rCut,SCF,rCut/SCF,opt};
308 SurfaceDerivative_zz<NORMAL,decltype(verletList)> Sdzz{
particles,verletList,2,rCut,SCF,rCut/SCF,opt};
340 std::cout<<
"DCPSE Time: "<<tt.
getwct()<<
" seconds."<<std::endl;
342 Pointer2Bulk = (
void *) &particles_bulk;
343 Pointer2Boundary = (
void *) &particles_boundary;
344 RHSFunctor<SurfaceDerivative_xx<NORMAL,decltype(verletList)>, SurfaceDerivative_yy<NORMAL,decltype(verletList)>,SurfaceDerivative_zz<NORMAL,decltype(verletList)>> System(Sdxx,Sdyy,Sdzz);
354 for(
int j=0;j<bulk.size();j++)
355 {
auto p=bulk.get<0>(j);
362 std::cout <<
"Maximum Analytic Error: " << worst1 << std::endl;
366 boost::numeric::odeint::euler< state_type_1d_ofp,double,state_type_1d_ofp,double,boost::numeric::odeint::vector_space_algebra_ofp > Euler;
367 size_t steps=boost::numeric::odeint::integrate_const(Euler,System,X,0.0,tf,dt,Obs);
376 if (v_cl.rank() == 0)
377 std::cout <<
"Simulation took: " << tt.
getcputime() <<
" s (CPU) - " << tt.
getwct() <<
" s (wall)\n";
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.
__device__ __host__ T distance(const Point< dim, T > &q) const
It calculate the distance between 2 points.
Class for cpu time benchmarking.
void stop()
Stop the timer.
double getcputime()
Return the cpu time.
void start()
Start the timer.
double getwct()
Return the elapsed real time.
openfpm::vector< aggregate< int > > & getIds()
Return the ids.
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.
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 load(const std::string &filename)
Load the distributed vector from an HDF5 file.
void ghost_get_subset()
Stub does not do anything.
void deleteGhost()
Delete the particles on the ghost.
auto getLastPos() -> decltype(vPos.template get< 0 >(0))
Get the position of the last element.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
A 1d Odeint and Openfpm compatible structure.