40 using std::endl;
using std::cout;
using std::cerr;
41 using std::ends;
using std::cin;
46 using bgeot::scalar_type;
53 typedef gmm::row_matrix<sparse_vector_type> sparse_matrix_type;
54 typedef gmm::col_matrix<sparse_vector_type> col_sparse_matrix_type;
55 typedef std::vector<scalar_type> plain_vector;
61 base_small_vector sol_K;
63 scalar_type sol_u(
const base_node &x) {
return sin(gmm::vect_sp(sol_K, x)); }
65 scalar_type sol_f(
const base_node &x)
66 {
return gmm::vect_sp(sol_K, sol_K) * sin(gmm::vect_sp(sol_K, x)); }
68 base_small_vector sol_grad(
const base_node &x)
69 {
return sol_K * cos(gmm::vect_sp(sol_K, x)); }
74 struct laplacian_problem {
76 enum { DIRICHLET_BOUNDARY_NUM = 0, NEUMANN_BOUNDARY_NUM = 1};
87 sparse_matrix_type SM;
88 std::vector<scalar_type> U, B;
90 std::vector<scalar_type> Ud;
91 col_sparse_matrix_type NS;
94 std::string datafilename;
95 bgeot::md_param PARAM;
100 void compute_error();
101 laplacian_problem(
void) : mim(mesh), mf_u(mesh), mf_rhs(mesh),
108 void laplacian_problem::init(
void) {
110 std::string MESH_TYPE = PARAM.string_value(
"MESH_TYPE",
"Mesh type ");
111 std::string FEM_TYPE = PARAM.string_value(
"FEM_TYPE",
"FEM name");
112 std::string INTEGRATION = PARAM.string_value(
"INTEGRATION",
113 "Name of integration method");
115 cout <<
"MESH_TYPE=" << MESH_TYPE <<
"\n";
116 cout <<
"FEM_TYPE=" << FEM_TYPE <<
"\n";
117 cout <<
"INTEGRATION=" << INTEGRATION <<
"\n";
123 std::vector<size_type> nsubdiv(N);
124 std::fill(nsubdiv.begin(),nsubdiv.end(),
125 PARAM.int_value(
"NX",
"Nomber of space steps "));
127 PARAM.int_value(
"MESH_NOISED") != 0);
129 bgeot::base_matrix M(N,N);
131 static const char *t[] = {
"LX",
"LY",
"LZ"};
132 M(i,i) = (i<3) ? PARAM.real_value(t[i],t[i]) : 1.0;
134 if (N>1) { M(0,1) = PARAM.real_value(
"INCLINE") * PARAM.real_value(
"LY"); }
137 mesh.transformation(M);
139 datafilename = PARAM.string_value(
"ROOTFILENAME",
"Base name of data files.");
140 scalar_type FT = PARAM.real_value(
"FT",
"parameter for exact solution");
141 residual = PARAM.real_value(
"RESIDUAL");
142 if (residual == 0.) residual = 1e-10;
145 sol_K[j] = ((j & 1) == 0) ? FT : -FT;
151 mim.set_integration_method(mesh.convex_index(), ppi);
152 mf_u.set_finite_element(mesh.convex_index(), pf_u);
156 std::string data_fem_name = PARAM.string_value(
"DATA_FEM_TYPE");
157 if (data_fem_name.size() == 0) {
158 GMM_ASSERT1(pf_u->is_lagrange(),
"You are using a non-lagrange FEM. " 159 <<
"In that case you need to set " 160 <<
"DATA_FEM_TYPE in the .param file");
161 mf_rhs.set_finite_element(mesh.convex_index(), pf_u);
163 mf_rhs.set_finite_element(mesh.convex_index(),
170 mf_coef.set_finite_element(mesh.convex_index(),
175 gen_dirichlet = PARAM.int_value(
"GENERIC_DIRICHLET");
177 if (!pf_u->is_lagrange() && !gen_dirichlet)
178 GMM_WARNING2(
"With non lagrange fem prefer the generic " 179 "Dirichlet condition option");
181 cout <<
"Selecting Neumann and Dirichlet boundaries\n";
186 base_node un = mesh.normal_of_face_of_convex(i.cv(), i.f());
188 if (gmm::abs(un[N-1] - 1.0) < 1.0E-7) {
189 mesh.region(NEUMANN_BOUNDARY_NUM).add(i.cv(), i.f());
191 mesh.region(DIRICHLET_BOUNDARY_NUM).add(i.cv(), i.f());
196 void laplacian_problem::assembly(
void) {
204 cout <<
"Number of dof : " << nb_dof << endl;
205 cout <<
"Assembling stiffness matrix" << endl;
207 std::vector<scalar_type>(mf_coef.nb_dof(), 1.0));
209 cout <<
"Assembling source term" << endl;
210 std::vector<scalar_type> F(nb_dof_rhs);
214 cout <<
"Assembling Neumann condition" << endl;
218 NEUMANN_BOUNDARY_NUM);
220 cout <<
"take Dirichlet condition into account" << endl;
221 if (!gen_dirichlet) {
222 std::vector<scalar_type> D(nb_dof);
224 getfem::assembling_Dirichlet_condition(SM, B, mf_u,
225 DIRICHLET_BOUNDARY_NUM, D);
232 col_sparse_matrix_type H(nb_dof_rhs, nb_dof);
233 std::vector<scalar_type> R(nb_dof_rhs);
234 std::vector<scalar_type> RHaux(nb_dof);
238 mf_rhs, F, DIRICHLET_BOUNDARY_NUM);
240 gmm::clean(H, 1e-12);
247 gmm::mult(SM, Ud, gmm::scaled(B, -1.0), RHaux);
250 gmm::mult(gmm::transposed(NS), gmm::scaled(RHaux, -1.0), B);
251 sparse_matrix_type SMaux(nbcols, nb_dof);
252 gmm::mult(gmm::transposed(NS), SM, SMaux);
255 sparse_matrix_type NSaux(nb_dof, nbcols); gmm::copy(NS, NSaux);
256 gmm::mult(SMaux, NSaux, SM);
261 bool laplacian_problem::solve(
void) {
265 cout <<
"Compute preconditionner\n";
267 double time = gmm::uclock_sec();
277 cout <<
"Time to compute preconditionner : " 278 << gmm::uclock_sec() - time <<
" seconds\n";
284 gmm::gmres(SM, U, B, P, 50, iter);
287 gmm::SuperLU_solve(SM, U, B, rcond);
288 cout <<
"cond = " << 1/rcond <<
"\n";
291 cout <<
"Total time to solve : " 292 << gmm::uclock_sec() - time <<
" seconds\n";
295 std::vector<scalar_type> Uaux(mf_u.nb_dof());
296 gmm::mult(NS, U, Ud, Uaux);
301 return (iter.converged());
305 void laplacian_problem::compute_error() {
306 std::vector<scalar_type> V(mf_rhs.nb_basic_dof());
308 for (
size_type i = 0; i < mf_rhs.nb_basic_dof(); ++i)
309 V[i] -= sol_u(mf_rhs.point_of_basic_dof(i));
320 int main(
int argc,
char *argv[]) {
322 GMM_SET_EXCEPTION_DEBUG;
327 p.PARAM.read_command_line(argc, argv);
329 p.mesh.write_to_file(p.datafilename +
".mesh");
331 if (!p.solve()) GMM_ASSERT1(
false,
"Solve procedure has failed");
334 GMM_STANDARD_CATCH_ERROR;
structure used to hold a set of convexes and/or convex faces.
Export solutions to various formats.
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.
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
The Iteration object calculates whether the solution has reached the desired accuracy, or whether the maximum number of iterations has been reached.
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.
Describe a mesh (collection of convexes (elements) and points).
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).
pintegration_method int_method_descriptor(std::string name, bool throw_if_not_found=true)
Get an integration method from its name .
Describe an integration method linked to a mesh.
pgeometric_trans geometric_trans_descriptor(std::string name)
Get the geometric transformation from its string name.
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 , where is in the space of multipliers correspondi...
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
size_t size_type
used as the common size type in the library
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norminf(const V &v)
Infinity norm of a vector.
"iterator" class for regions.
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 ...
sparse vector built upon std::vector.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Describe a finite element method linked to a mesh.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
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).
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...
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
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.
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.
Include common gmm files.
SuperLU interface for getfem.
Compute the gradient of a field on a getfem::mesh_fem.
Miscelleanous assembly routines for common terms. Use the low-level generic assembly. Prefer the high-level one.
void resize(M &v, size_type m, size_type n)
*/
Incomplete LU with threshold and K fill-in Preconditioner.
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.
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
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.