Esempio n. 1
0
*/	static REBSER *String_List_To_Block(REBCHR *str)
/*
**		Convert a series of null terminated strings to
**		a block of strings separated with '='.
**
***********************************************************************/
{
	REBCNT n;
	REBCNT len = 0;
	REBCHR *start = str;
	REBCHR *eq;
	REBSER *blk;

	while (n = LEN_STR(str)) {
		len++;
		str += n + 1; // next
	}

	blk = Make_Block(len*2);
	SAVE_SERIES(blk);

	str = start;
	while (NZ(eq = FIND_CHR(str+1, '=')) && NZ(n = LEN_STR(str))) {
		Set_Series(REB_STRING, Append_Value(blk), Copy_OS_Str(str, eq-str));
		Set_Series(REB_STRING, Append_Value(blk), Copy_OS_Str(eq+1, n-(eq-str)-1));
		str += n + 1; // next
	}

	Block_As_Map(blk);

	UNSAVE_SERIES(blk);
	return blk;
}
Esempio n. 2
0
/*****************************************************************
DataLine::close()

  closes the resource attached to this data line.
*****************************************************************/
eFlag DataLine::close(Sit S)
{
    sabassert(mode != DLMODE_NONE);
    switch(scheme)
    {
    case URI_FILE:
        {
            sabassert(f);
            if (!fileIsStd)
            {
	      if (fclose(f))
		Err1(S, E1_URI_CLOSE, fullUri);
            };
            f = NULL;
        }; break;
    case URI_ARG:
        break;
    case URI_EXTENSION:
        {
            if (gotWholeDocument)
            {
                NZ(handler) -> freeMemory(handlerUD, S.getProcessor(), buffer);
            }
            else
            {
                if(NZ(handler) -> close(handlerUD, S.getProcessor(), handle))
                    Err1(S, E1_URI_CLOSE, fullUri);
            }
        }; break;
    };
    mode = DLMODE_CLOSED;
    return OK;
}
Esempio n. 3
0
void Tree::excludeStdNamespaces()
{
  NZ(getCurrentInfo()) -> 
    getExcludedNS().addUri(stdPhrase(PHRASE_XML_NAMESPACE));
  if (XSLTree)
    {
      NZ(getCurrentInfo()) -> 
	getExcludedNS().addUri(stdPhrase(PHRASE_XSL_NAMESPACE));
    }
}
Esempio n. 4
0
StylesheetStructure* Tree::createStylesheetStructure(Sit S)
{
    // current subtree is created in Tree::Tree() so must be NZ
    SubtreeInfo *currSubtree = NZ( subtrees.getCurrent() );
    // there is always a structure for an existing subtree
    StylesheetStructure *currStruct  = NZ( currSubtree -> getStructure() );
    // create new structure with precedence one higher
    //StylesheetStructure *newStruct = new StylesheetStructure(
    //currStruct -> getImportPrecedence() + 1);
    StylesheetStructure *newStruct = new StylesheetStructure(0);

    // file newStruct into existing tree if stylesheet structures
    currStruct -> addImportStructure(S, newStruct);
    return newStruct;    
}
Esempio n. 5
0
double CSlotConnPrf::Y2X(double Y)
  {
  double X=0;
  long i0, i1, inc;
  if (m_bYReversed)
    {
    i0=m_Points.GetUpperBound();
    i1=0+1;
    inc=-1;
    }
  else
    {
    i0=0;
    i1=m_Points.GetUpperBound()-1;
    inc=1;
    }
  for (int i=i0; i!=i1; i+=inc)
    if (Y<=m_Points[i].Y)
      break;

  CSlotConnPrfPt & Pt0=m_Points[i];
  CSlotConnPrfPt & Pt1=m_Points[i+inc];

  X=Pt0.X+(Pt1.X-Pt0.X)*(Y-Pt0.Y)/NZ(Pt1.Y-Pt0.Y);

  return X;
  };
