20#include "Vector/vector_dist_subset.hpp"
21#include "DCPSE/DCPSE_op/DCPSE_surface_op.hpp"
23#include "OdeIntegrators/OdeIntegrators.hpp"
25void *PointerGlobal, *Pointer2Bulk,*Pointer2Boundary;
33constexpr int NORMAL=2;
37double dt,tf,max_steady_tol;
46 const double threshold;
56for (
int d = 0; d < dim-1; ++d)
57arg += (coord[d]-surf.center[d])*(coord[d]-surf.center[d]);
58arg2 = arg/(surf.radius*surf.radius);
60if (arg2 < (1 - surf.threshold)*(1 - surf.threshold))
61return 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]);
99Point<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);
116template<
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;
211int 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;
286 auto &bulk=particles_boundary.getIds();
298 opt=support_options::LOAD;
302 opt=support_options::ADAPTIVE_SURFACE;
304 SurfaceDerivative_xx<NORMAL> Sdxx{
particles,2,rCut,SCF,opt};
305 SurfaceDerivative_yy<NORMAL> Sdyy{
particles,2,rCut,SCF,opt};
306 SurfaceDerivative_zz<NORMAL> Sdzz{
particles,2,rCut,SCF,opt};
338 std::cout<<
"DCPSE Time: "<<tt.
getwct()<<
" seconds."<<std::endl;
340 Pointer2Bulk = (
void *) &particles_bulk;
341 Pointer2Boundary = (
void *) &particles_boundary;
352 for(
int j=0;j<bulk.size();j++)
353 {
auto p=bulk.get<0>(j);
360 std::cout <<
"Maximum Analytic Error: " << worst1 << std::endl;
364 boost::numeric::odeint::euler< state_type_1d_ofp,double,state_type_1d_ofp,double,boost::numeric::odeint::vector_space_algebra_ofp > Euler;
365 size_t steps=boost::numeric::odeint::integrate_const(Euler,
System,X,0.0,tf,dt,Obs);
374 if (v_cl.rank() == 0)
375 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.
This class implement the point shape in an N-dimensional space.
__device__ __host__ T distance(const Point< dim, T > &q) const
It calculate the distance between 2 points.
Implementation of 1-D std::vector like structure.
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(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
auto getLastProp() -> decltype(v_prp.template get< id >(0))
Get the property of the last 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 getLastPos() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
void add()
Add local particle.
void load(const std::string &filename)
Load the distributed vector from an HDF5 file.
void deleteGhost()
Delete the particles on the ghost.
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.