Mercurial > fem-fenics-eugenio
view src/assemble.cc @ 91:51bfdf30b822
New DLD functions for assembling a matrix/vector from a bilinear/linear form
* assemble.cc: assemble a form, applying the bc specified. Simmetry not
mantained.
* assemble_system.cc: assemble both the bilinear and the linear form at once,
simmetry is mantained (if any).
author | gedeone-octave <marcovass89@hotmail.it> |
---|---|
date | Wed, 07 Aug 2013 18:20:59 +0200 |
parents | |
children | dc9987325fea |
line wrap: on
line source
#include "form.h" #include "boundarycondition.h" DEFUN_DLD (assemble, args, , "A = assemble (FORM, BC)") { int nargin = args.length (); octave_value retval; if (nargin < 1) print_usage (); else { if (! form_type_loaded) { form::register_type (); form_type_loaded = true; mlock (); } if (args(0).type_id () == form::static_type_id ()) { const form & frm = static_cast<const form&> (args(0).get_rep ()); if (! error_state) { const dolfin::Form & a = frm.get_form (); a.check (); if (a.rank () == 2) { dolfin::Matrix A; dolfin::assemble (A, a); if (! boundarycondition_type_loaded) { boundarycondition::register_type (); boundarycondition_type_loaded = true; mlock (); } for (std::size_t i = 1; i < nargin; ++i) { if (args(i).type_id () == boundarycondition::static_type_id ()) { const boundarycondition & bc = static_cast<const boundarycondition&> (args(i).get_rep ()); const std::vector<boost::shared_ptr <const dolfin::DirichletBC> > & pbc = bc.get_bc (); for (std::size_t j = 0; j < pbc.size (); ++j) pbc[j]->apply(A); } else error ("assemble: unknown argument type"); } std::size_t nr = A.size (0), nc = A.size (1); // nz shoud be estimated in a better way double alpha = 0.0005; octave_idx_type nz = alpha * nr * nc; SparseMatrix sm (nr, nc, nz); std::size_t ii = 0; sm.cidx (0) = 0; for (std::size_t j = 0; j < nc; ++j) { for (std::size_t i = 0; i < nr; ++i) { double tmp = A(i, j); if (tmp != 0.) { if (ii == nz) { nz = 1.2 * ((nc * ii) / (j + 1)); sm.change_capacity (nz); } sm.data(ii) = tmp; sm.ridx(ii) = i; ++ii; } } sm.cidx(j+1) = ii; } sm.maybe_compress (); retval = sm; } else if (a.rank () == 1) { dolfin::Vector A; dolfin::assemble (A, a); if (! boundarycondition_type_loaded) { boundarycondition::register_type (); boundarycondition_type_loaded = true; mlock (); } for (std::size_t i = 1; i < nargin; ++i) { if (args(i).type_id () == boundarycondition::static_type_id ()) { const boundarycondition & bc = static_cast<const boundarycondition&> (args(i).get_rep ()); const std::vector<boost::shared_ptr <const dolfin::DirichletBC> > & pbc = bc.get_bc (); for (std::size_t j = 0; j < pbc.size (); ++j) pbc[j]->apply(A); } else error ("assemble: unknown argument type"); } dim_vector dims; dims.resize (2); dims(0) = A.size (); dims(1) = 1; Array<double> myb (dims); for (std::size_t i = 0; i < A.size (); ++i) myb(i) = A[i]; retval = myb; } else error ("assemble: unknown size"); } } } return retval; }