Ejemplo n.º 1
0
  //--------------------------------------------------------
  //  constuct a Green's submatrix 
  //--------------------------------------------------------
  void ChargeRegulatorMethodFeedback::set_influence_matrix(void)
  {
    // construct control-influence matrix bar{G}^-1: ds{p} = G{p,m}^-1 dphi{m}


//
    if (nInfluenceNodes_ < nControlNodes_) throw ATC_Error(" least square not implmented ");
    if (nInfluenceNodes_ > nControlNodes_) throw ATC_Error(" solve not possible ");
    DENS_MAT G(nInfluenceNodes_,nControlNodes_); 
    DENS_VEC G_I;
    set<int>::const_iterator itr,itr2,itr3;
    const Array<int> & nmap = atc_->fe_engine()->fe_mesh()->global_to_unique_map();
    int i = 0;
    for (itr = influenceNodes_.begin(); itr != influenceNodes_.end(); itr++) {
      poissonSolver_->greens_function(*itr, G_I);
      int j = 0;
      for (itr2 = controlNodes_.begin(); itr2 != controlNodes_.end(); itr2++) {
        int jnode = nmap(*itr2);
        G(i,j++) = G_I(jnode);  
      }
      i++;
    }
    invG_ = inv(G);

    // construct the prolong-restrict projector N N^T for influence nodes only

    InterscaleManager & interscaleManager(atc_->interscale_manager());
    const SPAR_MAT & N_Ia = (boundary_) ?
      (interscaleManager.per_atom_sparse_matrix("InterpolantGhost"))->quantity():
      (interscaleManager.per_atom_sparse_matrix("Interpolant"))->quantity();
    NT_.reset(nInfluenceAtoms_,nInfluenceNodes_);
    DENS_MAT NNT(nInfluenceNodes_,nInfluenceNodes_);
    int k = 0;
    for (itr3 = influenceAtoms_.begin(); itr3 != influenceAtoms_.end(); itr3++) {
      int katom = *itr3;
      int i = 0;
      for (itr = influenceNodes_.begin(); itr != influenceNodes_.end(); itr++) {
        int Inode = *itr;
        int j = 0;
        NT_(k,i) = N_Ia(katom,Inode);
        for (itr2 = influenceNodes_.begin(); itr2 != influenceNodes_.end(); itr2++) {
          int Jnode = *itr2;
          NNT(i,j++) += N_Ia(katom,Inode)*N_Ia(katom,Jnode);
        }
        i++;
      }
      k++;
    }
    // swap contributions across processors
    DENS_MAT localNNT = NNT;
    int count = NNT.nRows()*NNT.nCols(); 
    lammpsInterface_->allsum(localNNT.ptr(),NNT.ptr(),count);
    invNNT_ = inv(NNT);
  
    // total influence matrix
    if (nInfluenceAtoms_ > 0) { NTinvNNTinvG_ = NT_*invNNT_*invG_; }

  }
