void ASMHandler<GridType>::preprocess()
{
  int nodes = gv.size(dim);
  meqn.resize(nodes*dim);

  // iterate over nodes
  for (int indexi=0;indexi<nodes;++indexi) {
    fixIt it2 = fixedNodes.find(indexi);
    if (it2 == fixedNodes.end()) {
      for (int i=0;i<dim;++i) {
        MPC* mpc = getMPC(indexi,i);
        if (!mpc)
          meqn[indexi*dim+i] = maxeqn++;
        else
          meqn[indexi*dim+i] = -1;
      }
    } else {
      int flag=1;
      for (int i=0;i<dim;++i) {
        if (it2->second.first & flag)
          meqn[indexi*dim+i] = -1;
        else {
          MPC* mpc = getMPC(indexi,i);
          if (!mpc)
            meqn[indexi*dim+i] = maxeqn++;
          else
            meqn[indexi*dim+i] = -1;
        }
        flag *= 2;
      }
    }
  }
  std::cout << "\tnumber of equations: " << maxeqn << std::endl;
}
void ASMHandler<GridType>::addElement(
                    const Dune::FieldMatrix<double,esize,esize>* K,
                    const Dune::FieldVector<double,esize>* S,
                    const LeafIterator& cell,
                    Vector* b2)
{
  if (!b2)
    b2 = &b;
  const LeafIndexSet& set = gv.leafView().indexSet();
  for (int i=0;i<esize/dim;++i) {
    int index1 = set.subIndex(*cell,i,dim);
    fixIt it = fixedNodes.find(index1);
    if (it != fixedNodes.end() && it->second.first == XYZ)
      continue;
    for (int k=0;k<dim;++k) {
      MPC* mpc = getMPC(index1,k);
      if (mpc) {
        for (size_t n=0;n<mpc->getNoMaster();++n) {
          int idx = meqn[mpc->getMaster(n).node*dim+mpc->getMaster(n).dof-1];
          addDOF(idx,i*dim+k,K,S,set,cell,b2,mpc->getMaster(n).coeff);
        }
      } else
        addDOF(meqn[index1*dim+k],i*dim+k,K,S,set,cell,b2);
    }
  }
}
void ASMHandler<GridType>::addDOF(int row, int erow,
                              const Dune::FieldMatrix<double,esize,esize>* K,
                              const Dune::FieldVector<double,esize>* S,
                              const LeafIndexSet& set,
                              const LeafIterator& cell, 
                              Vector* b,
                              double scale)
{
  if (row == -1)
    return;
  if (K) {
    for (int j=0;j<esize/dim;++j) {
      int index2 = set.subIndex(*cell,j,dim);
      for (int l=0;l<dim;++l) {
        MPC* mpc = getMPC(index2,l);
        if (mpc) {
          for (size_t n=0;n<mpc->getNoMaster();++n) {
            int idx = meqn[mpc->getMaster(n).node*dim+mpc->getMaster(n).dof-1];
            if (idx != -1)
              A[row][idx] += scale*mpc->getMaster(n).coeff*(*K)[erow][j*dim+l];
          }
        } else if (meqn[index2*dim+l] != -1) {
          A[row][meqn[index2*dim+l]] += scale*(*K)[erow][j*dim+l];
        }
      }
    }
  }
  if (S && b)
    (*b)[row] += scale*(*S)[erow];
}
Exemple #4
0
void ASMHandler<GridType>::determineAdjacencyPattern()
{
  adjacencyPattern.resize(maxeqn);

  const LeafIndexSet& set = gv.leafView().indexSet();
  LeafIterator itend = gv.leafView().template end<0>();

  // iterate over cells
  for (LeafIterator it = gv.leafView().template begin<0>(); it != itend; ++it) {
    Dune::GeometryType gt = it->type();
    const Dune::template GenericReferenceElement<double,dim>& ref =
      Dune::GenericReferenceElements<double,dim>::general(gt);

    int vertexsize = ref.size(dim);
    for (int i=0; i < vertexsize; i++) {
      int indexi = set.subIndex(*it,i,dim);
      for (int k=0;k<dim;++k) {
        MPC* mpc = getMPC(indexi,k);
        if (mpc) {
          for (int l=0;l<mpc->getNoMaster();++l) {
            nodeAdjacency(it,vertexsize,
                          meqn[mpc->getMaster(l).node*dim+
                               mpc->getMaster(l).dof-1]);
          }
        } else
          nodeAdjacency(it,vertexsize,meqn[indexi*dim+k]);
      }
    }
  }
}
Exemple #5
0
void ASMHandler<GridType>::extractValues(Dune::FieldVector<double,comp>& v,
                                         const Vector& u,
                                         const LeafIterator& it)
{
  v = 0;
  const LeafIndexSet& set = gv.leafView().indexSet();
  Dune::GeometryType gt = it->type();
  const Dune::template GenericReferenceElement<double,dim> &ref =
                      Dune::GenericReferenceElements<double,dim>::general(gt);
  int vertexsize = ref.size(dim);
  int l=0;
  for (int i=0;i<vertexsize;++i) {
    int indexi = set.subIndex(*it,i,dim);
    fixIt it2 = fixedNodes.find(indexi);
    for (int n=0;n<dim;++n) {
      MPC* mpc = getMPC(indexi,n);
      if (it2 != fixedNodes.end() && it2->second.first & (1 << n))
        v[l++] = it2->second.second[n];
      else if (mpc) {
        for (int m=0;m<mpc->getNoMaster();++m) {
          int idx = meqn[mpc->getMaster(m).node*dim+mpc->getMaster(m).dof-1];
          if (idx != -1)
            v[l] += u[idx]*mpc->getMaster(m).coeff;
        }
        l++;
      } else
        v[l++] = u[meqn[indexi*dim+n]];
    }
  }
}
void ASMHandler<GridType>::determineAdjacencyPattern()
{
  adjacencyPattern.resize(maxeqn);
  std::cout << "\tsetting up sparsity pattern..." << std::endl;
  LoggerHelper help(gv.size(0), 5, 50000);

  const LeafIndexSet& set = gv.leafView().indexSet();
  LeafIterator itend = gv.leafView().template end<0>();

  // iterate over cells
  int cell=0;
  for (LeafIterator it = gv.leafView().template begin<0>(); it != itend; ++it, ++cell) {
    Dune::GeometryType gt = it->type();

#if DUNE_VERSION_NEWER(DUNE_GRID, 2, 3)
    const Dune::template ReferenceElement<double,dim>& ref =
      Dune::ReferenceElements<double,dim>::general(gt);
#else
    const Dune::template GenericReferenceElement<double,dim>& ref =
      Dune::GenericReferenceElements<double,dim>::general(gt);
#endif

    int vertexsize = ref.size(dim);
    for (int i=0; i < vertexsize; i++) {
      int indexi = set.subIndex(*it,i,dim);
      for (int k=0;k<dim;++k) {
        MPC* mpc = getMPC(indexi,k);
        if (mpc) {
          for (size_t l=0;l<mpc->getNoMaster();++l) {
            nodeAdjacency(it,vertexsize,
                          meqn[mpc->getMaster(l).node*dim+
                               mpc->getMaster(l).dof-1]);
          }
        } else
          nodeAdjacency(it,vertexsize,meqn[indexi*dim+k]);
      }
    }
    help.log(cell, "\t\t... still processing ... cell ");
  }
}
void ASMHandler<GridType>::expandSolution(Vector& result, const Vector& u)
{
  int nodes = gv.size(dim);
  result.resize(nodes*dim);
  result = 0;
  int l=0;
  for (int i=0;i<nodes;++i) {
    fixIt it = fixedNodes.find(i);
    Direction dir;
    if (it == fixedNodes.end())
      dir = NONE;
    else
      dir = it->second.first;

    int flag=1;
    for (int j=0;j<dim;++j) {
      if (dir & flag)
        result[l] = it->second.second[j];
      else if (meqn[l] != -1)
        result[l] = u[meqn[l]];
      l++;
      flag *= 2;
    }
  }
  // second loop - handle MPC couplings
  l = 0;
  for (int i=0;i<nodes;++i) {
    for (int j=0;j<dim;++j) {
      MPC* mpc = getMPC(i,j);
      if (mpc) {
        for (size_t n=0;n<mpc->getNoMaster();++n) {
          int idx = mpc->getMaster(n).node*dim+mpc->getMaster(n).dof-1;
          if (meqn[idx] != -1)
            result[l] += u[meqn[idx]]*mpc->getMaster(n).coeff;
        }
      }
      ++l;
    }
  }
}
void ASMHandler<GridType>::nodeAdjacency(const LeafIterator& it,
                                         int vertexsize, int row)
{
  if (row == -1)
    return;
  const LeafIndexSet& set = gv.leafView().indexSet();
  for (int j=0;j<vertexsize;++j) {
    int indexj = set.subIndex(*it,j,dim);
    for (int l=0;l<dim;++l) {
      MPC* mpc = getMPC(indexj,l);
      if (mpc) {
        for (size_t i=0;i<mpc->getNoMaster();++i) {
          int idx = meqn[mpc->getMaster(i).node*dim+
            mpc->getMaster(i).dof-1];
          if (idx != -1)
            adjacencyPattern[row].insert(idx);
        }
      } else if (meqn[indexj*dim+l] != -1)
        adjacencyPattern[row].insert(meqn[indexj*dim+l]);
    }
  }
}
void ASMHandler<GridType>::resolveMPCChain(MPC* mpc)
{
  size_t nMaster = mpc->getNoMaster();
  if (nMaster == 0) return; // no masters, prescribed displacement only

  for (size_t i = 0; i < nMaster; i++)
  {
    // Check if the master node has a local coordinate system attached. If yes,
    // the slave DOF might be coupled to all (local) DOFs of the master node.
    const MPC::DOF& master = mpc->getMaster(i);
    Dune::FieldVector<double,dim> coeff;
    coeff = 0;
    coeff[master.dof-1] = master.coeff;

    int removeOld = 0;
    for (int d = 1; d <= dim; d++)
      if (fabs(coeff[d-1]) > 1.0e-8)
      {
        MPC* mpc2 = getMPC(mpc->getMaster(i).node,d-1);
        if (mpc2)
        {
          // We have a master DOF which is a slave in another MPC.
          // Invoke resolveMPCchain recursively to ensure that all master DOFs
          // of that equation are not slaves themselves.
          resolveMPCChain(mpc2);

          // Remove current master specification, unless it has been updated
          if (!removeOld) removeOld = 1;

          // Add constant offset from the other equation
          mpc->addOffset(mpc2->getSlave().coeff*coeff[d-1]);

          // Add masters from the other equations
          for (size_t j = 0; j < mpc2->getNoMaster(); j++)
            mpc->addMaster(mpc2->getMaster(j).node,
                           mpc2->getMaster(j).dof,
                           mpc2->getMaster(j).coeff*coeff[d-1]);
        }
        else
          // The master node is free, but has a local coordinate system
          if (d != mpc->getMaster(i).dof)
            // Add coupling to the other local DOFs of this master node.
            mpc->addMaster(mpc->getMaster(i).node,d,coeff[d-1]);
          else if (coeff[d-1] != mpc->getMaster(i).coeff)
          {
            // Update the coupling coefficient of this master DOF
            // due to the local-to-global transformation
            mpc->updateMaster(i,coeff[d-1]);
            removeOld = -1;
          }
      }
      else if (d == mpc->getMaster(i).dof && !removeOld)
        // The coefficient of the current master DOF is zero,
        removeOld = 1; // so remove it from the contraint equation

    if (removeOld == 1)
    {
      // Remove the old master DOF specification when it has been replaced
      mpc->removeMaster(i--);
      nMaster--; // we don't need to check the added masters
    }
  }
}