changeset 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 7cd7bd1fc2b5
children 2ecab16e88e1
files src/assemble.cc src/assemble_system.cc
diffstat 2 files changed, 248 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/assemble.cc	Wed Aug 07 18:20:59 2013 +0200
@@ -0,0 +1,135 @@
+#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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/assemble_system.cc	Wed Aug 07 18:20:59 2013 +0200
@@ -0,0 +1,113 @@
+#include "form.h"
+#include "boundarycondition.h"
+
+DEFUN_DLD (assemble_system, args, , "A = assemble (FORM, BC)")
+{
+
+  int nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin < 2)
+    print_usage ();
+  else
+    {
+      if (! form_type_loaded)
+        {
+          form::register_type ();
+          form_type_loaded = true;
+          mlock ();
+        }
+      if (! boundarycondition_type_loaded)
+        {
+          boundarycondition::register_type ();
+          boundarycondition_type_loaded = true;
+          mlock ();
+        }
+
+      if (args(0).type_id () == form::static_type_id () 
+          && args(1).type_id () == form::static_type_id ())
+        {
+          const form & frm1
+            = static_cast<const form&> (args(0).get_rep ());
+
+          const form & frm2
+            = static_cast<const form&> (args(1).get_rep ());
+
+          std::vector<const dolfin::DirichletBC*> bcs (0);
+          for (std::size_t i = 2; 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)
+                    bcs.push_back (& *(pbc[j]));
+                }
+            }
+
+
+          if (! error_state)
+            {
+              const dolfin::Form & a = frm1.get_form ();
+              a.check ();
+              const dolfin::Form & L = frm2.get_form ();
+              L.check ();
+
+              if (a.rank () == 2 && L.rank () == 1)
+                {
+                  dolfin::Matrix A;
+                  dolfin::Vector b;
+                  dolfin::assemble_system (A, b, a, L, bcs);
+
+                  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 (0) = sm;
+
+                  dim_vector dims;
+                  dims.resize (2);
+                  dims(0) = b.size ();
+                  dims(1) = 1;
+                  Array<double> myb (dims);
+
+                  for (std::size_t i = 0; i < b.size (); ++i)
+                    myb(i) = b[i];
+
+                  retval(1) = myb;
+                }
+
+              else
+                error ("assemble: unknown size");
+            }
+        }
+    }
+  return retval;
+}