00001
00002
00003
00004
00005
00006 #ifndef AMROC_ELC_GFMSOLVER_H
00007 #define AMROC_ELC_GFMSOLVER_H
00008
00016 #include "AMRCoupledGFMSolver.h"
00017 #include "AMRGFMInterpolation.h"
00018 #include "CPTLevelSet.h"
00019 #include "Timing.h"
00020 #include "elc/EulerianCommBoundary.h"
00021 #include "elc/EulerianCommShell.h"
00022 #include <vector>
00023
00024
00031 template <class VectorType, class FixupType, class FlagType, int dim>
00032 class AMRELCGFMSolver : public AMRCoupledGFMSolver<VectorType,FixupType,FlagType,dim> {
00033 typedef AMRCoupledGFMSolver<VectorType,FixupType,FlagType,dim> base;
00034 typedef typename VectorType::InternalDataType DataType;
00035 public:
00036 typedef typename base::integrator_type integrator_type;
00037 typedef typename base::initial_condition_type initial_condition_type;
00038 typedef typename base::boundary_conditions_type boundary_conditions_type;
00039 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00040
00041 typedef AMRGFMInterpolation<VectorType,FixupType,FlagType,dim> interpolation_type;
00042 typedef typename interpolation_type::point_type point_type;
00043 typedef typename elc::EulerianComm<dim,DataType> eul_comm_type;
00044 typedef typename elc::EulerianCommShell<dim,DataType> eul_comm_pressure_on_face_type;
00045 typedef typename elc::EulerianCommBoundary<dim,DataType> eul_comm_pressure_on_node_type;
00046 typedef typename geom::BBox<dim,DataType> bbox_type;
00047 typedef CPTLevelSet<DataType,dim> cpt_type;
00048
00049 AMRELCGFMSolver(integrator_type& integ,
00050 initial_condition_type& init,
00051 boundary_conditions_type& bc) : base(integ, init, bc), _CoupleGFM(-1),
00052 _SendDataLocation(0), _ThinStructure(0), _LengthConversionFactor(1.), _PressureConversionFactor(1.),
00053 _SafeCFL(1.) {
00054 _Interpolation = new interpolation_type(*this);
00055 _eulComm = (eul_comm_type*) 0;
00056 }
00057
00058 virtual ~AMRELCGFMSolver() {
00059 delete _Interpolation;
00060 if (_eulComm) delete _eulComm;
00061 }
00062
00063 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00064 base::register_at(Ctrl,prefix);
00065 RegisterAt(base::LocCtrl,"DataLocation",_SendDataLocation);
00066 RegisterAt(base::LocCtrl,"ThinStructure",_ThinStructure);
00067 RegisterAt(base::LocCtrl,"LengthFactor",_LengthConversionFactor);
00068 RegisterAt(base::LocCtrl,"PressureFactor",_PressureConversionFactor);
00069 RegisterAt(base::LocCtrl,"SafeCFL",_SafeCFL);
00070 }
00071 virtual void register_at(ControlDevice& Ctrl) {
00072 base::register_at(Ctrl);
00073 }
00074
00075 virtual void finish() {
00076 if (_eulComm) {
00077 delete _eulComm;
00078 _eulComm = (eul_comm_type*) 0;
00079 }
00080 base::finish();
00081 }
00082
00083 virtual void SetupData() {
00084 base::SetupData();
00085 _Interpolation->SetupData(base::PGH(), base::NGhosts());
00086 if (_SendDataLocation!=0) _SendDataLocation=1;
00087 }
00088
00089 void SetupInterComm(const int solid_nodes, const int solid_root) {
00090 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
00091 if (SendDataLocation()==0)
00092 _eulComm = new eul_comm_pressure_on_face_type(MPI_COMM_WORLD, base::Comm(), solid_nodes,
00093 solid_root, elc::GlobalIdentifiers);
00094 else
00095 _eulComm = new eul_comm_pressure_on_node_type(MPI_COMM_WORLD, base::Comm(), solid_nodes,
00096 solid_root, elc::GlobalIdentifiers);
00097 #ifdef DEBUG_PRINT_ELC
00098 ( comm_service::log() << "*** EulerianComm created: SolidNodes=" << solid_nodes
00099 << " SolidRoot=" << solid_root << "\n" ).flush();
00100 #endif
00101 }
00102
00103 double CFLGather(double cfl) {
00104 #ifdef DAGH_NO_MPI
00105 #else
00106 if (comm_service::dce() && comm_service::proc_num() > 1) {
00107
00108 int num = comm_service::proc_num();
00109
00110 int R;
00111 int size = sizeof(double);
00112 void *values = (void *) new char[size*num];
00113
00114 START_WATCH;
00115 R = MPI_Allgather(&cfl, size, MPI_BYTE, values, size, MPI_BYTE,
00116 comm_service::comm(base::U().GF_Id()));
00117 END_WATCH(GATHERCFL);
00118 if ( MPI_SUCCESS != R )
00119 comm_service::error_die( "AMRELCGFMSolver::cfl", "MPI_Allgather", R );
00120
00121 for (int i=0;i<num;i++) {
00122 double tmax = *((double *)values + i);
00123 cfl = cfl > tmax ? cfl : tmax;
00124 }
00125 if (values) delete [] (char *)values;
00126 }
00127 #endif
00128 return cfl;
00129 }
00130
00131
00132
00133 virtual double IntegrateLevel(vec_grid_fct_type& u, const int Time, const int Level,
00134 double t, double dt, bool DoFixup, double tc,
00135 const int which) {
00136 double cfl_orig = base::IntegrateLevel(u,Time,Level,t,dt,DoFixup,tc,which);
00137 if (_SafeCFL > 0.) {
00138 double cfl_max = CFLGather(cfl_orig);
00139 int NSteps = int(cfl_max / _SafeCFL) + 1;
00140 while (cfl_max > _SafeCFL) {
00141 double tl = t;
00142 double dtl = dt/NSteps;
00143 #ifdef DEBUG_PRINT_AMRSOLVER
00144 ( comm_service::log() << "IntegrateLevel(): Level " << Level
00145 << " to be repeated with " << NSteps << " steps. Global CFL = " << cfl_max << "\n" ).flush();
00146 #endif
00147 cfl_max = 0.;
00148 for (int i=1; i<=NSteps; i++) {
00149 if (i==NSteps) dtl=t+dt-tl;
00150 double cfl = base::IntegrateLevel(u,Time,Level,tl,dtl,DoFixup,tc,which);
00151 cfl_max = cfl_max > cfl ? cfl_max : cfl;
00152 tl += dtl;
00153 }
00154 cfl_max = CFLGather(cfl_max);
00155 #ifdef DEBUG_PRINT_AMRSOLVER
00156 ( comm_service::log() << "IntegrateLevel(): Level " << Level
00157 << " repeated with " << NSteps << " steps. New global CFL = " << cfl_max << "\n" ).flush();
00158 #endif
00159 NSteps++;
00160 }
00161 }
00162 return cfl_orig;
00163 }
00164
00165 virtual void SendBoundaryData() {
00166 #ifdef DEBUG_PRINT
00167 ( comm_service::log() << "*** SendBoundaryData()\n" ).flush();
00168 #endif
00169 int Time = CurrentTime(base::GH(),base::CouplingLevel);
00170
00171
00172 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00173 int TimeC = CurrentTime(base::GH(),l);
00174 int TStepC = TimeStep(base::Work(),l);
00175 if (TimeC < Time) {
00176 double frac = 1.0*(Time-TimeC)/TStepC;
00177 forall (base::Work(),TimeC,l,c)
00178 base::Work()(TimeC,l,c).lin_interp(base::Work()(TimeC,l,c),(1.0-frac),
00179 base::Work()(TimeC+TStepC,l,c),frac);
00180 end_forall
00181 }
00182 else if (TimeC+TStepC == Time) {
00183 forall (base::Work(),TimeC,l,c)
00184 base::Work()(TimeC,l,c).copy(base::Work()(TimeC+TStepC,l,c));
00185 end_forall
00186 }
00187 }
00188 START_WATCH
00189 #ifdef DEBUG_PRINT
00190 ( comm_service::log() << "*** Geometry construction()\n" ).flush();
00191 #endif
00192 DataType distance = -base::GFM(CoupleGFM()).Boundary().Cutoff();
00193
00194 DataType dxmin = 1.e37;
00195 forall(base::U(),Time,base::CouplingLevel,c)
00196 DCoords dx = base::GH().worldStep(base::U()(Time,base::CouplingLevel,c).stepsize());
00197 for (register int d=0; d<base::Dim(); d++)
00198 if (dx(d)<dxmin) dxmin=dx(d);
00199 end_forall
00200 if (distance>dxmin*base::NGhosts()) {
00201 int ghn = static_cast<int>(distance/dxmin + 1);
00202 std::cerr << "\n\nToo few ghostcells for Cutoff=" << -distance
00203 << ". Set GhostCells>=" << ghn << " or set Cutoff<="
00204 << dxmin*base::NGhosts() << ".\n";
00205 std::cerr << "Aborting programm...\n" << std::flush;
00206 std::exit(-1);
00207 }
00208
00209 _eulComm->initializePressure();
00210
00211 register int n;
00212 int Npoints;
00213
00214 double *press_data = _eulComm->getPressuresData();
00215 const int* con = _eulComm->getConnectivitiesData();
00216 const point_type *pos = reinterpret_cast<const point_type *>(_eulComm->getPositionsData());
00217 if (_ThinStructure>0 || distance>1.e-12)
00218 _eulComm->computeFaceNormals();
00219 if (_ThinStructure>0 || SendDataLocation()!=1 || distance>1.e-12)
00220 _eulComm->computeFaceCentroids();
00221 const point_type *norm = reinterpret_cast<const point_type *>(_eulComm->getFaceNormalsData());
00222 const point_type *cent = reinterpret_cast<const point_type *>(_eulComm->getFaceCentroidsData());
00223
00224 if (SendDataLocation()==1)
00225 Npoints = _eulComm->getNumberOfNodes();
00226 else
00227 Npoints = _eulComm->getNumberOfFaces();
00228
00229 if (_ThinStructure>0) {
00230 point_type* positions = new point_type[2*Npoints];
00231 point_type* centroids = new point_type[2*Npoints];
00232 if (SendDataLocation()==1) {
00233 DataType* face_count = new DataType[Npoints];
00234 point_type* point_normal = new point_type[Npoints];
00235 START_WATCH
00236 for (n=0; n<Npoints; n++) {
00237 face_count[n] = static_cast<DataType>(0.);
00238 point_normal[n] = static_cast<point_type>(0.);
00239 }
00240
00241 int Nfaces = _eulComm->getNumberOfFaces();
00242 for (n=0; n<Nfaces; n++)
00243 for (register int d=0; d<dim; d++) {
00244 point_normal[con[dim*n+d]] += norm[n];
00245 face_count[con[dim*n+d]] += static_cast<DataType>(1.);
00246 }
00247
00248 for (n=0; n<Npoints; n++) {
00249 point_normal[n] /= face_count[n];
00250 positions[2*n] = pos[n]-distance*point_normal[n];
00251 positions[2*n+1] = pos[n]+distance*point_normal[n];
00252 centroids[2*n+1] = centroids[2*n] = pos[n];
00253 }
00254
00255 END_WATCH(FLUID_CPL_ELC_GEOMETRY)
00256 delete [] face_count;
00257 delete [] point_normal;
00258 }
00259 else {
00260 START_WATCH
00261 for (n=0; n<Npoints; n++) {
00262 positions[2*n] = cent[n]-distance*norm[n];
00263 positions[2*n+1] = cent[n]+distance*norm[n];
00264 centroids[2*n+1] = centroids[2*n] = cent[n];
00265 }
00266 END_WATCH(FLUID_CPL_ELC_GEOMETRY)
00267 }
00268 #ifdef DEBUG_PRINT
00269 ( comm_service::log() << "*** Pressure interpolation()\n" ).flush();
00270 #endif
00271 DataType* press_int = new DataType[2*Npoints];
00272
00273 START_WATCH
00274 int TimeZero = CurrentTime(base::GH(),0);
00275 int Lev=0, Np=2*Npoints;
00276 bool* lpos = new bool[Np];
00277 bool* lcent = new bool[Np];
00278 _Interpolation->LocalPoints(base::Work(),TimeZero,Lev,Np,positions,lpos);
00279 _Interpolation->LocalPoints(base::Work(),TimeZero,Lev,Np,centroids,lcent);
00280 int nlpos=0, nppos=0;
00281 for (n=0; n<Np; n++)
00282 if (lcent[n]) {
00283 if (lpos[n]) nlpos++;
00284 else nppos++;
00285 }
00286 int lm, pm;
00287 point_type* lpositions = new point_type[nlpos];
00288 point_type* ppositions = new point_type[nppos];
00289 DataType* lpress_int = new DataType[nlpos];
00290 DataType* ppress_int = new DataType[nppos];
00291 for (n=0, lm=0, pm=0; n<Np; n++)
00292 if (lcent[n]) {
00293 if (lpos[n]) lpositions[lm++] = positions[n];
00294 else ppositions[pm++] = positions[n];
00295 }
00296 _Interpolation->PointsValues(base::Work(),base::t[0],nlpos,lpositions,lpress_int);
00297 _Interpolation->PointsValuesPar(base::Work(),base::t[0],nppos,ppositions,ppress_int);
00298 for (n=0, lm=0, pm=0; n<Np; n++)
00299 if (lcent[n])
00300 if (lpos[n]) press_int[n] = lpress_int[lm++];
00301 else press_int[n] = ppress_int[pm++];
00302 else press_int[n] = _Interpolation->ErrorValue();
00303 delete [] lpositions;
00304 delete [] ppositions;
00305 delete [] lpress_int;
00306 delete [] ppress_int;
00307 delete [] lpos;
00308 delete [] lcent;
00309 END_WATCH(FLUID_CPL_INTERPOLATE)
00310
00311 for (n=0; n<Npoints; n++)
00312 if (press_int[2*n]==_Interpolation->ErrorValue() ||
00313 press_int[2*n+1]==_Interpolation->ErrorValue()) {
00314 press_data[n] = std::numeric_limits<DataType>::max();
00315 #ifdef DEBUG_PRINT
00316 if (press_int[2*n]!=press_int[2*n+1] && base::GFM(CoupleGFM()).Boundary().GetVerbose())
00317 ( comm_service::log() << "*** Thin structure interpolation error for center at "
00318 << centroids[2*n] << " " << positions[2*n] << ": " << press_int[2*n] << " "
00319 << positions[2*n+1] << ": " << press_int[2*n+1] << "\n" ).flush();
00320 #endif
00321 }
00322 else
00323 press_data[n] = press_int[2*n]-press_int[2*n+1];
00324
00325 delete [] positions;
00326 delete [] centroids;
00327 delete [] press_int;
00328 }
00329 else {
00330 if (SendDataLocation()==1) {
00331 if (distance>1.e-12) {
00332 int Nfaces = _eulComm->getNumberOfFaces();
00333 DataType* face_count = new DataType[Npoints];
00334 point_type* point_normal = new point_type[Npoints];
00335 START_WATCH
00336 for (n=0; n<Npoints; n++) {
00337 face_count[n] = static_cast<DataType>(0.);
00338 point_normal[n] = static_cast<point_type>(0.);
00339 }
00340
00341 for (n=0; n<Nfaces; n++)
00342 for (register int d=0; d<dim; d++) {
00343 point_normal[con[dim*n+d]] += norm[n];
00344 face_count[con[dim*n+d]] += static_cast<DataType>(1.);
00345 }
00346
00347 point_type* positions = new point_type[Npoints];
00348 for (n=0; n<Npoints; n++) {
00349 point_normal[n] /= face_count[n];
00350 positions[n] = pos[n]+distance*point_normal[n];
00351 }
00352 END_WATCH(FLUID_CPL_ELC_GEOMETRY)
00353 delete [] face_count;
00354 delete [] point_normal;
00355
00356 START_WATCH
00357 _Interpolation->PointsValues(base::Work(),base::t[0],Npoints,positions,press_data);
00358 END_WATCH(FLUID_CPL_INTERPOLATE)
00359
00360 delete [] positions;
00361 }
00362 else {
00363 START_WATCH
00364 _Interpolation->PointsValues(base::Work(),base::t[0],Npoints,pos,press_data);
00365 END_WATCH(FLUID_CPL_INTERPOLATE)
00366 }
00367 }
00368 else {
00369 point_type* positions = new point_type[Npoints];
00370 START_WATCH
00371 for (n=0; n<Npoints; n++) {
00372 positions[n] = cent[n];
00373 if (distance>1.e-12)
00374 positions[n] += distance*norm[n];
00375 }
00376 END_WATCH(FLUID_CPL_ELC_GEOMETRY)
00377
00378 START_WATCH
00379 _Interpolation->PointsValues(base::Work(),base::t[0],Npoints,positions,press_data);
00380 END_WATCH(FLUID_CPL_INTERPOLATE)
00381
00382 delete [] positions;
00383 }
00384 for (n=0; n<Npoints; n++)
00385 if (press_data[n]==_Interpolation->ErrorValue())
00386 press_data[n] = std::numeric_limits<DataType>::max();
00387 }
00388
00389 #ifdef DEBUG_PRINT_ELC
00390 ( comm_service::log() << "*** ELC::SendPressure" ).flush();
00391 #endif
00392
00393 if (PressureConversionFactor()!=1.) {
00394 for (n=0; n<Npoints; n++)
00395 if (press_data[n]!=std::numeric_limits<DataType>::max())
00396 press_data[n] *= static_cast<DataType>(PressureConversionFactor());
00397 }
00398
00399 ModifyELCSendData(_eulComm);
00400
00401 START_WATCH
00402 _eulComm->sendPressure();
00403 _eulComm->waitForPressure();
00404 END_WATCH(ELC_SENDPRESSURE)
00405
00406 #ifdef DEBUG_PRINT_ELC
00407 ( comm_service::log() << " done.\n" ).flush();
00408 #endif
00409 #ifdef DEBUG_PRINT_ELC_VALUES
00410 ( comm_service::log() << "*** Values passed to ELC ***\n" ).flush();
00411 for (n=0; n<Npoints; n++)
00412 ( comm_service::log() << press_data[n] << "\n" ).flush();
00413 #endif
00414 END_WATCH(FLUID_CPL_SEND_OVERHEAD)
00415 }
00416
00417 virtual void PostReceiveBoundaryData(bool FullDomain=false) {
00418 START_WATCH
00419 BBox wholebb;
00420
00421 if (!FullDomain) {
00422 int Level = 0;
00423 int Time = CurrentTime(base::GH(),Level);
00424 forall (base::U(),Time,Level,c)
00425 wholebb += base::U().boundingbbox(Time,Level,c);
00426 end_forall
00427 }
00428 else
00429 wholebb = base::GH().wholebbox();
00430
00431 DCoords lbcorner = base::GH().worldCoords(wholebb.lower(), wholebb.stepsize());
00432 DCoords ubcorner = base::GH().worldCoords(wholebb.upper()+wholebb.stepsize(),
00433 wholebb.stepsize());
00434 if (LengthConversionFactor()!=1.) {
00435 lbcorner /= LengthConversionFactor();
00436 ubcorner /= LengthConversionFactor();
00437 }
00438 bbox_type lregion(lbcorner(), ubcorner());
00439
00440 #ifdef DEBUG_PRINT_ELC
00441 ( comm_service::log() << "*** ELC::PostReceiveBoundaryData(), " << lregion ).flush();
00442 #endif
00443
00444 START_WATCH
00445 _eulComm->receiveMesh(lregion);
00446 END_WATCH(ELC_RECEIVEBOUNDARY)
00447
00448 #ifdef DEBUG_PRINT_ELC
00449 ( comm_service::log() << " done.\n" ).flush();
00450 #endif
00451 END_WATCH(FLUID_CPL_RECEIVE_OVERHEAD)
00452 }
00453
00454 virtual void WaitReceiveBoundaryData() {
00455 START_WATCH
00456 #ifdef DEBUG_PRINT_ELC
00457 ( comm_service::log() << "*** ELC::WaitReceiveBoundaryData()" ).flush();
00458 #endif
00459
00460 START_WATCH
00461 _eulComm->waitForMesh();
00462 END_WATCH(ELC_RECEIVEBOUNDARY)
00463
00464 ModifyELCReceiveData(_eulComm);
00465
00466 #ifdef DEBUG_PRINT_ELC
00467 ( comm_service::log() << " done.\n" ).flush();
00468 #endif
00469 int Npoints = _eulComm->getNumberOfNodes();
00470 point_type* positions = (point_type *)(_eulComm->getPositionsData());
00471 point_type* velocities = (point_type *)(_eulComm->getVelocitiesData());
00472 register int n;
00473 if (LengthConversionFactor()!=1.) {
00474 for (n=0; n<Npoints; n++) {
00475 positions[n] *= static_cast<DataType>(LengthConversionFactor());
00476 velocities[n] *= static_cast<DataType>(LengthConversionFactor());
00477 }
00478 }
00479 #ifdef DEBUG_PRINT_ELC_VALUES
00480 ( comm_service::log() << "*** Positions received from ELC ***\n" ).flush();
00481 for (n=0; n<Npoints; n++)
00482 ( comm_service::log() << positions[n] << "\n" ).flush();
00483 #endif
00484 END_WATCH(FLUID_CPL_RECEIVE_OVERHEAD)
00485
00486 (reinterpret_cast<cpt_type* >(base::GFM(CoupleGFM()).GetLevelSetP()))->SetBrep(_eulComm->getNumberOfNodes(),
00487 _eulComm->getPositionsData(), _eulComm->getNumberOfFaces(),
00488 _eulComm->getConnectivitiesData());
00489 }
00490
00491 void ExtractBoundaryVelocities(const BBox& bb, const int& nc,
00492 const point_type* xc, point_type* retvel) {
00493 START_WATCH
00494 int nodes = _eulComm->getNumberOfNodes();
00495 const point_type *positions = reinterpret_cast<const point_type *>(_eulComm->getPositionsData());
00496 const point_type *velocities = reinterpret_cast<const point_type *>(_eulComm->getVelocitiesData());
00497
00498 #ifdef DEBUG_PRINT_ELC_VALUES
00499 ( comm_service::log() << "*** Velocities constructed in " << bb << " ***\n" ).flush();
00500 #endif
00501
00502
00503
00504 DCoords lbcorner = base::GH().worldCoords(bb.lower(),bb.stepsize());
00505 DCoords ubcorner = base::GH().worldCoords(bb.upper()+bb.stepsize(),bb.stepsize());
00506 point_type lb, ub;
00507 register int m, n;
00508 for (m=0; m<base::Dim(); m++) {
00509 lb(m) = lbcorner(m); ub(m) = ubcorner(m);
00510 }
00511
00512 std::vector<int> pos_list;
00513 for (m=0; m<nodes; m++)
00514 if (!(lb>positions[m] || ub<positions[m]))
00515 pos_list.push_back(m);
00516 int s = pos_list.size();
00517
00518 if (s>0) {
00519 double min_dist, dist;
00520 register int min_point;
00521 for (n=0; n<nc; n++) {
00522 min_dist = Abs(xc[n]-positions[pos_list[0]]);
00523 min_point = pos_list[0];
00524 for (m=1; m<s; m++) {
00525 dist = Abs(xc[n]-positions[pos_list[m]]);
00526 if (dist<min_dist) {
00527 min_dist = dist;
00528 min_point = pos_list[m];
00529 }
00530 }
00531 retvel[n] = velocities[min_point];
00532 }
00533 }
00534 else
00535 for (n=0; n<nc; n++)
00536 retvel[n] = 0.;
00537
00538 #ifdef DEBUG_PRINT_ELC_VALUES
00539 for (n=0; n<nc; n++)
00540 ( comm_service::log() << xc[n] << " " << retvel[n] << "\n" ).flush();
00541 #endif
00542 END_WATCH(FLUID_CPL_VELOCITY_SEARCH)
00543 }
00544
00545 virtual void ModifyELCReceiveData(eul_comm_type* eulComm) {}
00546 virtual void ModifyELCSendData(eul_comm_type* eulComm) {}
00547
00548 inline void SetCoupleGFM(int gfm) { _CoupleGFM = gfm; }
00549 inline const int& CoupleGFM() const { return _CoupleGFM; }
00550 inline void SetSendDataLocation(int bd) { SendDataLocation = bd; }
00551 inline const int& SendDataLocation() const { return _SendDataLocation; }
00552 inline void SetLengthConversionFactor(DataType l) { _LengthConversionFactor = l; }
00553 inline const DataType& LengthConversionFactor() const { return _LengthConversionFactor; }
00554 inline void SetPressureConversionFactor(DataType p) { _PressureConversionFactor = p; }
00555 inline const DataType& PressureConversionFactor() const { return _PressureConversionFactor; }
00556
00557 protected:
00558 interpolation_type* _Interpolation;
00559 eul_comm_type* _eulComm;
00560 int _CoupleGFM;
00561 int rank;
00562 int _SendDataLocation, _ThinStructure;
00563 DataType _LengthConversionFactor, _PressureConversionFactor;
00564 double _SafeCFL;
00565 };
00566
00567
00568 template <class VectorType, int dim>
00569 class F77ELCGFMBoundary : public F77GFMBoundary<VectorType,dim> {
00570 typedef typename VectorType::InternalDataType DataType;
00571 typedef F77GFMBoundary<VectorType,dim> base;
00572 public:
00573 typedef typename base::vec_grid_data_type vec_grid_data_type;
00574 typedef typename base::grid_data_type grid_data_type;
00575 typedef typename base::generic_func_type generic_func_type;
00576 typedef typename base::point_type point_type;
00577 typedef AMRELCGFMSolver<VectorType,FixupType,FlagType,dim> amr_elc_solver;
00578
00579 F77ELCGFMBoundary(generic_func_type bnd, generic_func_type trs, amr_elc_solver& solver) :
00580 base(bnd,trs), _solver(solver) {
00581 base::SetNAux(base::Dim());
00582 }
00583
00584 virtual void SetBndryAux(vec_grid_data_type& gdu, grid_data_type& gdphi, const BBox& bb,
00585 const VectorType* u, DataType* aux, const int& Level,
00586 double t, const int& nc, const int* idx,
00587 const point_type* xc, const DataType* distance,
00588 const point_type* normal) {
00589 _solver.ExtractBoundaryVelocities(gdu.bbox(),nc,xc,reinterpret_cast<point_type *>(aux));
00590 }
00591
00592 protected:
00593 amr_elc_solver& _solver;
00594 };
00595
00596
00597 #endif