Esempio n. 6
0
*/  static void Bind_Relative_Words(REBSER *frame, REBSER *block)
/*
**      Recursive function for relative function word binding.
**
**      Note: frame arg points to an identifying series of the function,
**      not a normal frame. This will be used to verify the word fetch.
**
***********************************************************************/
{
	REBVAL *value = BLK_HEAD(block);
	REBINT n;

	for (; NOT_END(value); value++) {
		if (ANY_WORD(value)) {
			// Is the word (canon sym) found in this frame?
			if (NZ(n = WORDS_HEAD(Bind_Table)[VAL_WORD_CANON(value)])) {
				// Word is in frame, bind it:
				VAL_WORD_INDEX(value) = n;
				VAL_WORD_FRAME(value) = frame; // func body
			}
		}
		else if (ANY_BLOCK(value))
			Bind_Relative_Words(frame, VAL_SERIES(value));
	}
}
Esempio n. 7
0
File: t-pair.c Progetto: Oldes/r3
*/	REBINT PD_Pair(REBPVS *pvs)
/*
***********************************************************************/
{
	REBVAL *sel;
	REBVAL *val;
	REBINT n = 0;
	REBD32 dec;

	if (IS_WORD(sel = pvs->select)) {
		if (VAL_WORD_CANON(sel) == SYM_X) n = 1;
		else if (VAL_WORD_CANON(sel) == SYM_Y) n = 2;
		else return PE_BAD_SELECT;
	}
	else if (IS_INTEGER(sel)) {
		n = Int32(sel);
		if (n != 1 && n !=2) return PE_BAD_SELECT;
	}
	else
		return PE_BAD_SELECT;

	if (NZ(val = pvs->setval)) {
		if (IS_INTEGER(val)) dec = (REBD32)VAL_INT64(val);
		else if (IS_DECIMAL(val)) dec = (REBD32)VAL_DECIMAL(val);
		else return PE_BAD_SET;
		if (n == 1) VAL_PAIR_X(pvs->value) = dec;
		else VAL_PAIR_Y(pvs->value) = dec;
	} else {
		dec = (n == 1 ? VAL_PAIR_X(pvs->value) : VAL_PAIR_Y(pvs->value));
		SET_DECIMAL(pvs->store, dec);
		return PE_USE;
	}

	return PE_OK;
}
Esempio n. 8
0
*/	void Set_Error_Type(ERROR_OBJ *error)
/*
**		Sets error type and id fields based on code number.
**
***********************************************************************/
{
	REBSER *cats;		// Error catalog object
	REBSER *cat;		// Error category object
	REBCNT n;		// Word symbol number
	REBCNT code;

	code = VAL_INT32(&error->code);

	// Set error category:
	n = code / 100 + 1;
	cats = VAL_OBJ_FRAME(Get_System(SYS_CATALOG, CAT_ERRORS));

	if (code >= 0 && n < SERIES_TAIL(cats) &&
		NZ(cat = VAL_SERIES(BLK_SKIP(cats, n)))
	) {
		Set_Word(&error->type, FRM_WORD_SYM(cats, n), cats, n);

		// Find word related to the error itself:
		
		n = code % 100 + 3;
		if (n < SERIES_TAIL(cat))
			Set_Word(&error->id, FRM_WORD_SYM(cat, n), cat, n);
	}
}
Esempio n. 9
0
eFlag DataLine::save(Sit S, const char *data, int length)
{
    sabassert(mode == DLMODE_WRITE); // assume the file open for writing
    // int length = utf16Encoded ? my_wcslen(data) : strlen(data);
    switch (scheme)             // choose the output procedure 
    {
    case URI_FILE:              // file: scheme
        {
            sabassert(f);          // the file must be open
            // fputs(data, f);
            fwrite(data, 1, length, f);
        }; break;
    case URI_ARG:               // arg: scheme
        {
            sabassert(outBuf);     // the output buffer must exist
            outBuf -> nadd(data, length); 
        }; break;
    case URI_EXTENSION:         // external handler
        {
            int actual = length;
            if( NZ(handler) -> put(handlerUD, S.getProcessor(), handle, data, &actual) )
                Err1(S, E1_URI_WRITE, fullUri);
        };
    }
    return OK;
}
Esempio n. 10
0
*/	REBINT Form_Int_Len(REBYTE *buf, REBI64 val, REBINT maxl)
/*
**		Form an integer string into the given buffer. Result will
**		not exceed maxl length, including terminator.
**
**		Returns the length of the string.
**
**		Notes:
**			1. If result is longer than maxl, returns 0 length.
**			2. Make sure you have room in your buffer!
**
***********************************************************************/
{
	REBYTE tmp[MAX_NUM_LEN];
	REBYTE *tp = tmp;
	REBI64 n;
	REBI64 r;
	REBINT len = 0;

	// defaults for problem cases
	buf[0] = '?';
	buf[1] = 0;

	if (maxl == 0) return 0;

	if (val == 0) {
		*buf++ = '0';
		*buf = 0;
		return 1;
	}

	if (val < 0) {
		val = -val;
		*buf++ = '-';
		maxl--;
		len = 1;
	}

	// Generate string in reverse:
	*tp++ = 0;
	while (val != 0) {
		n = val / 10;	// not using ldiv for easier compatibility
		r = val % 10;
		if (r < 0) {	// check for overflow case when val = 0x80000000...
			r = -r;
			n = -n;
		}
		*tp++ = (REBYTE)('0' + (REBYTE)(r));
		val = n;
	}
	tp--;

	if (tp - tmp > maxl) return 0;

	while (NZ(*buf++ = *tp--)) len++;
	return len;
}
Esempio n. 11
0
double CCWashMixEffFnd::Function(double x) 
  {//x is fraction of wash to overflow
  
  //1) All solids go to underflow
  //2) Try meet user requirements for UF conc/liqFrac by adjusting wash fraction to overflow
  //3) Of the liquids reporting to the UF, we want (100%-RqdMixEff%) of liquids to retain mud liquids composition,
  //   the rest is the wash liquids.

  Qu.QSetF(Qm, som_Sol, 1.0, POut);
  Qu.QAddF(Qw, som_Sol, 1.0);
  const double WashLiqToUF = (1.0 - x)*QwLiq;
  const double RqdMudLiqToUF = WashLiqToUF*(1.0/GTZ(RqdMixEff)-1.0);
  const double RqdMudFracToUF = Min(1.0, RqdMudLiqToUF/GTZ(QmLiq));
  Qu.QAddF(Qm, som_Liq, RqdMudFracToUF);
  Qu.QAddF(Qw, som_Liq, (1.0 - x));

  Qo.QSetF(Qm, som_Liq, (1.0-RqdMudFracToUF), POut);
  Qo.QAddF(Qw, som_Liq, x);

  if (1)
    {// Correct Enthalpy...
    Qu.SetTemp(FT);
    Qo.SetTemp(FT);
    double P = POut;
    double H = Qu.totHf()+Qo.totHf();
    double dT = 0.0, H0, T0;
    for (int Hiter=0; Hiter<10; Hiter++)
      {
      if (ConvergedVV(HTot, H, 1.0e-12, 1.0e-12))
        break;
      if (dT!=0.0)
        dT = (HTot-H)*(FT-T0)/NZ(H-H0);
      else
        dT = 0.1;
      T0 = FT;
      H0 = H;
      FT += dT;
      H = Qu.totHf(som_ALL, FT, P)+Qo.totHf(som_ALL, FT, P);
      }
    Qu.SetTemp(FT);
    Qo.SetTemp(FT);
    }

  if (SA)  // Solids expressed as g/L.
    {
    double SolConc25  = Qu.PhaseConc(C_2_K(25.0), som_Sol, som_ALL);
    return SolConc25;
    }
  else    // Solids expressed as % w/w.
    {
    double solid   = Qu.QMass(som_Sol);
    double Totmass = Max(1e-6, Qu.QMass(som_ALL));
    double SolUF   = solid/Totmass;
    return SolUF;
    }
  }
