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 .