Beispiel #1
0
    void PolyInterpMixin<time>::fas(time dt, shared_ptr<ISweeper<time>> dst,
                                    shared_ptr<const ISweeper<time>> src)
    {
      auto& crse = pfasst::encap::as_encap_sweeper(dst);
      auto& fine = pfasst::encap::as_encap_sweeper(src);

      auto const ncrse = crse.get_nodes().size(); assert(ncrse >= 1);
      auto const nfine = fine.get_nodes().size(); assert(nfine >= 1);

      auto crse_factory = crse.get_factory();
      auto fine_factory = fine.get_factory();

      EncapVecT crse_int(ncrse), fine_int(nfine), rstr_int(ncrse);

      for (size_t m = 0; m < ncrse; m++) { crse_int[m] = crse_factory->create(solution); }
      for (size_t m = 0; m < ncrse; m++) { rstr_int[m] = crse_factory->create(solution); }
      for (size_t m = 0; m < nfine; m++) { fine_int[m] = fine_factory->create(solution); }

      // compute '0 to node' integral on the coarse level
      crse.integrate(dt, crse_int);

      // compute '0 to node' integral on the fine level
      fine.integrate(dt, fine_int);

      // restrict '0 to node' fine integral
      int trat = (int(nfine) - 1) / (int(ncrse) - 1);
      for (size_t m = 0; m < ncrse; m++) {
        this->restrict(rstr_int[m], fine_int[m * trat]);
      }

      // compute 'node to node' tau correction
      EncapVecT tau(ncrse), rstr_and_crse(2 * ncrse);
      // Attention: tau is getting filled with pointers to the crse's member
      for (size_t m = 0; m < ncrse; m++) { tau[m] = crse.get_tau(m); }
      for (size_t m = 0; m < ncrse; m++) { rstr_and_crse[m] = rstr_int[m]; }
      for (size_t m = 0; m < ncrse; m++) { rstr_and_crse[ncrse + m] = crse_int[m]; }

      if (fmat.rows() == 0) {
        fmat.resize(ncrse, 2 * ncrse);
        fmat.fill(0.0);

        for (size_t m = 0; m < ncrse; m++) {
          fmat(m, m) = 1.0;
          fmat(m, ncrse + m) = -1.0;

          // subtract 0-to-(m-1) FAS so resulting FAS is (m-1)-to-m FAS,
          //  which will be required in the sweeper logic
          for (size_t n = 0; n < m; n++) {
            fmat(m, n) = -1.0;
            fmat(m, ncrse + n) = 1.0;
          }
        }
      }

      tau[0]->mat_apply(tau, 1.0, fmat, rstr_and_crse, true);
    }
Beispiel #2
0
        virtual void fas(time dt, shared_ptr<ISweeper<time>> dst,
                         shared_ptr<const ISweeper<time>> src) override
        {
          auto& crse = pfasst::encap::as_encap_sweeper(dst);
          auto& fine = pfasst::encap::as_encap_sweeper(src);

          auto const ncrse = crse.get_nodes().size(); assert(ncrse >= 1);
          auto const nfine = fine.get_nodes().size(); assert(nfine >= 1);

          auto crse_factory = crse.get_factory();
          auto fine_factory = fine.get_factory();

          EncapVecT crse_int(ncrse), fine_int(nfine), rstr_int(ncrse);

          for (size_t m = 0; m < ncrse; m++) { crse_int[m] = crse_factory->create(solution); }
          for (size_t m = 0; m < ncrse; m++) { rstr_int[m] = crse_factory->create(solution); }
          for (size_t m = 0; m < nfine; m++) { fine_int[m] = fine_factory->create(solution); }

          // compute '0 to node' integral on the coarse level
          crse.integrate(dt, crse_int);

          // compute '0 to node' integral on the fine level
          fine.integrate(dt, fine_int);

          // restrict '0 to node' fine integral
          int trat = (int(nfine) - 1) / (int(ncrse) - 1);
          for (size_t m = 0; m < ncrse; m++) {
            this->restrict(rstr_int[m], fine_int[m * trat]);
          }

          // compute 'node to node' tau correction
          EncapVecT tau(ncrse), rstr_and_crse(2 * ncrse);
          for (size_t m = 0; m < ncrse; m++) { tau[m] = crse.get_tau(m); }
          for (size_t m = 0; m < ncrse; m++) { rstr_and_crse[m] = rstr_int[m]; }
          for (size_t m = 0; m < ncrse; m++) { rstr_and_crse[ncrse + m] = crse_int[m]; }

          if (fmat.rows() == 0) {
            fmat.resize(ncrse, 2 * ncrse);
            fmat.fill(0.0);

            for (size_t m = 0; m < ncrse; m++) {
              fmat(m, m) = 1.0;
              fmat(m, ncrse + m) = -1.0;

              for (size_t n = 0; n < m; n++) {
                fmat(m, n) = -1.0;
                fmat(m, ncrse + n) = 1.0;
              }
            }
          }

          tau[0]->mat_apply(tau, 1.0, fmat, rstr_and_crse, true);
        }