Пример #1
0
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);
        }
Пример #3
0
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);
}
Пример #5
0
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];
}
Пример #7
0
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)
{

}
Пример #8
0
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();

}
Пример #10
0
  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);
  }
Пример #11
0
  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;
      
    }
  }
Пример #12
0
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);
    }
}
Пример #13
0
  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];
                    }
                }                
            }
        }
Пример #16
0
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';
}
Пример #18
0
	double call(double rho)
	{
		return this->p - pFluid->pressure_Trho(T,rho);
	}