Esempio n. 12
0
/*#F:Normalises the vector and returns the original sum of all the elements .*/
double CDArray::Normalise()
{
    double t, total = 0.0;
    for (long i = 0; i < GetSize(); i++)
        total += m_pData[i];
    t = NZ(total);
    for (i = 0; i < GetSize(); i++)
        m_pData[i] /= t;
    return total;
};
Esempio n. 13
0
void DataSet_3D::GridInfo() const {
  if (gridBin_ == 0) return;
  Vec3 const& oxyz = gridBin_->GridOrigin();
  mprintf("\t\t-=Grid Dims=- %8s %8s %8s\n", "X", "Y", "Z");
  mprintf("\t\t        Bins: %8zu %8zu %8zu\n", NX(), NY(), NZ());
  mprintf("\t\t      Origin: %8g %8g %8g\n", oxyz[0], oxyz[1], oxyz[2]);
  if (gridBin_->IsOrthoGrid()) {
    GridBin_Ortho const& gb = static_cast<GridBin_Ortho const&>( *gridBin_ );
    mprintf("\t\t     Spacing: %8g %8g %8g\n", gb.DX(), gb.DY(), gb.DZ());
    mprintf("\t\t      Center: %8g %8g %8g\n",
            oxyz[0] + (NX()/2)*gb.DX(),
            oxyz[1] + (NY()/2)*gb.DY(),
            oxyz[2] + (NZ()/2)*gb.DZ());
    //mprintf("\tGrid max    : %8.3f %8.3f %8.3f\n", grid.MX(), grid.MY(), grid.MZ());
  } else {
    Box box(gridBin_->Ucell());
    mprintf("\t\tBox: %s ABC={%g %g %g} abg={%g %g %g}\n", box.TypeName(),
            box[0], box[1], box[2], box[3], box[4], box[5]);
  }
}
Esempio n. 14
0
eFlag Tree::findBestRule(
    Sit S, 
    XSLElement *&ret, 
    Context *c,
    QName *currMode,
    Bool importsOnly,
    SubtreeInfo *subtree /* NULL */)
{
  SubtreeInfo *start = (importsOnly && subtree) ? subtree : subtrees[0];
    return NZ(start) -> getStructure() -> findBestRule(
	S, ret, c, currMode, importsOnly);
}
Esempio n. 15
0
ConstantDamping::ConstantDamping(const Inputs& sp, MPIdata& mpi, fftwPlans& fft) :
dampFac(0.5),
equations_name("ConstantDamping"),
numMF_(1), numLin_(4),
f_noise_(sp.f_noise), nu_(sp.nu), eta_(sp.eta),
q_(sp.q),
dont_drive_ky0_modes_(0),// If true, no driving ky=0 modes
Model(sp.NZ, sp.NXY , sp.L), // Dimensions - stored in base
mpi_(mpi), // MPI data
fft_(fft) // FFT data
{
    // Setup MPI
    mpi_.Split_NXY_Grid( Dimxy_full() ); // Work out MPI splitting
    // Assign K data
    K = new Kdata(this, &mpi_); // Stores all the K data
    // Fourier transform plans
    fft_.calculatePlans( N(2),NZ() );
    
    // Random generator
    mt_ = boost::random::mt19937(1.0 + mpi_.my_n_v());  // Seed is 1.0, could change
    ndist_ = boost::random::normal_distribution<double>(0,f_noise_/sqrt(2)); // Normal distribution, standard deviation f_noise_ (factor 2 is since it's complex)
    noise_buff_ = dcmplxVec(num_Lin()*(NZ()-1));// NZ-1 since ky=kz=0 mode is not driven
    
    // Sizes of various arrays used for normalizing things
    totalN2_ = N(0)*N(1)*N(2); // Total number of grid points
    totalN2_ = totalN2_*totalN2_; // Squared
    mult_noise_fac_ = 1.0/(16*32*32); // Defined so that consistent with (16, 32, 32) results
    mult_noise_fac_ = mult_noise_fac_*mult_noise_fac_;
    // NZ^2 for normalizing  mean field energy
    nz2_ = N(2)*N(2);
    
    // Temps for evaulation of main equations
    uy_ = dcmplxVec( NZ() );
    by_ = dcmplxVec( NZ() );
    
    ////////////////////////////////////////////////////
    //               TEMPORARY ARRAYS                 //
    //  These are used during evaluation of the various parts of the model
    // There should never be any need to keep their value over more than 1 time-step
    //////////////////////////////////////////////////
    // These arrays are used for all sets of equations
    lapFtmp_ = doubVec( NZ() ); //For (time-dependent) k^2
    ilapFtmp_ = doubVec( NZ() ); // Inverse
    lap2tmp_ = doubVec( NZ() ); // For ky^2+kz^2 - could be pre-assigned
    ilap2tmp_ = doubVec( NZ() ); // Inverse


}
Esempio n. 16
0
*/	void Do_Native(REBVAL *func)
/*
***********************************************************************/
{
	REBVAL *ds;
	REBINT n;
#ifdef DEBUGGING
	REBYTE *fname = Get_Word_Name(DSF_WORD(DSF));	// for DEBUG
	Debug_Str(fname);
#endif

	Eval_Natives++;

	if (NZ(n = VAL_FUNC_CODE(func)(DS_RETURN))) {
		ds = DS_RETURN;
		switch (n) {
		case R_RET: // for compiler opt
			break;
		case R_TOS:
			*ds = *DS_TOP;
			break;
		case R_TOS1:
			*ds = *DS_NEXT;
			break;
		case R_NONE:
			SET_NONE(ds);
			break;
		case R_UNSET:
			SET_UNSET(ds);
			break;
		case R_TRUE:
			SET_TRUE(ds);
			break;
		case R_FALSE:
			SET_FALSE(ds);
			break;
		case R_ARG1:
			*ds = *D_ARG(1);
			break;
		case R_ARG2:
			*ds = *D_ARG(2);
			break;
		case R_ARG3:
			*ds = *D_ARG(3);
			break;
		}
	}
}
Esempio n. 17
0
*/  static void Bind_Block_Words(REBSER *frame, REBVAL *value, REBCNT mode)
/*
**      Inner loop of bind block. Modes are:
**
**          BIND_ONLY    Only bind the words found in the frame.
**          BIND_SET     Add set-words to the frame during the bind.
**          BIND_ALL     Add words to the frame during the bind.
**          BIND_DEEP    Recurse into sub-blocks.
**
**      NOTE: BIND_SET must be used carefully, because it does not
**      bind prior instances of the word before the set-word. That is
**      forward references are not allowed.
**
***********************************************************************/
{
	REBINT *binds = WORDS_HEAD(Bind_Table); // GC safe to do here
	REBCNT n;
	REBFLG selfish = !IS_SELFLESS(frame);

	for (; NOT_END(value); value++) {
		if (ANY_WORD(value)) {
			//Print("Word: %s", Get_Sym_Name(VAL_WORD_CANON(value)));
			// Is the word found in this frame?
			if (NZ(n = binds[VAL_WORD_CANON(value)])) {
				if (n == NO_RESULT) n = 0; // SELF word
				ASSERT1(n < SERIES_TAIL(frame), RP_BIND_BOUNDS);
				// Word is in frame, bind it:
				VAL_WORD_INDEX(value) = n;
				VAL_WORD_FRAME(value) = frame;
			}
			else if (selfish && VAL_WORD_CANON(value) == SYM_SELF) {
				VAL_WORD_INDEX(value) = 0;
				VAL_WORD_FRAME(value) = frame;
			}
			else {
				// Word is not in frame. Add it if option is specified:
				if ((mode & BIND_ALL) || ((mode & BIND_SET) && (IS_SET_WORD(value)))) {
					Append_Frame(frame, value, 0);
					binds[VAL_WORD_CANON(value)] = VAL_WORD_INDEX(value);
				}
			}
		}
		else if (ANY_BLOCK(value) && (mode & BIND_DEEP))
			Bind_Block_Words(frame, VAL_BLK_DATA(value), mode);
		else if ((IS_FUNCTION(value) || IS_CLOSURE(value)) && (mode & BIND_FUNC))
			Bind_Block_Words(frame, BLK_HEAD(VAL_FUNC_BODY(value)), mode);
	}
}
Esempio n. 18
0
ConstantDamping::ConstantDamping(const Inputs& sp, MPIdata& mpi, fftwPlans& fft) :
dampFac(1.0),
equations_name("ConstantDamping"),
numMF_(1), numLin_(1),
f_noise_(sp.f_noise), nu_(sp.nu), eta_(sp.eta),
Model(sp.NZ, sp.NXY , sp.L), // Dimensions - stored in base
mpi_(mpi), // MPI data
fft_(fft) // FFT data
{
    
    // Assign K data 
    K = new Kdata(this); // Stores all the K data
    // Setup MPI
    mpi_.Split_NXY_Grid( Dimxy_full() ); // Work out MPI splitting
    // Fourier transform plans
    fft_.calculatePlans( NZ() );
    
}
Esempio n. 19
0
*/	REBINT PD_Tuple(REBPVS *pvs)
/*
**		Implements PATH and SET_PATH for tuple.
**		Sets DS_TOP if found. Always returns 0.
**
***********************************************************************/
{
	REBVAL *val;
	REBINT n;
	REBINT i;
	REBYTE *dat;
	REBINT len;

	dat = VAL_TUPLE(pvs->value);
	len = VAL_TUPLE_LEN(pvs->value);
	if (len < 3) len = 3;
	n = Get_Num_Arg(pvs->select);

	if (NZ(val = pvs->setval)) {
		if (n <= 0 || n > MAX_TUPLE) return PE_BAD_SELECT;
		if (IS_INTEGER(val) || IS_DECIMAL(val)) i = Int32(val);
		else if (IS_NONE(val)) {
			n--;
			CLEAR(dat+n, MAX_TUPLE-n);
			VAL_TUPLE_LEN(pvs->value) = n;
			return PE_OK;
		}
		else return PE_BAD_SET;
		if (i < 0) i = 0;
		else if (i > 255) i = 255;
		dat[n-1] = i;
		if (n > len) VAL_TUPLE_LEN(pvs->value) = n;
		return PE_OK;
	} else {
		if (n > 0 && n <= len) {
			SET_INTEGER(pvs->store, dat[n-1]);
			return PE_USE;
		}
		else return PE_NONE;
	}
}
Esempio n. 20
0
void escapeChars(DStr& result, const Str& what, 
                 const char* toEscape, const char** substitutes)
{
    char *pStart = what, *p = pStart;
    int chunkLength;
    while (pStart)
    {
        p = strpbrk(pStart, toEscape);
        if (p)
        {
            if ((chunkLength = (int)(p - pStart)))
                result.nadd(pStart, chunkLength);
            result += substitutes[(int) (NZ(strchr(toEscape, *p)) - toEscape)];
            pStart = ++p;
        }
        else 
        {
            result += pStart;
            pStart = NULL;
        }
    }
}
Esempio n. 21
0
*/  REBVAL *In_Object(REBSER *base, ...)
/*
**      Get value from nested list of objects. List is null terminated.
**		Returns object value, else returns 0 if not found.
**
***********************************************************************/
{
	REBVAL *obj = 0;
	REBCNT n;
	va_list args;

	va_start(args, base);
	while (NZ(n = va_arg(args, REBCNT))) {
		if (n >= SERIES_TAIL(base)) return 0;
		obj = OFV(base, n);
		if (!IS_OBJECT(obj)) return 0;
		base = VAL_OBJ_FRAME(obj);
	}
	va_end(args);

	return obj;
}
Esempio n. 22
0
CCWashMixEffFnd::CCWashMixEffFnd (
                SpConduit &Qm_, SpConduit &Qw_, 
                SpConduit &Qu_, SpConduit &Qo_, 
                SpConduit &Qt_, 
                double RqdMixEff_, byte SA_, double POut_):
  MRootFinderBase("CCWasher2", s_Tol),//1.0e-8), 
  Qm(Qm_), Qw(Qw_), Qu(Qu_), Qo(Qo_), Qt(Qt_)
  {
  RqdMixEff = RqdMixEff_;
  SA = SA_;
  POut = POut_;

  QmLiq = Qm.QMass(som_Liq);
  QwLiq = Qw.QMass(som_Liq);
  Qt.QSetF(Qm, som_ALL, 1.0, Std_P);
  Qt.QAddF(Qw, som_ALL, 1.0);
  //limit is where 100% of mud liq reports to uf...
  const double xlim = (RqdMixEff*(QmLiq/GTZ(QwLiq) + 1.0) - 1.0) / NZ(RqdMixEff - 1.0);
  LoLimit = Range(0.0, xlim, 0.99999);
  FT = Qt.Temp();
  HTot = Qm.totHf()+Qw.totHf();
  }
