39 using std::endl; 
using std::cout; 
using std::cerr;
 
   40 using std::ends; 
using std::cin;
 
   45 using bgeot::scalar_type; 
 
   52 typedef gmm::row_matrix<sparse_vector_type> sparse_matrix_type;
 
   53 typedef gmm::col_matrix<sparse_vector_type> col_sparse_matrix_type;
 
   54 typedef std::vector<scalar_type> plain_vector;
 
   60 base_small_vector sol_K; 
 
   62 scalar_type sol_u(
const base_node &x) { 
return sin(gmm::vect_sp(sol_K, x)); }
 
   64 scalar_type sol_f(
const base_node &x)
 
   65 { 
return gmm::vect_sp(sol_K, sol_K) * sin(gmm::vect_sp(sol_K, x)); }
 
   67 base_small_vector sol_grad(
const base_node &x)
 
   68 { 
return sol_K * cos(gmm::vect_sp(sol_K, x)); }
 
   73 struct laplacian_problem {
 
   75   enum { DIRICHLET_BOUNDARY_NUM = 0, NEUMANN_BOUNDARY_NUM = 1};
 
   86   sparse_matrix_type SM;     
 
   87   std::vector<scalar_type> U, B;      
 
   89   std::vector<scalar_type> Ud; 
 
   90   col_sparse_matrix_type NS; 
 
   93   std::string datafilename;
 
   94   bgeot::md_param PARAM;
 
  100   laplacian_problem(
void) : mim(mesh), mf_u(mesh), mf_rhs(mesh),
 
  107 void laplacian_problem::init(
void) {
 
  109   std::string MESH_TYPE = PARAM.string_value(
"MESH_TYPE",
"Mesh type ");
 
  110   std::string FEM_TYPE  = PARAM.string_value(
"FEM_TYPE",
"FEM name");
 
  111   std::string INTEGRATION = PARAM.string_value(
"INTEGRATION",
 
  112                                                "Name of integration method");
 
  114   cout << 
"MESH_TYPE=" << MESH_TYPE << 
"\n";
 
  115   cout << 
"FEM_TYPE="  << FEM_TYPE << 
"\n";
 
  116   cout << 
"INTEGRATION=" << INTEGRATION << 
"\n";
 
  122   std::vector<size_type> nsubdiv(N);
 
  123   std::fill(nsubdiv.begin(),nsubdiv.end(),
 
  124             PARAM.int_value(
"NX", 
"Nomber of space steps "));
 
  126                             PARAM.int_value(
"MESH_NOISED") != 0);
 
  128   bgeot::base_matrix M(N,N);
 
  130     static const char *t[] = {
"LX",
"LY",
"LZ"};
 
  131     M(i,i) = (i<3) ? PARAM.real_value(t[i],t[i]) : 1.0;
 
  133   if (N>1) { M(0,1) = PARAM.real_value(
"INCLINE") * PARAM.real_value(
"LY"); }
 
  136   mesh.transformation(M);
 
  138   datafilename = PARAM.string_value(
"ROOTFILENAME",
"Base name of data files.");
 
  139   scalar_type FT = PARAM.real_value(
"FT", 
"parameter for exact solution");
 
  140   residual = PARAM.real_value(
"RESIDUAL");
 
  141   if (residual == 0.) residual = 1e-10;
 
  144     sol_K[j] = ((j & 1) == 0) ? FT : -FT;
 
  150   mim.set_integration_method(mesh.convex_index(), ppi);
 
  151   mf_u.set_finite_element(mesh.convex_index(), pf_u);
 
  155   std::string data_fem_name = PARAM.string_value(
"DATA_FEM_TYPE");
 
  156   if (data_fem_name.size() == 0) {
 
  157     GMM_ASSERT1(pf_u->is_lagrange(), 
"You are using a non-lagrange FEM. " 
  158                 << 
"In that case you need to set " 
  159                 << 
"DATA_FEM_TYPE in the .param file");
 
  160     mf_rhs.set_finite_element(mesh.convex_index(), pf_u);
 
  162     mf_rhs.set_finite_element(mesh.convex_index(),
 
  169   mf_coef.set_finite_element(mesh.convex_index(),
 
  174   gen_dirichlet = PARAM.int_value(
"GENERIC_DIRICHLET");
 
  176   if (!pf_u->is_lagrange() && !gen_dirichlet)
 
  177     GMM_WARNING2(
"With non lagrange fem prefer the generic " 
  178                  "Dirichlet condition option");
 
  180   cout << 
"Selecting Neumann and Dirichlet boundaries\n";
 
  185     base_node un = mesh.normal_of_face_of_convex(i.cv(), i.f());
 
  187     if (gmm::abs(un[N-1] - 1.0) < 1.0E-7) { 
 
  188       mesh.region(NEUMANN_BOUNDARY_NUM).add(i.cv(), i.f());
 
  190       mesh.region(DIRICHLET_BOUNDARY_NUM).add(i.cv(), i.f());
 
  195 void laplacian_problem::assembly(
void) {
 
  203   cout << 
"Number of dof : " << nb_dof << endl;
 
  204   cout << 
"Assembling stiffness matrix" << endl;
 
  206      std::vector<scalar_type>(mf_coef.nb_dof(), 1.0));
 
  208   cout << 
"Assembling source term" << endl;
 
  209   std::vector<scalar_type> F(nb_dof_rhs);
 
  213   cout << 
"Assembling Neumann condition" << endl;
 
  217                                  NEUMANN_BOUNDARY_NUM);
 
  219   cout << 
"take Dirichlet condition into account" << endl;
 
  220   if (!gen_dirichlet) {
 
  221     std::vector<scalar_type> D(nb_dof);
 
  223     getfem::assembling_Dirichlet_condition(SM, B, mf_u,
 
  224                                            DIRICHLET_BOUNDARY_NUM, D);
 
  231     col_sparse_matrix_type H(nb_dof_rhs, nb_dof);
 
  232     std::vector<scalar_type> R(nb_dof_rhs);
 
  233     std::vector<scalar_type> RHaux(nb_dof);
 
  237       mf_rhs, F, DIRICHLET_BOUNDARY_NUM);
 
  246     gmm::mult(SM, Ud, gmm::scaled(B, -1.0), RHaux);
 
  249     gmm::mult(gmm::transposed(NS), gmm::scaled(RHaux, -1.0), B);
 
  250     sparse_matrix_type SMaux(nbcols, nb_dof);
 
  251     gmm::mult(gmm::transposed(NS), SM, SMaux);
 
  254     sparse_matrix_type NSaux(nb_dof, nbcols); 
gmm::copy(NS, NSaux);
 
  260 bool laplacian_problem::solve(
void) {
 
  264   cout << 
"Compute preconditionner\n";
 
  266   double time = gmm::uclock_sec();
 
  276     cout << 
"Time to compute preconditionner : " 
  277          << gmm::uclock_sec() - time << 
" seconds\n";
 
  286 #if defined(GMM_USES_SUPERLU) 
  287     gmm::SuperLU_solve(SM, U, B, rcond);
 
  289     cout << 
"cond = " << 1/rcond << 
"\n";
 
  292   cout << 
"Total time to solve : " 
  293        << gmm::uclock_sec() - time << 
" seconds\n";
 
  296     std::vector<scalar_type> Uaux(mf_u.nb_dof());
 
  302   return (iter.converged());
 
  306 void laplacian_problem::compute_error() {
 
  307   std::vector<scalar_type> V(mf_rhs.nb_basic_dof());
 
  309   for (
size_type i = 0; i < mf_rhs.nb_basic_dof(); ++i)
 
  310     V[i] -= sol_u(mf_rhs.point_of_basic_dof(i));
 
  321 int main(
int argc, 
char *argv[]) {
 
  323   GETFEM_MPI_INIT(argc, argv);
 
  324   GMM_SET_EXCEPTION_DEBUG; 
 
  329     p.PARAM.read_command_line(argc, argv);
 
  331     p.mesh.write_to_file(p.datafilename + 
".mesh");
 
  333     if (!p.solve()) GMM_ASSERT1(
false, 
"Solve procedure has failed");
 
  336   GMM_STANDARD_CATCH_ERROR;
 
Describe a finite element method linked to a mesh.
 
Describe an integration method linked to a mesh.
 
"iterator" class for regions.
 
structure used to hold a set of convexes and/or convex faces.
 
Describe a mesh (collection of convexes (elements) and points).
 
Incomplete LU with threshold and K fill-in Preconditioner.
 
The Iteration object calculates whether the solution has reached the desired accuracy,...
 
sparse vector built upon std::vector.
 
Miscelleanous assembly routines for common terms. Use the low-level generic assembly....
 
Compute the gradient of a field on a getfem::mesh_fem.
 
Export solutions to various formats.
 
Include common gmm files.
 
void copy(const L1 &l1, L2 &l2)
*/
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norminf(const V &v)
Infinity norm of a vector.
 
void clear(L &l)
clear (fill with zeros) a vector or matrix.
 
void resize(V &v, size_type n)
*/
 
void clean(L &l, double threshold)
Clean a vector or matrix (replace near-zero entries with zeroes).
 
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
 
void gmres(const Mat &A, Vec &x, const VecB &b, const Precond &M, int restart, iteration &outer, Basis &KS)
Generalized Minimum Residual.
 
void asm_stiffness_matrix_for_laplacian(MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
assembly of  , where  is scalar.
 
size_type Dirichlet_nullspace(const MAT1 &H, MAT2 &NS, const VECT1 &R, VECT2 &U0)
Build an orthogonal basis of the kernel of H in NS, gives the solution of minimal norm of H*U = R in ...
 
void asm_source_term(const VECT1 &B, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT2 &F, const mesh_region &rg=mesh_region::all_convexes())
source term (for both volumic sources and boundary (Neumann) sources).
 
scalar_type asm_L2_norm(const mesh_im &mim, const mesh_fem &mf, const VEC &U, const mesh_region &rg=mesh_region::all_convexes())
compute , U might be real or complex
 
scalar_type asm_H1_norm(const mesh_im &mim, const mesh_fem &mf, const VEC &U, const mesh_region &rg=mesh_region::all_convexes())
compute the H1 norm of U.
 
void asm_dirichlet_constraints(MAT &H, VECT1 &R, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_mult, const mesh_fem &mf_r, const VECT2 &r_data, const mesh_region ®ion, int version=ASMDIR_BUILDALL)
Assembly of Dirichlet constraints  in a weak form.
 
void asm_normal_source_term(VECT1 &B, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT2 &F, const mesh_region &rg)
Normal source term (for boundary (Neumann) condition).
 
void APIDECL outer_faces_of_mesh(const mesh &m, const dal::bit_vector &cvlst, convex_face_ct &flist)
returns a list of "exterior" faces of a mesh (i.e.
 
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
 
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
 
pfem classical_fem(bgeot::pgeometric_trans pgt, short_type k, bool complete=false)
Give a pointer on the structures describing the classical polynomial fem of degree k on a given conve...
 
pgeometric_trans geometric_trans_descriptor(std::string name)
Get the geometric transformation from its string name.
 
size_t size_type
used as the common size type in the library
 
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
 
void interpolation_function(mesh_fem &mf_target, const VECT &VV, F &f, mesh_region rg=mesh_region::all_convexes())
interpolation of a function f on mf_target.
 
void regular_unit_mesh(mesh &m, std::vector< size_type > nsubdiv, bgeot::pgeometric_trans pgt, bool noised=false)
Build a regular mesh of the unit square/cube/, etc.
 
void interpolation(const mesh_fem &mf_source, const mesh_fem &mf_target, const VECTU &U, VECTV &V, int extrapolation=0, double EPS=1E-10, mesh_region rg_source=mesh_region::all_convexes(), mesh_region rg_target=mesh_region::all_convexes())
interpolation/extrapolation of (mf_source, U) on mf_target.
 
pintegration_method int_method_descriptor(std::string name, bool throw_if_not_found=true)
Get an integration method from its name .