Ejemplo n.º 1
0
void MucContact::changeAffiliation( ResourceContextRef rc, Affiliation newAffiliation ) {
    BOOST_ASSERT(newAffiliation<=OWNER);

    JabberDataBlockRef item=JabberDataBlockRef(new JabberDataBlock("item"));
    Jid rj(realJid);
    item->setAttribute("jid",rj.getBareJid());
    item->setAttribute("affiliation",affiliationName[newAffiliation-OUTCAST]);
    //todo:    
    //  if (!reason.empty) item->addChild("reason", reason);

    changeMucItem(rc, item);
}
Ejemplo n.º 2
0
double LCOrbits::ArmVelocity(int em, int rec, double trec)
{
	LCVector ri(MT), rj(MT), vi(MT), vj(MT), rij(MT), nij(MT), n(MT);	
	
	ri = position(rec, trec);
	vi = velocity(rec, trec);
	
	rj = position(em, trec);
	vj = velocity(em, trec);
	
	rij = rj-ri;
	nij = rij.unit();
	n   = nij * (-1.);
	
	return(vj*n-vi*n);	
}
void
TestJoinNode() {
    tbb::flow::graph g;

    TestSimpleSuccessorArc<tbb::flow::queueing>("queueing");
    TestSimpleSuccessorArc<tbb::flow::reserving>("reserving");
    TestSimpleSuccessorArc<tbb::flow::tag_matching>("tag_matching");

    // queueing and tagging join nodes have input queues, so the input ports do not reverse.
    REMARK(" reserving preds");
    {
        tbb::flow::join_node<tbb::flow::tuple<int,int>, tbb::flow::reserving> rj(g);
        tbb::flow::queue_node<int> q0(g);
        tbb::flow::queue_node<int> q1(g);
        tbb::flow::make_edge(q0,tbb::flow::input_port<0>(rj));
        tbb::flow::make_edge(q1,tbb::flow::input_port<1>(rj));
        q0.try_put(1);
        g.wait_for_all();  // quiesce
        ASSERT(!(tbb::flow::input_port<0>(rj).my_predecessors.empty()),"reversed port missing predecessor");
        ASSERT((tbb::flow::input_port<1>(rj).my_predecessors.empty()),"non-reversed port has pred");
        g.reset();
        ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"reversed port has pred after reset()");
        ASSERT((tbb::flow::input_port<1>(rj).my_predecessors.empty()),"non-reversed port has pred after reset()");
        q1.try_put(2);
        g.wait_for_all();  // quiesce
        ASSERT(!(tbb::flow::input_port<1>(rj).my_predecessors.empty()),"reversed port missing predecessor");
        ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"non-reversed port has pred");
        g.reset();
        ASSERT((tbb::flow::input_port<1>(rj).my_predecessors.empty()),"reversed port has pred after reset()");
        ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"non-reversed port has pred after reset()");
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
        // should reset predecessors just as regular reset.
        q1.try_put(3);
        g.wait_for_all();  // quiesce
        ASSERT(!(tbb::flow::input_port<1>(rj).my_predecessors.empty()),"reversed port missing predecessor");
        ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"non-reversed port has pred");
        g.reset(tbb::flow::rf_extract);
        ASSERT((tbb::flow::input_port<1>(rj).my_predecessors.empty()),"reversed port has pred after reset()");
        ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"non-reversed port has pred after reset()");
        ASSERT(q0.my_successors.empty(), "edge not removed by reset(rf_extract)");
        ASSERT(q1.my_successors.empty(), "edge not removed by reset(rf_extract)");
#endif
    }
    REMARK(" done\n");
}
Ejemplo n.º 4
0
	BOOST_GPU_ENABLED
	void operator()(const A &a, B &b, boost::mpl::vector_c<int,1,0>,
			const G &g, const TB &tb, size_t ni, size_t nj) {
	    BOOST_STATIC_ASSERT(A::dimensionality == 2);
	    BOOST_STATIC_ASSERT(B::dimensionality == 2);
	    const int Ni = ni/N + (ni%N > 0);
	    const int Nj = nj/N + (nj%N > 0);

	    for (int j = g.y(); j < Nj; j += g.ny()) {
		range rj(j*N, min<int>((j+1)*N,nj));
		for (int i = g.x(); i < Ni; i += g.nx()) {
		    range ri(i*N, min<int>((i+1)*N,ni));
		    tile<typename B::element,N> bij;
		    bij.load(ri, rj, a, tb);
		    bij.transpose(rj, ri, b, tb);
		}
	    }
	}
Ejemplo n.º 5
0
	BOOST_GPU_ENABLED
	void operator()(A &a, boost::mpl::vector_c<int,1,0>,
			const G &g, const TB &b, size_t n) {
	    BOOST_STATIC_ASSERT(A::dimensionality == 2);
	    typedef typename A::element T;
	    const int nB = n/B + (n%B > 0);

	    for (int j = g.y(); j < nB; j += g.ny()) {
		range rj(j*B, min<int>((j+1)*B,n));
		for (int i = g.x(); i <= j; i += g.nx()) {
		    range ri(i*B, min<int>((i+1)*B,n));
		    tile<T,B> aij, aji;
		    aij.load(ri, rj, a, b);
		    aji.load(rj, ri, a, b);
		    aij.transpose(rj, ri, a, b);
		    if (i == j) continue;
		    aji.transpose(ri, rj, a, b);
		}
	    }
	}
Ejemplo n.º 6
0
int main()
{
    FILE *fin = fopen("packrec.in", "r");
    FILE *fout = fopen("packrec.out", "w");
    int i, j, k, l, p, index;
    int min = 0x7fff;
    index = 0;
    struct rec in[4], out[100];
    
    for(i = 0; i < 4; i++)
        fscanf(fin, "%d %d", &in[i].side[0], &in[i].side[1]);
    
    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++){
            if(i == j)
                continue;
            for(k = 0; k < 4; k++){
                if(k == i || k == j)
                    continue;
                l = 6 - i - j - k;
                for(p = 0; p < 16; p++){
                    int h1, w1, h2, w2, h3, w3, h4, w4;
                    h1 = in[i].side[1 - (ri(p))];
                    w1 = in[i].side[ri(p)];
                    h2 = in[j].side[1 - (rj(p))];
                    w2 = in[j].side[rj(p)];
                    h3 = in[k].side[1 - (rk(p))];
                    w3 = in[k].side[rk(p)];
                    h4 = in[l].side[1 - (rl(p))];
                    w4 = in[l].side[rl(p)];
                    
                    int win, hin;
                    win = w1 + w2 + w3 + w4;
                    hin = max4(h1, h2, h3, h4);
                    store(out, &index, win, hin, &min); 

                    win = max2(w1+w2+w3, w4);
                    hin = max3(h1, h2, h3)+h4;
                    store(out, &index, win, hin, &min);
                    
                    win = max2(w1+w2, w3)+w4;
                    hin = max3(h1+h3, h2+h3, h4);
                    store(out, &index, win, hin, &min);
                    
                    win = w1+w4+max2(w2, w3);
                    hin = max3(h1, h2+h3, h4);
                    store(out, &index, win, hin, &min);
                    
                    if(h3 >= h2+h4)
                        win = max3(w1, w2+w3, w3+w4);
                    else if(h3 > h4 && h3 < h2+h4)
                        win = max3(w1+w2, w2+w3, w3+w4);
                    else if(h3 < h4 && h2+h4 <= h1+h3)
                        win = max3(w1+w2, w1+w4, w3+w4);
                    else if(h4 >= h1+h3)
                        win = max3(w2, w1+w4, w3+w4);
                    else if(h3 == h4)
                        win = max2(w1+w2, w3+w4);
                    hin = max2(h1+h3, h2+h4);
                    store(out, &index, win, hin, &min);
                }
            }
        }
    }
    
    insertionSort(out, index);
    fprintf(fout, "%d\n", min);
    for(i = 0; i < index; i++){
        if(i != 0 && out[i].side[0] == out[i-1].side[0])
            continue;
        fprintf(fout, "%d %d\n", out[i].side[0], out[i].side[1]);
    }
    
    fclose(fin);
    fclose(fout);
}
Ejemplo n.º 7
0
double LCOrbits::ArmCompute(int em, int rec, double trec)
{
	double tA(0.), tij;
	
	if ((em<1)||(em>NARMMAX)||((rec<1)&&(rec>NARMMAX))){
		std::cerr << "ERROR in LCOrbits::ArmCompute : Spacecraft number must be in [0," << NARMMAX << "]  ! " << Endl;
		throw std::invalid_argument ("ERROR in LCOrbits::ArmCompute : Spacecraft number must be in [0,NARMMAX]  ! ");
	}
	/*
	if(OrderArm != -10)
		OrderArm = order_default;
	if ((OrderArm<-2)||(OrderArm>2))
		throw std::invalid_argument ("ERROR in LCOrbits::ArmCompute : Order must be 0 (for 0), 1 (for 1/2), 2 (for 1) or -1 (for analytical MLDC eccentric formulation)");
	 */
	
	if(OrderArm >= 0){
		LCVector ri(MT), rj(MT), vi(MT), vj(MT), rij(MT), nij(MT), n(MT);
		
		/*! **** Read positions and velocities and compute related quantities
		 *	Index i refers to receiver and j to emitter
		 *  \f{eqnarray*}{
		 *	\vec{r}_{ij} & = & \vec{r}_j - \vec{r}_i = \vec{r}_{em} - \vec{r}_{rec}  \\
		 *	\vec{n}_{ij} & = & \vec{r}_{ij} / | \vec{r}_{ij} | \\
		 *	\hat{n}  & = & - \vec{n}_{ij} \\
		 *	t_{ij}   & = & - | \vec{r}_{ij} | / c = - | \vec{r}_{em} - \vec{r}_{rec} | / c
		 *  \f}
		 */ 
		
		ri = position(rec, trec);
		vi = velocity(rec, trec);
		vi = vi/LC::c_SI;
		
		rj = position(em, trec);
		vj = velocity(em, trec);
		vj = vj/LC::c_SI;
		
		/*
		ri.p[0] = 5.e9;
		ri.p[1] = 0.;
		ri.p[2] = 0.;
		rj.p[0] = -1.e-5;
		rj.p[1] = 0.;
		rj.p[2] = 0.;
		rij = rj-ri;
		*/
		
		 
		rij = rj-ri;
		nij = rij.unit();
		n = nij*(-1.);
		
		tij = rij.norm()/LC::c_SI;
		tij = -tij;  
		
		/*
		MT->o->precision(16);
		Cout << "em = " << em << "  -> rec = " << rec << " : " << rij.norm() << " ==> " << tij << Endl;
		for(int i=0; i<3; i++)
			Cout << "\t\t" << ri.p[i] << "\t\t" << rj.p[i] << "\t\t" << rij.p[i] << Endl;   
		*/
		 
		if (OrderArm>=0)
			tA += ArmOrderContrib(0, tij, ri, rj, vi, vj, rij, nij, n);
		
		if (OrderArm>=1)
			tA += ArmOrderContrib(1, tij, ri, rj, vi, vj, rij, nij, n);
		
		if (OrderArm>=2)
			tA += ArmOrderContrib(2, tij, ri, rj, vi, vj, rij, nij, n);
		
		return (tA);
			
	}else{
		return( ArmSpecific(em, rec, trec) );
	}
}
Ejemplo n.º 8
0
      /* Compute the value of satellite antenna phase correction, in meters.
       * @param satid     Satellite ID
       * @param time      Epoch of interest
       * @param satpos    Satellite position, as a Triple
       * @param sunpos    Sun position, as a Triple
       *
       * @return Satellite antenna phase correction, in meters.
       */
   double ComputeSatPCenter::getSatPCenter( const SatID& satid,
                                            const DayTime& time,
                                            const Triple& satpos,
                                            const Triple& sunPosition )
   {

         // Unitary vector from satellite to Earth mass center (ECEF)
      Triple rk( ( (-1.0)*(satpos.unitVector()) ) );

         // Unitary vector from Earth mass center to Sun (ECEF)
      Triple ri( sunPosition.unitVector() );

         // rj = rk x ri: Rotation axis of solar panels (ECEF)
      Triple rj(rk.cross(ri));

         // Redefine ri: ri = rj x rk (ECEF)
      ri = rj.cross(rk);

         // Let's convert ri to an unitary vector. (ECEF)
      ri = ri.unitVector();

         // Get vector from Earth mass center to receiver
      Triple rxPos(nominalPos.X(), nominalPos.Y(), nominalPos.Z());

         // Compute unitary vector vector from satellite to RECEIVER
      Triple rrho( (rxPos-satpos).unitVector() );

         // When not using Antex information, if satellite belongs to block
         // "IIR" its correction is 0.0, else it will depend on satellite model.

         // This variable that will hold the correction, 0.0 by default
      double svPCcorr(0.0);

         // Check is Antex antenna information is available or not, and if
         // available, whether satellite phase center information is absolute
         // or relative
      bool absoluteModel( false );
      if( pAntexReader != NULL )
      {
         absoluteModel = pAntexReader->isAbsolute();
      }

      if( absoluteModel )
      {

            // We will need the elevation, in degrees. It is found using
            // dot product and the corresponding unitary angles
         double elev( 90.0 - (std::acos( rrho.dot(rk) ) * RAD_TO_DEG) );

            // Get satellite information in Antex format. Currently this
            // only works for GPS and Glonass.
         if( satid.system == SatID::systemGPS )
         {
            std::stringstream sat;
            sat << "G";
            if( satid.id < 10 )
            {
               sat << "0";
            }
            sat << satid.id;

               // Get satellite antenna information out of AntexReader object
            Antenna antenna( pAntexReader->getAntenna( sat.str(), time ) );

               // Get antenna eccentricity for frequency "G01" (L1), in
               // satellite reference system.
               // NOTE: It is NOT in ECEF, it is in UEN!!!
            Triple satAnt( antenna.getAntennaEccentricity( Antenna::G01) );

               // Now, get the phase center variation.
            Triple var( antenna.getAntennaPCVariation( Antenna::G01, elev) );

               // We must substract them
            satAnt = satAnt - var;

                  // Change to ECEF
            Triple svAntenna( satAnt[2]*ri + satAnt[1]*rj + satAnt[0]*rk );

               // Projection of "svAntenna" vector to line of sight vector rrho
            svPCcorr =  (rrho.dot(svAntenna));

         }
         else
         {
               // Check if this satellite belongs to Glonass system
            if( satid.system == SatID::systemGlonass )
            {
               std::stringstream sat;
               sat << "R";
               if( satid.id < 10 )
               {
                  sat << "0";
               }
               sat << satid.id;

                  // Get satellite antenna information out of AntexReader object
               Antenna antenna( pAntexReader->getAntenna( sat.str(), time ) );

                  // Get antenna offset for frequency "R01" (Glonass), in
                  // satellite reference system.
                  // NOTE: It is NOT in ECEF, it is in UEN!!!
               Triple satAnt( antenna.getAntennaEccentricity( Antenna::R01) );

                  // Now, get the phase center variation.
               Triple var( antenna.getAntennaPCVariation( Antenna::R01, elev) );

                  // We must substract them
               satAnt = satAnt - var;

                     // Change to ECEF
               Triple svAntenna( satAnt[2]*ri + satAnt[1]*rj + satAnt[0]*rk );

                  // Project "svAntenna" vector to line of sight vector rrho
               svPCcorr = (rrho.dot(svAntenna));

            }
            else
            {
                  // In this case no correction will be computed
               svPCcorr = 0.0;
            }

         }  // End of 'if( satid.system == SatID::systemGPS )...'

      }
      else
      {
            // If no Antex information is given, or if phase center information
            // uses a relative model, then use a simpler, older approach

            // Please note that in this case all GLONASS satellite are
            // considered as having phase center at (0.0, 0.0, 0.0). The former
            // is not true for 'GLONASS-M' satellites (-0.545, 0.0, 0.0 ), but
            // currently there is no simple way to take this into account.

            // For satellites II and IIA:
         if( (satData.getBlock( satid, time ) == "II") ||
             (satData.getBlock( satid, time ) == "IIA") )
         {

               // First, build satellite antenna vector for models II/IIA
            Triple svAntenna(0.279*ri + 1.023*rk);

               // Projection of "svAntenna" vector to line of sight vector rrho
            svPCcorr =  (rrho.dot(svAntenna));

         }
         else
         {
               // For satellites belonging to block "I"
            if( (satData.getBlock( satid, time ) == "I") )
            {

                  // First, build satellite antenna vector for model I
               Triple svAntenna(0.210*ri + 0.854*rk);

                  // Projection of "svAntenna" to line of sight vector (rrho)
               svPCcorr =  (rrho.dot(svAntenna));
            }

         }  // End of 'if( (satData.getBlock( satid, time ) == "II") ||...'

      }  // End of 'if( absoluteModel )...'


         // This correction is interpreted as an "advance" in the signal,
         // instead of a delay. Therefore, it has negative sign
      return (-svPCcorr);

   }  // End of method 'ComputeSatPCenter::getSatPCenter()'
