예제 #1
0
// Read the number of layers from dictionary. Per patch 0 or the number
// of layers.
Foam::labelList Foam::layerParameters::readNumLayers
(
    const PtrList<dictionary>& surfaceDicts,
    const refinementSurfaces& refineSurfaces,
    const labelList& globalToPatch,
    const polyBoundaryMesh& boundaryMesh
)
{
    // Per surface the number of layers
    labelList globalSurfLayers(surfaceDicts.size());
    // Per surface, per region the number of layers
    List<Map<label> > regionSurfLayers(surfaceDicts.size());

    const labelList& surfaceIndices = refineSurfaces.surfaces();

    forAll(surfaceDicts, surfI)
    {
        const dictionary& dict = surfaceDicts[surfI];

        globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));

        if (dict.found("regions"))
        {
            // Per-region layer information

            PtrList<dictionary> regionDicts(dict.lookup("regions"));

            const wordList& regionNames =
                refineSurfaces.geometry()[surfaceIndices[surfI]].regions();

            forAll(regionDicts, dictI)
            {
                const dictionary& regionDict = regionDicts[dictI];

                const word regionName(regionDict.lookup("name"));

                label regionI = findIndex(regionNames, regionName);

                label nLayers = readLabel(regionDict.lookup("surfaceLayers"));

                Info<< "    region " << regionName << ':'<< nl
                    << "        surface layers:" << nLayers << nl;

                regionSurfLayers[surfI].insert(regionI, nLayers);
            }
        }
    }
