Target Fluid::clone( void ) { Fluid* newcopy = new Fluid( *this ); TargetValue* NEWTHIS = new TargetValue( newcopy ); newcopy->setTHIS(NEWTHIS); return Target(NEWTHIS); }
bool computeCellState(const Grid& grid, const Fluid& fluid, typename Grid::Vector gravity, int iCell, int iRef, double wo_contact_depth, double /* go_contact_depth */, double connate_water_saturation, double residual_oil_saturation, State& simstate) { typedef typename Fluid::PhaseVec PhaseVec; const int maxCnt = 30; const double eps = 1.0e-8; simstate.cell_z_[iCell] = simstate.cell_z_[iRef]; bool below_wo_contact = false; if (grid.cellCentroid(iCell)[2] > wo_contact_depth) below_wo_contact = true; double gZ = (grid.cellCentroid(iCell) - grid.cellCentroid(iRef))*gravity; double fluid_vol_dens; int cnt =0; do { double rho = 0.5*(simstate.cell_z_[iCell]*fluid.surfaceDensities() + simstate.cell_z_[iRef]*fluid.surfaceDensities()); double press = rho*gZ + simstate.cell_pressure_[iRef][0]; simstate.cell_pressure_[iCell] = PhaseVec(press); typename Fluid::FluidState state = fluid.computeState(simstate.cell_pressure_[iCell], simstate.cell_z_[iCell]); fluid_vol_dens = state.total_phase_volume_density_; double oil_vol_dens = state.phase_volume_density_[Fluid::Liquid] + state.phase_volume_density_[Fluid::Vapour]; double wat_vol_dens = state.phase_volume_density_[Fluid::Aqua]; if (below_wo_contact) { simstate.cell_z_[iCell][Fluid::Oil] *= residual_oil_saturation/oil_vol_dens; simstate.cell_z_[iCell][Fluid::Gas] *= residual_oil_saturation/oil_vol_dens; simstate.cell_z_[iCell][Fluid::Water] *= (1.0-residual_oil_saturation)/wat_vol_dens; } else { simstate.cell_z_[iCell][Fluid::Oil] *= (1.0-connate_water_saturation)/oil_vol_dens; simstate.cell_z_[iCell][Fluid::Gas] *= (1.0-connate_water_saturation)/oil_vol_dens; simstate.cell_z_[iCell][Fluid::Water] *= connate_water_saturation/wat_vol_dens; } ++cnt; } while (std::fabs(fluid_vol_dens-1.0) > eps && cnt < maxCnt); if (cnt == maxCnt) { std::cout << "z_cell_[" << iCell << "]: " << simstate.cell_z_[iCell] << " pressure: " << simstate.cell_pressure_[iCell][Fluid::Liquid] << " cnt: " << cnt << " eps: " << std::fabs(fluid_vol_dens-1.0) << std::endl; } return (cnt < maxCnt); }
int main(){ Fluid fluid; for(int l=0;l<1000;++l){ cout << "iteration : " << l << endl; fluid.Print(); cout << "iter start : " << endl; for(int t=0;t<100;++t){ fluid.update(); } } return 0; }
int main(int argc, char** argv) { Opm::parameter::ParameterGroup param(argc, argv); Dune::MPIHelper::instance(argc,argv); // Make a grid and props. Grid grid; Rock rock; Fluid fluid; FlowSolver solver; using namespace Dune; // Initialization. std::string fileformat = param.getDefault<std::string>("fileformat", "cartesian"); if (fileformat == "eclipse") { Opm::EclipseGridParser parser(param.get<std::string>("filename")); double z_tolerance = param.getDefault<double>("z_tolerance", 0.0); bool periodic_extension = param.getDefault<bool>("periodic_extension", false); bool turn_normals = param.getDefault<bool>("turn_normals", false); grid.processEclipseFormat(parser, z_tolerance, periodic_extension, turn_normals); double perm_threshold_md = param.getDefault("perm_threshold_md", 0.0); double perm_threshold = Opm::unit::convert::from(perm_threshold_md, Opm::prefix::milli*Opm::unit::darcy); rock.init(parser, grid.globalCell(), perm_threshold); fluid.init(parser); } else if (fileformat == "cartesian") { Dune::array<int, 3> dims = {{ param.getDefault<int>("nx", 1), param.getDefault<int>("ny", 1), param.getDefault<int>("nz", 1) }}; Dune::array<double, 3> cellsz = {{ param.getDefault<double>("dx", 1.0), param.getDefault<double>("dy", 1.0), param.getDefault<double>("dz", 1.0) }}; grid.createCartesian(dims, cellsz); double default_poro = param.getDefault("default_poro", 1.0); double default_perm_md = param.getDefault("default_perm_md", 100.0); double default_perm = Opm::unit::convert::from(default_perm_md, Opm::prefix::milli*Opm::unit::darcy); MESSAGE("Warning: For generated cartesian grids, we use uniform rock properties."); rock.init(grid.size(0), default_poro, default_perm); Opm::EclipseGridParser parser(param.get<std::string>("filename")); // Need a parser for the fluids anyway. fluid.init(parser); } else { THROW("Unknown file format string: " << fileformat); } solver.init(param); double dt = param.getDefault("dt", 1.0); // Run test. test_flowsolver<3>(grid, rock, fluid, solver, dt); }
std::shared_ptr<Fluid> PhysicsLib::createFluid(FluidType fluidType, int maxParticles, float fluidStaticRestitution, float fluidStaticAdhesion, float fluidDynamicRestitution, float fluidDynamicAdhesion, float fluidDamping, float fluidStiffness, float fluidViscosity, float fluidKernelRadiusMultiplier, float fluidRestParticlesPerMeter, float fluidRestDensity, float fluidMotionLimit, int fluidPacketSizeMultiplier, int collGroup) { Fluid *fluid = 0; if(data->scene) { NxFluidDesc fluidDesc; fluidDesc.setToDefault(); fluidDesc.flags |= NX_FF_DISABLE_GRAVITY; fluidDesc.maxParticles = maxParticles; fluidDesc.kernelRadiusMultiplier = fluidKernelRadiusMultiplier; fluidDesc.restParticlesPerMeter = fluidRestParticlesPerMeter; fluidDesc.stiffness = fluidStiffness; fluidDesc.viscosity = fluidViscosity; fluidDesc.restDensity = fluidRestDensity; fluidDesc.damping = fluidDamping; fluidDesc.restitutionForStaticShapes = fluidStaticRestitution; fluidDesc.dynamicFrictionForStaticShapes = fluidStaticAdhesion; fluidDesc.restitutionForDynamicShapes = fluidDynamicRestitution; fluidDesc.dynamicFrictionForDynamicShapes = fluidDynamicAdhesion; fluidDesc.collisionGroup = collGroup; fluidDesc.packetSizeMultiplier = /*8*/ fluidPacketSizeMultiplier; // Optimize this //fluidDesc.motionLimitMultiplier = 3.f * fluidDesc.kernelRadiusMultiplier; fluidDesc.motionLimitMultiplier = fluidMotionLimit * fluidDesc.restParticlesPerMeter; if(fluidType == FLUID_TYPE_SIMPLE) fluidDesc.simulationMethod = NX_F_NO_PARTICLE_INTERACTION; else { //fluidDesc.simulationMethod = NX_F_SPH; fluidDesc.simulationMethod = NX_F_MIXED_MODE; } fluid = new Fluid(*data->scene, fluidDesc, data->runningInHardware); if(!fluid->isValid()) { delete fluid; fluid = 0; } } return std::shared_ptr<Fluid> (fluid); }
void Init() { camera.Init(SCREEN_WIDTH, SCREEN_HEIGHT); shaderManager.Init(); raycaster.Init(SCREEN_WIDTH, SCREEN_HEIGHT); fluid.Init(); rawDataSize = gridXRes * gridYRes * gridZRes * sizeof(float); buffer = new char[rawDataSize]; pixelBuffer = new char[SCREEN_WIDTH * SCREEN_HEIGHT * 4]; }
Lattice::Lattice(const Grid& grid, const Module& module, const Fluid& red, const Fluid& blue) :externalForce_(red.tau()*(grid.spaceDim()+1)*4/(module.numDirection()-1)) ,fluxForce_(0.0) ,flux_(0.0) ,gff_(std::vector<double>(module.numDirection())) ,gfs_(std::vector<double>(module.numDirection())) ,grid_(grid) ,module_(module) ,red_(red) ,blue_(blue) { }
int main() { Fluid simulation; remove( "position_data.txt" ); //InitializeParticles(); simulation.InitializeParticles(); for (int i = currentTime; i <= endTime; i = i+deltaT) { simulation.FindNeighbours(); simulation.ComputeDensity(); simulation.ComputePressure(); simulation.ComputeAllForces(i); simulation.Update(); simulation.HandleCollisions(); cout << "timestep: " << i << endl; simulation.Output(i); } cout << "End" << endl; return 0; }
// Update renderer and check for Qt events void Update() { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); camera.Update(); fluid.Update(); CopyToFile(); // glEnable(GL_DEPTH_TEST); // GLuint shaderProgramID = shaderManager.UseShader(SmokeShader); // raycaster.Raycast(shaderProgramID, camera, fluid.hostDensities, fluid.hostTemperatures); // // glutSwapBuffers(); }
void system::set_problem(const bool init) { if (myproc == 0) fprintf(stderr, " ********* Setting up Orszag-Tang vortex ************* \n"); const real b0 = 1.0/sqrt(4.0*M_PI); const real d0 = 25.0/(36.0*M_PI); const real v0 = 1.0; const real p0 = 5.0/(12*M_PI); gamma_gas = 5.0/3; courant_no = 0.8; if (!init) return; U_local.resize(local_n); dU_local.resize(local_n); Wrec_local.resize(local_n); const real adv = 0.0; double dt_min = HUGE; for (int i = 0; i < (int)local_n; i++) { const Particle &pi = ptcl_local[i]; real x = pi.pos.x; real y = pi.pos.y; real d, p, vx, vy, vz, bx, by, bz; vx = -v0 * sin(2.0*M_PI*y) + adv; vy = +v0 * sin(2.0*M_PI*x) + adv; vz = 0.0; bx = -b0*sin(2*M_PI*y); by = +b0*sin(4*M_PI*x); bz = 0.0; // bx = by = bz= 0; // bz = b0; d = d0; p = p0; real scal = 1; #ifdef __ADVECT_PULSE_TEST__ vx = 0; vy = 0; vz = 0; bx = by = bz = 0; p = 1.0; d = 1.0; // vx = 1; vy = 0; // if (x > 0.3 && x < 0.7) d = 2; vx = 0; vy = 1; if (y > 0.25 && y < 0.75) { d = 10; // p = 1; } #endif #if 0 bx = by = bz = 0; #endif Fluid m; m[Fluid::DENS] = d ; m[Fluid::ETHM] = p/(gamma_gas - 1.0); m[Fluid::VELX] = vx; m[Fluid::VELY] = vy; m[Fluid::VELZ] = vz; m[Fluid::BX ] = bx; m[Fluid::BY ] = by; m[Fluid::BZ ] = bz; m[Fluid::PSI ] = 0.0; m[Fluid::ENTR] = compute_entropy_from_ethm(m); for (int k = 0 ; k < Fluid::NSCALARS; k++) m.scal(k) = scal; Wrec_local[i] = Fluid_rec(m); U_local [i] = m.to_conservative(cell_local[i].Volume); dU_local[i] = 0.0; ptcl_local[i].volume = cell_local[i].Volume; const double L = std::pow(cell_local[i].Volume, 1.0/3); const double cs_est = std::sqrt((p*gamma_gas + (bx*bx+by*by+bz*bz))/d); const double v_est = std::sqrt(vx*vx + vy*vy + vz*vz); const double dt_est = 0.1 * courant_no * L/(cs_est + v_est); ptcl_local[i].tlast = 0.0; ptcl_local[i].rung = scheduler.get_rung(dt_est); dt_min = std::min(dt_min, dt_est); } double dt_min_glob; MPI_Allreduce(&dt_min, &dt_min_glob, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); if (myproc == 0) fprintf(stderr , " pvel ... \n"); get_active_ptcl(true); MPI_Barrier(MPI_COMM_WORLD); if (myproc == 0) fprintf(stderr , " pvel ... \n"); cell_list.swap(cell_local); ptcl_import.swap(ptcl_local); U_import.swap(U_local); site_active_list.swap(active_ptcl); compute_pvel(); compute_timesteps(true); cell_list.swap(cell_local); ptcl_import.swap(ptcl_local); U_import.swap(U_local); site_active_list.swap(active_ptcl); for (int i = 0; i < (int)local_n; i++) { ptcl_local[i].rung += 1; ptcl_local[i].orig_vel = ptcl_local[i].vel; } all_active = true; scheduler.flush_list(); for (int i = 0; i < (int)local_n; i++) { scheduler.push_particle(i, (int)ptcl_local[i].rung); ptcl_local[i].tend = 0.0 + scheduler.get_dt(ptcl_local[i].rung); } boundary_n = 0; clear_mesh(true); MPI_Barrier(MPI_COMM_WORLD); if (myproc == 0) fprintf(stderr, " proc= %d: complete problem setup \n", myproc); }
void System::Problem_generate_IC(const int param) { const real b0 = 1.0/sqrt(4.0*M_PI); const real d0 = 25.0/(36.0*M_PI); const real v0 = 1.0; const real p0 = 5.0/(12*M_PI); gamma_gas = 5.0/3; courant_no = 0.4; t_global = 0; iteration = 0; real adv = 0.0; for (int i = 0; i < local_n; i++) { const Particle &pi = ptcl_list[i]; const real x = pi.get_pos().x; const real y = pi.get_pos().y; real d, p, vx, vy, vz, bx, by, bz; vx = -v0 * sin(2.0*M_PI*y) + adv; vy = +v0 * sin(2.0*M_PI*x) + adv; vz = 0.0; bx = -b0*sin(2*M_PI*y); by = +b0*sin(4*M_PI*x); bz = 0.0; d = d0; p = p0; real scal = 1; #ifdef __ADVECT_PULSE_TEST__ vx = 0; vy = 0; vz = 0; bx = by = bz = 0; p = 1.0; d = 1.0; vx = 0; vy = 1; if (y > 0.25 && y < 0.75) { d = 10; } #endif Fluid m; m[Fluid::DENS] = d ; m[Fluid::ETHM] = p/(gamma_gas - 1.0); m[Fluid::VELX] = vx; m[Fluid::VELY] = vy; m[Fluid::VELZ] = vz; m[Fluid::BX ] = bx; m[Fluid::BY ] = by; m[Fluid::BZ ] = bz; m[Fluid::PSI ] = 0.0; m[Fluid::ENTR] = Problem_compute_entropy_from_ethm(m); for (int k = 0 ; k < Fluid::NSCALARS; k++) m.scal(k) = scal; Wrec_list[i] = Fluid_rec(m); mesh_pnts[i].idx = thisIndex*(local_n << 1)+ i + 1; mesh_pnts[i].boundary = MeshPoint::NO_BOUNDARY; } }
void SceneXMLParser::loadFluidBoundingBox(rapidxml::xml_node<>* node, Fluid& fluid) { assert(node != NULL); rapidxml::xml_node<>* nd = node->first_node("boundingbox"); if (nd) { scalar xmin, xmax, ymin, ymax, zmin, zmax; if (nd->first_attribute("xmin")) { std::string attribute(nd->first_attribute("xmin")->value()); if( !stringutils::extractFromString(attribute,xmin) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of xmin attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing xmin attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("xmax")) { std::string attribute(nd->first_attribute("xmax")->value()); if( !stringutils::extractFromString(attribute,xmax) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of xmax attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing xmax attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("ymin")) { std::string attribute(nd->first_attribute("ymin")->value()); if( !stringutils::extractFromString(attribute,ymin) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of ymin attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing ymin attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("ymax")) { std::string attribute(nd->first_attribute("ymax")->value()); if( !stringutils::extractFromString(attribute,ymax) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of ymax attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing ymax attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("zmin")) { std::string attribute(nd->first_attribute("zmin")->value()); if( !stringutils::extractFromString(attribute,zmin) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of zmin attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing zmin attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("zmax")) { std::string attribute(nd->first_attribute("zmax")->value()); if( !stringutils::extractFromString(attribute,zmax) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of zmax attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing zmax attribute for bounding box of fluid. Value must be scalar. Exiting." << std::endl; exit(1); } FluidBoundingBox* boundingbox = new FluidBoundingBox(xmin, xmax, ymin, ymax, zmin, zmax); fluid.setBoundingBox(boundingbox); } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing bounding box for fluid. Exiting." << std::endl; exit(1); } }
bool System::Problem_computePvel() { for (int i = 0; i < nactive_loc; i++) { MeshPoint &p = *mesh_act[i]; p.vel = 0.0; const Fluid W = U_act[i]->to_primitive(p.Volume); p.vel = W.get_vel(); #if 0 const real D = std::log(W[Fluid::DENS]); const real DV = std::log(DVAC); const real dD = DV * 0.01/2; const real r = (D-DV)/std::abs(dD); const real vfac = (-r > 20) ? 0.0 : 1.0/(1.0 + std::exp(-r)); assert(vfac >= 0.0); assert(vfac <= 1.0); p.vel *= vfac; #endif #if 1 const real B2 = W.get_B().norm2(); const real pres = Problem_compute_pressure(W); const real cs2 = (gamma_gas * pres + B2)/W[Fluid::DENS]; const real vel2 = W.get_vel().norm2(); const real vabs = std::sqrt(cs2 + vel2); const vec3 centroid = cell_list[i].centroid - p.pos; const real d = centroid.abs(); if (d == 0.0) continue; const real eta = 0.25f; const real ki = 1.0f; const real f1 = 0.9f; const real f2 = 1.1f; const real R = std::pow(cell_list[i].Volume * (3.0/(4.0*M_PI)), 1.0/3.0); const real fac = d/(eta*R); real f; if (fac < f1) f = 0.0; else if (fac < f2) f = (d - f1*eta*R)/((f2 - f1)*eta*R); else f = 1.0; real tau = d / vabs; f *= ki/tau; p.vel += centroid*f; if (p.is_boundary()) p.vel = 0.0; if (p.pos.abs() > RoutBND) p.vel = 0.0; #endif p.vel = p.vel - (p.vel*p.pos)*p.pos/p.pos.norm2(); // subtract radial component #if 0 p.vel = 0.0; #endif } return true; }
virtual void init(const Opm::parameter::ParameterGroup& param, const Grid& grid, const Fluid& fluid, typename Grid::Vector gravity, State& simstate) { typedef typename Fluid::CompVec CompVec; typedef typename Fluid::PhaseVec PhaseVec; if (param.getDefault("heterogenous_initial_mix", false)) { CompVec init_oil(0.0); init_oil[Fluid::Oil] = 1.0; CompVec init_water(0.0); init_water[Fluid::Water] = 1.0; simstate.cell_z_.resize(grid.numCells()); std::fill(simstate.cell_z_.begin(), simstate.cell_z_.begin() + simstate.cell_z_.size()/2, init_oil); std::fill(simstate.cell_z_.begin() + simstate.cell_z_.size()/2, simstate.cell_z_.end(), init_water); OPM_MESSAGE("******* Assuming zero capillary pressures *******"); PhaseVec init_p(100.0*Opm::unit::barsa); simstate.cell_pressure_.resize(grid.numCells(), init_p); // if (gravity.two_norm() != 0.0) { // double ref_gravpot = grid.cellCentroid(0)*gravity; // double rho = init_z*fluid_.surfaceDensities(); // Assuming incompressible, and constant initial z. // for (int cell = 1; cell < grid.numCells(); ++cell) { // double press = rho*(grid.cellCentroid(cell)*gravity - ref_gravpot) + simstate.cell_pressure_[0][0]; // simstate.cell_pressure_[cell] = PhaseVec(press); // } // } } else if (param.getDefault("unstable_initial_mix", false)) { CompVec init_oil(0.0); init_oil[Fluid::Oil] = 1.0; init_oil[Fluid::Gas] = 0.0; CompVec init_water(0.0); init_water[Fluid::Water] = 1.0; CompVec init_gas(0.0); init_gas[Fluid::Gas] = 150.0; simstate.cell_z_.resize(grid.numCells()); std::fill(simstate.cell_z_.begin(), simstate.cell_z_.begin() + simstate.cell_z_.size()/3, init_water); std::fill(simstate.cell_z_.begin() + simstate.cell_z_.size()/3, simstate.cell_z_.begin() + 2*(simstate.cell_z_.size()/3), init_oil); std::fill(simstate.cell_z_.begin() + 2*(simstate.cell_z_.size()/3), simstate.cell_z_.end(), init_gas); OPM_MESSAGE("******* Assuming zero capillary pressures *******"); PhaseVec init_p(100.0*Opm::unit::barsa); simstate.cell_pressure_.resize(grid.numCells(), init_p); if (gravity.two_norm() != 0.0) { typename Fluid::FluidState state = fluid.computeState(simstate.cell_pressure_[0], simstate.cell_z_[0]); simstate.cell_z_[0] *= 1.0/state.total_phase_volume_density_; for (int cell = 1; cell < grid.numCells(); ++cell) { double fluid_vol_dens; int cnt =0; do { double rho = 0.5*((simstate.cell_z_[cell]+simstate.cell_z_[cell-1])*fluid.surfaceDensities()); double press = rho*((grid.cellCentroid(cell) - grid.cellCentroid(cell-1))*gravity) + simstate.cell_pressure_[cell-1][0]; simstate.cell_pressure_[cell] = PhaseVec(press); state = fluid.computeState(simstate.cell_pressure_[cell], simstate.cell_z_[cell]); fluid_vol_dens = state.total_phase_volume_density_; simstate.cell_z_[cell] *= 1.0/fluid_vol_dens; ++cnt; } while (std::fabs((fluid_vol_dens-1.0)) > 1.0e-8 && cnt < 10); } } else { std::cout << "---- Exit - BlackoilSimulator.hpp: No gravity, no fun ... ----" << std::endl; exit(-1); } } else if (param.getDefault("CO2-injection", false)) { CompVec init_water(0.0); // Initially water filled (use Oil-component for water in order // to utilise blackoil mechanisms for brine-co2 interaction) init_water[Fluid::Oil] = 1.0; simstate.cell_z_.resize(grid.numCells()); std::fill(simstate.cell_z_.begin(),simstate.cell_z_.end(),init_water); double datum_pressure_barsa = param.getDefault<double>("datum_pressure", 200.0); double datum_pressure = Opm::unit::convert::from(datum_pressure_barsa, Opm::unit::barsa); PhaseVec init_p(datum_pressure); simstate.cell_pressure_.resize(grid.numCells(), init_p); // Simple initial condition based on "incompressibility"-assumption double zMin = grid.cellCentroid(0)[2]; for (int cell = 1; cell < grid.numCells(); ++cell) { if (grid.cellCentroid(cell)[2] < zMin) zMin = grid.cellCentroid(cell)[2]; } typename Fluid::FluidState state = fluid.computeState(init_p, init_water); simstate.cell_z_[0] *= 1.0/state.total_phase_volume_density_; double density = (init_water*fluid.surfaceDensities())/state.total_phase_volume_density_; for (int cell = 0; cell < grid.numCells(); ++cell) { double pressure(datum_pressure + (grid.cellCentroid(cell)[2] - zMin)*gravity[2]*density); simstate.cell_pressure_[cell] = PhaseVec(pressure); state = fluid.computeState(simstate.cell_pressure_[cell], simstate.cell_z_[cell]); simstate.cell_z_[cell] *= 1.0/state.total_phase_volume_density_; } } else { CompVec init_z(0.0); double initial_mixture_gas = param.getDefault("initial_mixture_gas", 0.0); double initial_mixture_oil = param.getDefault("initial_mixture_oil", 1.0); double initial_mixture_water = param.getDefault("initial_mixture_water", 0.0); init_z[Fluid::Water] = initial_mixture_water; init_z[Fluid::Gas] = initial_mixture_gas; init_z[Fluid::Oil] = initial_mixture_oil; simstate.cell_z_.resize(grid.numCells(), init_z); OPM_MESSAGE("******* Assuming zero capillary pressures *******"); PhaseVec init_p(param.getDefault("initial_pressure", 100.0*Opm::unit::barsa)); simstate.cell_pressure_.resize(grid.numCells(), init_p); if (gravity.two_norm() != 0.0) { double ref_gravpot = grid.cellCentroid(0)*gravity; double rho = init_z*fluid.surfaceDensities(); // Assuming incompressible, and constant initial z. for (int cell = 1; cell < grid.numCells(); ++cell) { double press = rho*(grid.cellCentroid(cell)*gravity - ref_gravpot) + simstate.cell_pressure_[0][0]; simstate.cell_pressure_[cell] = PhaseVec(press); } } } }
virtual void init(const Opm::parameter::ParameterGroup& param, const Grid& grid, const Fluid& fluid, typename Grid::Vector gravity, State& simstate) { typedef typename Fluid::CompVec CompVec; double zeroDepth = param.getDefault("zero_depth", 2743.2); int nx = param.getDefault<int>("nx", 24); int ny = param.getDefault<int>("ny", 25); int nz = param.getDefault<int>("nz", 15); // double datum_depth = param.getDefault<double>("datum_depth", 2753.87) - zeroDepth; double datum_pressure_barsa = param.getDefault<double>("datum_pressure", 248.22); double datum_pressure = Opm::unit::convert::from(datum_pressure_barsa, Opm::unit::barsa); double wo_contact_depth = param.getDefault<double>("wo_contact_depth", 3032.76) - zeroDepth; double go_contact_depth = param.getDefault<double>("go_contact_depth", 2682.24) - zeroDepth; double connate_water_saturation = param.getDefault<double>("connate_water_saturation", 0.151090); double residual_oil_saturation = param.getDefault<double>("residual_oil_saturation", 0.118510); double initial_mixture_gas = param.getDefault("initial_mixture_gas", 247.43); double initial_mixture_oil = param.getDefault("initial_mixture_oil", 1.0); // Initial fluid state CompVec oil_sample(0.0); oil_sample[Fluid::Oil] = initial_mixture_oil; oil_sample[Fluid::Gas] = initial_mixture_gas; CompVec water_sample(0.0); water_sample[Fluid::Water] = 1.0; simstate.cell_z_.resize(grid.numCells()); simstate.cell_pressure_.resize(grid.numCells()); // Datum -cell // For now, assume that datum_depth corresponds the centroid of cell 0 (reasonable approx) simstate.cell_pressure_[0] = datum_pressure; typename Fluid::FluidState state = fluid.computeState(simstate.cell_pressure_[0],oil_sample); simstate.cell_z_[0] = oil_sample; simstate.cell_z_[0] *= (1.0-connate_water_saturation)/state.total_phase_volume_density_; state = fluid.computeState(simstate.cell_pressure_[0],water_sample); simstate.cell_z_[0][Fluid::Water] = water_sample[Fluid::Water]; simstate.cell_z_[0][Fluid::Water] *= connate_water_saturation/state.total_phase_volume_density_; // Rest of the cells -- NOTE: Assume uniform cell properties in y-direction for (int i=0; i<nx; ++i) { int k0=i*nz; for (int k=0; k<nz; ++k) { int kk=k0+k; if (i>0 && k==0) { computeCellState(grid, fluid, gravity, kk, kk-nz, wo_contact_depth, go_contact_depth, connate_water_saturation, residual_oil_saturation, simstate); } else if (k>0) { computeCellState(grid, fluid, gravity, kk, kk-1, wo_contact_depth, go_contact_depth, connate_water_saturation, residual_oil_saturation, simstate); } // Copy cell properties to y-layers for (int j=1; j<ny; ++j) { int jj = j*nx*nz + kk; simstate.cell_z_[jj] = simstate.cell_z_[kk]; simstate.cell_pressure_[jj] = simstate.cell_pressure_[kk]; } } } }
void SceneXMLParser::loadFluidVolumes(rapidxml::xml_node<>* node, Fluid& fluid) { assert(node != NULL); int volumenum = 0; for (rapidxml::xml_node<>* nd = node->first_node("fluidvolume"); nd; nd = nd->next_sibling("fluidvolume")) { scalar xmin, xmax, ymin, ymax, zmin, zmax; scalar r = 0.317, g = 0.639, b = 1.0, a = 0.5; int numparticles = 100; fluid_volume_mode_t mode; bool random; scalar spacing; bool particle_selected = false; bool spacing_selected = false; if (nd->first_attribute("xmin")) { std::string attribute(nd->first_attribute("xmin")->value()); if( !stringutils::extractFromString(attribute,xmin) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of xmin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing xmin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("xmax")) { std::string attribute(nd->first_attribute("xmax")->value()); if( !stringutils::extractFromString(attribute,xmax) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of xmax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing xmax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("ymin")) { std::string attribute(nd->first_attribute("ymin")->value()); if( !stringutils::extractFromString(attribute,ymin) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of ymin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing ymin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("ymax")) { std::string attribute(nd->first_attribute("ymax")->value()); if( !stringutils::extractFromString(attribute,ymax) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of ymax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing ymax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("zmin")) { std::string attribute(nd->first_attribute("zmin")->value()); if( !stringutils::extractFromString(attribute,zmin) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of zmin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing zmin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("zmax")) { std::string attribute(nd->first_attribute("zmax")->value()); if( !stringutils::extractFromString(attribute,zmax) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of zmax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing zmax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("numparticles")) { std::string attribute(nd->first_attribute("numparticles")->value()); if( !stringutils::extractFromString(attribute,numparticles) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of numparticles attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } particle_selected = true; } if (nd->first_attribute("spacing")) { std::string attribute(nd->first_attribute("spacing")->value()); if( !stringutils::extractFromString(attribute,spacing) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of spacing attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } spacing_selected = true; } if (!particle_selected && !spacing_selected) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing either spacing or numparticles attribute for fluid volume. Values must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("mode")) { std::string mode_string(nd->first_attribute("mode")->value()); if( mode_string != "box" && mode_string != "sphere" ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of mode attribute for fluid volume. Value must be either box or sphere. Exiting." << std::endl; exit(1); } if (mode_string == "box") { mode = kFLUID_VOLUME_MODE_BOX; } else if (mode_string == "sphere") { mode = kFLUID_VOLUME_MODE_SPHERE; } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing mode attribute for fluid volume. Value must be either box or sphere. Exiting." << std::endl; exit(1); } if (nd->first_attribute("random")) { std::string attribute(nd->first_attribute("random")->value()); if( !stringutils::extractBoolFromString(attribute,random) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of random attribute for fluid volume. Value must be boolean. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing random attribute for fluid volume. Value must be boolean. Exiting." << std::endl; exit(1); } if (nd->first_attribute("r")) { std::string attribute(nd->first_attribute("r")->value()); if( !stringutils::extractFromString(attribute,r) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of r attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (r < 0 || r > 1) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of r attribute for fluid volume. Value must be between 0 and 1. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "Missing r attribute for fluid volume. Using default values." << std::endl; } if (nd->first_attribute("g")) { std::string attribute(nd->first_attribute("g")->value()); if( !stringutils::extractFromString(attribute,g) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of g attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (g < 0 || g > 1) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of g attribute for fluid volume. Value must be between 0 and 1. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "Missing g attribute for fluid volume. Using default values." << std::endl; } if (nd->first_attribute("b")) { std::string attribute(nd->first_attribute("b")->value()); if( !stringutils::extractFromString(attribute,b) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of b attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (b < 0 || b > 1) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of b attribute for fluid volume. Value must be between 0 and 1. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "Missing b attribute for fluid volume. Using default values." << std::endl; } if (nd->first_attribute("a")) { std::string attribute(nd->first_attribute("a")->value()); if( !stringutils::extractFromString(attribute,a) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of a attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (a < 0 || a > 1) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of a attribute for fluid volume. Value must be between 0 and 1. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "Missing a attribute for fluid volume. Using default values." << std::endl; } FluidVolume volume(xmin, xmax, ymin, ymax, zmin, zmax, numparticles, mode, random, r, g, b, a); if (spacing_selected) { volume.setSpacing(spacing); } fluid.insertFluidVolume(volume); volumenum++; } if (volumenum == 0) { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "No fluid volumes in fluid." << std::endl; } }
void test_flowsolver(const Grid& grid, const Rock& rock, const Fluid& fluid, FlowSolver& solver, const double dt) { // Boundary conditions. typedef Dune::FlowBC BC; typedef Dune::BasicBoundaryConditions<true, false> FBC; FBC flow_bc(7); flow_bc.flowCond(1) = BC(BC::Dirichlet, 300.0*Opm::unit::barsa); flow_bc.flowCond(2) = BC(BC::Dirichlet, 100.0*Opm::unit::barsa); // Gravity. typename Grid::Vector gravity(0.0); // gravity[2] = Dune::unit::gravity; Opm::Wells wells; // Flow solver setup. solver.setup(grid, rock, fluid, wells, gravity, flow_bc); // Source terms. std::vector<double> src(grid.numCells(), 0.0); // if (g.numberOfCells() > 1) { // src[0] = 1.0; // src.back() = -1.0; // } int num_cells = grid.numCells(); int num_faces = grid.numFaces(); // Initial state. typedef typename Fluid::CompVec CompVec; typedef typename Fluid::PhaseVec PhaseVec; CompVec init_z(0.0); init_z[Fluid::Oil] = 1.0; std::vector<CompVec> z(grid.numCells(), init_z); MESSAGE("******* Assuming zero capillary pressures *******"); PhaseVec init_p(100.0*Opm::unit::barsa); std::vector<PhaseVec> cell_pressure(grid.numCells(), init_p); // Rescale z values so that pore volume is filled exactly // (to get zero initial volume discrepancy). for (int cell = 0; cell < grid.numCells(); ++cell) { typename Fluid::FluidState state = fluid.computeState(cell_pressure[cell], z[cell]); double fluid_vol = state.total_phase_volume_density_; z[cell] *= 1.0/fluid_vol; } std::vector<PhaseVec> face_pressure(num_faces); for (int face = 0; face < num_faces; ++face) { int bid = grid.boundaryId(face); if (flow_bc.flowCond(bid).isDirichlet()) { face_pressure[face] = flow_bc.flowCond(bid).pressure(); } else { int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; face_pressure[face] = 0.0; int num = 0; for (int j = 0; j < 2; ++j) { if (c[j] >= 0) { face_pressure[face] += cell_pressure[c[j]]; ++num; } } face_pressure[face] /= double(num); } } std::vector<double> face_flux, well_bhp_pressure, well_perf_pressure, well_flux; // Solve flow system. solver.solve(cell_pressure, face_pressure, z, face_flux, well_bhp_pressure, well_perf_pressure, well_flux, src, dt); // Output to VTK. std::vector<typename Grid::Vector> cell_velocity; estimateCellVelocitySimpleInterface(cell_velocity, grid, face_flux); // Dune's vtk writer wants multi-component data to be flattened. std::vector<double> cell_pressure_flat(&*cell_pressure.front().begin(), &*cell_pressure.back().end()); std::vector<double> cell_velocity_flat(&*cell_velocity.front().begin(), &*cell_velocity.back().end()); Dune::VTKWriter<typename Grid::LeafGridView> vtkwriter(grid.leafView()); vtkwriter.addCellData(cell_pressure_flat, "pressure", Fluid::numPhases); vtkwriter.addCellData(cell_velocity_flat, "velocity", Grid::dimension); vtkwriter.write("testsolution", Dune::VTKOptions::ascii); // Dump data for Matlab. std::ofstream dump("celldump"); dump.precision(15); std::vector<double> liq_press(num_cells); for (int cell = 0; cell < num_cells; ++cell) { liq_press[cell] = cell_pressure[cell][Fluid::Liquid]; } std::copy(liq_press.begin(), liq_press.end(), std::ostream_iterator<double>(dump, " ")); dump << '\n'; }
double call(double rho) { return this->p - pFluid->pressure_Trho(T,rho); }