Ejemplo n.º 9
0
int main(int argc, char** argv)
try
{
    if (argc == 1) {
        std::cout << "Usage: cpchop gridfilename=filename.grdecl [subsamples=10] [ilen=5] [jlen=5] " << std::endl;
        std::cout << "       [zlen=5] [imin=] [imax=] [jmin=] [jmax=] [upscale=true] [bc=fixed]" << std::endl;
        std::cout << "       [resettoorigin=true] [seed=111] [z_tolerance=0.0] [minperm=1e-9] " << std::endl;
        std::cout << "       [dips=false] [azimuthdisplacement=] [satnumvolumes=false] [mincellvolume=1e-9]" << std::endl;
        std::cout << "       [filebase=] [resultfile=] [endpoints=false] [cappres=false]" << std::endl;
        std::cout << "       [rock_list=] [anisotropicrocks=false]" << std::endl;
        exit(1);
    }
    Opm::parameter::ParameterGroup param(argc, argv);
    std::string gridfilename = param.get<std::string>("gridfilename");
    Opm::CornerPointChopper ch(gridfilename);

    // The cells with i coordinate in [imin, imax) are included, similar for j.
    // The z limits may be changed inside the chopper to match actual min/max z.
    const int* dims = ch.dimensions();
    int imin = param.getDefault("imin", 0);
    int imax = param.getDefault("imax", dims[0]);
    int jmin = param.getDefault("jmin", 0);
    int jmax = param.getDefault("jmax", dims[1]);
    double zmin = param.getDefault("zmin", ch.zLimits().first);
    double zmax = param.getDefault("zmax", ch.zLimits().second);
    int subsamples = param.getDefault("subsamples", 1);
    int ilen = param.getDefault("ilen", imax - imin);
    int jlen = param.getDefault("jlen", jmax - jmin);
    double zlen = param.getDefault("zlen", zmax - zmin);
    bool upscale = param.getDefault("upscale", true);
    std::string bc = param.getDefault<std::string>("bc", "fixed");
    bool resettoorigin = param.getDefault("resettoorigin", true);
    boost::mt19937::result_type userseed = param.getDefault("seed", 0);

    int outputprecision = param.getDefault("outputprecision", 8);
    std::string filebase = param.getDefault<std::string>("filebase", "");
    std::string resultfile = param.getDefault<std::string>("resultfile", "");

    double minperm = param.getDefault("minperm", 1e-9);
    double minpermSI = Opm::unit::convert::from(minperm, Opm::prefix::milli*Opm::unit::darcy);

    // Following two options are for dip upscaling (slope of cell top and bottom edges)
    bool dips = param.getDefault("dips", false);  // whether to do dip averaging
    double azimuthdisplacement = param.getDefault("azimuthdisplacement", 0.0);  // posibility to add/subtract a value to/from azimuth for dip plane.
    double mincellvolume = param.getDefault("mincellvolume", 1e-9); // ignore smaller cells for dip calculations

    bool satnumvolumes = param.getDefault("satnumvolumes", false); // whether to count volumes pr. satnum

    // upscaling of endpoints and capillary pressure
    // Conversion factor, multiply mD numbers with this to get m² numbers
    const double milliDarcyToSqMetre = 9.869233e-16;
    // Input for surfaceTension is dynes/cm, SI units are Joules/square metre
    const double surfaceTension = param.getDefault("surfaceTension", 11.0) * 1e-3; // multiply with 10^-3 to obtain SI units

    bool endpoints = param.getDefault("endpoints", false); // whether to upscale saturation endpoints
    bool cappres = param.getDefault("cappres", false); // whether to upscale capillary pressure
    if (cappres) {
        endpoints = true;
    }
    std::string rock_list = param.getDefault<std::string>("rock_list", "no_list");
    bool anisorocks = param.getDefault("anisotropicrocks", false);
    std::vector<std::vector<double> > rocksatendpoints_;
    std::vector<std::vector<double> > jfuncendpoints_; // Used if isotropic rock input
    int nsatpoints = 5; // nuber of saturation points in upscaled capillary pressure function per subsample
    double saturationThreshold = 0.00001;

    // For isotropic input rocks:
    std::vector<Opm::MonotCubicInterpolator> InvJfunctions; // Holds the inverse of the loaded J-functions.
    // For anisotropic input rocks:
    std::vector<Opm::MonotCubicInterpolator> SwPcfunctions; // Holds Sw(Pc) for each rocktype.

    // Read rock data from files specifyed in rock_list
    if (endpoints) {
        if (!rock_list.compare("no_list")) {
            std::cout << "Can't do endponts without rock list (" << rock_list << ")" << std::endl;
            throw std::exception();
        }
        // Code copied from ReservoirPropertyCommon.hpp for file reading
        std::ifstream rl(rock_list.c_str());
        if (!rl) {
            OPM_THROW(std::runtime_error, "Could not open file " << rock_list);
        }
        int num_rocks = -1;
        rl >> num_rocks;
        assert(num_rocks >= 1);
        rocksatendpoints_.resize(num_rocks);
        jfuncendpoints_.resize(num_rocks);
        // Loop through rock files defined in rock_list and store the data we need
        for (int i = 0; i < num_rocks; ++i) {
            std::string spec;
            while (spec.empty()) {
                std::getline(rl, spec);
            }
            // Read the contents of the i'th rock
            std::istringstream specstream(spec);
            std::string rockname;
            specstream >> rockname;
            std::string rockfilename = rockname;

            std::ifstream rock_stream(rockfilename.c_str());
            if (!rock_stream) {
                OPM_THROW(std::runtime_error, "Could not open file " << rockfilename);
            }

            if (! anisorocks) { //Isotropic input rocks (Sw Krw Kro J)
                Opm::MonotCubicInterpolator Jtmp;
                try {
                    Jtmp = Opm::MonotCubicInterpolator(rockname, 1, 4);
                }
                catch (const char * errormessage) {
                    std::cerr << "Error: " << errormessage << std::endl;
                    std::cerr << "Check filename" << std::endl;
                    exit(1);
                }

                // Invert J-function, now we get saturation as a function of pressure:
                if (Jtmp.isStrictlyMonotone()) {
                    InvJfunctions.push_back(Opm::MonotCubicInterpolator(Jtmp.get_fVector(), Jtmp.get_xVector()));
                }
                else {
                    std::cerr << "Error: Jfunction " << i+1 << " in rock file " << rockname << " was not invertible." << std::endl;
                    exit(1);
                }

                jfuncendpoints_[i][0] = Jtmp.getMinimumX().second;
                jfuncendpoints_[i][1] = Jtmp.getMaximumX().second;
                rocksatendpoints_[i][0] = Jtmp.getMinimumX().first;
                rocksatendpoints_[i][1] = Jtmp.getMaximumX().first;
                if (rocksatendpoints_[i][0] < 0 || rocksatendpoints_[i][0] > 1) {
                    OPM_THROW(std::runtime_error, "Minimum rock saturation (" << rocksatendpoints_[i][0] << ") not sane for rock "
                              << rockfilename << "." << std::endl << "Did you forget to specify anisotropicrocks=true ?");
                }
            }
            else { //Anisotropic input rocks (Pc Sw Krxx Kryy Krzz)
                Opm::MonotCubicInterpolator Pctmp;
                try {
                    Pctmp = Opm::MonotCubicInterpolator(rockname, 2, 1);
                }
                catch (const char * errormessage) {
                    std::cerr << "Error: " << errormessage << std::endl;
                    std::cerr << "Check filename and columns 1 and 2 (Pc and Sw)" << std::endl;
                    exit(1);
                }
                if (cappres) {
                    // Invert Pc(Sw) curve into Sw(Pc):
                    if (Pctmp.isStrictlyMonotone()) {
                        SwPcfunctions.push_back(Opm::MonotCubicInterpolator(Pctmp.get_fVector(), Pctmp.get_xVector()));
                    }
                    else {
                        std::cerr << "Error: Pc(Sw) curve " << i+1 << " in rock file " << rockname << " was not invertible." << std::endl;
                        exit(1);
                    }
                }
                rocksatendpoints_[i][0] = Pctmp.getMinimumX().first;
                rocksatendpoints_[i][1] = Pctmp.getMaximumX().first;
            }
        }
    }

    double z_tolerance = param.getDefault("z_tolerance", 0.0);
    double residual_tolerance = param.getDefault("residual_tolerance", 1e-8);
    int linsolver_verbosity = param.getDefault("linsolver_verbosity", 0);
    int linsolver_type = param.getDefault("linsolver_type", 1);

    //  Guarantee initialization
    double Pcmax = -DBL_MAX, Pcmin = DBL_MAX;

    // Check that we do not have any user input
    // that goes outside the coordinates described in
    // the cornerpoint file (runtime-exception will be thrown in case of error)
    ch.verifyInscribedShoebox(imin, ilen, imax,
                              jmin, jlen, jmax,
                              zmin, zlen, zmax);

    // Random number generator from boost.
    boost::mt19937 gen;

    // Seed the random number generators with the current time, unless specified on command line
    // Warning: Current code does not allow 0 for the seed!!
    boost::mt19937::result_type autoseed = time(NULL);
    if (userseed == 0) {
        gen.seed(autoseed);
    }
    else {
        gen.seed(userseed);
    }

    Opm::SinglePhaseUpscaler::BoundaryConditionType bctype = Opm::SinglePhaseUpscaler::Fixed;
    bool isFixed, isPeriodic;
    isFixed = isPeriodic = false;
    if (upscale) {
        if (bc == "fixed") {
            isFixed = true;
            bctype = Opm::SinglePhaseUpscaler::Fixed;
        }
        else if (bc == "periodic") {
            isPeriodic = true;
            bctype = Opm::SinglePhaseUpscaler::Periodic;
        }
        else {
            std::cout << "Boundary condition type (bc=" << bc << ") not allowed." << std::endl;
            std::cout << "Only bc=fixed or bc=periodic implemented." << std::endl;
            throw std::exception();
        }
    }

    // Check for unused parameters (potential typos).
    if (param.anyUnused()) {
        std::cout << "*****     WARNING: Unused parameters:     *****\n";
        param.displayUsage();
    }

    // Note that end is included in interval for uniform_int.
    boost::uniform_int<> disti(imin, imax - ilen);
    boost::uniform_int<> distj(jmin, jmax - jlen);
    boost::uniform_real<> distz(zmin, std::max(zmax - zlen, zmin));
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > ri(gen, disti);
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rj(gen, distj);
    boost::variate_generator<boost::mt19937&, boost::uniform_real<> > rz(gen, distz);

    // Storage for results
    std::vector<double> porosities;
    std::vector<double> permxs;
    std::vector<double> permys;
    std::vector<double> permzs;
    std::vector<double> permyzs;
    std::vector<double> permxzs;
    std::vector<double> permxys;
    std::vector<double> minsws, maxsws;
    std::vector<std::vector<double> > pcvalues;
    std::vector<double> dipangs, azimuths;

    // Initialize a matrix for subsample satnum volumes.
    // Outer index is subsample index, inner index is SATNUM-value
    std::vector<std::vector<double> > rockvolumes;
    int maxSatnum = 0; // This value is determined from the chopped cells.

    int finished_subsamples = 0; // keep explicit count of successful subsamples
    for (int sample = 1; sample <= subsamples; ++sample) {
        int istart = ri();
        int jstart = rj();
        double zstart = rz();
        ch.chop(istart, istart + ilen, jstart, jstart + jlen, zstart, zstart + zlen, resettoorigin);
        std::string subsampledgrdecl = filebase;

        // Output grdecl-data to file if a filebase is supplied.
        if (filebase != "") {
            std::ostringstream oss;
            if ((size_t) subsamples > 1) { // Only add number to filename if more than one sample is asked for
                oss << 'R' << std::setw(4) << std::setfill('0') << sample;
                subsampledgrdecl += oss.str();
            }
            subsampledgrdecl += ".grdecl";
            ch.writeGrdecl(subsampledgrdecl);
        }

        try { /* The upscaling may fail to converge on icky grids, lets just pass by those */
            if (upscale) {
                Opm::EclipseGridParser subparser = ch.subparser();
                subparser.convertToSI();
                Opm::SinglePhaseUpscaler upscaler;

                upscaler.init(subparser, bctype, minpermSI, z_tolerance,
                              residual_tolerance, linsolver_verbosity, linsolver_type, false);

                Opm::SinglePhaseUpscaler::permtensor_t upscaled_K = upscaler.upscaleSinglePhase();
                upscaled_K *= (1.0/(Opm::prefix::milli*Opm::unit::darcy));


                porosities.push_back(upscaler.upscalePorosity());
                permxs.push_back(upscaled_K(0,0));
                permys.push_back(upscaled_K(1,1));
                permzs.push_back(upscaled_K(2,2));
                permyzs.push_back(upscaled_K(1,2));
                permxzs.push_back(upscaled_K(0,2));
                permxys.push_back(upscaled_K(0,1));

            }

            if (endpoints) {
                // Calculate minimum and maximum water volume in each cell
                // Create single-phase upscaling object to get poro and perm values from the grid
                Opm::EclipseGridParser subparser = ch.subparser();
                std::vector<double>  perms = subparser.getFloatingPointValue("PERMX");
                subparser.convertToSI();
                Opm::SinglePhaseUpscaler upscaler;
                upscaler.init(subparser, bctype, minpermSI, z_tolerance,
                              residual_tolerance, linsolver_verbosity, linsolver_type, false);
                std::vector<int>   satnums = subparser.getIntegerValue("SATNUM");
                std::vector<double>  poros = subparser.getFloatingPointValue("PORO");
                std::vector<double> cellVolumes, cellPoreVolumes;
                cellVolumes.resize(satnums.size(), 0.0);
                cellPoreVolumes.resize(satnums.size(), 0.0);
                int tesselatedCells = 0;
                //double maxSinglePhasePerm = 0;
                double Swirvolume = 0;
                double Sworvolume = 0;
                const std::vector<int>& ecl_idx = upscaler.grid().globalCell();
                Dune::CpGrid::Codim<0>::LeafIterator c = upscaler.grid().leafbegin<0>();
                for (; c != upscaler.grid().leafend<0>(); ++c) {
                    unsigned int cell_idx = ecl_idx[c->index()];
                    if (satnums[cell_idx] > 0) { // Satnum zero is "no rock"
                        cellVolumes[cell_idx] = c->geometry().volume();
                        cellPoreVolumes[cell_idx] = cellVolumes[cell_idx] * poros[cell_idx];
                        double Pcmincandidate = 0.0, Pcmaxcandidate = 0.0, minSw, maxSw;
                        if (!anisorocks) {
                            if (cappres) {
                                Pcmincandidate = jfuncendpoints_[int(satnums[cell_idx])-1][1]
                                                 / sqrt(perms[cell_idx] * milliDarcyToSqMetre/poros[cell_idx]) * surfaceTension;
                                Pcmaxcandidate = jfuncendpoints_[int(satnums[cell_idx])-1][0]
                                                 / sqrt(perms[cell_idx] * milliDarcyToSqMetre/poros[cell_idx]) * surfaceTension;
                            }
                            minSw = rocksatendpoints_[int(satnums[cell_idx])-1][0];
                            maxSw = rocksatendpoints_[int(satnums[cell_idx])-1][1];
                        }
                        else { // anisotropic input, we do not to J-function scaling
                            if (cappres) {
                                Pcmincandidate = SwPcfunctions[int(satnums[cell_idx])-1].getMinimumX().first;
                                Pcmaxcandidate = SwPcfunctions[int(satnums[cell_idx])-1].getMaximumX().first;
                            }
                            minSw = rocksatendpoints_[int(satnums[cell_idx])-1][0];
                            maxSw = rocksatendpoints_[int(satnums[cell_idx])-1][1];
                        }
                        if (cappres) {
                            Pcmin = std::min(Pcmincandidate, Pcmin);
                            Pcmax = std::max(Pcmaxcandidate, Pcmax);
                        }
                        Swirvolume += minSw * cellPoreVolumes[cell_idx];
                        Sworvolume += maxSw * cellPoreVolumes[cell_idx];
                    }
                    ++tesselatedCells; // keep count.
                }

                // If upscling=false, we still (may) want to have porosities together with endpoints
                if (!upscale) {
                    porosities.push_back(upscaler.upscalePorosity());
                }

                // Total porevolume and total volume -> upscaled porosity:
                double poreVolume = std::accumulate(cellPoreVolumes.begin(),
                                                    cellPoreVolumes.end(),
                                                    0.0);
                double Swir = Swirvolume/poreVolume;
                double Swor = Sworvolume/poreVolume;
                minsws.push_back(Swir);
                maxsws.push_back(Swor);
                if (cappres) {
                    // Upscale capillary pressure function
                    Opm::MonotCubicInterpolator WaterSaturationVsCapPressure;
                    double largestSaturationInterval = Swor-Swir;
                    double Ptestvalue = Pcmax;
                    while (largestSaturationInterval > (Swor-Swir)/double(nsatpoints)) {
                        if (Pcmax == Pcmin) {
                            // This is a dummy situation, we go through once and then
                            // we are finished (this will be triggered by zero permeability)
                            Ptestvalue = Pcmin;
                            largestSaturationInterval = 0;
                        }
                        else if (WaterSaturationVsCapPressure.getSize() == 0) {
                            /* No data values previously computed */
                            Ptestvalue = Pcmax;
                        }
                        else if (WaterSaturationVsCapPressure.getSize() == 1) {
                            /* If only one point has been computed, it was for Pcmax. So now
                               do Pcmin */
                            Ptestvalue = Pcmin;
                        }
                        else {
                            /* Search for largest saturation interval in which there are no
                               computed saturation points (and estimate the capillary pressure
                               that will fall in the center of this saturation interval)
                            */
                            std::pair<double,double> SatDiff = WaterSaturationVsCapPressure.getMissingX();
                            Ptestvalue = SatDiff.first;
                            largestSaturationInterval = SatDiff.second;
                        }
                        // Check for saneness of Ptestvalue:
                        if (std::isnan(Ptestvalue) || std::isinf(Ptestvalue)) {
                            std::cerr << "ERROR: Ptestvalue was inf or nan" << std::endl;
                            break; // Jump out of while-loop, just print out the results
                            // up to now and exit the program
                        }

                        double waterVolume = 0.0;
                        for (unsigned int i = 0; i < ecl_idx.size(); ++i) {
                            unsigned int cell_idx = ecl_idx[i];
                            double waterSaturationCell = 0.0;
                            if (satnums[cell_idx] > 0) { // handle "no rock" cells with satnum zero
                                double PtestvalueCell;

                                PtestvalueCell = Ptestvalue;

                                if (!anisorocks) {
                                    double Jvalue = sqrt(perms[cell_idx] * milliDarcyToSqMetre /poros[cell_idx]) * PtestvalueCell / surfaceTension;
                                    waterSaturationCell
                                        = InvJfunctions[int(satnums[cell_idx])-1].evaluate(Jvalue);
                                }
                                else { // anisotropic_input, then we do not do J-function-scaling
                                    waterSaturationCell = SwPcfunctions[int(satnums[cell_idx])-1].evaluate(PtestvalueCell);
                                }
                            }
                            waterVolume += waterSaturationCell  * cellPoreVolumes[cell_idx];
                        }
                        WaterSaturationVsCapPressure.addPair(Ptestvalue, waterVolume/poreVolume);
                    }
                    WaterSaturationVsCapPressure.chopFlatEndpoints(saturationThreshold);
                    std::vector<double> wattest = WaterSaturationVsCapPressure.get_fVector();
                    std::vector<double> cprtest = WaterSaturationVsCapPressure.get_xVector();
                    Opm::MonotCubicInterpolator CapPressureVsWaterSaturation(WaterSaturationVsCapPressure.get_fVector(),
                            WaterSaturationVsCapPressure.get_xVector());
                    std::vector<double> pcs;
                    for (int satp=0; satp<nsatpoints; ++satp) {
                        pcs.push_back(CapPressureVsWaterSaturation.evaluate(Swir+(Swor-Swir)/(nsatpoints-1)*satp));
                    }
                    pcvalues.push_back(pcs);
                }

            }


            if (dips) {
                Opm::EclipseGridParser subparser = ch.subparser();
                std::vector<int>  griddims = subparser.getSPECGRID().dimensions;
                std::vector<double> xdips_subsample, ydips_subsample;

                Opm::EclipseGridInspector gridinspector(subparser);
                for (int k=0; k < griddims[2]; ++k) {
                    for (int j=0; j < griddims[1]; ++j) {
                        for (int i=0; i < griddims[0]; ++i) {
                            if (gridinspector.cellVolumeVerticalPillars(i, j, k) > mincellvolume) {
                                std::pair<double,double> xydip = gridinspector.cellDips(i, j, k);
                                xdips_subsample.push_back(xydip.first);
                                ydips_subsample.push_back(xydip.second);
                            }
                        }
                    }
                }


                //  double azimuth = atan(xydip.first/xydip.second);
                //              double dip = acos(1.0/sqrt(pow(xydip.first,2.0)+pow(xydip.second,2.0)+1.0));
                //	dips_subsample.push_back( xydip.first );
                //	azims_subsample.push_back(atan(xydip.first/xydip.second));

                // Average xdips and ydips
                double xdipaverage = accumulate(xdips_subsample.begin(), xdips_subsample.end(), 0.0)/xdips_subsample.size();
                double ydipaverage = accumulate(ydips_subsample.begin(), ydips_subsample.end(), 0.0)/ydips_subsample.size();

                // Convert to dip and azimuth
                double azimuth = atan(xdipaverage/ydipaverage)+azimuthdisplacement;
                double dip = acos(1.0/sqrt(pow(xdipaverage,2.0)+pow(ydipaverage,2.0)+1.0));
                dipangs.push_back(dip);
                azimuths.push_back(azimuth);
            }

            if (satnumvolumes) {
                Opm::EclipseGridParser subparser = ch.subparser();
                Opm::EclipseGridInspector subinspector(subparser);
                std::vector<int>  griddims = subparser.getSPECGRID().dimensions;
                int number_of_subsamplecells = griddims[0] * griddims[1] * griddims[2];

                // If SATNUM is non-existent in input grid, this will fail:
                std::vector<int> satnums = subparser.getIntegerValue("SATNUM");

                std::vector<double> rockvolumessubsample;
                for (int cell_idx=0; cell_idx < number_of_subsamplecells; ++cell_idx) {
                    maxSatnum = std::max(maxSatnum, int(satnums[cell_idx]));
                    rockvolumessubsample.resize(maxSatnum); // Ensure long enough vector
                    rockvolumessubsample[int(satnums[cell_idx])-1] += subinspector.cellVolumeVerticalPillars(cell_idx);
                }

                // Normalize volumes to obtain relative volumes:
                double subsamplevolume = std::accumulate(rockvolumessubsample.begin(),
                                         rockvolumessubsample.end(), 0.0);
                std::vector<double> rockvolumessubsample_normalized;
                for (size_t satnum_idx = 0; satnum_idx < rockvolumessubsample.size(); ++satnum_idx) {
                    rockvolumessubsample_normalized.push_back(rockvolumessubsample[satnum_idx]/subsamplevolume);
                }
                rockvolumes.push_back(rockvolumessubsample_normalized);
            }

            finished_subsamples++;
        }
        catch (...) {
            std::cerr << "Warning: Upscaling chopped subsample nr. " << sample << " failed, proceeding to next subsample\n";
        }

    }


    // Make stream of output data, to be outputted to screen and optionally to file
    std::stringstream outputtmp;

    outputtmp << "################################################################################################" << std::endl;
    outputtmp << "# Results from property analysis on subsamples" << std::endl;
    outputtmp << "#" << std::endl;
    time_t now = time(NULL);
    outputtmp << "# Finished: " << asctime(localtime(&now));

    utsname hostname;
    uname(&hostname);
    outputtmp << "# Hostname: " << hostname.nodename << std::endl;
    outputtmp << "#" << std::endl;
    outputtmp << "# Options used:" << std::endl;
    outputtmp << "#     gridfilename: " << gridfilename << std::endl;
    outputtmp << "#   i; min,len,max: " << imin << " " << ilen << " " << imax << std::endl;
    outputtmp << "#   j; min,len,max: " << jmin << " " << jlen << " " << jmax << std::endl;
    outputtmp << "#   z; min,len,max: " << zmin << " " << zlen << " " << zmax << std::endl;
    outputtmp << "#       subsamples: " << subsamples << std::endl;
    if (userseed == 0) {
        outputtmp << "#      (auto) seed: " << autoseed << std::endl;
    }
    else {
        outputtmp << "#    (manual) seed: " << userseed << std::endl;
    }
    outputtmp << "################################################################################################" << std::endl;
    outputtmp << "# id";
    if (upscale) {
        if (isPeriodic) {
            outputtmp << "          porosity                 permx                   permy                   permz                   permyz                  permxz                  permxy";
        }
        else if (isFixed) {
            outputtmp << "          porosity                 permx                   permy                   permz";
        }
    }
    if (endpoints) {
        if (!upscale) {
            outputtmp << "          porosity";
        }
        outputtmp << "                  Swir                    Swor";
        if (cappres) {
            outputtmp << "                  Pc(Swir)                Pc2                     Pc3                     Pc4                     Pc(Swor)";
        }
    }
    if (dips) {
        outputtmp << "                  dip                     azim(displacement:" << azimuthdisplacement << ")";
    }
    if (satnumvolumes) {
        for (int satnumidx = 0; satnumidx < maxSatnum; ++satnumidx) {
            outputtmp << "               satnum_" << satnumidx+1;
        }
    }
    outputtmp << std::endl;

    const int fieldwidth = outputprecision + 8;
    for (int sample = 1; sample <= finished_subsamples; ++sample) {
        outputtmp << sample << '\t';
        if (upscale) {
            outputtmp <<
                      std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << porosities[sample-1] << '\t' <<
                      std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permxs[sample-1] << '\t' <<
                      std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permys[sample-1] << '\t' <<
                      std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permzs[sample-1] << '\t';
            if (isPeriodic) {
                outputtmp <<
                          std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permyzs[sample-1] << '\t' <<
                          std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permxzs[sample-1] << '\t' <<
                          std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permxys[sample-1] << '\t';
            }
        }
        if (endpoints) {
            if (!upscale) {
                outputtmp <<
                          std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << porosities[sample-1] << '\t';
            }
            outputtmp <<
                      std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << minsws[sample-1] << '\t' <<
                      std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << maxsws[sample-1];
            if (cappres) {
                outputtmp <<
                          std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << pcvalues[sample-1][0] << '\t' <<
                          std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << pcvalues[sample-1][1] << '\t' <<
                          std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << pcvalues[sample-1][2] << '\t' <<
                          std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << pcvalues[sample-1][3] << '\t' <<
                          std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << pcvalues[sample-1][4];
            }
        }
        if (dips) {
            outputtmp <<
                      std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << dipangs[sample-1] << '\t' <<
                      std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << azimuths[sample-1];
        }
        if (satnumvolumes) {
            rockvolumes[sample-1].resize(maxSatnum, 0.0);
            for (int satnumidx = 0; satnumidx < maxSatnum; ++satnumidx) {
                outputtmp <<
                          std::showpoint << std::setw(fieldwidth) <<
                          std::setprecision(outputprecision) << rockvolumes[sample-1][satnumidx] << '\t';
            }
        }
        outputtmp <<  std::endl;
    }

    if (resultfile != "") {
        std::cout << "Writing results to " << resultfile << std::endl;
        std::ofstream outfile;
        outfile.open(resultfile.c_str(), std::ios::out | std::ios::trunc);
        outfile << outputtmp.str();
        outfile.close();
    }



    std::cout << outputtmp.str();
}
catch (const std::exception &e) {
    std::cerr << "Program threw an exception: " << e.what() << "\n";
    throw;
}
Ejemplo n.º 10
0
int main(int argc, char** argv)
try
{
    Dune::MPIHelper::instance(argc, argv);

    Opm::parameter::ParameterGroup param(argc, argv);
    std::string gridfilename = param.get<std::string>("gridfilename");
    Opm::CornerPointChopper ch(gridfilename);

    // The cells with i coordinate in [imin, imax) are included, similar for j.
    // The z limits may be changed inside the chopper to match actual min/max z.
    const int* dims = ch.dimensions();
    int imin = param.getDefault("imin", 0);
    int imax = param.getDefault("imax", dims[0]);
    int jmin = param.getDefault("jmin", 0);
    int jmax = param.getDefault("jmax", dims[1]);
    double zmin = param.getDefault("zmin", ch.zLimits().first);
    double zmax = param.getDefault("zmax", ch.zLimits().second);
    int pairs = param.getDefault("pairs", 100);
    std::string direction = param.get<std::string>("direction");
    int ilen = param.getDefault("ilen", 0);
    int jlen = param.getDefault("jlen", 0);
    double zlen = param.getDefault("zlen", 0.0);
    boost::mt19937::result_type userseed = param.getDefault("seed", 0);

    int outputprecision = param.getDefault("outputprecision", 8);
    std::string resultfile = param.getDefault<std::string>("resultfile", "");

    double minperm = param.getDefault("minperm", 1e-9);
    double minpermSI = Opm::unit::convert::from(minperm, Opm::prefix::milli*Opm::unit::darcy);
    double z_tolerance = param.getDefault("z_tolerance", 0.0);
    double residual_tolerance = param.getDefault("residual_tolerance", 1e-8);
    int linsolver_verbosity = param.getDefault("linsolver_verbosity", 0);
    int linsolver_type = param.getDefault("linsolver_type", 1);
    
    // Check for unused parameters (potential typos).
    if (param.anyUnused()) {
	std::cout << "*****     WARNING: Unused parameters:     *****\n";
	param.displayUsage();
    }


    if (ilen <= 0) {
        std::cerr << "Error: ilen (" << ilen << ") must be greater than zero\n";
        exit(1);
    }
    if (jlen <= 0) {
        std::cerr << "Error: jlen (" << jlen <<") must be greater than zero\n";
        exit(1);
    }
    if (zlen <= 0.0) {
        std::cerr << "Eror: zlen (" << zlen <<") must be greater than zero\n";
        exit(1);
    }

    // Check user supplied variogram direction, either horizontal or vertical 
    enum variogram_directions { undefined, horizontal, vertical };
    variogram_directions variogram_direction = undefined;
    std::string distancemetric;
    if ( direction == "vertical" || direction == "vert" ) {
	variogram_direction = vertical;
	distancemetric = "zcorn";
    }
    else { // if (direction == "horizontal" || direction == "horiz") {
	variogram_direction = horizontal;
	distancemetric = "cells";
    }


    if (variogram_direction == undefined) {
        std::cerr << "Error: variogram direction is undefined, user supplied '" << direction << "'.\n";
        exit(1);
    }
    
    
    // Check that we do not have any user input 
    // that goes outside the coordinates described in
    // the cornerpoint file (runtime-exception will be thrown in case of error)
    ch.verifyInscribedShoebox(imin, ilen, imax,
                              jmin, jlen, jmax,
                              zmin, zlen, zmax);
    
    // Random number generator from boost.
    boost::mt19937 gen;
    
    // Seed the random number generators with the current time, unless specified on command line
    // Warning: Current code does not allow 0 for the seed!!
    if (userseed == 0) {
        gen.seed(time(NULL));
    }
    else {
        gen.seed(userseed);
    }
        

    // Note that end is included in interval for uniform_int.
    boost::uniform_int<> disti(imin, imax - ilen);
    boost::uniform_int<> distj(jmin, jmax - jlen);
    boost::uniform_real<> distz(zmin, std::max(zmax - zlen, zmin));
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > ri(gen, disti);
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rj(gen, distj);
    boost::variate_generator<boost::mt19937&, boost::uniform_real<> > rz(gen, distz);
    
    // Storage for results
    std::vector<double> distances;
    std::vector<double> porodiffs;
    std::vector<double> permxdiffs;
    std::vector<double> permydiffs;
    std::vector<double> permzdiffs;
    
    for (int pair = 1; pair <= pairs; ++pair) {
        int istart_1 = ri();
        int jstart_1 = rj();
        double zstart_1 = rz();
        ch.chop(istart_1, istart_1 + ilen, jstart_1, jstart_1 + jlen, zstart_1, zstart_1 + zlen, false);
	
        Opm::EclipseGridParser subparser_1 = ch.subparser();
        subparser_1.convertToSI();
        Opm::SinglePhaseUpscaler upscaler_1;
        upscaler_1.init(subparser_1, Opm::SinglePhaseUpscaler::Fixed, minpermSI, z_tolerance,
			residual_tolerance, linsolver_verbosity, linsolver_type, false);
        Opm::SinglePhaseUpscaler::permtensor_t upscaled_K_1 = upscaler_1.upscaleSinglePhase();
        upscaled_K_1 *= (1.0/(Opm::prefix::milli*Opm::unit::darcy));
	double porosity_1 = upscaler_1.upscalePorosity();

        // Pick another location to form a location-pair to be compared
        int istart_2 = 0, jstart_2 = 0;
        double zstart_2 = 0;
        if (variogram_direction == horizontal) {
            istart_2 = ri();
            jstart_2 = rj();
            zstart_2 = zstart_1;
        }
        else if (variogram_direction == vertical) {
            istart_2 = istart_1;
            jstart_2 = jstart_1;
            zstart_2 = rz();
        }   
        ch.chop(istart_2, istart_2 + ilen, jstart_2, jstart_2 + jlen, zstart_2, zstart_2 + zlen, false);
	
        Opm::EclipseGridParser subparser_2 = ch.subparser();
	subparser_2.convertToSI();
        Opm::SinglePhaseUpscaler upscaler_2;
        upscaler_2.init(subparser_2, Opm::SinglePhaseUpscaler::Fixed, minpermSI, z_tolerance,
			residual_tolerance, linsolver_verbosity, linsolver_type, false);
        Opm::SinglePhaseUpscaler::permtensor_t upscaled_K_2 = upscaler_2.upscaleSinglePhase();
        upscaled_K_2 *= (1.0/(Opm::prefix::milli*Opm::unit::darcy));
	double porosity_2 = upscaler_2.upscalePorosity();

        if (variogram_direction == horizontal) {
            distances.push_back(sqrt(pow(istart_2 - istart_1,2) + pow(jstart_2 - jstart_1,2)));
	}
        else if (variogram_direction == vertical) {
            distances.push_back(fabs(zstart_2 - zstart_1));
        }
        porodiffs.push_back(fabs(porosity_2 - porosity_1));
        permxdiffs.push_back(fabs(upscaled_K_2(0,0) - upscaled_K_1(0,0)));
	permydiffs.push_back(fabs(upscaled_K_2(1,1) - upscaled_K_1(1,1)));
        permzdiffs.push_back(fabs(upscaled_K_2(2,2) - upscaled_K_1(2,2)));
    }
    
    // Make stream of output data, to be outputted to screen and optionally to file
    std::stringstream outputtmp;
    
    outputtmp << "################################################################################################" << std::endl;
    outputtmp << "# Data for experimental variogram" << std::endl;
    outputtmp << "#" << std::endl;
    time_t now = time(NULL);
    outputtmp << "# Finished: " << asctime(localtime(&now));
        
    utsname hostname;   uname(&hostname);
    outputtmp << "# Hostname: " << hostname.nodename << std::endl;
    outputtmp << "#" << std::endl;
    outputtmp << "# Options used:" << std::endl;
    outputtmp << "#     gridfilename: " << gridfilename << std::endl;
    outputtmp << "#   i; min,len,max: " << imin << " " << ilen << " " << imax << std::endl;
    outputtmp << "#   j; min,len,max: " << jmin << " " << jlen << " " << jmax << std::endl;
    outputtmp << "#   z; min,len,max: " << zmin << " " << zlen << " " << zmax << std::endl;
    outputtmp << "#        direction: " << direction << std::endl;
    outputtmp << "#            pairs: " << pairs << std::endl;
    outputtmp << "################################################################################################" << std::endl;
    outputtmp << "# distance (" << distancemetric << ")      porositydiff                permxdiff               permydiff                permzdiff" << std::endl;
    
    const int fieldwidth = outputprecision + 8;
    for (int pair = 1; pair <= pairs; ++pair) {
	outputtmp << std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << distances[pair-1] << '\t' <<
	    std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << porodiffs[pair-1] << '\t' <<
	    std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permxdiffs[pair-1] << '\t' <<
	    std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permydiffs[pair-1] << '\t' <<
	    std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permzdiffs[pair-1] << '\t' <<
	    std::endl;
    }
    
    if (resultfile != "") {
	std::cout << "Writing results to " << resultfile << std::endl;
	std::ofstream outfile;
	outfile.open(resultfile.c_str(), std::ios::out | std::ios::trunc);
	outfile << outputtmp.str();
	outfile.close();      
    }
    
        
    
    std::cout << outputtmp.str();
}
catch (const std::exception &e) {
    std::cerr << "Program threw an exception: " << e.what() << "\n";
    throw;
}
Ejemplo n.º 11
0
bool Coord_cl::lineOfSight( const Coord_cl &target, UI16 targetheight, bool touch )
{
	//Console::instance()->send( QString( "LOScheck: Source:%1,Target:%2,Targetheight:%3\n" ).arg( z ).arg( target.z ).arg( targetheight ) );
	if( target.map != map )
		return false;

	if( (x == target.x) && (y == target.y) && (z == target.z) )
		return true;		// if source and target are on the same position

	SI32 n = ( target.x - x ), m = ( target.y - y ), i = 0;
	SI08 sgn_x = ( x <= target.x ) ? 1 : (-1); // signum for x
	SI08 sgn_y = ( y <= target.y ) ? 1 : (-1); // signum for y
	SI08 sgn_z = ( z <= target.z ) ? 1 : (-1); // signum for z
	if( x == target.x )
		sgn_x = 0;
	if( y == target.y )
		sgn_y = 0;
	if( z == target.z )
		sgn_z = 0;

	QValueList< Coord_cl > collisions;

	//first we get our x-y-coordinates
	if( sgn_x == 0 && sgn_y == 0 && !sgn_z == 0 ) // should fix shooting through floor issues
		{
			collisions.push_back( Coord_cl( x, y, 0, map ) );
		}
	else if( sgn_x == 0 ) // if we are on the same x-level, just push every x/y coordinate in y-direction from src to trg into the array
		for( i = 0; i <= (sgn_y * m); ++i )
		{
			collisions.push_back( Coord_cl( x, y + (sgn_y * i), 0, map ) );
		}
	else if ( sgn_y == 0 ) // if we are on the same y-level, just push every x/y coordinate in x-direction from src to trg into the array
		for( i = 0; i <= (sgn_x * n); ++i )
		{
			collisions.push_back( Coord_cl( x + (sgn_x * i), y, 0, map ) );
		}
	else
	{
		SI32 oldpos = y;
		bool exaktpos = false;
		for( i = 0; (sgn_x * n >= sgn_y * m) && (i <= (sgn_x * n)); i++ )
		{
			//Console::instance()->send( QString( "x:%1\n" ).arg( i ) );
			SI32 gridx = x + (sgn_x * i);
			if( ( ( n == 0 ) && ( gridx == 0 ) ) ||
				( ( n + ( gridx * m ) == 0 ) ) )
				continue;
			else
			{
				if( exaktpos )
				{
					collisions.push_back( Coord_cl( gridx, oldpos-sgn_y, 0, map ) );
					//Console::instance()->send( QString( "add exaktpos coordinate %1,%2\n" ).arg( gridx ).arg( oldpos-sgn_y ) );
					exaktpos = false;
				}
					
				// linear evaluation of extended 2x2 matrix, abbreviated
				double t = (double)sgn_x * ((double)i+0.5) * (double)m / (double)n + (double)y;
				//Console::instance()->send( QString( "t:%1\n" ).arg( t ) );

				if( ((sgn_y>0) && (specialFloor(t)==oldpos+0.5)) || ((sgn_y<0) && (specialFloor(t)==oldpos-0.5)) )
				{
					exaktpos = true;
				}
				
				if( ((sgn_y>0) && (t<oldpos+0.5)) || ((sgn_y<0) && (t>oldpos-0.5)) || (oldpos==target.y) )
				{
					collisions.push_back( Coord_cl( gridx, oldpos, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( gridx ).arg( oldpos ) );
				}
				// but if not, we have to take BOTH coordinates, which the calculated collision is between!
				else
				{ 
					collisions.push_back( Coord_cl( gridx, oldpos, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( gridx ).arg( oldpos ) );
					oldpos += sgn_y;
					collisions.push_back( Coord_cl( gridx, oldpos, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( gridx ).arg( oldpos ) );
				}
			}
		}
		
		oldpos = x;
		exaktpos = false;
		for( i = 0; (sgn_y * m >= sgn_x * n) && (i <= (sgn_y * m)); ++i )
		{
			//Console::instance()->send( QString( "y:%1\n" ).arg( i ) );
			SI32 gridy = y + (sgn_y * i);
			if( ( ( m == 0 ) && ( gridy == 0 ) ) ||
				( ( m + ( gridy * n ) == 0 ) ) )
				continue;
			else
			{
				if( exaktpos )
				{
					collisions.push_back( Coord_cl( oldpos-sgn_x, gridy, 0, map ) );
					//Console::instance()->send( QString( "add exaktpos coordinate %1,%2\n" ).arg( oldpos-sgn_x ).arg( gridy ) );
					exaktpos = false;
				}

				double t = (double)x + (double)n / (double)m * (double)sgn_y * ((double)i+0.5);
				//Console::instance()->send( QString( "t:%1\n" ).arg( t ) );

				if( ((sgn_x>0) && (specialFloor(t)==oldpos+0.5)) || ((sgn_x<0) && (specialFloor(t)==oldpos-0.5)) )
				{
					exaktpos = true;
				}

				if( ((sgn_x>0) && (t<oldpos+0.5)) || ((sgn_x<0) && (t>oldpos-0.5)) || (oldpos==target.x) )
				{
					collisions.push_back( Coord_cl( oldpos, gridy, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( oldpos ).arg( gridy ) );

				}
				// but if not, we have to take BOTH coordinates, which the calculated collision is between!
				else
				{ 
					collisions.push_back( Coord_cl( oldpos, gridy, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( oldpos ).arg( gridy ) );
					oldpos += sgn_x;;
					collisions.push_back( Coord_cl( oldpos, gridy, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( oldpos ).arg( gridy ) );
				}
			}
		}
	}

	// the next will search for multis
	QPtrList< cItem > multis;
	RegionIterator4Items ri( *this );
	for( ri.Begin(); !ri.atEnd(); ri++ )
	{
		P_ITEM pi = ri.GetData();
		if( pi && pi->id() >= 0x4000 )
		{
			multis.append( pi );
		}
	}

	//touch wird von notouch getrennt, da der notouch algorithmus wesentlich aufwändiger
	//ist (touch benötigt die erste for-schleife nicht), macht den code zwar bisserl
	//unübersichtlicher, aber ist wesentlich effizienter

	//touch is separated from notouch, because the notouch calculation is much more to do
	//( one additional for-loop )

	if( targetheight > 0 )
	{
		--targetheight;
	}

	if( !touch )
	{
		for( i = target.z+targetheight; i >= target.z; --i )
		{
			bool blocked = false;
			//Console::instance()->send( QString( "i:%1\n" ).arg( i ) );
			double dz;
			double gradient;
			double offset;
			if( (sgn_x == 0) && (sgn_y == 0) )
			{
				dz = (double)i - (double)z;
				gradient = 1; //only to avoid problems, isnt used
				offset = 1;
			}
			else
			{
				dz = ( (double)i -(double)z ) / sqrt( ((double)target.x - (double)x)*((double)target.x - (double)x) + ((double)target.y - (double)y)*((double)target.y - (double)y) );
				gradient = (double)m / (double)n;
				offset = 0.5*( (double)y + (double)target.y - gradient*( x + target.x ) );
			}
	
			map_st map1, map2;
			SI32 j;
	
			bool posHigherThanMap;
			map1 = Map->seekMap( (*this) );
			if( map1.z > z )
			{
				posHigherThanMap = false;
			}
			else
			{
				posHigherThanMap = true;
			}
			
			//Console::instance()->send( QString( "after first things\n" ) );
			QValueList< Coord_cl >::iterator pit = collisions.begin();
			while( pit != collisions.end() )
			{
				//Console::instance()->send( QString( "coordinate:%1,%2 dz:%3\n" ).arg( (*pit).x ).arg( (*pit).y ).arg( dz ) );
				//lets see what z-coordinates we have to test
				//we do our calculations exakt, because its the only way to solve all problems
				//of floor
				//"minimum" ist am anfang der platte, "maximum" am ende
				//our line is y = gradient * x + offset
				//or x = ( y - offset ) / gradient
				//we now have to test, where the line cuts one position
				//start and endposition has to be done alone
				
				double z1 = -300;
				double z2 = -300;
				SI08 zmin, zmax;

				if( (sgn_x == 0) && (sgn_y == 0) )
				{
					if( dz > 0 )
					{
						zmin = z+1;
						zmax = i;
					}
					else
					{
						zmin = i+1;
						zmax = z;
					}
				}
				else if( sgn_x == 0 )
				{
					//gradient only in y-direction
					z1 = (double)i - dz*( fabs( (double)target.y - (double)((*pit).y) ) -0.5 ); 
					z2 = (double)i - dz*( fabs( (double)target.y - (double)((*pit).y) ) +0.5 );
					//Console::instance()->send( QString( "i:%1,ty:%2,cy:%3\n" ).arg( i ).arg( target.y ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );

					if( z1 > z2 )
					{
						zmin = (SI08)floor( z2 );
						zmax = (SI08)ceilf( z1 );
					}
					else
					{
						zmin = (SI08)floor( z1 );
						zmax = (SI08)ceilf( z2 );
					}

					/*another try, but i think its needed for all positions, not only start and end...
					//target 
					if( (*pit).y == target.y )
					{
						if( dz > 0 )
						{
							zmax = QMIN( zmax, i );
							//Console::instance()->send( QString( "TargetY, zmax:%1, i:%2\n" ).arg( zmax ).arg( i ) );
						}
						else
						{
							zmin = QMAX( zmin, i+1 );
							//Console::instance()->send( QString( "TargetY, zmin:%1, i:%2\n" ).arg( zmin ).arg( i ) );
						}
					}

					//source
					if( (*pit).y == y )
					{
						if( dz > 0 )
						{
							zmin = QMAX( zmin, z );
							//Console::instance()->send( QString( "SourceY, zmin:%1, i:%2\n" ).arg( zmax ).arg( i ) );
						}
						else
						{
							zmax = QMIN( zmax, z );
							//Console::instance()->send( QString( "SourceY, zmax:%1, i:%2\n" ).arg( zmax ).arg( i ) );
						}
					}*/
					if( dz > 0 )
					{
						zmax = QMIN( zmax, i );
						zmin = QMAX( zmin, z );
					}
					else
					{
						zmin = QMAX( zmin, i+1 );
						zmax = QMIN( zmax, z );
					}

				}
				else if( sgn_y == 0 )
				{
					//gradient only in y-direction
					z1 = (double)i - dz*( fabs( (double)target.x - (double)((*pit).x) ) -0.5 ); 
					z2 = (double)i - dz*( fabs( (double)target.x - (double)((*pit).x) ) +0.5 );
					//Console::instance()->send( QString( "i:%1,tx:%2,cx:%3\n" ).arg( i ).arg( target.x ).arg( (*pit).x ) );
					//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );

					if( z1 > z2 )
					{
						zmin = (SI08)floor( z2 );
						zmax = (SI08)ceilf( z1 );
					}
					else
					{
						zmin = (SI08)floor( z1 );
						zmax = (SI08)ceilf( z2 );
					}
					
					if( dz > 0 )
					{
						zmax = QMIN( zmax, i );
						zmin = QMAX( zmin, z );
					}
					else
					{
						zmin = QMAX( zmin, i+1 );
						zmax = QMIN( zmax, z );
					}

				}
				else
				{
					//4 lines to test
					double gradx = ( (double)target.y*(double)z - (double)y*(double)i ) / ( (double)target.y*(double)x - (double)y*(double)target.x );
					double grady = ( (double)target.x*(double)z - (double)x*(double)i ) / ( (double)y*(double)target.x - (double)target.y*(double)x );

					//Console::instance()->send( QString( "gradx:%1,grady:%2\n" ).arg( gradx ).arg( grady ) );
					//Console::instance()->send( QString( "Gradient:%1,Offset:%2\n" ).arg( gradient ).arg( offset ) );
					double temp;
					temp = specialFloor( gradient*( (double)((*pit).x) - 0.5 ) + offset );
					//Console::instance()->send( QString( "temp1:%1\n" ).arg( temp ) );
					if( ( temp >= ((double)((*pit).y)-0.5) ) && ( temp <= ((double)((*pit).y)+0.5) ) )
					{
						if( z1 > -300 )
						{
							z2 = gradx * ( (double)((*pit).x)-0.5 ) + grady * temp;
						}
						else
						{	
							z1 = gradx * ( (double)((*pit).x)-0.5 ) + grady * temp;
						}
						//Console::instance()->send( QString( "1:i:%1,tx:%2,ty:%3,cy:%4,cy:%5\n" ).arg( i ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
						//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					}
					temp = specialFloor( gradient*( (double)((*pit).x) + 0.5 ) + offset );
					//Console::instance()->send( QString( "temp2:%1\n" ).arg( temp ) );
					if( ( temp >= ((double)((*pit).y)-0.5) ) && ( temp <= ((double)((*pit).y)+0.5) ) )
					{
						if( z1 > -300 )
						{
							z2 = gradx * ( (double)((*pit).x)+0.5 ) + grady * temp;
						}
						else
						{	
							z1 = gradx * ( (double)((*pit).x)+0.5 ) + grady * temp;
						}
						//Console::instance()->send( QString( "2:i:%1,tx:%2,ty:%3,cy:%4,cy:%5\n" ).arg( i ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
						//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					}
					temp = specialFloor( (double)((*pit).y) - 0.5 - offset ) / gradient;
					//Console::instance()->send( QString( "temp3:%1\n" ).arg( temp ) );
					if( ( temp > ((double)((*pit).x)-0.5) ) && ( temp < ((double)((*pit).x)+0.5) ) )
					{
						if( z1 > -300 )
						{
							z2 = gradx * temp + grady * ((double)((*pit).y)-0.5);
						}
						else
						{
							z1 = gradx * temp + grady * ((double)((*pit).y)-0.5);
						}
						//Console::instance()->send( QString( "3:i:%1,tx:%2,ty:%3,cy:%4,cy:%5\n" ).arg( i ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
						//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					}
					temp = specialFloor( (double)((*pit).y) + 0.5 - offset ) / gradient;
					//Console::instance()->send( QString( "temp4:%1\n" ).arg( temp ) );
					if( ( temp > ((double)((*pit).x)-0.5) ) && ( temp < ((double)((*pit).x)+0.5) ) )
					{
						if( z1 > -300 )
						{
							z2 = gradx * temp + grady * ((double)((*pit).y)+0.5);
						}
						else
						{
							z1 = gradx * temp + grady * ((double)((*pit).y)+0.5);
						}
						//Console::instance()->send( QString( "4:i:%1,tx:%2,ty:%3,cy:%4,cy:%5\n" ).arg( i ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
						//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					}
					
					//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					if( z1 > z2 )
					{
						zmin = (SI08)floor( z2 );
						zmax = (SI08)ceilf( z1 );
					}
					else
					{
						zmin = (SI08)floor( z1 );
						zmax = (SI08)ceilf( z2 );
					}

					if( z2 == -300 )
					{
						zmin = (SI08)floor( z1 );
					}

					if( dz > 0 )
					{
						zmax = QMIN( zmax, i );
						zmin = QMAX( zmin, z );
					}
					else
					{
						zmin = QMAX( zmin, i+1 );
						zmax = QMIN( zmax, z );
					}
					//Console::instance()->send( QString( "zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );
				}

				/*SI08 zmin = (SI08)floor( i - dz*sqrt( ((double)target.x - (double)(*pit).x)*((double)target.x - (double)(*pit).x) + ((double)target.y - (double)(*pit).y)*((double)target.y - (double)(*pit).y) ) );
				SI08 zmax;
				//Console::instance()->send( QString( "zmin:%1,dz:%2\n" ).arg( zmin ).arg( dz ) );
				if( dz > 0 )
				{
					zmin = QMAX( (SI08)floor( zmin - dz/2 ), z+1 );
					zmax = QMIN( zmin + dz + 1, target.z+targetheight+1 );	//to prevent floor-mistakes
				}
				else
				{
					zmin = QMIN( (SI08)floor( zmin + dz/2 ), target.z+1 );
					zmax = QMAX( zmin - dz + 1, z );	//to prevent floor-mistakes
				}*/
	
				// Texture mapping  
				map1 = Map->seekMap( *pit );
				map2 = Map->seekMap( Coord_cl( (*pit).x + sgn_x, (*pit).y + sgn_y, (*pit).z, map ) );
			
				//Console::instance()->send( QString( "maphoehe:%1\n" ).arg( map1.z ) );
				StaticsIterator msi = Map->staticsIterator( *pit );
				if( (map1.id != 2) && (map2.id != 2) ) 
				{
					if( ( map1.z >= zmin ) && ( map1.z <= zmax ) )
					{
						//its just in our way
						//Console::instance()->send( QString( "Map gescheitert\n" ) );
						blocked = true;
						break;
					}
	
					//now we have to test, if this tile is under our line and the next above or
					//vice verse
					//in this case, both dont cut our line, but the mapconnection between them
					//should do
					if( ( ( map1.z < map2.z ) && ( map1.z < zmin ) && ( map2.z > zmax+dz ) ) ||						// 1) lineofsight collides with a map "wall"
						( ( map1.z > map2.z ) && ( map1.z > zmin ) && ( map2.z < zmax-dz ) ) ||
						( ( ( map1.id >= 431  && map1.id <= 432  ) ||	// 3) lineofsight cuts a mountain
						( map1.id >= 467  && map1.id <= 475  ) ||
						( map1.id >= 543  && map1.id <= 560  ) ||
						( map1.id >= 1754 && map1.id <= 1757 ) ||
						( map1.id >= 1787 && map1.id <= 1789 ) ||
						( map1.id >= 1821 && map1.id <= 1824 ) ||
						( map1.id >= 1851 && map1.id <= 1854 ) ||
						( map1.id >= 1881 && map1.id <= 1884 ) ) &&
						( posHigherThanMap ) && ( msi.atEnd() ) ) ) // mountains cut only if we are not beneath them
					{
						//Console::instance()->send( QString( "map1:%1,map2:%2\n" ).arg( map1.z ).arg( map2.z ) );
						blocked = true;
						break;
					}
				}	 
				
				//Console::instance()->send( QString( "after map\n" ) );
	
				// Statics
				tile_st tile;
				while( !msi.atEnd() )
				{
					tile = TileCache::instance()->getTile( msi->itemid );
					//if it is in our way
					//Console::instance()->send( QString( "tilepos:%1,zmax:%2" ).arg( msi->zoff ).arg( zmax ) );
					//Console::instance()->send( QString( "zmin:%3\n" ).arg( zmin ) );
					if( ( zmax >= msi->zoff ) && ( zmin <= ( msi->zoff + tile.height ) ) )
					{
						//Console::instance()->send( QString( "statictile, id: %1\n" ).arg( msi->itemid ) );
						if( tile.isNoShoot() )
						{
							blocked = true;
							break;
						}
					}
		
					++msi;
				}
				if( blocked )
				{
					break;
				}
				
				//Console::instance()->send( QString( "after statics\n" ) );
				// Items
				RegionIterator4Items rj( (*pit), 0 );
				for( rj.Begin(); !rj.atEnd(); rj++ )
				{
					P_ITEM pi = rj.GetData();
					if( pi && pi->id() < 0x4000 )
					{
						tile = TileCache::instance()->getTile( pi->id() );
						if(	( zmax >= pi->pos().z ) && ( zmin <= ( pi->pos().z + tile.height ) ) && ( pi->visible() == 0 ) )
						{
							//Console::instance()->send( QString( "item, id: %1" ).arg( pi->id() ) );
							if( tile.isNoShoot() )
							{
								blocked = true;
								break;
							}
						}	
					}
				}
				if( blocked )
				{
					break;
				}
	
				//Console::instance()->send( QString( "after items\n" ) );
				// Multis
				QPtrListIterator< cItem > mit( multis );
				P_ITEM pi;
				while( ( pi = mit.current() ) )
				{
					MultiDefinition* def = MultiCache::instance()->getMulti( pi->id() - 0x4000 );
					if ( !def )
						continue;
					QValueVector<multiItem_st> multi = def->getEntries();
					for( j = 0; j < multi.size(); ++j )
					{
						if( ( multi[j].visible ) && ( pi->pos().x + multi[j].x == (*pit).x ) &&
							( pi->pos().y + multi[j].y == (*pit).y ) )			
						{
							tile = TileCache::instance()->getTile( multi[j].tile );
							if( ( zmax >= pi->pos().z + multi[j].z ) &&
								( zmin <= pi->pos().z + multi[j].z + tile.height ) )
							{
								if( tile.isNoShoot() )
								{
									blocked = true;
									break;
								}
							}	
						}
					}
					++mit;
				}
				//Console::instance()->send( QString( "after multis\n" ) );
				++pit;
			}
	
			if( !blocked )
				return true;
		}
		//there was no line to see through
		return false;
	}
	//now touch=true
	else
	{
		//Console::instance()->send( "touch\n" );
		double dz_up, dz_down;
		double gradient;
		double offset;
		if( (sgn_x == 0) && (sgn_y == 0) )
		{
			dz_up = ( (double)targetheight + (double)target.z ) - (double)z;
			dz_down = (double)target.z - ( (double)z - (double)15 );
			gradient = 1; //only to prevent problems, isnt used
			offset = 1;
		}
		else
		{
			//Console::instance()->send( QString( "xdiff:%1,ydiff:%2\n" ).arg( (double)target.x - (double)x ).arg( (double)target.y - (double)y ) );
			dz_up = ( ( (double)targetheight + (double)target.z ) - (double)z ) / sqrt( ((double)target.x - (double)x)*((double)target.x - (double)x) + ((double)target.y - (double)y)*((double)target.y - (double)y) );
			dz_down = ( (double)target.z - ( (double)z - (double)15 ) ) / sqrt( ((double)target.x - (double)x)*((double)target.x - (double)x) + ((double)target.y - (double)y)*((double)target.y - (double)y) );
			gradient = (double)m / (double)n;
			offset = 0.5*( (double)y + (double)target.y - gradient*( x + target.x ) );
		}
	
		map_st map1, map2;
		SI32 j;
	
		bool posHigherThanMap;
		map1 = Map->seekMap( (*this) );
		if( map1.z > z )
		{
			posHigherThanMap = false;
		}
		else
		{
			posHigherThanMap = true;
		}
		
		//Console::instance()->send( QString( "after first things\n" ) );
		QValueList< Coord_cl >::iterator pit = collisions.begin();
		while( pit != collisions.end() )
		{
			//Console::instance()->send( QString( "coordinate:%1,%2\n" ).arg( (*pit).x ).arg( (*pit).y ) );				
			//lets see what z-coordinates we have to test
			//anmerkung: touch kommt nur für chars vor, grösse von chars ist 15
			//SI08 zmin = (SI08)floor(  (double)z - (double)sourceheight + dz_down*sqrt( ((double)target.x - (double)(*pit).x)*((double)target.x - (double)(*pit).x) + ((double)target.y - (double)(*pit).y)*((double)target.y - (double)(*pit).y) ) );
			//SI08 zmax = (SI08)floor(  (double)z + dz_up*sqrt( ((double)target.x - (double)(*pit).x)*((double)target.x - (double)(*pit).x) + ((double)target.y - (double)(*pit).y)*((double)target.y - (double)(*pit).y) ) );
			SI08 zmin, zmax;
			double z1_up = -300;
			double z2_up = -300;
			double z1_down = -300;
			double z2_down = -300;
			bool targetpos = false;
			//Console::instance()->send( QString( "dz_down:%3,dz_up:%4\n" ).arg( dz_down ).arg( dz_up ) );

			if( (sgn_x == 0) && (sgn_y == 0) )
			{
				if( dz_up > 0 )
				{
					zmin = z+1;
					zmax = target.z;
				}
				else
				{
					zmin = target.z+1;
					zmax = z;
				}
				targetpos = true;
				if( (dz_up >= 0) && (dz_down >= 0) )
				{
					if( zmin < target.z )
					{
						zmax = target.z -1;
					}
					else
					{
						//we ignore this coordinate
						++pit;
						continue;
					}
				}
				else if( (dz_up <= 0) && (dz_down <= 0) )
				{
					if( zmax > target.z + targetheight+1 )
					{
						zmin = target.z + targetheight + 2;
					}
					else
					{
						++pit;
						continue;
					}
				}
				else 
				{
					//we may have to split the test into two if we would do it exactly
					//but i think we can throw away the test from down in this case
					if( zmax > target.z + targetheight+1 )
					{
						zmin = target.z + targetheight + 2;
					}
					else if( zmin < target.z )
					{
						zmax = target.z -1;
					}
					else
					{
						++pit;
						continue;
					}
				}
			}
			else if( sgn_x == 0 )
			{
				z1_up = target.z + targetheight - dz_up*( fabs( (double)target.y - (double)((*pit).y) ) -0.5 ); 
				z2_up = target.z + targetheight - dz_up*( fabs( (double)target.y - (double)((*pit).y) ) +0.5 );
			
				z1_down = target.z - dz_down*( fabs( (double)target.y - (double)((*pit).y) ) -0.5 );
				z2_down = target.z - dz_down*( fabs( (double)target.y - (double)((*pit).y) ) +0.5 );

				//Console::instance()->send( QString( "ty:%2,cy:%3\n" ).arg( target.y ).arg( (*pit).y ) );
				//Console::instance()->send( QString( "z1_up:%1,z2_up:%2,z1_down:%3,z2_down:%4\n" ).arg( z1_up ).arg( z2_up ).arg( z1_down ).arg( z2_down ) );

				zmax = QMAX( ceil( z1_up ), ceil( z2_up ) );
				zmin = QMIN( floor( z1_down ), floor( z2_down ) );

				//Console::instance()->send( QString( "y:zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( dz_up > 0 )
				{
					zmax = QMIN( zmax, target.z+targetheight );
				}
				else
				{
					zmax = QMIN( zmax, z );
				}

				//Console::instance()->send( QString( "y2:zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( dz_down > 0 )
				{
					zmin = QMAX( zmin, z-14 );
				}
				else
				{
					zmin = QMAX( zmin, target.z+1 );
				}

				//Console::instance()->send( QString( "y3:zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( (*pit).y == target.y )
				{
					targetpos = true;
					if( (dz_up >= 0) && (dz_down >= 0) )
					{
						if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							//we ignore this coordinate
							++pit;
							continue;
						}
					}
					else if( (dz_up <= 0) && (dz_down <= 0) )
					{
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else
						{
							++pit;
							continue;
						}
					}
					else 
					{
						//we may have to split the test into two if we would do it exactly
						//but i think we can throw away the test from down in this case
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							++pit;
							continue;
						}
					}
					//Console::instance()->send( QString( "y4:zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );
				}
			}
			else if( sgn_y == 0 )
			{
				z1_up = target.z + targetheight - dz_up*( fabs( (double)target.x - (double)((*pit).x) ) -0.5 ); 
				z2_up = target.z + targetheight - dz_up*( fabs( (double)target.x - (double)((*pit).x) ) +0.5 );
			
				z1_down = target.z - dz_down*( fabs( (double)target.x - (double)((*pit).x) ) -0.5 );
				z2_down = target.z - dz_down*( fabs( (double)target.x - (double)((*pit).x) ) +0.5 );

				//Console::instance()->send( QString( "tx:%2,cx:%3\n" ).arg( target.x ).arg( (*pit).x ) );
				//Console::instance()->send( QString( "z1_up:%1,z2_up:%2,z1_down:%3,z2_down:%4\n" ).arg( z1_up ).arg( z2_up ).arg( z1_down ).arg( z2_down ) );

				zmax = QMAX( ceil( z1_up ), ceil( z2_up ) );
				zmin = QMIN( floor( z1_down ), floor( z2_down ) );

				if( dz_up > 0 )
				{
					zmax = QMIN( zmax, target.z+targetheight );
				}
				else
				{
					zmax = QMIN( zmax, z );
				}

				if( dz_down > 0 )
				{
					zmin = QMAX( zmin, z-14 );
				}
				else
				{
					zmin = QMAX( zmin, target.z+1 );
				}

				if( (*pit).x == target.x )
				{
					targetpos = true;
					if( (dz_up >= 0) && (dz_down >= 0) )
					{
						if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							//we ignore this coordinate
							++pit;
							continue;
						}
					}
					else if( (dz_up <= 0) && (dz_down <= 0) )
					{
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else
						{
							++pit;
							continue;
						}
					}
					else 
					{
						//we may have to split the test into two if we would do it exactly
						//but i think we can throw away the test from down in this case
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							++pit;
							continue;
						}
					}
				}
			}
			else
			{
				double gradx_up = ( (double)target.y*(double)z - (double)y*(double)(target.z + targetheight) ) / ( (double)target.y*(double)x - (double)y*(double)target.x );
				double grady_up = ( (double)target.x*(double)z - (double)x*(double)(target.z + targetheight) ) / ( (double)y*(double)target.x - (double)target.y*(double)x );
				double gradx_down = ( (double)target.y*(double)(z-15) - (double)y*(double)(target.z) ) / ( (double)target.y*(double)x - (double)y*(double)target.x );
				double grady_down = ( (double)target.x*(double)(z-15) - (double)x*(double)(target.z) ) / ( (double)y*(double)target.x - (double)target.y*(double)x );

				//Console::instance()->send( QString( "gradx_up:%1,grady_up:%2,gradx_down:%3,grady_down:%4\n" ).arg( gradx_up ).arg( grady_up ).arg( gradx_down ).arg( grady_down ) );
				//Console::instance()->send( QString( "Gradient:%1,Offset:%2\n" ).arg( gradient ).arg( offset ) );

				double temp = specialFloor( gradient*( (double)((*pit).x) - 0.5 ) + offset );
				//Console::instance()->send( QString( "temp1:%1\n" ).arg( temp ) );
				if( ( temp >= ((double)((*pit).y)-0.5) ) && ( temp <= ((double)((*pit).y)+0.5) ) )
				{
					if( z1_up > -300 )
					{
						z2_up = gradx_up * ( (double)((*pit).x)-0.5 ) + grady_up * temp;
						z2_down = gradx_down * ( (double)((*pit).x)-0.5 ) + grady_down * temp;
					}
					else
					{
						z1_up = gradx_up * ( (double)((*pit).x)-0.5 ) + grady_up * temp;
						z1_down = gradx_down * ( (double)((*pit).x)-0.5 ) + grady_down * temp;
					}
					//Console::instance()->send( QString( "tx:%1,ty:%2,cy:%3,cy:%4\n" ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );
				}
				temp = specialFloor( gradient*( (double)((*pit).x) + 0.5 ) + offset );
				//Console::instance()->send( QString( "temp2:%1\n" ).arg( temp ) );
				if( ( temp >= ((double)((*pit).y)-0.5) ) && ( temp <= ((double)((*pit).y)+0.5) ) )
				{
					if( z1_up > -300 )
					{
						z2_up = gradx_up * ( (double)((*pit).x)+0.5 ) + grady_up * temp;
						z2_down = gradx_down * ( (double)((*pit).x)+0.5 ) + grady_down * temp;
					}
					else
					{	
						z1_up = gradx_up * ( (double)((*pit).x)+0.5 ) + grady_up * temp;
						z1_down = gradx_down * ( (double)((*pit).x)+0.5 ) + grady_down * temp;
					}
					//Console::instance()->send( QString( "tx:%1,ty:%2,cy:%3,cy:%4\n" ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );
				}
				temp = specialFloor( (double)((*pit).y) - 0.5 - offset ) / gradient;
				//Console::instance()->send( QString( "temp3:%1\n" ).arg( temp ) );
				if( ( temp > ((double)((*pit).x)-0.5) ) && ( temp < ((double)((*pit).x)+0.5) ) )
				{
					if( z1_up > -300 )
					{
						z2_up = gradx_up * temp + grady_up * ((double)((*pit).y)-0.5);
						z2_down = gradx_down * temp + grady_down * ((double)((*pit).y)-0.5);
					}
					else
					{
						z1_up = gradx_up * temp + grady_up * ((double)((*pit).y)-0.5);
						z1_down = gradx_down * temp + grady_down * ((double)((*pit).y)-0.5);
					}
					//Console::instance()->send( QString( "tx:%1,ty:%2,cy:%3,cy:%4\n" ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );
				}
				temp = specialFloor( (double)((*pit).y) + 0.5 - offset ) / gradient;
				//Console::instance()->send( QString( "temp4:%1\n" ).arg( temp ) );
				if( ( temp > ((double)((*pit).x)-0.5) ) && ( temp < ((double)((*pit).x)+0.5) ) )
				{
					if( z1_up > -300 )
					{
						z2_up = gradx_up * temp + grady_up * ((double)((*pit).y)+0.5);
						z2_down = gradx_down * temp + grady_down * ((double)((*pit).y)+0.5);
					}
					else
					{
						z1_up = gradx_up * temp + grady_up * ((double)((*pit).y)+0.5);
						z1_down = gradx_down * temp + grady_down * ((double)((*pit).y)+0.5);
					}
					//Console::instance()->send( QString( "tx:%1,ty:%2,cy:%3,cy:%4\n" ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );
				}

				//Console::instance()->send( QString( "ergebnis: z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );

				if( z2_up == -300 )
				{
					zmin = floor( z1_down );
					zmax = ceil( z1_up );
				}
				else
				{
					zmin = QMIN( floor( z1_down ), floor( z2_down ) );
					zmax = QMAX( ceil( z1_up ), ceil( z2_up ) );
				}

				//Console::instance()->send( QString( "zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( dz_up > 0 )
				{
					zmax = QMIN( zmax, target.z+targetheight );
				}
				else
				{
					zmax = QMIN( zmax, z );
				}

				if( dz_down > 0 )
				{
					zmin = QMAX( zmin, z-14 );
				}
				else
				{
					zmin = QMAX( zmin, target.z+1 );
				}

				//Console::instance()->send( QString( "zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( ((*pit).x == target.x) && ((*pit).y == target.y) )
				{
					targetpos = true;
					if( (dz_up >= 0) && (dz_down >= 0) )
					{
						if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							//we ignore this coordinate
							++pit;
							continue;
						}
					}
					else if( (dz_up <= 0) && (dz_down <= 0) )
					{
						if( zmax > target.z + targetheight+1)
						{
							zmin = target.z + targetheight + 2;
						}
						else
						{
							++pit;
							continue;
						}
					}
					else 
					{
						//we may have to split the test into two if we would do it exactly
						//but i think we can throw away the test from down in this case
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							++pit;
							continue;
						}
					}
				}				
			}
			//Console::instance()->send( QString( "zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

			// Texture mapping  
			map1 = Map->seekMap( *pit );
			map2 = Map->seekMap( Coord_cl( (*pit).x + sgn_x, (*pit).y + sgn_y, (*pit).z, map ) );
			
			//Console::instance()->send( QString( "try2" ) );
			StaticsIterator msi = Map->staticsIterator( *pit );
			RegionIterator4Items rj( (*pit), 0 );
			if( (map1.id != 2) && (map2.id != 2) ) 
			{
				if( ( map1.z > zmin ) && ( map1.z < zmax ) )
				{
					//its just in our way
					//Console::instance()->send( QString( "map cut 1\n" ) );
					return false;
				}
				
				//now we have to test, if this tile is under our line and the next above or
				//vice verse
				//in this case, both dont cut our line, but the mapconnection between them
				//should do
				land_st tile = TileCache::instance()->getLand( map1.id );
				if( ( ( map1.z < map2.z ) && ( map1.z < zmin ) && ( map2.z > zmax+dz_down ) && !targetpos ) ||						// 1) lineofsight collides with a map "wall"
					( ( map1.z > map2.z ) && ( map1.z > zmin ) && ( map2.z < zmin+dz_down ) && !targetpos ) ||
					( tile.isBlocking() && posHigherThanMap && msi.atEnd() && rj.atEnd() ) )
				{
					//Console::instance()->send( QString( "map1:%1,map2:%2,map1id:%3\n" ).arg( map1.z ).arg( map2.z ).arg( map1.id ) );
					if( ( map1.z < map2.z ) && ( map1.z < zmin ) && ( map2.z > zmax+dz_down ) )
					{
						//Console::instance()->send( QString( "mapcut1\n" ) ); 
					}
					else if( ( map1.z > map2.z ) && ( map1.z > zmin ) && ( map2.z < zmin+dz_down ) )
					{
						//Console::instance()->send( QString( "mapcut2\n" ) );
					}
					else if( tile.isBlocking() && posHigherThanMap && msi.atEnd() && rj.atEnd() )
					{
						//Console::instance()->send( QString( "mapcut3\n" ) );
					}
					else
					{
						//Console::instance()->send( QString( "mapcut: this isnt possible\n" ) );
					}
					return false;
				}
			}	 
			
			//Console::instance()->send( QString( "after map\n" ) );
		
			// Statics
			tile_st tile;
			while( !msi.atEnd() )
			{
				tile = TileCache::instance()->getTile( msi->itemid );
				//Console::instance()->send( QString( "statictilepos:%1,zmax:%2,zmin:%3\n" ).arg( msi->zoff ).arg( zmax ).arg( zmin ) );
				//if it is in our way
				if(	( zmax >= msi->zoff ) && ( zmin <= ( msi->zoff + tile.height ) ) )
				{
					if( tile.isBlocking() || tile.isRoofOrFloorTile() )
					{
						return false;
					}
				}
			
				++msi;
			}
			
			//Console::instance()->send( QString( "after statics\n" ) );
			// Items
			//Console::instance()->send( QString( "Items at: %1,%2,%3,%4\n" ).arg( (*pit).x ).arg( (*pit).y ).arg( (*pit).z ).arg( (*pit).map ) );
			for( rj.Begin(); !rj.atEnd(); rj++ )
			{
				//Console::instance()->send( QString( "foritem\n" ) );
				P_ITEM pi = rj.GetData();
				if( pi && pi->id() < 0x4000 )
				{
					tile = TileCache::instance()->getTile( pi->id() );
					//Console::instance()->send( QString( "itemtilepos:%1,zmax:%2,zmin:%3\n" ).arg( pi->pos().z ).arg( zmax ).arg( zmin ) );
					if(	( zmax >= pi->pos().z ) && ( zmin <= ( pi->pos().z + tile.height ) ) && ( pi->visible() == 0 ) )
					{
						if( tile.isBlocking() || tile.isRoofOrFloorTile() )
						{
							//Console::instance()->send( QString( "Item:%1,Z:%2,Height:%3\n" ).arg( pi->id() ).arg( pi->pos().z ).arg( tile.height ) );
							return false;
						}
					}	
				}
			}
			
			//Console::instance()->send( QString( "after items\n" ) );
			// Multis
			QPtrListIterator< cItem > mit( multis );
			P_ITEM pi;
			while( ( pi = mit.current() ) )
			{
				MultiDefinition* def = MultiCache::instance()->getMulti( pi->id() - 0x4000 );
				if ( !def )
				{
					++mit;
					continue;
				}
				QValueVector<multiItem_st> multi = def->getEntries();
				for( j = 0; j < multi.size(); ++j )
				{
					if( ( multi[j].visible ) && ( pi->pos().x + multi[j].x == (*pit).x ) &&
						( pi->pos().y + multi[j].y == (*pit).y ) )			
					{
						tile = TileCache::instance()->getTile( multi[j].tile );
						if( ( zmax >= pi->pos().z + multi[j].z ) &&
							( zmin <= pi->pos().z + multi[j].z + tile.height ) )
						{
							if( tile.isBlocking() || tile.isRoofOrFloorTile() )
							{
								return false;							
							}
						}	
					}
				}
				++mit;
			}
			//Console::instance()->send( QString( "after multis\n" ) );
			++pit;
		}
		return true;
	}
}
Ejemplo n.º 12
0
/*
CXXCircle::CXXCircle (const CXXCircle &oldOne) :
theAtomJ(oldOne.getAtomJ()),
theBallJ(oldOne.getBallJ()),
theParent(oldOne.getParent()),
centreOfSecondSphere(oldOne.getCentreOfSecondSphere()),
theNormal(oldOne.getNormal()),
radiusOfSecondSphere(oldOne.getRadiusOfSecondSphere()),
radiusOfSphere(oldOne.getRadiusOfSphere()),
centreOfCircle(oldOne.centreOfCircle),
centreToCircle(oldOne.getCentreToCircle()),
referenceUnitRadius(oldOne.getReferenceUnitRadius()),
radiusOfCircle(oldOne.getRadiusOfCircle()),
theNodes(oldOne.getNodes()),
nIntersectingCircles(oldOne.getNIntersectingCircles()),
completelyEaten(oldOne.getEaten())
{
	for (unsigned i=0; i<oldOne.getNNodes(); i++){
		theNodes[i].setParent(this);
	}
	theStarts.resize(oldOne.nSegments());
	theStops.resize(oldOne.nSegments());
	for (unsigned i=0; i<oldOne.nSegments(); i++){
		theStarts[i] = oldOne.start(i);
		theStops[i] = oldOne.stop(i);
	}
}
*/
int CXXCircle::meetsCircle(const CXXCircle &otherCircle, vector<CXXCoord, CXX::CXXAlloc<CXXCoord> > &nodeList) const{
	
	// check if there is an intersection between this circle and another circle
	// return 0 if there is intersection
	// 2 if the this circle is entirely swallowedd by the atom that generates the otherCircle, 
	// 1 if the converse of the above applies
	// and 3 otherwise
	
	CXXCoord intersectA, intersectB;
	
	// some simplifications:	rj - centreToCircle of current (this) arc circle
	//							rk - centreToCircle of newArc circle
	
	CXXCoord rj(getCentreToCircle());
	CXXCoord rk(otherCircle.getCentreToCircle());
	CXXCoord rjxrk;
	
	// following Totrovs vector match - plane intersection of the two circles.
	// PlaneIntersectioon points at intersection of two this- and new- circlePlanes
	// with plane spanned by the centre of the two VDW spheres and the centre of thisArc
	
	// some dummy variables
	
	double rjrk, rjSquared, rkSquared;
	double a, b, distSq, radiusOfSphereSq, x;
	
	rjSquared = rj*rj;
	rkSquared = rk*rk;
	rjrk = rj*rk;
	
	a = ((rjSquared - rjrk)*rkSquared)/(rjSquared*rkSquared - rjrk*rjrk);
	b = ((rkSquared - rjrk)*rjSquared)/(rjSquared*rkSquared - rjrk*rjrk);
	
	// with this now:
	CXXCoord planeIntersect((rj*a) + (rk*b));
	
	// if the distance between the intersection point of the three planes is closer then
	//the radius of the VDW + probe sphere, then the two circle of this arc and new arc intersect....
	
	// distance of intersectino point
	distSq = planeIntersect*planeIntersect;			
	radiusOfSphereSq = radiusOfSphere*radiusOfSphere;
	
	// distance of (VDW + probe) sphere of thisAtom = radiusOfSphere therefore:
	if (distSq < radiusOfSphereSq) {
		
		// the CIRCLES corresponding to the new and the current (old) arc cross each other
		// the crossingpoints of the two CIRCLES are the points where the line defined by the 
		// intersection of the two arcplanes cuts throught the new circle 
		
		// the intersection line is perpendicular the plane spanned by rj and rk - that is parallel to:
		rjxrk = rj ^ rk;
		rjxrk.normalise();
		
		//the intersection line is defined by this vector and one of its point - the planeIntersection vector:
		// => line planeIntersect + x*(rjxrk), x some real number
		// intersection points have x=+-0.5*length of the secante of circle therefore:
		x = sqrt(radiusOfSphereSq - distSq);
		
		rjxrk.scale(x);
		
		//We need to see whether the centreToCircle vectors of these circles indicate that the
		//corresponding torus is "behind" the centre of the first circle, or in front.  This determines
		//Whether the first or the second calculated intersection point represents a point to start drawing.
		//It boils down to a sort of parity thing.  Think about it !
		
		CXXCoord unitCentreToCircle(centreToCircle);
		unitCentreToCircle.normalise();
	    int forwardOne = (theNormal*unitCentreToCircle > 0.?1:-1);
		CXXCoord otherCircleUnitCentreToCircle(otherCircle.getCentreToCircle());
		otherCircleUnitCentreToCircle.normalise();
	    int forwardTwo = (otherCircle.getNormal()*otherCircleUnitCentreToCircle > 0.?1:-1);
		if (forwardOne*forwardTwo > 0){
			intersectA = planeIntersect+rjxrk;
			intersectB = planeIntersect-rjxrk;
		}
		else {
			intersectB = planeIntersect+rjxrk;
			intersectA = planeIntersect-rjxrk;
		}
		nodeList[0] = intersectA + getCentreOfSphere();
		nodeList[1] = intersectB + getCentreOfSphere();
		
		return 0;
		
	}
	else {
		//We get here if the two circles don't intersect
		//Now check whether this circle falls somewhere inside the
		//sphere indicated by the other circle.  If it does, then 
		//(given it doesn't intersect), it must *always* be inside
		// otherwise it must *always* be outside
		
		if (otherCircle.accIsBehind(getCentreOfCircle()) == 0) return 2;
		if(accIsBehind(otherCircle.getCentreOfCircle()) == 0) return 1;
		return 3;
	}
	
}
Ejemplo n.º 13
0
int main(int argc, char** argv)
{
   if (argc == 1) {
        std::cout << "Usage: cpchop_depthtrend gridfilename=filename.grdecl [zresolution=1] [zlen=1] [ilen=5] [jlen=5] " << std::endl;
        std::cout << "       [zlen=5] [imin=] [imax=] [jmin=] [jmax=] [upscale=true] [resettoorigin=true]" << std::endl;
        std::cout << "       [seed=111] [z_tolerance=0.0] [minperm=1e-9] " << std::endl;
        exit(1);
    }

    Opm::parameter::ParameterGroup param(argc, argv);
    std::string gridfilename = param.get<std::string>("gridfilename");
    Opm::CornerPointChopper ch(gridfilename);

    // The cells with i coordinate in [imin, imax) are included, similar for j.
    // The z limits may be changed inside the chopper to match actual min/max z.
    const int* dims = ch.dimensions();
    int imin = param.getDefault("imin", 0);
    int imax = param.getDefault("imax", dims[0]);
    int jmin = param.getDefault("jmin", 0);
    int jmax = param.getDefault("jmax", dims[1]);
    double zmin = param.getDefault("zmin", ch.zLimits().first);
    double zmax = param.getDefault("zmax", ch.zLimits().second);
    int ilen = param.getDefault("ilen", imax - imin);
    int jlen = param.getDefault("jlen", jmax - jmin);
    double zresolution = param.getDefault("zresolution", 1.0);
    double zlen = param.getDefault("zlen", zresolution);
    bool upscale = param.getDefault("upscale", true);
    bool resettoorigin = param.getDefault("resettoorigin", true);
    boost::mt19937::result_type userseed = param.getDefault("seed", 0);

    int outputprecision = param.getDefault("outputprecision", 8);
    std::string filebase = param.getDefault<std::string>("filebase", "");
    std::string resultfile = param.getDefault<std::string>("resultfile", "");

    double minperm = param.getDefault("minperm", 1e-9);
    double minpermSI = Opm::unit::convert::from(minperm, Opm::prefix::milli*Opm::unit::darcy);

    double z_tolerance = param.getDefault("z_tolerance", 0.0);
    double residual_tolerance = param.getDefault("residual_tolerance", 1e-8);
    double linsolver_verbosity = param.getDefault("linsolver_verbosity", 0);
    double linsolver_type = param.getDefault("linsolver_type", 1);
        
    // Check for unused parameters (potential typos).
    if (param.anyUnused()) {
	std::cout << "*****     WARNING: Unused parameters:     *****\n";
	param.displayUsage();
    }
    
    // Check that we do not have any user input 
    // that goes outside the coordinates described in
    // the cornerpoint file (runtime-exception will be thrown in case of error)
    ch.verifyInscribedShoebox(imin, ilen, imax, 
			      jmin, jlen, jmax,
			      zmin, zlen, zmax);

    // Random number generator from boost.
    boost::mt19937 gen;
    
    // Seed the random number generators with the current time, unless specified on command line
    // Warning: Current code does not allow 0 for the seed!!
    if (userseed == 0) {
        gen.seed(time(NULL));
    }
    else {
        gen.seed(userseed);
    }
        

    // Note that end is included in interval for uniform_int.
    boost::uniform_int<> disti(imin, imax - ilen);
    boost::uniform_int<> distj(jmin, jmax - jlen);
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > ri(gen, disti);
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rj(gen, distj);
    
    // Storage for results
    std::vector<double> zstarts;
    std::vector<double> porosities;
    std::vector<double> permxs;
    std::vector<double> permys;
    std::vector<double> permzs;

    
    /* z_start is the topmost point of the subsample to extract */
    for (double zstart = 0.0; zstart  <= zmax-zlen; zstart += zresolution) {
        /* Horizontally, we pick by random, even though default behaviour is
           to have ilen=imax-min so that there is no randomness */
        int istart = ri();
        int jstart = rj();
        ch.chop(istart, istart + ilen, jstart, jstart + jlen, zstart, std::min(zstart + zlen,zmax), resettoorigin);
        std::string subsampledgrdecl = filebase;

        // Output grdecl-data to file if a filebase is supplied.
        if (filebase != "") {
            std::ostringstream oss;
            oss << 'Z' << std::setw(4) << std::setfill('0') << zstart;
            subsampledgrdecl += oss.str();
            subsampledgrdecl += ".grdecl";
            ch.writeGrdecl(subsampledgrdecl);
        }

        try { /* The upscaling may fail to converge on icky grids, lets just pass by those */
            if (upscale) {
                Opm::EclipseGridParser subparser = ch.subparser();
                subparser.convertToSI();
                Opm::SinglePhaseUpscaler upscaler;
                upscaler.init(subparser, Opm::SinglePhaseUpscaler::Fixed, minpermSI, z_tolerance,
                              residual_tolerance, linsolver_verbosity, linsolver_type, false);
                
                Opm::SinglePhaseUpscaler::permtensor_t upscaled_K = upscaler.upscaleSinglePhase();
                upscaled_K *= (1.0/(Opm::prefix::milli*Opm::unit::darcy));
                
                
                zstarts.push_back(zstart);
                porosities.push_back(upscaler.upscalePorosity());
                permxs.push_back(upscaled_K(0,0));
                permys.push_back(upscaled_K(1,1));
                permzs.push_back(upscaled_K(2,2));
                
            }   
        }
        catch (...) {
            std::cerr << "Warning: Upscaling chopped subsample at z=" << zstart << "failed, proceeding to next subsample\n";
        }
        
    }
     
    if (upscale) {
        
        // Make stream of output data, to be outputted to screen and optionally to file
        std::stringstream outputtmp;
        
        outputtmp << "################################################################################################" << std::endl;
        outputtmp << "# Results from depth trend analysis on subsamples" << std::endl;
        outputtmp << "#" << std::endl;
        time_t now = time(NULL);
        outputtmp << "# Finished: " << asctime(localtime(&now));
        
        utsname hostname;   uname(&hostname);
        outputtmp << "# Hostname: " << hostname.nodename << std::endl;
        outputtmp << "#" << std::endl;
        outputtmp << "# Options used:" << std::endl;
        outputtmp << "#     gridfilename: " << gridfilename << std::endl;
        outputtmp << "#   i; min,len,max: " << imin << " " << ilen << " " << imax << std::endl;
        outputtmp << "#   j; min,len,max: " << jmin << " " << jlen << " " << jmax << std::endl;
        outputtmp << "#   z; min,len,max: " << zmin << " " << zlen << " " << zmax << std::endl;
        outputtmp << "#      zresolution: " << zresolution << std::endl;
        outputtmp << "################################################################################################" << std::endl;
        outputtmp << "# zstart          porosity                 permx                   permy                   permz" << std::endl;
        
        const int fieldwidth = outputprecision + 8;
        for (size_t sample = 1; sample <= porosities.size(); ++sample) {
            outputtmp << 
                std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << zstarts[sample-1] << '\t' <<
                std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << porosities[sample-1] << '\t' <<
                std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permxs[sample-1] << '\t' <<
                std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permys[sample-1] << '\t' <<
                std::showpoint << std::setw(fieldwidth) << std::setprecision(outputprecision) << permzs[sample-1] << '\t' <<
                std::endl;
        }
        
        if (resultfile != "") {
            std::cout << "Writing results to " << resultfile << std::endl;
            std::ofstream outfile;
            outfile.open(resultfile.c_str(), std::ios::out | std::ios::trunc);
            outfile << outputtmp.str();
            outfile.close();      
        }
        
        
        
        std::cout << outputtmp.str();
    }
}