ReactingMultiphaseParcel.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "mathematicalConstants.H"
28 
29 using namespace Foam::constant::mathematical;
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 template<class ParcelType>
35 
36 template<class ParcelType>
38 
39 template<class ParcelType>
41 
42 
43 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
44 
45 template<class ParcelType>
46 template<class TrackData>
48 (
49  TrackData& td,
50  const scalar p,
51  const scalar T,
52  const label idG,
53  const label idL,
54  const label idS
55 ) const
56 {
57  return
58  this->Y_[GAS]*td.cloud().composition().Cp(idG, YGas_, p, T)
59  + this->Y_[LIQ]*td.cloud().composition().Cp(idL, YLiquid_, p, T)
60  + this->Y_[SLD]*td.cloud().composition().Cp(idS, YSolid_, p, T);
61 }
62 
63 
64 template<class ParcelType>
65 template<class TrackData>
67 (
68  TrackData& td,
69  const scalar p,
70  const scalar T,
71  const label idG,
72  const label idL,
73  const label idS
74 ) const
75 {
76  return
77  this->Y_[GAS]*td.cloud().composition().Hs(idG, YGas_, p, T)
78  + this->Y_[LIQ]*td.cloud().composition().Hs(idL, YLiquid_, p, T)
79  + this->Y_[SLD]*td.cloud().composition().Hs(idS, YSolid_, p, T);
80 }
81 
82 
83 template<class ParcelType>
84 template<class TrackData>
86 (
87  TrackData& td,
88  const scalar p,
89  const scalar T,
90  const label idG,
91  const label idL,
92  const label idS
93 ) const
94 {
95  return
96  this->Y_[GAS]*td.cloud().composition().L(idG, YGas_, p, T)
97  + this->Y_[LIQ]*td.cloud().composition().L(idL, YLiquid_, p, T)
98  + this->Y_[SLD]*td.cloud().composition().L(idS, YSolid_, p, T);
99 }
100 
101 
102 template<class ParcelType>
104 (
105  const scalar mass0,
106  const scalarField& dMassGas,
107  const scalarField& dMassLiquid,
108  const scalarField& dMassSolid
109 )
110 {
111  scalarField& YMix = this->Y_;
112 
113  scalar massGas =
114  this->updateMassFraction(mass0*YMix[GAS], dMassGas, YGas_);
115  scalar massLiquid =
116  this->updateMassFraction(mass0*YMix[LIQ], dMassLiquid, YLiquid_);
117  scalar massSolid =
118  this->updateMassFraction(mass0*YMix[SLD], dMassSolid, YSolid_);
119 
120  scalar massNew = max(massGas + massLiquid + massSolid, ROOTVSMALL);
121 
122  YMix[GAS] = massGas/massNew;
123  YMix[LIQ] = massLiquid/massNew;
124  YMix[SLD] = 1.0 - YMix[GAS] - YMix[LIQ];
125 
126  return massNew;
127 }
128 
129 
130 // * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
131 
132 template<class ParcelType>
133 template<class TrackData>
135 (
136  TrackData& td,
137  const scalar dt,
138  const label celli
139 )
140 {
141  ParcelType::setCellValues(td, dt, celli);
142 }
143 
144 
145 template<class ParcelType>
146 template<class TrackData>
148 (
149  TrackData& td,
150  const scalar dt,
151  const label celli
152 )
153 {
154  // Re-use correction from reacting parcel
155  ParcelType::cellValueSourceCorrection(td, dt, celli);
156 }
157 
158 
159 template<class ParcelType>
160 template<class TrackData>
162 (
163  TrackData& td,
164  const scalar dt,
165  const label celli
166 )
167 {
168  typedef typename TrackData::cloudType::reactingCloudType reactingCloudType;
170  td.cloud().composition();
171 
172 
173  // Define local properties at beginning of timestep
174  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
175 
176  const scalar np0 = this->nParticle_;
177  const scalar d0 = this->d_;
178  const vector& U0 = this->U_;
179  const scalar T0 = this->T_;
180  const scalar mass0 = this->mass();
181 
182  const scalar pc = this->pc_;
183 
184  const scalarField& YMix = this->Y_;
185  const label idG = composition.idGas();
186  const label idL = composition.idLiquid();
187  const label idS = composition.idSolid();
188 
189 
190  // Calc surface values
191  scalar Ts, rhos, mus, Prs, kappas;
192  this->calcSurfaceValues(td, celli, T0, Ts, rhos, mus, Prs, kappas);
193  scalar Res = this->Re(U0, d0, rhos, mus);
194 
195 
196  // Sources
197  //~~~~~~~~
198 
199  // Explicit momentum source for particle
200  vector Su = Zero;
201 
202  // Linearised momentum source coefficient
203  scalar Spu = 0.0;
204 
205  // Momentum transfer from the particle to the carrier phase
206  vector dUTrans = Zero;
207 
208  // Explicit enthalpy source for particle
209  scalar Sh = 0.0;
210 
211  // Linearised enthalpy source coefficient
212  scalar Sph = 0.0;
213 
214  // Sensible enthalpy transfer from the particle to the carrier phase
215  scalar dhsTrans = 0.0;
216 
217 
218  // 1. Compute models that contribute to mass transfer - U, T held constant
219  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
220 
221  // Phase change in liquid phase
222  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
223 
224  // Mass transfer due to phase change
225  scalarField dMassPC(YLiquid_.size(), 0.0);
226 
227  // Molar flux of species emitted from the particle (kmol/m^2/s)
228  scalar Ne = 0.0;
229 
230  // Sum Ni*Cpi*Wi of emission species
231  scalar NCpW = 0.0;
232 
233  // Surface concentrations of emitted species
234  scalarField Cs(composition.carrier().species().size(), 0.0);
235 
236  // Calc mass and enthalpy transfer due to phase change
237  this->calcPhaseChange
238  (
239  td,
240  dt,
241  celli,
242  Res,
243  Prs,
244  Ts,
245  mus/rhos,
246  d0,
247  T0,
248  mass0,
249  idL,
250  YMix[LIQ],
251  YLiquid_,
252  dMassPC,
253  Sh,
254  Ne,
255  NCpW,
256  Cs
257  );
258 
259 
260  // Devolatilisation
261  // ~~~~~~~~~~~~~~~~
262 
263  // Mass transfer due to devolatilisation
264  scalarField dMassDV(YGas_.size(), 0.0);
265 
266  // Calc mass and enthalpy transfer due to devolatilisation
267  calcDevolatilisation
268  (
269  td,
270  dt,
271  this->age_,
272  Ts,
273  d0,
274  T0,
275  mass0,
276  this->mass0_,
277  YMix[GAS]*YGas_,
278  YMix[LIQ]*YLiquid_,
279  YMix[SLD]*YSolid_,
280  canCombust_,
281  dMassDV,
282  Sh,
283  Ne,
284  NCpW,
285  Cs
286  );
287 
288 
289  // Surface reactions
290  // ~~~~~~~~~~~~~~~~~
291 
292  // Change in carrier phase composition due to surface reactions
293  scalarField dMassSRGas(YGas_.size(), 0.0);
294  scalarField dMassSRLiquid(YLiquid_.size(), 0.0);
295  scalarField dMassSRSolid(YSolid_.size(), 0.0);
296  scalarField dMassSRCarrier(composition.carrier().species().size(), 0.0);
297 
298  // Calc mass and enthalpy transfer due to surface reactions
299  calcSurfaceReactions
300  (
301  td,
302  dt,
303  celli,
304  d0,
305  T0,
306  mass0,
307  canCombust_,
308  Ne,
309  YMix,
310  YGas_,
311  YLiquid_,
312  YSolid_,
313  dMassSRGas,
314  dMassSRLiquid,
315  dMassSRSolid,
316  dMassSRCarrier,
317  Sh,
318  dhsTrans
319  );
320 
321 
322  // 2. Update the parcel properties due to change in mass
323  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
324 
325  scalarField dMassGas(dMassDV + dMassSRGas);
326  scalarField dMassLiquid(dMassPC + dMassSRLiquid);
327  scalarField dMassSolid(dMassSRSolid);
328  scalar mass1 =
329  updateMassFractions(mass0, dMassGas, dMassLiquid, dMassSolid);
330 
331  this->Cp_ = CpEff(td, pc, T0, idG, idL, idS);
332 
333  // Update particle density or diameter
334  if (td.cloud().constProps().constantVolume())
335  {
336  this->rho_ = mass1/this->volume();
337  }
338  else
339  {
340  this->d_ = cbrt(mass1/this->rho_*6.0/pi);
341  }
342 
343  // Remove the particle when mass falls below minimum threshold
344  if (np0*mass1 < td.cloud().constProps().minParcelMass())
345  {
346  td.keepParticle = false;
347 
348  if (td.cloud().solution().coupled())
349  {
350  scalar dm = np0*mass0;
351 
352  // Absorb parcel into carrier phase
353  forAll(YGas_, i)
354  {
355  label gid = composition.localToCarrierId(GAS, i);
356  td.cloud().rhoTrans(gid)[celli] += dm*YMix[GAS]*YGas_[i];
357  }
358  forAll(YLiquid_, i)
359  {
360  label gid = composition.localToCarrierId(LIQ, i);
361  td.cloud().rhoTrans(gid)[celli] += dm*YMix[LIQ]*YLiquid_[i];
362  }
363 
364  // No mapping between solid components and carrier phase
365  /*
366  forAll(YSolid_, i)
367  {
368  label gid = composition.localToCarrierId(SLD, i);
369  td.cloud().rhoTrans(gid)[celli] += dm*YMix[SLD]*YSolid_[i];
370  }
371  */
372 
373  td.cloud().UTrans()[celli] += dm*U0;
374 
375  td.cloud().hsTrans()[celli] += dm*HsEff(td, pc, T0, idG, idL, idS);
376 
377  td.cloud().phaseChange().addToPhaseChangeMass(np0*mass1);
378  }
379 
380  return;
381  }
382 
383  // Correct surface values due to emitted species
384  this->correctSurfaceValues(td, celli, Ts, Cs, rhos, mus, Prs, kappas);
385  Res = this->Re(U0, this->d_, rhos, mus);
386 
387 
388  // 3. Compute heat- and momentum transfers
389  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
390 
391  // Heat transfer
392  // ~~~~~~~~~~~~~
393 
394  // Calculate new particle temperature
395  this->T_ =
396  this->calcHeatTransfer
397  (
398  td,
399  dt,
400  celli,
401  Res,
402  Prs,
403  kappas,
404  NCpW,
405  Sh,
406  dhsTrans,
407  Sph
408  );
409 
410 
411  this->Cp_ = CpEff(td, pc, this->T_, idG, idL, idS);
412 
413 
414  // Motion
415  // ~~~~~~
416 
417  // Calculate new particle velocity
418  this->U_ =
419  this->calcVelocity(td, dt, celli, Res, mus, mass1, Su, dUTrans, Spu);
420 
421 
422  // 4. Accumulate carrier phase source terms
423  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
424 
425  if (td.cloud().solution().coupled())
426  {
427  // Transfer mass lost to carrier mass, momentum and enthalpy sources
428  forAll(YGas_, i)
429  {
430  scalar dm = np0*dMassGas[i];
431  label gid = composition.localToCarrierId(GAS, i);
432  scalar hs = composition.carrier().Hs(gid, pc, T0);
433  td.cloud().rhoTrans(gid)[celli] += dm;
434  td.cloud().UTrans()[celli] += dm*U0;
435  td.cloud().hsTrans()[celli] += dm*hs;
436  }
437  forAll(YLiquid_, i)
438  {
439  scalar dm = np0*dMassLiquid[i];
440  label gid = composition.localToCarrierId(LIQ, i);
441  scalar hs = composition.carrier().Hs(gid, pc, T0);
442  td.cloud().rhoTrans(gid)[celli] += dm;
443  td.cloud().UTrans()[celli] += dm*U0;
444  td.cloud().hsTrans()[celli] += dm*hs;
445  }
446 
447  // No mapping between solid components and carrier phase
448  /*
449  forAll(YSolid_, i)
450  {
451  scalar dm = np0*dMassSolid[i];
452  label gid = composition.localToCarrierId(SLD, i);
453  scalar hs = composition.carrier().Hs(gid, pc, T0);
454  td.cloud().rhoTrans(gid)[celli] += dm;
455  td.cloud().UTrans()[celli] += dm*U0;
456  td.cloud().hsTrans()[celli] += dm*hs;
457  }
458  */
459 
460  forAll(dMassSRCarrier, i)
461  {
462  scalar dm = np0*dMassSRCarrier[i];
463  scalar hs = composition.carrier().Hs(i, pc, T0);
464  td.cloud().rhoTrans(i)[celli] += dm;
465  td.cloud().UTrans()[celli] += dm*U0;
466  td.cloud().hsTrans()[celli] += dm*hs;
467  }
468 
469  // Update momentum transfer
470  td.cloud().UTrans()[celli] += np0*dUTrans;
471  td.cloud().UCoeff()[celli] += np0*Spu;
472 
473  // Update sensible enthalpy transfer
474  td.cloud().hsTrans()[celli] += np0*dhsTrans;
475  td.cloud().hsCoeff()[celli] += np0*Sph;
476 
477  // Update radiation fields
478  if (td.cloud().radiation())
479  {
480  const scalar ap = this->areaP();
481  const scalar T4 = pow4(T0);
482  td.cloud().radAreaP()[celli] += dt*np0*ap;
483  td.cloud().radT4()[celli] += dt*np0*T4;
484  td.cloud().radAreaPT4()[celli] += dt*np0*ap*T4;
485  }
486  }
487 }
488 
489 
490 template<class ParcelType>
491 template<class TrackData>
493 (
494  TrackData& td,
495  const scalar dt,
496  const scalar age,
497  const scalar Ts,
498  const scalar d,
499  const scalar T,
500  const scalar mass,
501  const scalar mass0,
502  const scalarField& YGasEff,
503  const scalarField& YLiquidEff,
504  const scalarField& YSolidEff,
505  label& canCombust,
506  scalarField& dMassDV,
507  scalar& Sh,
508  scalar& N,
509  scalar& NCpW,
510  scalarField& Cs
511 ) const
512 {
513  // Check that model is active
514  if (!td.cloud().devolatilisation().active())
515  {
516  return;
517  }
518 
519  // Initialise demand-driven constants
520  (void)td.cloud().constProps().TDevol();
521  (void)td.cloud().constProps().LDevol();
522 
523  // Check that the parcel temperature is within necessary limits for
524  // devolatilisation to occur
525  if (T < td.cloud().constProps().TDevol() || canCombust == -1)
526  {
527  return;
528  }
529 
530  typedef typename TrackData::cloudType::reactingCloudType reactingCloudType;
532  td.cloud().composition();
533 
534 
535  // Total mass of volatiles evolved
536  td.cloud().devolatilisation().calculate
537  (
538  dt,
539  age,
540  mass0,
541  mass,
542  T,
543  YGasEff,
544  YLiquidEff,
545  YSolidEff,
546  canCombust,
547  dMassDV
548  );
549 
550  scalar dMassTot = sum(dMassDV);
551 
552  td.cloud().devolatilisation().addToDevolatilisationMass
553  (
554  this->nParticle_*dMassTot
555  );
556 
557  Sh -= dMassTot*td.cloud().constProps().LDevol()/dt;
558 
559  // Update molar emissions
560  if (td.cloud().heatTransfer().BirdCorrection())
561  {
562  // Molar average molecular weight of carrier mix
563  const scalar Wc =
564  max(SMALL, this->rhoc_*RR*this->Tc_/this->pc_);
565 
566  // Note: hardcoded gaseous diffusivities for now
567  // TODO: add to carrier thermo
568  const scalar beta = sqr(cbrt(15.0) + cbrt(15.0));
569 
570  forAll(dMassDV, i)
571  {
572  const label id = composition.localToCarrierId(GAS, i);
573  const scalar Cp = composition.carrier().Cp(id, this->pc_, Ts);
574  const scalar W = composition.carrier().W(id);
575  const scalar Ni = dMassDV[i]/(this->areaS(d)*dt*W);
576 
577  // Dab calc'd using API vapour mass diffusivity function
578  const scalar Dab =
579  3.6059e-3*(pow(1.8*Ts, 1.75))
580  *sqrt(1.0/W + 1.0/Wc)
581  /(this->pc_*beta);
582 
583  N += Ni;
584  NCpW += Ni*Cp*W;
585  Cs[id] += Ni*d/(2.0*Dab);
586  }
587  }
588 }
589 
590 
591 template<class ParcelType>
592 template<class TrackData>
594 (
595  TrackData& td,
596  const scalar dt,
597  const label celli,
598  const scalar d,
599  const scalar T,
600  const scalar mass,
601  const label canCombust,
602  const scalar N,
603  const scalarField& YMix,
604  const scalarField& YGas,
605  const scalarField& YLiquid,
606  const scalarField& YSolid,
607  scalarField& dMassSRGas,
608  scalarField& dMassSRLiquid,
609  scalarField& dMassSRSolid,
610  scalarField& dMassSRCarrier,
611  scalar& Sh,
612  scalar& dhsTrans
613 ) const
614 {
615  // Check that model is active
616  if (!td.cloud().surfaceReaction().active())
617  {
618  return;
619  }
620 
621  // Initialise demand-driven constants
622  (void)td.cloud().constProps().hRetentionCoeff();
623  (void)td.cloud().constProps().TMax();
624 
625  // Check that model is active
626  if (canCombust != 1)
627  {
628  return;
629  }
630 
631 
632  // Update surface reactions
633  const scalar hReaction = td.cloud().surfaceReaction().calculate
634  (
635  dt,
636  celli,
637  d,
638  T,
639  this->Tc_,
640  this->pc_,
641  this->rhoc_,
642  mass,
643  YGas,
644  YLiquid,
645  YSolid,
646  YMix,
647  N,
648  dMassSRGas,
649  dMassSRLiquid,
650  dMassSRSolid,
651  dMassSRCarrier
652  );
653 
654  td.cloud().surfaceReaction().addToSurfaceReactionMass
655  (
656  this->nParticle_
657  *(sum(dMassSRGas) + sum(dMassSRLiquid) + sum(dMassSRSolid))
658  );
659 
660  const scalar xsi = min(T/td.cloud().constProps().TMax(), 1.0);
661  const scalar coeff =
662  (1.0 - xsi*xsi)*td.cloud().constProps().hRetentionCoeff();
663 
664  Sh += coeff*hReaction/dt;
665 
666  dhsTrans += (1.0 - coeff)*hReaction;
667 }
668 
669 
670 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
671 
672 template<class ParcelType>
674 (
676 )
677 :
678  ParcelType(p),
679  YGas_(p.YGas_),
680  YLiquid_(p.YLiquid_),
681  YSolid_(p.YSolid_),
682  canCombust_(p.canCombust_)
683 {}
684 
685 
686 template<class ParcelType>
688 (
690  const polyMesh& mesh
691 )
692 :
693  ParcelType(p, mesh),
694  YGas_(p.YGas_),
695  YLiquid_(p.YLiquid_),
696  YSolid_(p.YSolid_),
697  canCombust_(p.canCombust_)
698 {}
699 
700 
701 // * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * * * //
702 
704 
705 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
label canCombust_
Flag to identify if the particle can devolatilise and combust.
basicMultiComponentMixture & composition
label localToCarrierId(const label phaseI, const label id, const bool allowNotFound=false) const
Return carrier id of component given local id.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
virtual label idSolid() const =0
Solid id.
void setCellValues(TrackData &td, const scalar dt, const label celli)
Set cell values.
dimensionedScalar sqrt(const dimensionedScalar &ds)
void cellValueSourceCorrection(TrackData &td, const scalar dt, const label celli)
Correct cell values using latest transfer information.
void calc(TrackData &td, const scalar dt, const label celli)
Update parcel properties over the time interval.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
const basicSpecieMixture & carrier() const
Return the carrier components (wrapper function)
scalarField YGas_
Mass fractions of gases [].
mathematical constants.
dimensionedScalar cbrt(const dimensionedScalar &ds)
ReactingMultiphaseParcel(const polyMesh &mesh, const vector &position, const label celli, const label tetFacei, const label tetPtI)
Construct from owner, position, and cloud owner.
static const zero Zero
Definition: zero.H:91
virtual label idLiquid() const =0
Liquid id.
scalarField YSolid_
Mass fractions of solids [].
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
scalarField YLiquid_
Mass fractions of liquids [].
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
dimensionedScalar pow4(const dimensionedScalar &ds)
Multiphase variant of the reacting parcel class with one/two-way coupling with the continuous phase...
dimensionedScalar beta("beta", dimless/dimTemperature, laminarTransport)
void calcDevolatilisation(TrackData &td, const scalar dt, const scalar age, const scalar Ts, const scalar d, const scalar T, const scalar mass, const scalar mass0, const scalarField &YGasEff, const scalarField &YLiquidEff, const scalarField &YSolidEff, label &canCombust, scalarField &dMassDV, scalar &Sh, scalar &N, scalar &NCpW, scalarField &Cs) const
Calculate Devolatilisation.
void calcSurfaceReactions(TrackData &td, const scalar dt, const label celli, const scalar d, const scalar T, const scalar mass, const label canCombust, const scalar N, const scalarField &YMix, const scalarField &YGas, const scalarField &YLiquid, const scalarField &YSolid, scalarField &dMassSRGas, scalarField &dMassSRLiquid, scalarField &dMassSRSolid, scalarField &dMassSRCarrier, scalar &Sh, scalar &dhsTrans) const
Calculate surface reactions.
const scalar RR
Universal gas constant (default in [J/(kmol K)])
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
virtual label idGas() const =0
Gas id.
Templated reacting parcel composition model class Consists of carrier species (via thermo package)...
Definition: ReactingCloud.H:52
tmp< GeometricField< Type, fvPatchField, volMesh > > Su(const GeometricField< Type, fvPatchField, volMesh > &su, const GeometricField< Type, fvPatchField, volMesh > &vf)
Definition: fvcSup.C:44
scalarField Re(const UList< complex > &cf)
Definition: complexFields.C:97