Ejemplo n.º 2
0
NNT Lexer::NextOperator() {
  switch (*cursor) {
  case '`': IncrementCursor(); RETURN_NNT("`", op_bl, 1);
  case '@': IncrementCursor(); RETURN_NNT("@", op_l, 1);
  case ',': IncrementCursor(); RETURN_NNT(",", comma, 1);
  case ';': IncrementCursor(); RETURN_NNT(";", semicolon, 1);
  case '(': IncrementCursor(); RETURN_NNT("(", l_paren, 1);
  case ')': IncrementCursor(); RETURN_NNT(")", r_paren, 1);
  case '[': IncrementCursor(); RETURN_NNT("[", l_bracket, 1);
  case ']': IncrementCursor(); RETURN_NNT("]", r_bracket, 1);
  case '{': IncrementCursor(); RETURN_NNT("{", l_brace, 1);
  case '}': IncrementCursor(); RETURN_NNT("}", r_brace, 1);
  case '$': IncrementCursor(); RETURN_NNT("$", op_l, 1);

  case '.': {
    Cursor cursor_copy  = cursor;

    // Note: safe because we know we have a null-terminator
    while (*cursor == '.') { IncrementCursor(); }
    size_t num_dots = cursor.offset - cursor_copy.offset;

    if (num_dots == 1) {
      RETURN_NNT(".", op_b, 1);
    } else {
      if (num_dots > 2) { ErrorLog::TooManyDots(cursor_copy, num_dots); }
      RETURN_NNT("..", dots, 2);
    }
  } break;

  case '\\': {
    Cursor cursor_copy = cursor;
    size_t dist = 1;

    IncrementCursor();
    ++dist;
    switch(*cursor) {
    case '\\':
      IncrementCursor();
      RETURN_NNT("", newline, 0);
      break;
    case '\0':
      // Ignore the following newline
      IncrementCursor();
      return Next();
    case ' ':
    case '\t':
      while (IsWhitespace(*cursor)) {
        IncrementCursor();
        ++dist;
      }
      if (*cursor == '\0') {
        IncrementCursor();
        return Next();
      }

    // Intentionally falling through. Looking at a non-whitespace after a '\'
    default:
      ErrorLog::NonWhitespaceAfterNewlineEscape(cursor_copy, dist);
      return Next();
    }
  } break;

  case '#': {
    IncrementCursor();
    Cursor cursor_copy = cursor;

    if (!IsAlpha(*cursor)) {
      ErrorLog::InvalidHashtag(cursor_copy);
      return Next();
    }

    do { IncrementCursor(); } while (IsAlphaNumericOrUnderscore(*cursor));

    if (cursor.offset - cursor_copy.offset == 0) {
      ErrorLog::InvalidHashtag(cursor_copy);
    }

    char old_char       = *cursor;
    *cursor             = '\0';
    const char *tag_ref = cursor.line.ptr + cursor_copy.offset;
    size_t tag_len      = strlen(tag_ref);
    char *tag           = new char[tag_len + 1];
    strcpy(tag, tag_ref);
    *cursor             = old_char;

    RETURN_NNT(tag, hashtag, tag_len + 1);
  } break;

  case '+':
  case '%':
  case '<': 
  case '>': 
  case '|':
  case '^': {
    char first_char = *cursor;
    IncrementCursor();

    char *token = new char[3];
    token[0] = first_char;
    if (*cursor == '=') {
      IncrementCursor();
      token[1] = '=';
    } else {
      token[1] = '\0';
    }
    token[2] = '\0';

    RETURN_NNT(token, op_b, strlen(token));
  } break;

  case '*':
    IncrementCursor();
    if (*cursor == '/') {
      IncrementCursor();
      if (*cursor == '/') {
        // Looking at "*//" which should be parsed as an asterisk followed by a
        // one-line comment.
        BackUpCursor();
        RETURN_NNT("*", op_b, 1);
      } else {
        Cursor cursor_copy = cursor;
        cursor_copy.offset -= 2;
        ErrorLog::NotInMultilineComment(cursor_copy);
        return Next();
      }
    } else if (*cursor == '=') {
      IncrementCursor();
      RETURN_NNT("*=", op_b, 2);
    } else {
      RETURN_NNT("*", op_b, 1);
    }

  case '&': {
    IncrementCursor();
    if (*cursor == '=') {
      IncrementCursor();
      RETURN_NNT("&=", op_b, 2);
    } else {
      RETURN_NNT("&", op_bl, 1);
    }
  } break;

  case ':':  {
    IncrementCursor();

    if (*cursor == '=') {
      IncrementCursor();
      RETURN_NNT(":=", op_b, 2);

    } else if (*cursor == '>') {
      IncrementCursor();
      RETURN_NNT(":>", op_b, 2);

    } else {
      RETURN_NNT(":", colon, 1);
    }
  } break;

  case '!': {
    IncrementCursor();
    if (*cursor == '=') {
      IncrementCursor();
      RETURN_NNT("!=", op_b, 2);
    } else {
      RETURN_NNT("!", op_l, 1);
    }
  } break;

  case '-': {
    IncrementCursor();
    if (*cursor == '=') {
      IncrementCursor();
      RETURN_NNT("-=", op_b, 2);

    } else if (*cursor == '>') {
      IncrementCursor();
      auto nptr = new AST::TokenNode(cursor, "->");
      nptr->op = Language::Operator::Arrow;
      return NNT(nptr, Language::fn_arrow);

    } else if (*cursor == '-') {
      IncrementCursor();
      RETURN_TERMINAL(Hole, Unknown, IR::Value::None());

    } else {
      RETURN_NNT("-", op_bl, 1);
    }
  } break;

  case '=': {
    IncrementCursor();
    if (*cursor == '=') {
      IncrementCursor();
      RETURN_NNT("==", op_b, 2);

    } else if (*cursor == '>') {
      IncrementCursor();
      RETURN_NNT("=>", op_b, 2);

    } else {
      RETURN_NNT("=", eq, 1);
    }
  } break;

  case '/': {
    IncrementCursor();
    if (*cursor == '/') {
      // Ignore comments altogether
      SkipToEndOfLine();
      return Next();

    } else if (*cursor == '=') {
      IncrementCursor();
      RETURN_NNT("/=", op_b, 2);

    } else if (*cursor == '*') {
      IncrementCursor();
      char back_one = *cursor;
      IncrementCursor();

      size_t comment_layer = 1;

      while (comment_layer != 0) {
        if (ifs.eof()) {
          ErrorLog::RunawayMultilineComment();
          RETURN_NNT("", eof, 0);

        } else if (back_one == '/' && *cursor == '*') {
          ++comment_layer;

        } else if (back_one == '*' && *cursor == '/') {
          --comment_layer;
        }

        back_one = *cursor;
        IncrementCursor();
      }

      // Ignore comments altogether
      return Next();

    } else {
      RETURN_NNT("/", op_b, 1);
    }

  } break;

  case '"': {
    IncrementCursor();

    std::string str_lit = "";

    while (*cursor != '"' && *cursor != '\0') {
      if (*cursor == '\\') {
        IncrementCursor();
        switch (*cursor) {
        case '\'': {
          str_lit += '\'';
          Cursor cursor_copy = cursor;
          --cursor_copy.offset;
          ErrorLog::EscapedSingleQuoteInStringLit(cursor_copy);
        } break;

        case '\\': str_lit += '\\'; break;
        case '"':  str_lit += '"';  break;
        case 'a':  str_lit += '\a'; break;
        case 'b':  str_lit += '\b'; break;
        case 'f':  str_lit += '\f'; break;
        case 'n':  str_lit += '\n'; break;
        case 'r':  str_lit += '\r'; break;
        case 't':  str_lit += '\t'; break;
        case 'v':  str_lit += '\v'; break;

        default: {
          Cursor cursor_copy = cursor;
          --cursor_copy.offset;
          ErrorLog::InvalidEscapeCharInStringLit(cursor_copy);

          str_lit += *cursor;
        } break;
        }
      } else {
        str_lit += *cursor;
      }

      IncrementCursor();
    }

    if (*cursor == '\0') {
      ErrorLog::RunawayStringLit(cursor);
    } else {
      IncrementCursor();
    }

    // Not leaked. It's owned by a terminal which is persistent.
    char *cstr = new char[str_lit.size() + 2];
    strcpy(cstr + 1, str_lit.c_str());
    cstr[0] = '\1';
    RETURN_TERMINAL(StringLiteral, String, IR::Value(cstr));
  } break;

  case '\'': {
    IncrementCursor();
    char result;

    switch (*cursor) {
    case '\t':
      ErrorLog::TabInCharLit(cursor);
      result = '\t';
      break;

    case '\0': {
      ErrorLog::RunawayCharLit(cursor);

      RETURN_TERMINAL(Char, Char, IR::Value::Char('\0'));
    }
    case '\\': {
      IncrementCursor();
      switch (*cursor) {
      case '\"': {
        result = '"';
        Cursor cursor_copy = cursor;
        --cursor_copy.offset;
        ErrorLog::EscapedDoubleQuoteInCharLit(cursor_copy);
      } break;
      case '\\': result = '\\'; break;
      case '\'': result = '\''; break;
      case 'a': result  = '\a'; break;
      case 'b': result  = '\b'; break;
      case 'f': result  = '\f'; break;
      case 'n': result  = '\n'; break;
      case 'r': result  = '\r'; break;
      case 't': result  = '\t'; break;
      case 'v': result  = '\v'; break;
      default:
        Cursor cursor_copy = cursor;
        --cursor_copy.offset;
        ErrorLog::InvalidEscapeCharInCharLit(cursor_copy);
        result = *cursor;
      }
      break;
    }
    default: { result = *cursor; } break;
    }

    IncrementCursor();

    if (*cursor == '\'') {
      IncrementCursor();
    } else {
      ErrorLog::RunawayCharLit(cursor);
    }

    RETURN_TERMINAL(Char, Char, IR::Value::Char(result));
  } break;

  case '?':
    ErrorLog::InvalidCharQuestionMark(cursor);
    IncrementCursor();
    return Next();

  case '~':
    ErrorLog::InvalidCharTilde(cursor);
    IncrementCursor();
    return Next();

  case '_': UNREACHABLE;
  default: UNREACHABLE;
  }
}
Ejemplo n.º 3
0
NNT Lexer::NextWord() {
  // Match [a-zA-Z_][a-zA-Z0-9_]*
  // We have already matched the first character

  auto starting_offset = cursor.offset;

  do {
    IncrementCursor();
  } while (IsAlphaNumericOrUnderscore(*cursor));

  char old_char     = *cursor;
  *cursor           = '\0';
  std::string token = cursor.line.ptr + starting_offset;
  *cursor           = old_char;

  // Check if the word is a type primitive/literal and if so, build the
  // appropriate Node.
  for (const auto &type_lit : PrimitiveTypes) {
    if (type_lit.first == token) {
      RETURN_TERMINAL(Type, Type_, IR::Value::Type(type_lit.second));
    }
  }

  if (token == "true" || token == "false") {
    RETURN_TERMINAL(True, Bool, IR::Value::Bool(token == "true"));

  } else if (token == "null") {
    RETURN_TERMINAL(Null, NullPtr, IR::Value::None());

  } else if (token == "ord") {
    RETURN_TERMINAL(Ord, Func(Char, Uint), IR::Value::None());

  } else if (token == "ascii") {
    RETURN_TERMINAL(ASCII, Func(Uint, Char), IR::Value::None());

  } else if (token == "else") {
    auto term_ptr           = new AST::Terminal;
    Cursor loc              = cursor;
    loc.offset              = starting_offset;
    term_ptr->loc           = loc;
    term_ptr->terminal_type = Language::Terminal::Else;
    term_ptr->type          = Bool;

    return NNT(term_ptr, Language::kw_else);

  }

#define CASE_RETURN_NNT(str, op, len)                                          \
  if (strcmp(token_cstr, str) == 0) { RETURN_NNT(str, op, len); }

  auto token_cstr = token.c_str();

  CASE_RETURN_NNT("in",       op_b,          2)
  CASE_RETURN_NNT("print",    op_l,          5)
  CASE_RETURN_NNT("import",   op_l,          6)
  CASE_RETURN_NNT("free",     op_l,          4)
  CASE_RETURN_NNT("while",    kw_expr_block, 5)
  CASE_RETURN_NNT("for",      kw_expr_block, 3)
  CASE_RETURN_NNT("if",       kw_if,         2)
  CASE_RETURN_NNT("case",     kw_block,      4)
  CASE_RETURN_NNT("enum",     kw_block,      4)
  CASE_RETURN_NNT("struct",   kw_struct,     6)
  CASE_RETURN_NNT("return",   op_lt,         6)
  CASE_RETURN_NNT("continue", op_lt,         8)
  CASE_RETURN_NNT("break",    op_lt,         5)
  CASE_RETURN_NNT("repeat",   op_lt,         6)
  CASE_RETURN_NNT("restart",  op_lt,         7)

#undef CASE_RETURN_NNT

  Cursor loc = cursor;
  loc.offset = starting_offset;
  return NNT(new AST::Identifier(loc, token), Language::expr);
}