Esempio n. 23
0
*/	static int Find_Command(REBSER *dialect, REBVAL *word)
/*
**		Given a word, check to see if it is in the dialect object.
**		If so, return its index. If not, return 0.
**
***********************************************************************/
{
	REBINT n;

	if (dialect == VAL_WORD_FRAME(word)) n = VAL_WORD_INDEX(word);
	else {
		if (NZ(n = Find_Word_Index(dialect, VAL_WORD_SYM(word), FALSE))) {
			VAL_WORD_FRAME(word) = dialect;
			VAL_WORD_INDEX(word) = n;
		}
		else return 0;
	}

	// If keyword (not command) return negated index:
	if (IS_NONE(FRM_VALUES(dialect) + n)) return -n;
	return n;
}
Esempio n. 24
0
eFlag Tree::startSubtree(Sit S, const Str& baseURI, XSL_OP dependency,
			 Bool isInline /* = FALSE */)
{
    // look if the URI is on the way to root of the include tree
    if (subtrees.findAmongPredecessors(baseURI))
	Err1(S, E1_CIRCULAR_INCLUSION, baseURI);
    StylesheetStructure *structure;
    if (dependency == XSL_IMPORT)
	structure = createStylesheetStructure(S);
    else
	// find structure of current subtree (always defined since Tree::Tree)
	structure = NZ(subtrees.getCurrent()) -> getStructure();

    subtrees.push(
	new SubtreeInfo(
	    baseURI, 
	    dependency,
	    structure,
	    isInline));

    excludeStdNamespaces();
    //set parent tree (closest non-inline)
    if (isInline)
      for (SubtreeInfo *nfo = subtrees.getCurrent();
	   nfo;
	   nfo = nfo -> getParentSubtree())
	{
	  if (!nfo -> isInline())
	    {
	      subtrees.getCurrent() -> setMasterSubtree(nfo);
	      break;
	    }
	}

    return OK;
}
Esempio n. 25
0
DynBlock* DataLine::getOutBuffer()
{
    // check that the output buffer exists and that we're open for write
    sabassert(mode == DLMODE_WRITE && scheme == URI_ARG); 
    return NZ(outBuf); // -> getPointer();
}
Esempio n. 26
0
static void Append_Obj(REBSER *obj, REBVAL *arg)
{
	REBCNT i;
	REBCNT len = 0;
	REBVAL *val;
	REBVAL *start = arg;

	// Can be a word:
	if (ANY_WORD(arg)) {
		if (!Find_Word_Index(obj, VAL_WORD_SYM(arg), TRUE)) {
			if (VAL_WORD_CANON(arg) == SYM_SELF) Trap0(RE_SELF_PROTECTED);
			Expand_Frame(obj, 1, 1); // copy word table also
			Append_Frame(obj, 0, VAL_WORD_SYM(arg));
			// val is UNSET
		}
		return;
	}

	if (!IS_BLOCK(arg)) Trap_Arg(arg);

	// Verify word/value argument block:
	for (arg = VAL_BLK_DATA(arg); NOT_END(arg); arg += 2) {

		if (!IS_WORD(arg) && !IS_SET_WORD(arg)) Trap_Arg(arg);

		if (NZ(i = Find_Word_Index(obj, VAL_WORD_SYM(arg), TRUE))) {
			// Just change the value, do not append it.
			val = FRM_VALUE(obj, i);
			if (GET_FLAGS(VAL_OPTS(FRM_WORD(obj, i)), OPTS_HIDE, OPTS_LOCK)) { 
				// Back out... reset any prior flags:
				for (; arg != VAL_BLK_DATA(start); arg -= 2) VAL_CLR_OPT(arg, OPTS_TEMP);
				if (VAL_PROTECTED(FRM_WORD(obj, i))) Trap1(RE_LOCKED_WORD, FRM_WORD(obj, i));
				Trap0(RE_HIDDEN);
			}
			// Problem above: what about prior OPTS_FLAGS? Ok to leave them as is?
			if (IS_END(arg+1)) SET_NONE(val);
			else *val = arg[1];
			VAL_SET_OPT(arg, OPTS_TEMP);
		} else {
			if (VAL_WORD_CANON(arg) == SYM_SELF) Trap0(RE_SELF_PROTECTED);
			len++;
			// was: Trap1(RE_DUP_VARS, arg);
		}
	
		if (IS_END(arg+1)) break; // fix bug#708
	}

	// Append new values to end of frame (if necessary):
	if (len > 0) {
		Expand_Frame(obj, len, 1); // copy word table also
		for (arg = VAL_BLK_DATA(start); NOT_END(arg); arg += 2) {
			if (VAL_GET_OPT(arg, OPTS_TEMP)) VAL_CLR_OPT(arg, OPTS_TEMP);
			else {
				val = Append_Frame(obj, 0, VAL_WORD_SYM(arg));
				if (IS_END(arg+1)) {
					SET_NONE(val);
					break;
				}
				else *val = arg[1];
			}
		}
	}
}
Esempio n. 27
0
int DataLine::get(Sit S, char *dest,int maxcount)
{
    int result = 0;
    sabassert(mode == DLMODE_READ);  // assume the file open for reading
    switch(scheme)
    {
    case URI_FILE:
        {
            sabassert(f);          // the file must be open
            result = fread(dest,1,maxcount,f);
            // return the number of bytes read
        }; break;
    case URI_ARG:
        {
            sabassert(buffer);     // the buffer must exist
            // do a 'strncpy' that shifts dest and bufCurr;
            // i counts the number of bytes transferred
			char * copyChar = dest;
            int i;
            for (i = 0; 
                (!pointsAtEnd(buffer + bufCurr, utf16Encoded)) && (i < maxcount); 
                i++)
                {
                    *(copyChar++) = buffer[bufCurr++];
                };
                result = i;
        }; break;
    case URI_EXTENSION:         // external handler
        {
            if (gotWholeDocument)
            {
                // ugly hack: copied the following from above
                sabassert(buffer);     // the buffer must exist
				char * copyChar = dest;
                int i;
                for (i = 0; 
                (!pointsAtEnd(buffer + bufCurr, utf16Encoded)) && (i < maxcount); 
                i++)
                {
                    *(copyChar++) = buffer[bufCurr++];
                };
                result = i;
            }
            else
            {
                int actual = maxcount;
                if( NZ(handler) -> get(handlerUD, S.getProcessor(), handle, dest, &actual) )
                {
                    S.message( MT_ERROR, E1_URI_READ, fullUri, "" );
                    return -1;
                }
                result = actual;
            }
        }; break;
    }
	// need to NUL terminate in order to prevent C string
	// functions running off the end of the buffer

	// assignment assumes that the passed in dest is allocated
	// one bigger than maxcount
	dest[result] = '\0';
    return result;              // return the number of bytes read
}
Esempio n. 28
0
Str& Str::operator=(const char* chars)
{
    nset(NZ(chars), strlen(chars));
    return *this;
}
Esempio n. 29
0
void FilterPress::EvalProducts()
{
	try {
		int idPressNote = 0, idWashNote = 1;
		MStreamI QFeed;
		FlwIOs.AddMixtureIn_Id(QFeed, idFeed);
		const double dFeedSolidMass = QFeed.Mass(MP_Sol);
		const double dFeedLiquidMass = QFeed.Mass(MP_Liq);

    MStreamI QWashWater;
		const bool bWashWaterConnected = (FlwIOs.getCount(idWash) > 0);
		if (bWashWaterConnected)
			FlwIOs.AddMixtureIn_Id(QWashWater, idWash);

		//MStream QUnwashedCake = QFeed; BAD idea, QUnwashedCake becomes a reference to QFeed!!!!
		MStreamI QUnwashedCake;
    QUnwashedCake = QFeed;
		QUnwashedCake.ZeroMass();

    MStream&	QFiltrate	= FlwIOs[FlwIOs.First[idFiltrate]].Stream;
    QFiltrate	= QFeed;
    MStream&	QCake		= FlwIOs[FlwIOs.First[idCake]].Stream;
    QCake		= QFeed;

		const bool bWashingsConnected = (FlwIOs.Count[idWashings] > 0);

		//First off: The filtrate & UnwashedCake:

		/*Equations Solved using Mathematica 6.0, under the constrainsts of:
		 - Conservation of mass
		 - Cake Moisture Content
		 - Filtrate Solid Concentration [Either in % or g/L]
			- When using g/L, assume solid and liquid densities don't change [The (Aq) conc's don't]
		*/
		double dSolConcConstFac, dLiqConcConstFac;
		bool bTooWet;
		switch (eFiltrateMethod) {
		case FM_SolidsToFiltrateFrac:
			dSolConcConstFac = dReqSolidsToFiltrate;
			dLiqConcConstFac = dReqSolidsToFiltrate;
			bTooWet = dFeedSolidMass / NZ(dFeedSolidMass + dFeedLiquidMass) < dReqSolidsToFiltrate;
			break;
		case FM_FiltrateConc:
			dSolConcConstFac = dReqFiltSolConc / QFeed.Density(MP_Sol, C_2_K(25));
			dLiqConcConstFac= dReqFiltSolConc / QFeed.Density(MP_Liq, C_2_K(25));
			bTooWet = dFeedSolidMass / NZ(QFeed.Volume(MP_SL, C_2_K(25))) < dReqFiltSolConc;
			break;
		}
		/*Situations where variables can be out of range:
		 - Mass comes in too wet - required loss causes all mass to be sent to filtrate
		 - Mass comes in too dry - mass is drier than required moisture frac.
		*/
		double dFiltSolidFactor, dFiltLiquidFactor, dCakeSolidFactor, dCakeLiquidFactor;
		if (bTooWet)
		{
			SetNote(idPressNote, "Input feed too wet: All feed solids sent to filtrate");
			dFiltSolidFactor = dFiltLiquidFactor = 1;
			dCakeSolidFactor = dCakeLiquidFactor = 0;
		}
		else if (dFeedLiquidMass / NZ(dFeedSolidMass + dFeedLiquidMass) < dReqCakeMoisture)
		{
			SetNote(idPressNote, "Input feed too dry: All feed liquids sent to Cake");
			dFiltSolidFactor = dFiltLiquidFactor = 0;
			dCakeSolidFactor = dCakeLiquidFactor = 1;
		}
		else
		{
			dFiltSolidFactor = (((dFeedLiquidMass * (dReqCakeMoisture - 1) + dFeedSolidMass * dReqCakeMoisture) * dLiqConcConstFac)
									/ NZ(dReqCakeMoisture * dLiqConcConstFac - (dReqCakeMoisture - 1)*(dSolConcConstFac-1))) / dFeedSolidMass;
			dFiltLiquidFactor = - (((dFeedLiquidMass * (dReqCakeMoisture - 1) + dFeedSolidMass * dReqCakeMoisture) * (dSolConcConstFac - 1))
									/ NZ(dReqCakeMoisture * dLiqConcConstFac - (dReqCakeMoisture - 1)*(dSolConcConstFac - 1))) / dFeedLiquidMass;

			dCakeSolidFactor = 1 - dFiltSolidFactor;
			dCakeLiquidFactor = 1 - dFiltLiquidFactor;
		}

		for (int i = 0; i < gs_MVDefn.Count(); i++)
			if (gs_MVDefn[i].IsSolid())
			{
				QFiltrate.M[i] = QFeed.M[i] * dFiltSolidFactor;
				QUnwashedCake.M[i] = QFeed.M[i] * dCakeSolidFactor;
			}
			else if (gs_MVDefn[i].IsLiquid())
			{
				QFiltrate.M[i] = QFeed.M[i] * dFiltLiquidFactor;
				QUnwashedCake.M[i] = QFeed.M[i] * dCakeLiquidFactor;
			}

		//Now, wash it:
		//First, add the washwater solids, and record what mass of solids we add.
		//The equations associated with this are exceedingly ugly.
		if (FlwIOs.getCount(idWash) > 0) {
			//Short variables to create fewer errors translating the equations
			double WS = QWashWater.Mass(MP_Sol);
			double WL = QWashWater.Mass(MP_Liq);
			double CS = QUnwashedCake.Mass(MP_Sol);
			double CL = QUnwashedCake.Mass(MP_Liq);
			double a, rWS, rWL, rCS, rCL;
			double m = dReqCakeMoisture;
			double w;
			switch (eWashMethod)
			{
			case WM_ConstantEfficiency:
				w = dReqWashEfficiency;
			case WM_WashRatio:
				dWashRatio = WL / NZ(CL);
				w = 1 - pow(1-dReqWashEfficiency, dWashRatio);
			}
			switch (eFiltrateMethod) {
			case FM_SolidsToFiltrateFrac:
				a = dReqSolidsToFiltrate;
				rWS = rWL = rCS = rCL = 1;
				break;
			case FM_FiltrateConc:
				a = dReqFiltSolConc;
				rWS = QWashWater.Density(MP_Sol, C_2_K(25));
				rWL = QWashWater.Density(MP_Liq, C_2_K(25));
				rCS = QUnwashedCake.Density(MP_Sol, C_2_K(25));
				rCL = QUnwashedCake.Density(MP_Liq, C_2_K(25));
				break;
			}
			/*Possible situations where variables are out of range:
			 - A: Too much wash liquid - all solids are sent out in washings ['Fix' by sending everyhing to washings. Assume we will not end up with only washing solids]
			 - B: Not enough wash liquid - required wash efficiency impossible ['Fix' by putting all wash water in cake]
			 - C: Cake comes in dry [And very dry] - wash efficiency is higher than requested even if no cake moisture is displaced. 
				[Fix by sending everything].
			 - D: Wash water has FAAR too many solids - cake moisture is lower than required. [Fix by putting everything into cake]
			 - Cake should never come in too wet.
			 */
			//CO - Cake Out. WO - Washings out.
			double dCLtoCO, dCStoCO, dWStoCO;
			
			double dTemp = (WS*rCL*rCS*rWL*(a-rWS)+(a*WL*rCL*rCS+(CS*rCL*(a-rCS)+a*CL*rCS)*rWL)*rWS)
				/ NZ(CS*(m*a*(1-w)*rCS*rWL+rCL*((1-m)*a*rWL+rCS*(m*a*w-(1-m)*rWL)))*rWS + WS*rCL*rCS*((1-m)*rWL*(a-rWS)+m*a*rWS));

			double dWLtoCO = m * (w*CS + WS) * dTemp;
			if (dWLtoCO > WL)
			{ //Case B - not enough wash liquid
				SetNote(idWashNote, "Not enough wash water: All wash water sent to cake");
				//double dTemp1 = (WS*rCL*rCS*(a-rWS)+(CS*rCL*(a-rCS)+a*CL*rCS)*rWS)
				//			/ NZ(CS*((1-m)*rCL*(a-rCS)+m*a*rCS)*rWS + WS*rCS*((1-m)*rCL*(a-rWS) + m*a*rWS));
				double dTemp1 = 1 / (CS * ((1-m) * rCL * (a-rCS) + m*a*rCS) * rWS + WS * rCS * ((1-m) * rCL * (a-rWS) + m*a*rWS));
				double dTemp2 = WS * rCL * rCS * (a-rWS) + (CS * rCL * (a-rCS) + a*(CL+WL)*rCS)*rWS;
				
				dWLtoCO = WL;
				dCLtoCO = (m*CS*CS*rCL*(a-rCS)*rWS + CS*((-(1-m)*WL*rCL*(a-rCS) + m*a*CL*rCS)*rWS+m*WS*rCL*(rCS*(a-2*rWS)+a*rWS))
							+ WS*rCS*(-(1-m)*WL*rCL*(a-rWS) + m*(WS*rCL*(a-rWS) + a*CL*rWS))) * dTemp1;
				dCStoCO = (1-m) * CS * dTemp1 * dTemp2;
				dWStoCO = (1-m) * WS * dTemp1 * dTemp2;
			}
			else
			{
				//dWLtoCO already set.
				dCLtoCO = m * (1-w) * CS * dTemp;
				dCStoCO = (1-m) * CS * dTemp;
				dWStoCO = (1-m) * WS * dTemp;
			}

			if (dCLtoCO > CL) { //Case C - not enough cake moisture [Can only happen if cake comes in with moisture content v. low.]
				dCLtoCO = CL;	//Although this results in a lower than required moisture content, well, the cake is comming in drier than required.
				SetNote(idWashNote, "Cake too dry"); }
			
			//Simple Cons of Mass:
			double dWLtoWO = WL - dWLtoCO;
			double dCLtoWO = CL - dCLtoCO;
			double dWStoWO = WS - dWStoCO;
			double dCStoWO = CS - dCStoCO;

			double dWLtoCOFrac,dCLtoCOFrac,dWStoCOFrac,dCStoCOFrac,dWLtoWOFrac,dCLtoWOFrac,dWStoWOFrac,dCStoWOFrac;
			if (dCStoCO < 0) //Case A, Too wet: Everything sent with washings
			{
				SetNote(idWashNote, "Too much liquid in WashWater. Everything sent to washings");
				dWLtoCOFrac=dCLtoCOFrac=dWStoCOFrac=dCStoCOFrac=0;
				dWLtoWOFrac=dCLtoWOFrac=dWStoWOFrac=dCStoWOFrac=1;
			}
			else if ((CL+WL)/NZ(CS+WS+CL+WL) < m)	//Case D, Too Dry: Send everything to cake.
			{
				SetNote(idWashNote, "Not enough liquid in washing stage. Everything sent to cake");
				dWLtoCOFrac=dCLtoCOFrac=dWStoCOFrac=dCStoCOFrac=1;
				dWLtoWOFrac=dCLtoWOFrac=dWStoWOFrac=dCStoWOFrac=0;
			}
			else
			{
				//Here's where we handle if we have any other zeros.
				//Also handle if a variable manages to slip by the other checks [It is possible with outlandish input parameters.]
				dWLtoCOFrac = WL > 0 ? dWLtoCO / WL : 0;
				dCLtoCOFrac = CL > 0 ? dCLtoCO / CL : 0;
				dWStoCOFrac = WS > 0 ? dWStoCO / WS : 0;
				dCStoCOFrac = CS > 0 ? dCStoCO / CS : 0;
				dWLtoWOFrac = WL > 0 ? dWLtoWO / WL : 0;
				dCLtoWOFrac = CL > 0 ? dCLtoWO / CL : 0;
				dWStoWOFrac = WS > 0 ? dWStoWO / WS : 0;
				dCStoWOFrac = CS > 0 ? dCStoWO / CS : 0;
			}

			dWashEfficiency = CL > 0 ? 1 - dCLtoCOFrac : dNAN;

		  //MStream QWashingOutput = QCake; BAD idea, QWashingOutput becomes a reference to QCake!!!!
			MStreamI QWashingOutput;
			QWashingOutput = QCake;
			QWashingOutput.ZeroMass();

			for (int i = 0; i < gs_MVDefn.Count(); i++)
				if (gs_MVDefn[i].IsSolid())
				{
					QWashingOutput.M[i] = QUnwashedCake.M[i] * dCStoWOFrac + QWashWater.M[i] * dWStoWOFrac;
					QCake.M[i] = QUnwashedCake.M[i] * dCStoCOFrac + QWashWater.M[i] * dWStoCOFrac;
				}
				else if (gs_MVDefn[i].IsLiquid())
				{
					QWashingOutput.M[i] = QUnwashedCake.M[i] * dCLtoWOFrac + QWashWater.M[i] * dWLtoWOFrac;
					QCake.M[i] = QUnwashedCake.M[i] * dCLtoCOFrac + QWashWater.M[i] * dWLtoCOFrac;
				}

			double dInputHf;
			
			MStream* pQWashingOutput;
			if (bWashingsConnected) //bWashingsConnected indicates whether OUTPUT washings are connected.
			{
				dInputHf = QUnwashedCake.totHf() + QWashWater.totHf();
				pQWashingOutput = &QWashingOutput;
			}
			else
			{
				dInputHf = QUnwashedCake.totHf() + QWashWater.totHf() + QFiltrate.totHf();
				for (int i = 0; i < gs_MVDefn.Count(); i++)
					QFiltrate.M[i] += QWashingOutput.M[i];
				pQWashingOutput = &QFiltrate;	//For thermal property managing
			}

			double dgbTi = pQWashingOutput->T;
			bool converged = false;
			for (int i = 0; i < 10 && !converged; i++)
			{
				double dbgTt = pQWashingOutput->T;

				double dOutputHf = QCake.totHf() + pQWashingOutput->totHf();

				double deltaT = -(dOutputHf - dInputHf) / NZ(pQWashingOutput->totCp() + QCake.totCp());

				pQWashingOutput->T += deltaT;
				QCake.T = pQWashingOutput->T;

				converged = abs(dInputHf - dOutputHf) < 1; //TODO: Check what sort of convergence we require.
			}

			double dbgT = pQWashingOutput->T;
			double dbgT2 = QWashingOutput.T;

			if (bWashingsConnected)
			{
				MStream& QWashings = FlwIOs[FlwIOs.First[idWashings]].Stream;
				QWashings = QWashingOutput;
			}
		}
		else //If we have no washings
		{
			if (bWashingsConnected)
			{
				MStream& QWashings = FlwIOs[FlwIOs.First[idWashings]].Stream;
				QWashings.ZeroMass();
			}
			QCake = QUnwashedCake;
		}

		//Vent:
		if (FlwIOs.Count[idVent] > 0)
		{
			MStream& QVent = FlwIOs[FlwIOs.First[idVent]].Stream;
			QVent = QCake;
			QVent.ZeroMass();
			MStreamI QWashWater;
			if (FlwIOs.Count[idWash] > 0)
				QWashWater = FlwIOs[FlwIOs.First[idWash]].Stream;
			else
				QWashWater.ZeroMass();

			for (int i = 0; i < gs_MVDefn.Count(); i++)
				if (gs_MVDefn[i].IsGas())
					QVent.M[i] = QCake.M[i] + QWashWater.M[i];
		}
		
		//Update "Actual" values.
		dCakeSolids = QCake.MassFrac(MP_Sol);
		dFiltSolids = QFiltrate.MassFrac(MP_Sol);
		dCakeSolConc = QCake.Mass(MP_Sol) / NZ(QCake.Volume(MP_All, C_2_K(25.0)));
		dFiltSolConc = QFiltrate.Mass(MP_Sol) / NZ(QFiltrate.Volume(MP_All, C_2_K(25.0)));
		if (bWashWaterConnected)
		{
			double CFeed = QFeed.SpecieConc(MP_Liq, nWashCompSpecie, C_2_K(25.0));
			double CCake = QCake.SpecieConc(MP_Liq, nWashCompSpecie, C_2_K(25.0));
			double CWash = QWashWater.SpecieConc(MP_Liq, nWashCompSpecie, C_2_K(25.0));
			dWashCompEff = (CFeed - CCake) / NZ(CFeed - CWash);
		}
		else
		{
			dWashCompEff = 0;
			dWashEfficiency = 0;
		}
	}
  catch (MMdlException &e)
    {
    Log.Message(MMsg_Error, e.Description);
    }
  catch (MFPPException &e)
    {
    e.ClearFPP();
    Log.Message(MMsg_Error, e.Description);
    }
  catch (MSysException &e)
    {
    Log.Message(MMsg_Error, e.Description);
    }
  catch (...)
    {
    Log.Message(MMsg_Error, "Some Unknown Exception occured");
    }
}
Esempio n. 30
0
//////////////////////////////////////////////////////////
//   DRIVING NOISE
void ConstantDamping::DrivingNoise(double t, double dt, solution *sol) {
    // NZ() is now dealiased NZ!!!
    // So - drive all of NZ and Nyquist frequency is not included
    
    // Adds noise onto linear part of solution
    for (int i=0; i<Dimxy(); ++i) {
        
        if (K->ky_index[i] != 0){ // ky=0 dealt with seperately. kx=ky=0 missed automatically
            
            ///////////////////////////
            // Noise multipliers
            assign_laplacians_(i,t,0); // Assign laplacian's - no inverses
            
            // ky=0 so not many if statements
            double noise_multfac = dt*totalN2_*mult_noise_fac_; // f_noise is included in normal distribution
            lapFtmp_ = noise_multfac*lap2tmp_/lapFtmp_; // lapFtmp_ is no longer lapF!
            
            lap2tmp_ = (-noise_multfac*lap2tmp_).sqrt();
            lapFtmp_ = lapFtmp_.sqrt();
            
            double *multU_pnt = lapFtmp_.data();
            double *multZeta_pnt = lap2tmp_.data();
            /////////////////////////////
            
            // ky != 0 modes are completely random
            // U
            dcmplx* ePoint = (*(sol->pLin(i,0) )).data();
            for (int jj=0; jj<NZ(); ++jj) {
                ePoint[jj] += multU_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
            }
            // zeta
            ePoint = (*(sol->pLin(i,1) )).data();
            for (int jj=0; jj<NZ(); ++jj) {
                ePoint[jj] += multZeta_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
            }
            // b
            ePoint = (*(sol->pLin(i,2) )).data();
            for (int jj=0; jj<NZ(); ++jj) {
                ePoint[jj] += multU_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
            }
            // eta
            ePoint = (*(sol->pLin(i,3) )).data();
            for (int jj=0; jj<NZ(); ++jj) {
                ePoint[jj] += multZeta_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
            }
        }
        
        // Don't drive kx=ky=0 modes (mean fields) or ky=kz=0 modes (non-invertible).These are both taken care of in laplacian
        // Still need to make sure that ky=0 kx!=0 kz!=0 modes are symmetric. In particular ky=0, kx=a, kz=b must be the complex conjugate to kx=-a, kz=-b
        // To do this, have to communicate between processors!
        
        
    }
    
    if (!dont_drive_ky0_modes_){
        // Deal with ky=0 part - a real PIA!!
        // Iterators for vectors
        K->i_tosend = K->match_kx_tosend.begin();
        K->i_loc = K->match_kx_local.begin();
        K->i_from = K->match_kx_from.begin();
        K->i_fp = K->match_kx_from_p.begin();
        K->i_sp = K->match_kx_tosend_p.begin();
        int nz = NZ()-1; // For noise
#ifdef USE_MPI_FLAG
        //////////////////////////////////////////////////
        // Sending - create noise here and broadcast
        while (K->i_sp < K->match_kx_tosend_p.end()) {
            
            int i = *(K->i_tosend); // Index in k array
            if (K->ky_index[i]!=0) // Be paranoid
                mpi_.print1("Warning: Something wrong in noise data swapping!!");
            ///////////////////////////
            // Noise multipliers
            
            assign_laplacians_(i,t,0); // Assign laplacian's - no inverses
            
            double noise_multfac = dt*totalN2_*mult_noise_fac_; // f_noise is included in normal distribution
            lap2tmp_(0) = 0.0; // Don't drive ky=kz=0
            
            lapFtmp_ = noise_multfac*lap2tmp_/lapFtmp_; // lapFtmp_ is no longer lapF!
            
            lap2tmp_ = (-noise_multfac*lap2tmp_).sqrt();
            lapFtmp_ = lapFtmp_.sqrt();
            
            double *multU_pnt = lapFtmp_.data();
            double *multZeta_pnt = lap2tmp_.data();
            /////////////////////////////
            
            // Make some noise - add to current k value
            dcmplx* noise_buff_dat_ = noise_buff_.data();
            dcmplx* ePoint = (*(sol->pLin(i,0) )).data();
            for (int jj=1; jj<NZ(); ++jj){
                noise_buff_dat_[jj-1]=multU_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
                ePoint[jj] += noise_buff_dat_[jj-1];
            }
            // zeta
            noise_buff_dat_ = noise_buff_.data()+nz;
            ePoint = (*(sol->pLin(i,1) )).data();
            for (int jj=1; jj<NZ(); ++jj){
                noise_buff_dat_[jj-1]=multZeta_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
                ePoint[jj] += noise_buff_dat_[jj-1];
            }
            // b
            noise_buff_dat_ = noise_buff_.data()+2*nz;
            ePoint = (*(sol->pLin(i,2) )).data();
            for (int jj=1; jj<NZ(); ++jj){
                noise_buff_dat_[jj-1]=multU_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
                ePoint[jj] += noise_buff_dat_[jj-1];
            }
            // eta
            noise_buff_dat_ = noise_buff_.data()+3*nz;
            ePoint = (*(sol->pLin(i,3) )).data();
            for (int jj=1; jj<NZ(); ++jj){
                noise_buff_dat_[jj-1]=multZeta_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
                ePoint[jj] += noise_buff_dat_[jj-1];
            }
            
            // Send data
            mpi_.Send_dcmplx(noise_buff_.data(), num_Lin()*nz, *(K->i_sp), *(K->i_tosend));
            
            //        cout << "(kx,ky)=(" << K->kx[i] <<"," << K->ky[i] << ")" << endl;
            //        cout << noise_buff_.segment(0, nz).transpose() << endl<<endl;
            // Update iterator
            ++(K->i_tosend);
            ++(K->i_sp);
        }
        ////////////////////////////////////////////
        // Recieving
        while (K->i_fp < K->match_kx_from_p.end()) {
            
            int i = *(K->i_loc);
            // Receive data from matching call
            mpi_.Recv_dcmplx(noise_buff_.data(), num_Lin()*nz, *(K->i_fp), *(K->i_from));
            
            // Flip noise around
            for (int nV=0; nV<num_Lin(); ++nV) {
                noise_buff_.segment(nV*nz, nz).reverseInPlace();
            }
            
            //        cout << "(kx,ky)=(" << K->kx[i] <<"," << K->ky[i] << ")" << endl;
            //        cout << noise_buff_.segment(0, nz).transpose().conjugate() <<endl<<endl;
            
            // Add to solution
            for (int nV=0; nV<num_Lin(); ++nV) {
                (*(sol->pLin(i,nV) )).segment(1,nz) += noise_buff_.segment(nV*nz, nz).conjugate();
            }
            
            
            // Update iterators
            ++(K->i_fp);
            ++(K->i_loc);
            ++(K->i_from);
        }
        
        // mpi_.Barrier();  // This is probably not necessary but don't see why it would cause harm
        ////////////////////////////////////////////////////////////////////
#else       // Need a separate "no-mpi" case, since MPI_Send functions not defined
        ////////////////////////////////////////////////////////////////////
        
        while (K->i_tosend < K->match_kx_tosend.end()) {
            ///////////////////////////
            // Noise multipliers
            int i = *(K->i_tosend); // index
            assign_laplacians_(i,t,0); // Assign laplacian's - no inverses
            
            double noise_multfac = dt*totalN2_*mult_noise_fac_; // f_noise is included in normal distribution
            lap2tmp_(0) = 0.0; // Don't drive ky=kz=0
            lap2tmp_(NZ()/2)=0.0; // Or Nyquist
            
            lapFtmp_ = noise_multfac*lap2tmp_/lapFtmp_; // lapFtmp_ is no longer lapF!
            
            lap2tmp_ = (-noise_multfac*lap2tmp_).sqrt();
            lapFtmp_ = lapFtmp_.sqrt();
            
            double *multU_pnt = lapFtmp_.data();
            double *multZeta_pnt = lap2tmp_.data();
            /////////////////////////////
            
            // Make some noise - add to current k value
            dcmplx* noise_buff_dat_ = noise_buff_.data();
            dcmplx* ePoint = (*(sol->pLin(i,0) )).data();
            for (int jj=1; jj<NZ(); ++jj){
                noise_buff_dat_[jj-1]=multU_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
                ePoint[jj] += noise_buff_dat_[jj-1];
            }
            // zeta
            noise_buff_dat_ = noise_buff_.data()+nz;
            ePoint = (*(sol->pLin(i,1) )).data();
            for (int jj=1; jj<NZ(); ++jj){
                noise_buff_dat_[jj-1]=multZeta_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
                ePoint[jj] += noise_buff_dat_[jj-1];
            }
            // b
            noise_buff_dat_ = noise_buff_.data()+2*nz;
            ePoint = (*(sol->pLin(i,2) )).data();
            for (int jj=1; jj<NZ(); ++jj){
                noise_buff_dat_[jj-1]=multU_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
                ePoint[jj] += noise_buff_dat_[jj-1];
            }
            // eta
            noise_buff_dat_ = noise_buff_.data()+3*nz;
            ePoint = (*(sol->pLin(i,3) )).data();
            for (int jj=1; jj<NZ(); ++jj){
                noise_buff_dat_[jj-1]=multZeta_pnt[jj]*dcmplx(ndist_(mt_), ndist_(mt_));
                ePoint[jj] += noise_buff_dat_[jj-1];
            }
            
            
            // Find matching K value and use the same noise
            i = *(K->i_loc);
            
            // Flip noise around
            for (int nV=0; nV<num_Lin(); ++nV) {
                noise_buff_.segment(nV*nz, nz).reverseInPlace();
            }
            
            // Add to solution
            for (int nV=0; nV<num_Lin(); ++nV) {
                (*(sol->pLin(i,nV) )).segment(1,nz) += noise_buff_.segment(nV*nz, nz).conjugate();
            }
            
            
            // Update iterators
            ++(K->i_tosend);
            ++(K->i_loc);
        }
        
#endif
        ////////////////////////////////////////////////////////////////////
        
    }
    
}