예제 #2
0
void print(const char* msg, Ostream& os, const PtrList<GeoField>& flds)
{
    if (flds.size())
    {
        os << msg;
        forAll(flds, i)
        {
            os<< ' ' << flds[i].name();
        }
        os << endl;
    }
void Foam::PODOrthoNormalBase<Type>::calcOrthoBase
(
    const PtrList<GeometricField<Type, fvPatchField, volMesh> >& snapshots,
    const scalar accuracy
)
{
    // Calculate ortho-normal base for each component
    PtrList<PODEigenBase> eigenBase(pTraits<Type>::nComponents);

    const label nSnapshots = snapshots.size();

    typename
    powProduct<Vector<label>, pTraits<Type>::rank>::type validComponents
    (
        pow
        (
            snapshots[0].mesh().solutionD(),
            pTraits
            <
                typename powProduct<Vector<label>,
                pTraits<Type>::rank
            >::type>::zero
        )
    );

    label nValidCmpts = 0;

    for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
    {
        // Component not valid, skipping
        if (validComponents[cmpt] == -1) continue;

        // Create a list of snapshots
        PtrList<volScalarField> sf(nSnapshots);

        forAll (snapshots, i)
        {
            sf.set(i, new volScalarField(snapshots[i].component(cmpt)));
        }

        // Create eigen base
        eigenBase.set(cmpt, new PODEigenBase(sf));

        Info<< "Cumulative eigen-values for component " << cmpt
            << ": " << setprecision(14)
            << eigenBase[nValidCmpts].cumulativeEigenValues() << endl;

        nValidCmpts++;
    }
bool CMapTile::IsPassable(CVector Pos, CMap* pMap, CEntity* pTrespasser)
{
	if(!Flags.Is_Set(MTF_PASSABLE))
		return false;
	else {
		PtrList<CEntity*> EntityList = pMap->GetTileEntityList(Pos);
		for(Uint16 i=0;i<EntityList.size();i++) {
			if(EntityList[i] == pTrespasser)
				continue;
			if(EntityList[i]->EntityFlags.Is_Set(EF_MOB))
				return false;
		}
	}
	return true;
}
예제 #5
0
void readFields
(
    const vtkMesh& vMesh,
    const typename GeoField::Mesh& mesh,
    const IOobjectList& objects,
    const HashSet<word>& selectedFields,
    PtrList<GeoField>& fields
)
{
    // Search list of objects for volScalarFields
    IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));

    // Construct the vol scalar fields
    label nFields = fields.size();
    fields.setSize(nFields + fieldObjects.size());

    for
    (
        IOobjectList::iterator iter = fieldObjects.begin();
        iter != fieldObjects.end();
        ++iter
    )
    {
        if (selectedFields.empty() || selectedFields.found(iter()->name()))
        {
            fields.set
            (
                nFields,
                vMesh.interpolate
                (
                    GeoField
                    (
                        *iter(),
                        mesh
                    )
                )
            );
            nFields++;
        }
    }

    fields.setSize(nFields);
}
예제 #6
0
void CEntity::Attack(CMap *pMap)
{
	CVector AttackPoint = Pos + GetEntityCorner(FacingLeft ? CVector(-1, 0) : CVector(1, 0)) * 2.0f;
	CVector EAttackPointY = AttackPoint + CVector(0, ((AttackPoint.Y < 0.5f) ? 1 : -1)); //Extended AttackPoint in Y direction
	CVector EAttackPointX = AttackPoint + CVector(((AttackPoint.X < 0.5f) ? -1 : 1), 0);

	PtrList<CEntity*> EntityList = pMap->GetTileEntityList(AttackPoint);
	PtrList<CEntity*> EEntityListY = pMap->GetTileEntityList(EAttackPointY);
	PtrList<CEntity*> EEntityListX = pMap->GetTileEntityList(EAttackPointX);

	PtrList<CEntity*> AttackList = PtrList<CEntity*>::join(EntityList,
			PtrList<CEntity*>::join(EEntityListY, EEntityListX));
	for(Uint16 i = 0;i < AttackList.size();i++) {
		if (AttackList[i] == this)
			continue;
		AttackList[i]->OnHurt(pMap, this);
		if (AttackList[i]->Health == 0)
			pMap->RemoveEntity(pMap->GetEntityId(AttackList[i]));
	}
}
예제 #7
0
void Foam::readFields::loadField
(
    const word& fieldName,
    PtrList<GeometricField<Type, fvPatchField, volMesh> >& vflds,
    PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >& sflds
) const
{
    typedef GeometricField<Type, fvPatchField, volMesh> vfType;
    typedef GeometricField<Type, fvsPatchField, surfaceMesh> sfType;

    if (obr_.foundObject<vfType>(fieldName))
    {
        if (debug)
        {
            Info<< "readFields : Field " << fieldName << " already in database"
                << endl;
        }
    }
    else if (obr_.foundObject<sfType>(fieldName))
    {
        if (debug)
        {
            Info<< "readFields : Field " << fieldName << " already in database"
                << endl;
        }
    }
    else
    {
        const fvMesh& mesh = refCast<const fvMesh>(obr_);

        IOobject fieldHeader
        (
            fieldName,
            mesh.time().timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        );

        if
        (
            fieldHeader.headerOk()
         && fieldHeader.headerClassName() == vfType::typeName
        )
        {
            // store field locally
            Info<< "    Reading " << fieldName << endl;
            label sz = vflds.size();
            vflds.setSize(sz+1);
            vflds.set(sz, new vfType(fieldHeader, mesh));
        }
        else if
        (
            fieldHeader.headerOk()
         && fieldHeader.headerClassName() == sfType::typeName
        )
        {
            // store field locally
            Info<< "    Reading " << fieldName << endl;
            label sz = sflds.size();
            sflds.setSize(sz+1);
            sflds.set(sz, new sfType(fieldHeader, mesh));
        }
    }
}
void Foam::nearWallFields::createFields
(
    PtrList<GeometricField<Type, fvPatchField, volMesh> >& sflds
) const
{
    typedef GeometricField<Type, fvPatchField, volMesh> vfType;

    HashTable<const vfType*> flds(obr_.lookupClass<vfType>());

    forAllConstIter(typename HashTable<const vfType*>, flds, iter)
    {
        const vfType& fld = *iter();

        if (fieldMap_.found(fld.name()))
        {
            const word& sampleFldName = fieldMap_[fld.name()];

            if (obr_.found(sampleFldName))
            {
                Info<< "    a field " << sampleFldName
                    << " already exists on the mesh."
                    << endl;
            }
            else
            {
                label sz = sflds.size();
                sflds.setSize(sz+1);

                IOobject io(fld);
                io.readOpt() = IOobject::NO_READ;
                io.rename(sampleFldName);

                sflds.set(sz, new vfType(io, fld));
                vfType& sampleFld = sflds[sz];

                // Reset the bcs to be directMapped
                forAllConstIter(labelHashSet, patchSet_, iter)
                {
                    label patchI = iter.key();

                    sampleFld.boundaryField().set
                    (
                        patchI,
                        new selfContainedDirectMappedFixedValueFvPatchField
                            <Type>
                        (
                            sampleFld.mesh().boundary()[patchI],
                            sampleFld.dimensionedInternalField(),

                            sampleFld.mesh().name(),
                            directMappedPatchBase::NEARESTCELL,
                            word::null,     // samplePatch
                            -distance_,

                            sampleFld.name(),       // fieldName
                            false,                  // setAverage
                            pTraits<Type>::zero,    // average
                            interpolationCellPoint<Type>::typeName
                        )
                    );
                }

                Info<< "    created " << sampleFld.name() << " to sample "
                    << fld.name() << endl;
            }
        }
    }
예제 #9
0
void CEntity::OnMove(float fTime, CMap* pMap)
{
	float MovementAtom = 1.0f / BLOCK_SIZE;

	if ((0.1f > Vel.X) && (Vel.X > -0.1f)) {
		Vel.X = Mov.X = 0;
	}
	if ((0.1f > Vel.Y) && (Vel.Y > -0.1f)) {
		Vel.Y = Mov.Y = 0;
	}

	if (CanMove(CVector(0, MovementAtom), pMap))
		Vel += CVector(0, 9.81f * fTime * 8);

	if (Vel != CVector(0, 0)) {

		Vel *= pow(0.125f, fTime * 4);

		Mov += Vel * fTime;
		int X = abs(Mov.X * BLOCK_SIZE), Y = abs(Mov.Y * BLOCK_SIZE);

		int Xdir = 0, Ydir = 0;
		if (X > 0)
			Xdir = (int) (Mov.X * BLOCK_SIZE) / abs(Mov.X * BLOCK_SIZE);
		if (Y > 0)
			Ydir = (int) (Mov.Y * BLOCK_SIZE) / abs(Mov.Y * BLOCK_SIZE);

		while(X > 0 || Y > 0) {

			if (X > 0) {
				if (CanMove(CVector(Xdir * MovementAtom, 0), pMap)) {
					Pos.X += MovementAtom * Xdir;
					Mov.X -= Xdir * MovementAtom;
					--X;
				} else {
					X = 0;
					Vel.X = Mov.X = 0;
				}
			}
			if (Y > 0) {
				if (CanMove(CVector(0, Ydir * MovementAtom), pMap)) {
					Pos.Y += MovementAtom * Ydir;
					Mov.Y -= Ydir * MovementAtom;
					--Y;
				} else {
					Y = 0;
					Vel.Y = Mov.Y = 0;
				}
			}
		}
	}

	if (AttackTimer > 0) {
		AttackTimer -= fTime;
		if (AttackTimer < 0)
			AttackTimer = 0.0f;
	}

	if(!IsCollectible()) { //Collect Things
		PtrList<CEntity*> CollectibleList = pMap->GetEntitiesInRadius(Pos, 1);
		for(Uint16 i=0;i<CollectibleList.size();i++) {
			if(!CollectibleList[i]->IsCollectible())
				continue;
			else CollectibleList[i]->OnCollect(this, pMap);
		}
	}
}
void Foam::decompositionConstraints::singleProcessorFaceSetsConstraint::add
(
    const polyMesh& mesh,
    boolList& blockedFace,
    PtrList<labelList>& specifiedProcessorFaces,
    labelList& specifiedProcessor,
    List<labelPair>& explicitConnections
) const
{
    blockedFace.setSize(mesh.nFaces(), true);

    // Mark faces already in set
    labelList faceToSet(mesh.nFaces(), -1);
    forAll(specifiedProcessorFaces, setI)
    {
        const labelList& faceLabels = specifiedProcessorFaces[setI];
        forAll(faceLabels, i)
        {
            faceToSet[faceLabels[i]] = setI;
        }
    }


    forAll(setNameAndProcs_, setI)
    {
        //Info<< "Keeping all cells connected to faceSet "
        //    << setNameAndProcs_[setI].first()
        //    << " on processor " << setNameAndProcs_[setI].second() << endl;

        const label destProcI = setNameAndProcs_[setI].second();

        // Read faceSet
        const faceSet fz(mesh, setNameAndProcs_[setI].first());

        // Check that it does not overlap with existing specifiedProcessorFaces
        labelList nMatch(specifiedProcessorFaces.size(), 0);
        forAllConstIter(faceSet, fz, iter)
        {
            label setI = faceToSet[iter.key()];
            if (setI != -1)
            {
                nMatch[setI]++;
            }
        }


        // Only store if all faces are not yet in specifiedProcessorFaces
        // (on all processors)
        bool store = true;

        forAll(nMatch, setI)
        {
            if (nMatch[setI] == fz.size())
            {
                // full match
                store = false;
                break;
            }
            else if (nMatch[setI] > 0)
            {
                // partial match
                store = false;
                break;
            }
        }

        reduce(store, andOp<bool>());


        if (store)
        {
            specifiedProcessorFaces.append(new labelList(fz.sortedToc()));
            specifiedProcessor.append(destProcI);
        }
    }
tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
tetPointFieldDecomposer::decomposeField
(
    const GeometricField<Type, tetPolyPatchField, tetPointMesh>& field
) const
{
    // Create and map the internal field values
    Field<Type> internalField(field.internalField(), directAddressing());

    // Create and map the patch field values
    PtrList<tetPolyPatchField<Type> > patchFields
    (
        boundaryAddressing_.size() + 1
    );

    forAll (boundaryAddressing_, patchI)
    {
        if (boundaryAddressing_[patchI] >= 0)
        {
            patchFields.set
            (
                patchI,
                tetPolyPatchField<Type>::New
                (
                    field.boundaryField()
                        [boundaryAddressing_[patchI]],
                    processorMesh_.boundary()[patchI],
                    DimensionedField<Type, tetPointMesh>::null(),
                    *patchFieldDecompPtrs_[patchI]
                )
            );
        }
        else
        {
            patchFields.set
            (
                patchI,
                new ProcessorPointPatchField
                <
                    tetPolyPatchField,
                    tetPointMesh,
                    tetPolyPatch,
                    processorTetPolyPatch,
                    tetFemMatrix,
                    Type
                >
                (
                    processorMesh_.boundary()[patchI],
                    DimensionedField<Type, tetPointMesh>::null()
                )
            );
        }
    }

    // Add the global patch by hand.  This needs to be present on
    // all processors
    patchFields.set
    (
        patchFields.size() - 1,
        new GlobalPointPatchField
        <
            tetPolyPatchField,
            tetPointMesh,
            tetPolyPatch,
            globalTetPolyPatch,
            tetFemMatrix,
            Type
        >
        (
            processorMesh_.boundary().globalPatch(),
            DimensionedField<Type, tetPointMesh>::null()
        )
    );

    // Create the field for the processor
    return tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
    (
        new GeometricField<Type, tetPolyPatchField, tetPointMesh>
        (
            IOobject
            (
                field.name(),
                processorMesh_().time().timeName(),
                processorMesh_(),
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            processorMesh_,
            field.dimensions(),
            internalField,
            patchFields
        )
    );
}
void Foam::equationReader::removePowExponents
(
    const label index,
    tokenList& tl,
    PtrList<equationOperation>& map,
    labelList& opLvl,
    labelList& pl
) const
{
    // Remove pow(a,b) exponent part 'b' from an equation and create a sub-
    // equation.
    label tokenI(0);

    while (tokenI < map.size())
    {
        if (map[tokenI].operation() == equationOperation::otpow)
        {
            // Found a 'pow('. Look for ','; fail on ')', or end of list
            // pl checks ensure the ',' or ')' relate to the 'pow(', and not
            // another function / parethesis
            const label powFoundAt(tokenI);
            const label pLvl(pl[tokenI]);
            while ((opLvl[tokenI] != 5) || (pl[tokenI] != pLvl))
            {
                if
                (
                    ((opLvl[tokenI] == -4) && (pl[tokenI] == pLvl))
                 || (tokenI == (map.size() - 1))
                )
                {
                    OStringStream description;
                    description << "pow() function takes two arguments.";
                    fatalParseError
                    (
                        index,
                        tl,
                        powFoundAt,
                        tokenI,
                        "equationReader::removePowExponents",
                        description
                    );
                }
                tokenI++;
            }

            // Found 'pow( ... ,' look for ')', fail on list end
            const label commaFoundAt(tokenI);
            while ((opLvl[tokenI] != -4) || (pl[tokenI] != pLvl))
            {
                if (tokenI == (map.size() - 1))
                {
                    OStringStream description;
                    description << "Can't find closing parenthesis for "
                        << "pow() function.";
                    fatalParseError
                    (
                        index,
                        tl,
                        powFoundAt,
                        tokenI,
                        "equationReader::removePowExponents",
                        description
                    );
                }
                tokenI++;
            }

            const label closeFoundAt(tokenI);
            // Ignore if the exponent is only 1 token
            if ((closeFoundAt - commaFoundAt) > 2)
            {

                // Now create sub-equation
                OStringStream subEqnStream;
                for
                (
                    label subTokenI(commaFoundAt + 1);
                    subTokenI < closeFoundAt;
                    subTokenI++
                )
                {
                    if
                    (
                        tl[subTokenI].isPunctuation()
                     && (tl[subTokenI].pToken() == token::COLON))
                    {
                        subEqnStream << "^";
                    }
                    else
                    {
                        subEqnStream << tl[subTokenI];
                    }
                }
                string subEqnRawText(subEqnStream.str());
                const equation& eqn(operator[](index));
                equation subEqn
                (
                    eqn.name() + "_powExponent_" + name(powFoundAt),
                    subEqnRawText,
                    eqn.overrideDimensions(),
                    eqn.changeDimensions()
                );

                bool eqnCreated(false);
                for (label eqnI(0); eqnI < size(); eqnI++)
                {
                    const equation& eqnTest(operator[](eqnI));
                    if (eqnTest.name() == subEqn.name())
                    {
                        clearEquation(eqnI);
                        eqnTest.setRawText(subEqn.rawText());
                        eqnTest.setOverrideDimensions
                        (
                            subEqn.overrideDimensions()
                        );
                        eqnTest.setChangeDimensions
                        (
                            eqnTest.changeDimensions()
                        );
                        eqnCreated = true;
                    }
                }

                if (!eqnCreated)
                {
                    createEquation(subEqn);
                }

                // Change commaFoundAt + 1 entry to reflect new subEquation
                // reference
                tl[commaFoundAt + 1] = token(subEqn.name());
                map.set
                (
                    commaFoundAt + 1,
                    new equationOperation(findSource(subEqn.name()))
                );
                opLvl[commaFoundAt + 1] = 0;
                pl[commaFoundAt + 1] = pl[commaFoundAt];

                // Remove the subEquation from tl, map, opLvl and pl
                label tokensRemoved(closeFoundAt - (commaFoundAt + 2));
                label newSize(map.size() - tokensRemoved);
                for
                (
                    label subTokenI(commaFoundAt + 2);
                    subTokenI < newSize;
                    subTokenI++
                )
                {
                    tl[subTokenI] = tl[subTokenI + tokensRemoved];
                    map[subTokenI] = map[subTokenI + tokensRemoved];
                    opLvl[subTokenI] = opLvl[subTokenI + tokensRemoved];
                    pl[subTokenI] = pl[subTokenI + tokensRemoved];
                }
                tl.setSize(newSize);
                map.setSize(newSize);
                opLvl.setSize(newSize);
                pl.setSize(newSize);
            }
        }
        tokenI++;
    }
}
void Foam::equationReader::createMap
(
    const label index,
    const tokenList& tl,
    PtrList<equationOperation>& map,
    labelList& opLvl,
    labelList& pl
) const
{
//    equation * eqn(&this->operator[](index));

    // current parenthesis level - note, a negative parenthesis value indicates
    // that this is the root level of a function, and therefore ',' is allowed
    label p(0);

    forAll(tl, i)
    {
        if (tl[i].isNumber())
        {
            // Internal constant.  Save to internalScalars and record source
            opLvl[i] = 0;
            pl[i] = p;
            map.set
            (
                i,
                new equationOperation
                (
                    equationOperation::stinternalScalar,
                    addInternalScalar(tl[i].number()) + 1,
                    0,
                    0,
                    equationOperation::otnone
                )
            );
        }
        else if (tl[i].isWord())
        {
            // could be a variable name, function or mathematical constant
            // - check for function first - function is [word][punctuation '(']
            if
            (
                (i < (tl.size() - 1))
             && (tl[i + 1].isPunctuation())
             && (tl[i + 1].pToken() == token::BEGIN_LIST)
            )
            {
                // Function detected; function brackets are negative
                opLvl[i] = 4;
                p = -mag(p) - 1;
                pl[i] = p;
                map.set
                (
                    i,
                    new equationOperation
                    (
                        equationOperation::stnone,
                        0,
                        0,
                        0,
                        equationOperation::findOp(tl[i].wordToken())
                    )
                );

                if (map[i].operation() == equationOperation::otnone)
                {
                    OStringStream description;
                    description << tl[i].wordToken() << " is not a recognized "
                        << "function.";
                    fatalParseError
                    (
                        index,
                        tl,
                        i,
                        i,
                        "equationReader::parse",
                        description
                    );
                }

                // Set next token as well (function opening parenthesis)
                i++;
                opLvl[i] = 4;
                pl[i] = p;
                map.set
                (
                    i,
                    new equationOperation
                    (
                        equationOperation::stnone,
                        0,
                        0,
                        0,
                        equationOperation::otnone
                    )
                );
            }
            else if
            (
                (tl[i].wordToken() == "e_")
             || (tl[i].wordToken() == "pi_")
             || (tl[i].wordToken() == "twoPi_")
             || (tl[i].wordToken() == "piByTwo_")
             || (tl[i].wordToken() == "GREAT_")
             || (tl[i].wordToken() == "VGREAT_")
             || (tl[i].wordToken() == "ROOTVGREAT_")
             || (tl[i].wordToken() == "SMALL_")
             || (tl[i].wordToken() == "VSMALL_")
             || (tl[i].wordToken() == "ROOTVSMALL_")
            )
            {
                // Mathematical constant
                if
                (
                    findSource(tl[i].wordToken()).sourceType()
                 != equationOperation::stnone
                )
                {
                    // Found a possible conflicting variable name - warn
                    WarningIn("equationReader::createMap")
                        << "Equation for " << operator[](index).name()
                        << ", given by:" << token::NL << token::TAB
                        << operator[](index).rawText() << token:: NL << "refers "
                        << "to '" << tl[i].wordToken() << "'. Although "
                        << "variable " << tl[i].wordToken() << "was found in "
                        << "the data sources, " << tl[i].wordToken() << " is a"
                        << " mathematical constant. The mathematical constant "
                        << "will be used." << endl;
                }

                opLvl[i] = 0;
                pl[i] = p;
                label internalIndex(0);
                if (tl[i].wordToken() == "e_")
                {
                    // MathConstantScope is a hack that allows equationReader
                    // to work in multiple versions of OpenFOAM.  See
                    // include/versionSpecific.H
                    internalIndex =
                        addInternalScalar(MathConstantScope::e) + 1;
                }
                else if (tl[i].wordToken() == "pi_")
                {
                    internalIndex =
                        addInternalScalar(MathConstantScope::pi) + 1;
                }
                else if (tl[i].wordToken() == "twoPi_")
                {
                    internalIndex =
                        addInternalScalar(MathConstantScope::twoPi) + 1;
                }
                else if (tl[i].wordToken() == "piByTwo_")
                {
                    internalIndex =
                        addInternalScalar(MathConstantScope::piByTwo) + 1;
                }
                else if (tl[i].wordToken() == "GREAT_")
                {
                    internalIndex =
                        addInternalScalar(GREAT) + 1;
                }
                else if (tl[i].wordToken() == "VGREAT_")
                {
                    internalIndex =
                        addInternalScalar(VGREAT) + 1;
                }
                else if (tl[i].wordToken() == "ROOTVGREAT_")
                {
                    internalIndex =
                        addInternalScalar(ROOTVGREAT) + 1;
                }
                else if (tl[i].wordToken() == "SMALL_")
                {
                    internalIndex =
                        addInternalScalar(SMALL) + 1;
                }
                else if (tl[i].wordToken() == "VSMALL_")
                {
                    internalIndex =
                        addInternalScalar(VSMALL) + 1;
                }
                else  // tl[i].wordToken() == "ROOTVSMALL_"
                {
                    internalIndex =
                        addInternalScalar(ROOTVSMALL) + 1;
                }
                map.set
                (
                    i,
                    new equationOperation
                    (
                        equationOperation::stinternalScalar,
                        internalIndex,
                        0,
                        0,
                        equationOperation::otnone
                    )
                );
            }
            else
            {
                // Variable name
                opLvl[i] = 0;
                pl[i] = p;
                map.set
                (
                    i,
                    new equationOperation(findSource(tl[i].wordToken()))
                );
                if (map[i].sourceIndex() == 0)
                {
                    OStringStream description;
                    description << "Variable name " << tl[i].wordToken()
                        << " not found in any available sources.";
                    fatalParseError
                    (
                        index,
                        tl,
                        i,
                        i,
                        "equationReader::parse",
                        description
                    );
                }
                if (map[i].componentIndex() < 0)
                {
                    OStringStream description;
                    description << "Variable name " << tl[i].wordToken()
                        << " is interpretted as variablePart.componentPart, "
                        << "and the componentPart is not valid, or is "
                        << "required, but is missing.";
                    fatalParseError
                    (
                        index,
                        tl,
                        i,
                        i,
                        "equationReader::parse",
                        description
                    );
                }
            }
        }
        else if (tl[i].isPunctuation())
        {
            switch (tl[i].pToken())
            {
                case token::BEGIN_LIST: // (
                    opLvl[i] = 4;
                    p = mag(p) + 1;
                    pl[i] = p;
                    map.set
                    (
                        i,
                        new equationOperation
                        (
                            equationOperation::stnone,
                            0,
                            0,
                            0,
                            equationOperation::otnone
                        )
                    );
                    break;
                case token::END_LIST: // )
                {
                    opLvl[i] = -4;
                    pl[i] = p;
                    p = mag(p) - 1;
                    if (p < 0)
                    {
                        OStringStream description;
                        description << "Too many ')'.";
                        fatalParseError
                        (
                            index,
                            tl,
                            i,
                            i,
                            "equationReader::parse",
                            description
                        );

                    }

                    // Look for preceding parenthesis change - was it negative?
                    for (label j(i - 1); j >= 0; j--)
                    {
                        if (mag(pl[j]) == p)
                        {
                            if (pl[j] < 0)
                            {
                                p = -p;
                            }
                            break;
                        }
                    }

                    map.set
                    (
                        i,
                        new equationOperation
                        (
                            equationOperation::stnone,
                            0,
                            0,
                            0,
                            equationOperation::otnone
                        )
                    );
                    break;
                }
                case token::COMMA: // ,
                    // , is only accepted in a function level parenthesis
                    if (p < 0)
                    {
                        opLvl[i] = 5;
                        pl[i] = p;
                        map.set
                        (
                            i,
                            new equationOperation
                            (
                                equationOperation::stnone,
                                0,
                                0,
                                0,
                                equationOperation::otnone
                            )
                        );
                    }
                    else
                    {
                        OStringStream description;
                        description << "The comma, ',' does not make sense "
                            << "here.  Only permitted in the root parenthesis "
                            << "level of a function.";
                        fatalParseError
                        (
                            index,
                            tl,
                            i,
                            i,
                            "equationReader::parse",
                            description
                        );
                    }
                    break;
                case token::ADD: // +
                    opLvl[i] = 1;
                    pl[i] = p;
                    map.set
                    (
                        i,
                        new equationOperation
                        (
                            equationOperation::stnone,
                            0,
                            0,
                            0,
                            equationOperation::otplus
                        )
                    );
                    break;
                case token::SUBTRACT: // -
                    opLvl[i] = 1;
                    pl[i] = p;
                    map.set
                    (
                        i,
                        new equationOperation
                        (
                            equationOperation::stnone,
                            0,
                            0,
                            0,
                            equationOperation::otminus
                        )
                    );
                    break;
                case token::MULTIPLY: // *
                    opLvl[i] = 2;
                    pl[i] = p;
                    map.set
                    (
                        i,
                        new equationOperation
                        (
                            equationOperation::stnone,
                            0,
                            0,
                            0,
                            equationOperation::ottimes
                        )
                    );
                    break;
                case token::DIVIDE: // /
                    opLvl[i] = 2;
                    pl[i] = p;
                    map.set
                    (
                        i,
                        new equationOperation
                        (
                            equationOperation::stnone,
                            0,
                            0,
                            0,
                            equationOperation::otdivide
                        )
                    );
                    break;
                case token::COLON: // :, means ^
                {
                    OStringStream description;
                    description << "The '^' operator is not currently "
                        << "supported.  Use pow(a,b) instead.";
                    fatalParseError
                    (
                        index,
                        tl,
                        i,
                        i,
                        "equationReader::parse",
                        description
                    );
                    break;
                }
                /*
                    opLvl[i] = 3;
                    pl[i] = p;
                    map.set
                    (
                        i,
                        new equationOperation
                        (
                            equationOperation::stnone,
                            0,
                            0,
                            0,
                            equationOperation::otpow
                        )
                    );
                    break;
                */
                default:
                {
                    OStringStream description;
                    description << "Punctuation character '" << tl[i].pToken()
                    << "' is prohibitted.";
                    fatalParseError
                    (
                        index,
                        tl,
                        i,
                        i,
                        "equationReader::parse",
                        description
                    );
                    break;
                }
            } // end punctuation switch
        } // end if punctuation
        else
        {
            OStringStream description;
            description << "Unrecognized token: [" << tl[i] << "].";
            fatalParseError
            (
                index,
                tl,
                i,
                i,
                "equationReader::parse",
                description
            );
        }
    } // mapping loop

    if (p)
    {
        OStringStream description;
        description << "Parentheses do not match.  Expecting " << mag(p)
            << " additional ')'s.";
        fatalParseError
        (
            index,
            tl,
            0,
            tl.size() - 1,
            "equationReader::parse",
            description
        );
    }

    // Assign negatives (distinguish these from subtraction)
    // The difference is characterized by the preceding character:
    // -preceeded by an operator = negative '+' '-' '*' '/' '^'
    // -preceeded by an open bracket = negative '('
    // -preceeded by a comma = negative ','
    // -preceeded by a variable = subtract 'word' or 'number'
    // -preceeded by a close bracket = subtract ')'
    // Negatives are identified by a negative dictLookupIndex

    if (map[0].operation() == equationOperation::otminus)
    {
        opLvl[0] = 2;
        map[0].dictLookupIndex() = -1;
    }

    for (label i(1); i < map.size(); i++)
    {
        if (map[i].operation() == equationOperation::otminus)
        {
            if (opLvl[i-1] > 0)
            {
               opLvl[i] = 2;
               map[i].dictLookupIndex() = -1;
            }
        }
    }
}