ExpPtr parseCall (Lexer& lex, ExpPtr in) { auto args = parseTuple(lex); ExpList exps; exps.reserve(args->subexps.size() + 1); exps.push_back(in); exps.insert(exps.end(), args->subexps.begin(), args->subexps.end()); return Exp::make(eCall, exps, in->span + args->span); }
void TreePrinter::printExpList(const ExpList &elist) { ExpList::const_iterator it = elist.begin(); while (it != elist.end()) { TreePrinter treePrinter; (*it)->accept(&treePrinter); DBG("-----\n"); DBG("%s\n", treePrinter.result.c_str()); ++it; } }
ExpPtr parseList (Lexer& lex) { Span spStart, spEnd; ExpList vals; spStart = lex.eat(tLBrack).span; while (lex.current() != tRBrack) { vals.push_back(parseExp(lex)); if (lex.current() == tComma) lex.advance(); else break; } spEnd = lex.eat(tRBrack).span; return Exp::make(eList, std::move(vals), spStart + spEnd); }
void parseBlockExp (Lexer& lex, ExpList& list) { switch (lex.current().tok) { case tSemicolon: lex.advance(); break; case tLet: list.push_back(parseLet(lex)); lex.eat(tSemicolon); break; case tLCurl: list.push_back(parseBlock(lex)); break; case tIf: list.push_back(parseCond(lex)); break; case tLoop: list.push_back(parseLoop(lex)); break; case tFor: list.push_back(parseFor(lex)); break; // everthing else does default: list.push_back(parseAssign(lex, parseExp(lex))); if (lex.current() != tSemicolon) lex.expect(tRCurl); else lex.eat(tSemicolon); break; } }
ExpPtr parseLoop (Lexer& lex) { Span spStart, spEnd; ExpPtr body; spStart = lex.eat(tLoop).span; ExpList sub; sub.reserve(2); if (lex.current() == tLCurl) { sub.push_back(body = parseBlock(lex)); } else { sub.push_back(parseExp(lex)); sub.push_back(body = parseBlock(lex)); } spEnd = body->span; return Exp::make(eLoop, std::move(sub), spStart + spEnd); }
ExpPtr parseTuple (Lexer& lex) { ExpList exps; ExpPtr e; Span spStart, spEnd; spStart = lex.eat(tLParen).span; while (lex.current() != tRParen) { e = parseExp(lex); exps.push_back(e); if (lex.current() == tComma) lex.advance(); else break; } spEnd = lex.eat(tRParen).span; return Exp::make(eTuple, exps, spStart + spEnd); }
ExpPtr parseExp (Lexer& lex) { Span spStart, spEnd; ExpList vals; ExpPtr e; Token tok; e = parseTerm(lex); vals.push_back(e); spStart = spEnd = e->span; while (lex.current() == tIdent) if (lex.current().isOperator()) { // <op> tok = lex.advance(); e = Exp::make(eVar, tok.str, bool(true), {}, tok.span); vals.push_back(e); // <term> e = parseTerm(lex); vals.push_back(e); spEnd = e->span; } else lex.expect("operator"); if (vals.size() == 1) return vals[0]; // else if (vals.size() == 3) // return Exp::make(eCall, { vals[1], vals[0], vals[2] }, // spStart + spEnd); else return Exp::make(eInfix, vals, spStart + spEnd); }
/** * Construction of the local->global map is achieved in several stages. * A mesh vertex renumbering is constructed as follows * - Domain Dirichlet boundaries are numbered first. * - Domain periodic boundaries are numbered next and given * consistent global indices. * - Remaining vertices are ordered last. * This mesh vertex renumbering is then used to generate the first * part of the local to global mapping of the degrees of freedom. The * remainder of the map consists of the element-interior degrees of * freedom. This leads to the block-diagonal submatrix as each * element-interior mode is globally orthogonal to modes in all other * elements. * * The boundary condition mapping is generated from the same vertex * renumbering. */ void AssemblyMapCG1D::SetUp1DExpansionC0ContMap( const int numLocalCoeffs, const ExpList &locExp, const Array<OneD, const MultiRegions::ExpListSharedPtr> &bndCondExp, const Array<OneD, const SpatialDomains::BoundaryConditionShPtr> &bndConditions, const map<int,int>& periodicVerticesId) { int i,j; int cnt = 0; int meshVertId; int meshVertId2; int graphVertId = 0; int globalId; const LocalRegions::ExpansionVector &locExpVector = *(locExp.GetExp()); LocalRegions::SegExpSharedPtr locSegExp; int nbnd = bndCondExp.num_elements(); m_staticCondLevel = 0; m_signChange = false; m_numPatches = locExpVector.size(); m_numLocalCoeffs = numLocalCoeffs; m_numLocalBndCoeffs = 2*locExpVector.size(); m_localToGlobalMap = Array<OneD, int>(m_numLocalCoeffs,-1); m_localToGlobalBndMap = Array<OneD, int>(m_numLocalBndCoeffs,-1); m_bndCondCoeffsToGlobalCoeffsMap = Array<OneD, int>(nbnd); m_numLocalBndCoeffsPerPatch = Array<OneD, unsigned int>(m_numPatches); m_numLocalIntCoeffsPerPatch = Array<OneD, unsigned int>(m_numPatches); for(i = 0; i < m_numPatches; ++i) { m_numLocalBndCoeffsPerPatch[i] = (unsigned int) locExpVector[locExp.GetOffset_Elmt_Id(i)]->NumBndryCoeffs(); m_numLocalIntCoeffsPerPatch[i] = (unsigned int) locExpVector[locExp.GetOffset_Elmt_Id(i)]->GetNcoeffs() - locExpVector[locExp.GetOffset_Elmt_Id(i)]->NumBndryCoeffs(); } // The only unique identifiers of the vertices of the mesh // are the vertex id (stored in their corresponding // Geometry object). However, setting up a global // numbering based on these id's will not lead to a // suitable or optimal numbering. Mainly because: - we // want the Dirichlet DOF's to be listed first - we want // an optimal global numbering of the remaining DOF's // (strategy still need to be defined but can for example // be: minimum bandwith or minimum fill-in of the // resulting global system matrix) // // That's why the vertices be rearranged. Currently, this // is done in the following way: The vertices of the mesh // are considered as vertices of a graph. (We then will // use algorithms to reorder these graph-vertices - // although not implemented yet in 1D). // // A container is used to store the graph vertex id's of // the different mesh vertices. This is implemented as a // STL map such that the graph vertex id can later be // retrieved by the unique mesh vertex id's which serve as // the key of the map. map<int, int> vertReorderedGraphVertId; map<int,int>::const_iterator mapConstIt; // STEP 1: Order the Dirichlet vertices first m_numGlobalDirBndCoeffs = 0; for(i = 0; i < nbnd; i++) { if(bndConditions[i]->GetBoundaryConditionType()==SpatialDomains::eDirichlet) { meshVertId = bndCondExp[i]->GetVertex()->GetVid(); vertReorderedGraphVertId[meshVertId] = graphVertId++; m_numGlobalDirBndCoeffs++; m_numLocalDirBndCoeffs++; } } // STEP 2: Order the periodic vertices next // This allows to give corresponding DOF's the same // global ID for(mapConstIt = periodicVerticesId.begin(); mapConstIt != periodicVerticesId.end(); mapConstIt++) { meshVertId = mapConstIt->first; meshVertId2 = mapConstIt->second; ASSERTL0(vertReorderedGraphVertId.count(meshVertId) == 0, "This periodic boundary vertex has been specified before"); ASSERTL0(vertReorderedGraphVertId.count(meshVertId) == 0, "This periodic boundary vertex has been specified before"); vertReorderedGraphVertId[meshVertId] = graphVertId; vertReorderedGraphVertId[meshVertId2] = graphVertId++; } // STEP 3: List the other vertices // STEP 4: Set up simple map based on vertex and edge id's for(i = 0; i < locExpVector.size(); ++i) { cnt = locExp.GetCoeff_Offset(i); if((locSegExp = boost::dynamic_pointer_cast<LocalRegions::SegExp>(locExpVector[i]))) { for(j = 0; j < locSegExp->GetNverts(); ++j) { meshVertId = (locSegExp->GetGeom1D())->GetVid(j); if(vertReorderedGraphVertId.count(meshVertId) == 0) { vertReorderedGraphVertId[meshVertId] = graphVertId++; } m_localToGlobalMap[cnt+locSegExp->GetVertexMap(j)] = vertReorderedGraphVertId[meshVertId]; } } else { ASSERTL0(false,"dynamic cast to a segment expansion failed"); } } // Set up the mapping for the boundary conditions for(i = 0; i < nbnd; i++) { meshVertId = bndCondExp[i]->GetVertex()->GetVid(); m_bndCondCoeffsToGlobalCoeffsMap[i] = vertReorderedGraphVertId[meshVertId]; } // Setup interior mapping and the boundary map globalId = graphVertId; m_numGlobalBndCoeffs = globalId; cnt=0; for(i = 0; i < m_numLocalCoeffs; ++i) { if(m_localToGlobalMap[i] == -1) { m_localToGlobalMap[i] = globalId++; } else { m_localToGlobalBndMap[cnt++]=m_localToGlobalMap[i]; } } m_numGlobalCoeffs = globalId; SetUpUniversalC0ContMap(locExp); m_hash = boost::hash_range(m_localToGlobalMap.begin(), m_localToGlobalMap.end()); // Add up hash values if parallel int hash = m_hash; m_comm->AllReduce(hash, LibUtilities::ReduceSum); m_hash = hash; }