00001
00002
00003
00004
00005
00006 #ifndef AMROC_AMRGFMINTERPOLATION_H
00007 #define AMROC_AMRGFMINTERPOLATION_H
00008
00015 #include "AMRGFMSolver.h"
00016 #include "AMRInterpolation.h"
00017 #include "GFMGeom.h"
00018
00025 template <class VectorType, class FixupType, class FlagType, int dim>
00026 class AMRGFMInterpolation : public AMRInterpolation<VectorType,dim>,
00027 public GFMGeom<typename VectorType::InternalDataType,dim> {
00028 typedef typename VectorType::InternalDataType DataType;
00029 typedef AMRInterpolation<VectorType,dim> base;
00030 typedef GFMGeom<DataType,dim> gfm_geom_base;
00031
00032 public:
00033 typedef AMRGFMSolver<VectorType,FixupType,FlagType,dim> gfm_solver_type;
00034 typedef GhostFluidMethod<VectorType,dim> gfm_type;
00035 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00036 typedef typename base::vec_grid_data_type vec_grid_data_type;
00037 typedef typename base::grid_fct_type grid_fct_type;
00038 typedef typename base::grid_data_type grid_data_type;
00039 typedef typename base::point_type point_type;
00040 typedef typename base::interpolation_type interpolation_type;
00041 typedef GridFunction<bool,dim> bool_grid_fct_type;
00042
00043 AMRGFMInterpolation(gfm_solver_type& solver) : base(), _solver(solver) {}
00044
00045 virtual ~AMRGFMInterpolation() {}
00046
00047 void PointsGeom(grid_fct_type& phi, const double& t, const int& Npoints,
00048 const point_type* xc, point_type* normal, DataType* distance) {
00049
00050 if (Npoints<=0 || (!normal && !distance)) return;
00051 for (register int n=0; n<Npoints; n++) {
00052 if (normal) normal[n] = base::ErrorValue();
00053 if (distance) distance[n] = base::ErrorValue();
00054 }
00055
00056 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00057 int Time = CurrentTime(base::GH(),l);
00058 PointsGeom(phi,Time,l,t,Npoints,xc,normal,distance);
00059 }
00060 }
00061
00062 void PointsGeom(grid_fct_type& phi, const int& Time, const int& Level,
00063 const double& t, const int& Npoints, const point_type* xc,
00064 point_type* normal, DataType* distance) {
00065
00066 if (Npoints<=0 || (!normal && !distance)) return;
00067 bool* lused = new bool[Npoints];
00068
00069 forall (phi,Time,Level,c)
00070 BBox bb = phi.interiorbbox(Time,Level,c);
00071 int ncl = base::LocalList(base::GH(),bb,Npoints,xc,lused);
00072 if (ncl>0) {
00073 register int n, nl;
00074 point_type* xcl = new point_type[ncl];
00075 int* idxl = new int[dim*ncl];
00076 for (n=0, nl=0; n<Npoints; n++)
00077 if (lused[n]) xcl[nl++] = xc[n];
00078
00079 base::CellIndices(base::GH(),bb.stepsize(),ncl,xcl,idxl);
00080 if (normal) {
00081 point_type* normall = new point_type[ncl];
00082 gfm_geom_base::CellNormals(base::GH(),phi(Time,Level,c),ncl,idxl,normall);
00083 for (n=0, nl=0; n<Npoints; n++)
00084 if (lused[n]) normal[n] = normall[nl++];
00085 delete [] normall;
00086 }
00087 if (distance) {
00088 DataType* distancel = new DataType[ncl];
00089 gfm_geom_base::CellDistances(base::GH(),phi(Time,Level,c),ncl,idxl,distancel);
00090 for (n=0, nl=0; n<Npoints; n++)
00091 if (lused[n]) distance[n] = distancel[nl++];
00092 delete [] distancel;
00093 }
00094 delete [] idxl;
00095 delete [] xcl;
00096 }
00097 end_forall
00098
00099 delete [] lused;
00100 }
00101
00102 virtual void GetGrid(vec_grid_data_type& gdu, const int& Time, const int& Level,
00103 const int& c, const double& t, const int& Npoints,
00104 const point_type* xcl, VectorType* uvl) {
00105
00106 if (!base::_interpolation) return;
00107 if (NGFM()>0)
00108 base::Interpolation_().Interpolate(base::GH(),gdu,BF()(Time,Level,c),
00109 Npoints,xcl,uvl,base::ErrorValue());
00110 else
00111 base::Interpolation_().Interpolate(base::GH(),gdu,Npoints,xcl,uvl,base::ErrorValue());
00112 }
00113
00114 virtual void GetGrid(grid_data_type& gdu, const int& Time, const int& Level,
00115 const int& c, const double& t, const int& Npoints,
00116 const point_type* xcl, DataType* uvl) {
00117
00118 if (!base::_interpolation) return;
00119 if (NGFM()>0)
00120 base::Interpolation_().Interpolate(base::GH(),gdu,BF()(Time,Level,c),
00121 Npoints,xcl,uvl,base::ErrorValue());
00122 else
00123 base::Interpolation_().Interpolate(base::GH(),gdu,Npoints,xcl,uvl,base::ErrorValue());
00124 }
00125
00126 void PointsGeomPar(grid_fct_type& phi, const double& t, const int& Npoints,
00127 const point_type* xc, point_type* normal, DataType* distance) {
00128 if (!normal && !distance) return;
00129 for (register int n=0; n<Npoints; n++) {
00130 if (normal) normal[n] = base::ErrorValue();
00131 if (distance) distance[n] = base::ErrorValue();
00132 }
00133
00134 int Np,Npr;
00135 int num = comm_service::proc_num();
00136 point_type *xcp = 0;
00137 base::PointsAllGather(Npoints,xc,Np,xcp);
00138 DataType* geomp = new DataType[(dim+1)*Np*num];
00139
00140 PointsGeom(phi,t,Np*num,xcp,(point_type *)geomp,geomp+dim*Np*num);
00141 delete [] xcp;
00142
00143 DataType* geompr = 0;
00144 base::DataAllScatter((dim+1)*Np,geomp,Npr,geompr);
00145 for (int p=0; p<num; p++)
00146 for (register int n=0; n<Npoints; n++) {
00147 if (normal) {
00148 point_type* normalpr = (point_type *)(geompr+p*Npr+dim*n);
00149 if ((*normalpr) != base::ErrorValue())
00150 normal[n] = (*normalpr);
00151 }
00152
00153 if (distance) {
00154 DataType* distancepr = geompr+p*Npr+dim*(Npr/(dim+1))+n;
00155 if ((*distancepr) != base::ErrorValue())
00156 distance[n] = (*distancepr);
00157 }
00158 }
00159
00160 delete [] geompr;
00161 delete [] geomp;
00162 }
00163
00164 inline gfm_type& GFM(const int& n) { return _solver.GFM(n); }
00165 inline const int& NGFM() { return _solver.NGFM(); }
00166 inline bool_grid_fct_type& BF() { return _solver.BF(); }
00167 inline const bool_grid_fct_type& BF() const{ return _solver.BF(); }
00168
00169 protected:
00170 gfm_solver_type& _solver;
00171 };
00172
00173 #endif