コード例 #1
0
ファイル: fem_1d.cpp プロジェクト: NDiscacciati/pacs
int main (int argc, char **argv)
{

  GetPot cl (argc, argv);

  if (cl.search (2, "-h", "--help"))
    {
      std::cerr << help_text << std::endl;
      return 0;
    }
  const double a = cl.follow (0.0, "-a");
  const double b = cl.follow (1.0, "-b");
  const unsigned int nnodes = cl.follow (100, 2, "-n", "--nnodes");
  const std::string diffusion = cl.follow ("1.0", 2, "-d", "--diffusion");
  const std::string forcing = cl.follow ("1.0", 2, "-f", "--forcing");
  
  std::unique_ptr<mesh<double>> m (new mesh<double> (a, b, nnodes));
  fem_1d<double> problem (std::move (m));

  coeff<double> a_coeff (diffusion);
  problem.set_diffusion_coefficient (a_coeff);

  coeff<double> f_coeff (forcing);
  problem.set_source_coefficient (f_coeff);

  problem.assemble ();
  
  problem.set_dirichlet (fem_1d<double>::left_boundary, 0.0);
  problem.set_dirichlet (fem_1d<double>::right_boundary, 0.0);

  problem.solve ();
  
  for (unsigned int ii = 0; ii < nnodes; ++ii)
    std::cout << problem.m->nodes[ii] << " "
              << problem.result ()(ii, 0)
              << std:: endl;
      
  return 0;
};
コード例 #2
0
ConstitutiveModelParameters<EvalT, Traits>::
ConstitutiveModelParameters(Teuchos::ParameterList& p,
    const Teuchos::RCP<Albany::Layouts>& dl) :
    have_temperature_(false),
    dl_(dl)
{
  // get number of integration points and spatial dimensions
  std::vector<PHX::DataLayout::size_type> dims;
  dl_->qp_vector->dimensions(dims);
  num_pts_ = dims[1];
  num_dims_ = dims[2];

  // get the Parameter Library
  Teuchos::RCP<ParamLib> paramLib =
      p.get<Teuchos::RCP<ParamLib> >("Parameter Library", Teuchos::null);

  // get the material parameter list
  Teuchos::ParameterList* mat_params =
      p.get<Teuchos::ParameterList*>("Material Parameters");

  // Check for optional field: temperature
  if (p.isType<std::string>("Temperature Name")) {
    have_temperature_ = true;
    PHX::MDField<ScalarT, Cell, QuadPoint>
    tmp(p.get<std::string>("Temperature Name"), dl_->qp_scalar);
    temperature_ = tmp;
    this->addDependentField(temperature_);
  }

  // step through the possible parameters, registering as necessary
  //
  // elastic modulus
  std::string e_mod("Elastic Modulus");
  if (mat_params->isSublist(e_mod)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(e_mod, dl_->qp_scalar);
    elastic_mod_ = tmp;
    field_map_.insert(std::make_pair(e_mod, elastic_mod_));
    parseParameters(e_mod, p, paramLib);
  }
  // Poisson's ratio
  std::string pr("Poissons Ratio");
  if (mat_params->isSublist(pr)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(pr, dl_->qp_scalar);
    poissons_ratio_ = tmp;
    field_map_.insert(std::make_pair(pr, poissons_ratio_));
    parseParameters(pr, p, paramLib);
  }
  // bulk modulus
  std::string b_mod("Bulk Modulus");
  if (mat_params->isSublist(b_mod)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(b_mod, dl_->qp_scalar);
    bulk_mod_ = tmp;
    field_map_.insert(std::make_pair(b_mod, bulk_mod_));
    parseParameters(b_mod, p, paramLib);
  }
  // shear modulus
  std::string s_mod("Shear Modulus");
  if (mat_params->isSublist(s_mod)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(s_mod, dl_->qp_scalar);
    shear_mod_ = tmp;
    field_map_.insert(std::make_pair(s_mod, shear_mod_));
    parseParameters(s_mod, p, paramLib);
  }
  // yield strength
  std::string yield("Yield Strength");
  if (mat_params->isSublist(yield)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(yield, dl_->qp_scalar);
    yield_strength_ = tmp;
    field_map_.insert(std::make_pair(yield, yield_strength_));
    parseParameters(yield, p, paramLib);
  }
  // hardening modulus
  std::string h_mod("Hardening Modulus");
  if (mat_params->isSublist(h_mod)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(h_mod, dl_->qp_scalar);
    hardening_mod_ = tmp;
    field_map_.insert(std::make_pair(h_mod, hardening_mod_));
    parseParameters(h_mod, p, paramLib);
  }
  // recovery modulus
  std::string r_mod("Recovery Modulus");
  if (mat_params->isSublist(r_mod)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(r_mod, dl_->qp_scalar);
    recovery_mod_ = tmp;
    field_map_.insert(std::make_pair(r_mod, recovery_mod_));
    parseParameters(r_mod, p, paramLib);
  }
  // concentration equilibrium parameter
  std::string c_eq("Concentration Equilibrium Parameter");
  if (mat_params->isSublist(c_eq)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(c_eq, dl_->qp_scalar);
    conc_eq_param_ = tmp;
    field_map_.insert(std::make_pair(c_eq, conc_eq_param_));
    parseParameters(c_eq, p, paramLib);
  }
  // diffusion coefficient
  std::string d_coeff("Diffusion Coefficient");
  if (mat_params->isSublist(d_coeff)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(d_coeff, dl_->qp_scalar);
    diff_coeff_ = tmp;
    field_map_.insert(std::make_pair(d_coeff, diff_coeff_));
    parseParameters(d_coeff, p, paramLib);
  }
  // thermal conductivity
  std::string th_cond("Thermal Conductivity");
  if (mat_params->isSublist(th_cond)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(th_cond, dl_->qp_scalar);
    thermal_cond_ = tmp;
    field_map_.insert(std::make_pair(th_cond, thermal_cond_));
    parseParameters(th_cond, p, paramLib);
  }
  // flow rule coefficient
  std::string f_coeff("Flow Rule Coefficient");
  if (mat_params->isSublist(f_coeff)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(f_coeff, dl_->qp_scalar);
    flow_coeff_ = tmp;
    field_map_.insert(std::make_pair(f_coeff, flow_coeff_));
    parseParameters(f_coeff, p, paramLib);
  }
  // flow rule exponent
  std::string f_exp("Flow Rule Exponent");
  if (mat_params->isSublist(f_exp)) {
    PHX::MDField<ScalarT, Cell, QuadPoint> tmp(f_exp, dl_->qp_scalar);
    flow_exp_ = tmp;
    field_map_.insert(std::make_pair(f_exp, flow_exp_));
    parseParameters(f_exp, p, paramLib);
  }

  // register evaluated fields
  typename
  std::map<std::string, PHX::MDField<ScalarT, Cell, QuadPoint> >::iterator it;
  for (it = field_map_.begin();
      it != field_map_.end();
      ++it) {
    this->addEvaluatedField(it->second);
  }
  this->setName(
      "Constitutive Model Parameters" + PHX::TypeString<EvalT>::value);
}
コード例 #3
0
ファイル: fem1d.cpp プロジェクト: NDiscacciati/pacs
int main (int argc, char **argv)
{

  GetPot cl (argc, argv);

  if (cl.search (2, "-h", "--help"))
    {
      std::cerr << help_text << std::endl;
      return 0;
    }
  const double a = cl.follow (double (0.0), "-a");
  const double b = cl.follow (double (1.0), "-b");
  const unsigned int nnodes = cl.follow (100, 2, "-n", "--nnodes");
  const unsigned int nel = nnodes - 1;
  const std::string diffusion = cl.follow ("1.0", 2, "-d", "--diffusion");
  const std::string forcing = cl.follow ("1.0", 2, "-f", "--forcing");

  const double tol = 1e-6;
  const unsigned int maxit = 43;
  const unsigned int overlap = 3;
  const double L = b - a;
  const int mpi_size = 3;

  const double L_loc = L / double (mpi_size);
  const double h = L_loc / ceil (double(nel) / double(mpi_size));

  std::vector<double> a_loc (mpi_size);
  std::vector<double> b_loc (mpi_size);
  std::vector<unsigned int> nel_loc (mpi_size);
  std::vector<unsigned int> ndof_loc (mpi_size);
  std::vector<fem_1d<double>*> subproblems (mpi_size);
  
  coeff<double> a_coeff (diffusion);
  coeff<double> f_coeff (forcing);

  int mpi_rank;
  for (mpi_rank = 0; mpi_rank < mpi_size; ++mpi_rank)
    {
      a_loc[mpi_rank] = a + mpi_rank * L_loc;
      b_loc[mpi_rank] = a_loc[mpi_rank] + L_loc;
      nel_loc[mpi_rank] = ceil (double(nel) / double(mpi_size));
      if (mpi_rank > 0)
        {
          a_loc[mpi_rank] -= overlap * h;
          nel_loc[mpi_rank] += overlap;
        }
      if (mpi_rank < mpi_size - 1)
        {
          b_loc[mpi_rank] += overlap * h;
          nel_loc[mpi_rank] += overlap;
        }
      ndof_loc[mpi_rank] = nel_loc[mpi_rank] + 1;
      fem_1d<double>* tmp = new fem_1d<double>(new mesh<double>
                                               (a_loc[mpi_rank],
                                                b_loc[mpi_rank],
                                                ndof_loc[mpi_rank]));
      subproblems[mpi_rank] = tmp;
      
      subproblems[mpi_rank]->set_diffusion_coefficient (a_coeff);
      subproblems[mpi_rank]->set_source_coefficient (f_coeff);
      subproblems[mpi_rank]->assemble ();
      subproblems[mpi_rank]->set_dirichlet (fem_1d<double>::left_boundary, 0.0);
      subproblems[mpi_rank]->set_dirichlet (fem_1d<double>::right_boundary, 0.0);
      subproblems[mpi_rank]->solve ();
    };

  for (unsigned int it = 0; it < maxit; ++it)
    for (mpi_rank = 0; mpi_rank < mpi_size; ++mpi_rank)
      {
        if (mpi_rank > 0)
          subproblems[mpi_rank]->set_dirichlet
            (fem_1d<double>::left_boundary,
             subproblems[mpi_rank-1]->result ()
             [ndof_loc[mpi_rank-1]-1-2*overlap]);
        else
          subproblems[mpi_rank]->set_dirichlet
            (fem_1d<double>::left_boundary, 0.0);
        if (mpi_rank < mpi_size - 1)
          subproblems[mpi_rank]->set_dirichlet
            (fem_1d<double>::right_boundary,
             subproblems[mpi_rank+1]->result ()
             [2*overlap]);
        else
          subproblems[mpi_rank]->set_dirichlet
            (fem_1d<double>::right_boundary, 0.0);
        subproblems[mpi_rank]->solve ();
      }

  for (mpi_rank = 0; mpi_rank < mpi_size; ++mpi_rank)
    for (unsigned int ii = 0; ii < ndof_loc[mpi_rank]; ++ii)
      std::cout << subproblems[mpi_rank]->m->nodes[ii] << " "
                << subproblems[mpi_rank]->result ()(ii, 0)
                << std::endl;

  return 0;
};
コード例 #4
0
ファイル: fem1d.cpp プロジェクト: NDiscacciati/pacs
int main (int argc, char **argv)
{

  GetPot cl (argc, argv);

  if (cl.search (2, "-h", "--help"))
    {
      std::cerr << help_text << std::endl;
      return 0;
    }

  const double a =
    cl.follow (0.0, "-a");

  const double b =
    cl.follow (1.0, "-b");

  const unsigned int nnodes =
    cl.follow (100, 2, "-n", "--nnodes");

  const std::string diffusion =
    cl.follow ("1.0", 2, "-d", "--diffusion");

  const std::string forcing =
    cl.follow ("1.0", 2, "-f", "--forcing");
  
  coeff f_coeff (forcing);
  coeff a_coeff (diffusion);

  const std::string quadrature =
    cl.follow ("trapezoidal.so",
               2, "-q", "--quadrature-rule");

  std::function <void ()> r_r;
  
  void * handle = dlopen (quadrature.c_str (), RTLD_NOW);
  if (! handle)
    {
      std::cerr << "fem1d: cannot load dynamic object!"
                << std::endl;
      std::cerr << dlerror ()
                << std::endl;
      return (-1);
    }

  void * sym = dlsym (handle, "register_rules");
  if (! sym)
    {
      std::cerr << "fem1d: cannot load symbol!"
                << std::endl;
      std::cerr << dlerror ()
                << std::endl;
      return (-1);
    }


  r_r = reinterpret_cast <void (*) ()> (sym);
  r_r ();

  auto & the_factory = quadrature_factory::instance (); 
  auto integrate = the_factory.create ("trapezoidal");
  if (! integrate)
    {
      std::cerr << "rule name unknown" << std::endl;
      return (-1);
    }
    
  mesh m (a, b, nnodes);
  Eigen::SparseMatrix<double> A(nnodes, nnodes);
  
  Eigen::Matrix2d mloc;
  mloc << 0, 0, 0, 0;
  for (unsigned int iel = 0; iel < m.nels; ++iel)
    {

      mloc << 0, 0, 0, 0;      
      for (unsigned int inode = 0; inode < 2; ++inode)
        {

          auto igrad = [=, &m] (double x) -> double
            {
              return basisfungrad
              (x, m.nodes[m.elements[iel][0]],
               m.nodes[m.elements[iel][1]],
               inode == 0 ? 1.0 : 0.0, 
               inode == 1 ? 1.0 : 0.0);
            };

          
          for (unsigned int jnode = 0; jnode < 2; ++jnode)
            {

              auto jgrad = [=, &m] (double x) -> double
                {
                  return basisfungrad
                  (x, m.nodes[m.elements[iel][0]],
                   m.nodes[m.elements[iel][1]],
                   jnode == 0 ? 1.0 : 0.0, 
                   jnode == 1 ? 1.0 : 0.0);
                };
              
              mloc(inode,jnode) +=
                (*integrate) ([=, &m, &igrad, &jgrad, &a_coeff]
                           (double x) -> double
                           {
                             return (igrad (x) *
                                     jgrad (x) *
                                     a_coeff (x));
                           },
                           m.nodes[m.elements[iel][0]],
                           m.nodes[m.elements[iel][1]]);

              
              A.coeffRef(m.elements[iel][inode],
                         m.elements[iel][jnode]) += 
                mloc(inode,jnode);
              
            }
        }
    }

  Eigen::VectorXd f(nnodes);
  for (unsigned int ii = 0; ii < nnodes; ++ii)
    f(ii) = 0.0;
    
  Eigen::Vector2d vloc;

  for (unsigned int iel = 0; iel < m.nels; ++iel)
    {
      vloc << 0, 0;
      
      for (unsigned int inode = 0; inode < 2; ++inode)
        {

          auto ifun = [=, &m] (double x) -> double
            {
              return basisfun
              (x, m.nodes[m.elements[iel][0]],
               m.nodes[m.elements[iel][1]],
               inode == 0 ? 1.0 : 0.0,
               inode == 1 ? 1.0 : 0.0);
            };
          
            vloc(inode) +=
              (*integrate) ([=, &m, &ifun, &f_coeff]
                         (double x) -> double
                         {
                           return (ifun (x) *
                                   f_coeff (x));
                         },
                         m.nodes[m.elements[iel][0]],
                         m.nodes[m.elements[iel][1]]);

              
          f(m.elements[iel][inode]) += vloc(inode);
        }
    }

  f(0) = 0;
  f(nnodes - 1) = 0;

  A.coeffRef(0,0) = 1.0e10;
  A.coeffRef(nnodes-1,nnodes-1) = 1.0e10;
  for (unsigned int ii = 1; ii < nnodes; ++ii)
    {
      A.coeffRef(0, ii) = 0.0;
      A.coeffRef(nnodes-1, nnodes-1-ii) = 0.0;
    }
    
  Eigen::SparseLU<Eigen::SparseMatrix<double>> solver;
  A.makeCompressed ();
  solver.analyzePattern(A); 
  solver.factorize(A);
  
  Eigen::VectorXd uh = solver.solve (f);

  for (unsigned int ii = 0; ii < nnodes; ++ii)
    std::cout << m.nodes[ii] << " "
              << uh(ii, 0)
              << std:: endl;
      
  return 0;
};
コード例 #5
0
ファイル: fem1d.cpp プロジェクト: NDiscacciati/pacs
int main (int argc, char **argv)
{


  MPI_Init (&argc, &argv);
    
  GetPot cl (argc, argv);

  if (cl.search (2, "-h", "--help"))
    {
      std::cerr << help_text << std::endl;
      return 0;
    }
  
  const double a = cl.follow (double (0.0), "-a");
  const double b = cl.follow (double (1.0), "-b");
  const unsigned int nnodes = cl.follow (100, 2, "-n", "--nnodes");
  const unsigned int nel = nnodes - 1;
  const std::string diffusion = cl.follow ("1.0", 2, "-d", "--diffusion");
  const std::string forcing = cl.follow ("1.0", 2, "-f", "--forcing");
  const double L = b - a;

  constexpr double tol = 1e-6;
  constexpr unsigned int maxit = 100;
  constexpr unsigned int overlap = 100;

  MPI_Status status;
  int mpi_size, mpi_rank, tag;
  MPI_Comm_size (MPI_COMM_WORLD, &mpi_size);
  MPI_Comm_rank (MPI_COMM_WORLD, &mpi_rank);
  
  const double L_loc = L / double(mpi_size);
  const double h = L_loc / ceil (double(nel) / double(mpi_size));

  double a_loc  = .0;
  double lval   = .0;
  double b_loc  = .0;
  double rval   = .0;
  double buffer = .0;
  
  unsigned int nel_loc = 0;
  unsigned int ndof_loc = 1;
  fem_1d<double> *subproblems;
  
  coeff<double> a_coeff (diffusion);
  coeff<double> f_coeff (forcing);


  a_loc = a + mpi_rank * L_loc;
  b_loc = a_loc + L_loc;
  nel_loc = ceil (double(nel) / double(mpi_size));
  if (mpi_rank > 0)
    {
      a_loc -= overlap * h;
      nel_loc += overlap;
    }
  if (mpi_rank < mpi_size - 1)
    {
      b_loc += overlap * h;
      nel_loc += overlap;
    }
  ndof_loc = nel_loc + 1;
  subproblems = new fem_1d<double>
    (new mesh<double> (a_loc, b_loc, ndof_loc));
      
  subproblems->set_diffusion_coefficient (a_coeff);
  subproblems->set_source_coefficient (f_coeff);
  subproblems->assemble ();
  subproblems->set_dirichlet (fem_1d<double>::left_boundary, 0.0);
  subproblems->set_dirichlet (fem_1d<double>::right_boundary, 0.0);
  subproblems->solve ();

  for (unsigned int it = 0; it < maxit; ++it)
    {

      // With the following implementation
      // communication will occur sequentailly
      // left to right first then right to left
      
      // Receive from left neighbour
      if (mpi_rank > 0)
        {

          std::cerr << "rank " << mpi_rank
                    << " receiving lval from rank "
                    << mpi_rank - 1
                    << std::endl;

          MPI_Recv (&buffer, 1, MPI_DOUBLE, mpi_rank - 1, MPI_ANY_TAG,
                    MPI_COMM_WORLD, &status);

          std::cerr << "rank " << mpi_rank
                    << " received lval from rank "
                    << mpi_rank - 1
                    << std::endl;
            
          lval = buffer;
        }

      tag = 10*mpi_rank;
      // Send to right neighbour
      if (mpi_rank < mpi_size - 1)
        {
          buffer = subproblems->result ()
            [ndof_loc - 1 - 2*overlap];

          std::cerr << "rank " << mpi_rank
                    << " sending lval to rank "
                    << mpi_rank + 1
                    << std::endl;

          MPI_Send (&buffer, 1, MPI_DOUBLE, mpi_rank + 1, tag,
                    MPI_COMM_WORLD);

          std::cerr << "rank " << mpi_rank
                    << " sent lval to rank "
                    << mpi_rank + 1
                    << std::endl;
        }


      // Receive from right neighbour
      if (mpi_rank < mpi_size - 1)
        {
          std::cerr << "rank " << mpi_rank
                    << " receiving rval from rank "
                    << mpi_rank + 1
                    << std::endl;
          
          MPI_Recv (&buffer, 1, MPI_DOUBLE, mpi_rank + 1, MPI_ANY_TAG,
                    MPI_COMM_WORLD, &status);

          std::cerr << "rank " << mpi_rank
                    << " received rval from rank "
                    << mpi_rank + 1
                    << std::endl;

          rval = buffer;
        }

      tag = 10*mpi_rank + 1;
      // Send to right neighbour
      if (mpi_rank > 0)
        {
          buffer = subproblems->result () [2*overlap];

          std::cerr << "rank " << mpi_rank
                    << " sending rval to rank "
                    << mpi_rank - 1
                    << std::endl;

          MPI_Send (&buffer, 1, MPI_DOUBLE, mpi_rank - 1, tag,
                    MPI_COMM_WORLD);

          std::cerr << "rank " << mpi_rank
                    << " sent rval to rank "
                    << mpi_rank - 1
                    << std::endl;
        }


      subproblems->set_dirichlet
        (fem_1d<double>::left_boundary, lval);
      
      subproblems->set_dirichlet
        (fem_1d<double>::right_boundary, rval);
      
      subproblems->solve ();

    }

  for (int rank = 0; rank < mpi_size; ++rank)
    {
      if (rank == mpi_rank)
        for (unsigned int ii = 0; ii < ndof_loc; ++ii)
          std::cout << subproblems->m->nodes[ii] << " "
                    << subproblems->result ()(ii, 0)
                    << std::endl;
      MPI_Barrier (MPI_COMM_WORLD);
    }

  MPI_Finalize ();
  return 0;

};