getfem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Getfem-commits] r4535 - in /trunk/getfem: ./ doc/sphinx/source/userdoc/


From: Yves . Renard
Subject: [Getfem-commits] r4535 - in /trunk/getfem: ./ doc/sphinx/source/userdoc/ src/ src/getfem/ tests/
Date: Fri, 14 Mar 2014 14:46:34 -0000

Author: renard
Date: Fri Mar 14 15:46:33 2014
New Revision: 4535

URL: http://svn.gna.org/viewcvs/getfem?rev=4535&view=rev
Log:
Allowing the use of tensor fields in generic assembly and allowing up to order 
6 tensors

Modified:
    trunk/getfem/configure.ac
    trunk/getfem/doc/sphinx/source/userdoc/gasm_high.rst
    trunk/getfem/src/getfem/getfem_generic_assembly.h
    trunk/getfem/src/getfem_generic_assembly.cc
    trunk/getfem/tests/test_assembly.cc

Modified: trunk/getfem/configure.ac
URL: 
http://svn.gna.org/viewcvs/getfem/trunk/getfem/configure.ac?rev=4535&r1=4534&r2=4535&view=diff
==============================================================================
--- trunk/getfem/configure.ac   (original)
+++ trunk/getfem/configure.ac   Fri Mar 14 15:46:33 2014
@@ -159,6 +159,8 @@
        AC_CHECK_CXX_FLAG([-fmessage-length=0],CXXFLAGS)
        AC_CHECK_CXX_FLAG([-ftemplate-depth-40],CXXFLAGS)
        AC_CHECK_CXX_FLAG([-pedantic],CXXFLAGS)
+       AC_CHECK_CXX_FLAG([-std=c++0x],CXXFLAGS)
+       AC_CHECK_CXX_FLAG([-std=c++11],CXXFLAGS)
        AC_CHECK_CXX_FLAG([-Wshadow],CXXFLAGS)
        AC_CHECK_CXX_FLAG([-Wno-unknown-pragmas],CXXFLAGS)
        AC_CHECK_CXX_FLAG([-Wpointer-arith],CXXFLAGS)

Modified: trunk/getfem/doc/sphinx/source/userdoc/gasm_high.rst
URL: 
http://svn.gna.org/viewcvs/getfem/trunk/getfem/doc/sphinx/source/userdoc/gasm_high.rst?rev=4535&r1=4534&r2=4535&view=diff
==============================================================================
--- trunk/getfem/doc/sphinx/source/userdoc/gasm_high.rst        (original)
+++ trunk/getfem/doc/sphinx/source/userdoc/gasm_high.rst        Fri Mar 14 
15:46:33 2014
@@ -44,7 +44,7 @@
 
   - A certain number of operators: ``+``, ``-``, ``*``, ``/``, ``:``, ``.``, 
``.*``, ``./``, address@hidden, ``'``.
 
-  - Some constants : ``pi``, ``meshdim`` (the dimension of the current mesh), 
``qdim(u)`` the dimension of the variable ``u`` (the size for fixed size 
variables and the dimension of the vector field for f.e.m. variables), 
``Id(n)`` the identity :math:`n\times n` matrix.
+  - Some constants : ``pi``, ``meshdim`` (the dimension of the current mesh), 
``qdim(u)`` and ``qdims(u)`` the dimensions of the variable ``u`` (the size for 
fixed size variables and the dimension of the vector field for f.e.m. 
variables), ``Id(n)`` the identity :math:`n\times n` matrix.
 
   - Parentheses can be used to change the operations order in a standard way. 
For instance ``(1+2)*4`` or ``(u+v)*Test_u`` are correct. 
 
@@ -347,7 +347,7 @@
 The tensors
 ***********
 
-Basically, what is manipulated in the generic assembly language are tensors. 
This can be order 0 tensors in scalar expressions (for instance in 
``3+sin(pi/2)``), order 1 tensors in vector expressions (such as ``x.x`` or 
``Grad_u`` if u is a scalar variable), order 2 tensors for matrix expressions 
and so on. For efficiency reasons, the language manipulates tensors up to order 
four. The language could be easily extended to support tensors of order greater 
than four but it may lead to inefficient computations. When an expression 
contains tests functions (as in ``Trace(Grad_Test_u)`` for a vector field 
``u``), the computation is done for each test functions, which means that the 
tensor implicitly have a supplementary component. This means that, implicitly, 
the maximal order of manipulated tensors are in fact six (in 
``Grad_Test_u:Grad_Test2_u`` there are two components implicitly added for 
first and second order test functions).
+Basically, what is manipulated in the generic assembly language are tensors. 
This can be order 0 tensors in scalar expressions (for instance in 
``3+sin(pi/2)``), order 1 tensors in vector expressions (such as ``x.x`` or 
``Grad_u`` if u is a scalar variable), order 2 tensors for matrix expressions 
and so on. For efficiency reasons, the language manipulates tensors up to order 
six. The language could be easily extended to support tensors of order greater 
than six but it may lead to inefficient computations. When an expression 
contains tests functions (as in ``Trace(Grad_Test_u)`` for a vector field 
``u``), the computation is done for each test functions, which means that the 
tensor implicitly have a supplementary component. This means that, implicitly, 
the maximal order of manipulated tensors are in fact six (in 
``Grad_Test_u:Grad_Test2_u`` there are two components implicitly added for 
first and second order test functions).
 
 Order four tensors are necessary for instance to express elasticity tensors or 
in general to obtain the tangent term for vector valued unknowns.
 
@@ -487,7 +487,12 @@
 Explicit order four tensors
 ***************************
 
-Explicit order four tensors are also allowed. To this aim, the two 
supplementary dimensions compared to matrices are separated by  ``,,`` and 
``;;``. For instance ``[1,1;1,2,,1,1;1,2;;1,1;1,2,,1,1;1,2]`` is a 2x2x2x2 
valid tensor. Note that constant fourth order tensors can also be obtained by 
the tensor product of two constant matrices. Note also that constant third 
order tensors are not supported.
+Explicit order four tensors are also allowed. To this aim, the two 
supplementary dimensions compared to matrices are separated by  ``,,`` and 
``;;``. For instance ``[1,1;1,2,,1,1;1,2;;1,1;1,2,,1,1;1,2]`` is a 2x2x2x2 
valid tensor. Note that constant fourth order tensors can also be obtained by 
the tensor product of two constant matrices. 
+
+Explicit order five or six tensors
+**********************************
+
+Explicit order five or six tensors are not directly supported by the assembly 
language. However, they can be easily obtained via the Reshape instruction.
 
 
 Access to tensor components
@@ -501,7 +506,8 @@
   - ``pi``: the constant Pi. 
   - ``meshdim``: the dimension of the current mesh (i.e. size of geometrical 
nodes)
   - ``Id(n)``: the identity matrix of size :math:`n\times n`. `n` should be an 
integer expression. For instance ``Id(meshdim)`` is allowed.
-  - ``qdim(u)``: the dimension of the variable ``u`` (i.e. the  size for fixed 
size variables and the dimension of the vector field for f.e.m. variables)
+  - ``qdim(u)``: the total dimension of the variable ``u`` (i.e. the  size for 
fixed size variables and the total dimension of the vector/tensor field for 
f.e.m. variables)
+  - ``qdims(u)``: the dimensions of the variable ``u`` (i.e. the size for 
fixed size variables and the vector of dimensions of the vector/tensor field 
for f.e.m. variables)
 
 Special expressions linked to the current position 
 **************************************************

Modified: trunk/getfem/src/getfem/getfem_generic_assembly.h
URL: 
http://svn.gna.org/viewcvs/getfem/trunk/getfem/src/getfem/getfem_generic_assembly.h?rev=4535&r1=4534&r2=4535&view=diff
==============================================================================
--- trunk/getfem/src/getfem/getfem_generic_assembly.h   (original)
+++ trunk/getfem/src/getfem/getfem_generic_assembly.h   Fri Mar 14 15:46:33 2014
@@ -312,6 +312,21 @@
       return mf ? associated_mf(name)->get_qdim() * (n / ndof) : n;
     }
 
+    bgeot::multi_index qdims(const std::string &name) const {
+      const mesh_fem *mf = associated_mf(name);
+      size_type n = gmm::vect_size(value(name));
+      if (mf) {
+        bgeot::multi_index mi = mf->get_qdims();
+        size_type qmult = n / mf->nb_dof();
+        if (qmult > 1) {
+          if (mi.back() == 1) mi.back() *= qmult; else mi.push_back(qmult);
+        }
+        return mi;
+      } else {
+        bgeot::multi_index mi(1); mi[0] = n; return mi;
+      }
+    }
+
     const model_real_plain_vector &value(const std::string &name) const {
       if (model)
         return model->real_variable(name);

Modified: trunk/getfem/src/getfem_generic_assembly.cc
URL: 
http://svn.gna.org/viewcvs/getfem/trunk/getfem/src/getfem_generic_assembly.cc?rev=4535&r1=4534&r2=4535&view=diff
==============================================================================
--- trunk/getfem/src/getfem_generic_assembly.cc (original)
+++ trunk/getfem/src/getfem_generic_assembly.cc Fri Mar 14 15:46:33 2014
@@ -769,6 +769,7 @@
     case 0:
       str << (nt ? scalar_type(0) : pnode->t[0]);
       break;
+
     case 1:
       str << "[";
       for (size_type i = 0; i < pnode->tensor_proper_size(0); ++i) {
@@ -777,6 +778,7 @@
       }
       str << "]";
       break;
+
     case 2:
       str << "[";
       for (size_type i = 0; i < pnode->tensor_proper_size(0); ++i) {
@@ -788,6 +790,7 @@
       }
       str << "]";
       break;
+
     case 3:
       str << "[";
       for (size_type i = 0; i < pnode->tensor_proper_size(0); ++i) {
@@ -802,6 +805,7 @@
       }
       str << "]";
       break;
+
     case 4:
       str << "[";
       for (size_type i = 0; i < pnode->tensor_proper_size(0); ++i) {
@@ -819,6 +823,21 @@
       }
       str << "]";
       break;
+
+    case 5: case 6:
+      str << "Reshape([";
+      for (size_type i = 0; i < pnode->tensor_proper_size(); ++i) {
+        if (i != 0) str << "; ";
+        str << (nt ? scalar_type(0) : pnode->t[i]);
+      }
+      str << "]";
+      for (size_type i = 0; i < pnode->tensor_order(); ++i) {
+        if (i != 0) str << ", ";
+        str << pnode->tensor_proper_size(i);
+      }
+      str << ")";
+      break;
+      
     default: GMM_ASSERT1(false, "Invalid tensor dimension");
     }
     GMM_ASSERT1(pnode->children.size() == 0, "Invalid tree");
@@ -918,9 +937,8 @@
         if (pnode->qdim1 == 1)
           str << "*Test_" << pnode->name_test1;
         else {
-          str << "*([ 0";
-          for (size_type i = 1; i < pnode->qdim1; ++i) str << ", 0";
-          str << "].Test_" << pnode->name_test1 << ")";
+          str << "*(Reshape(Test_" << pnode->name_test1 << ","
+              << pnode->qdim1<< ")(1))";
         }
       }
       if (pnode->name_test2.size()) {
@@ -928,9 +946,8 @@
         if (pnode->qdim2 == 1)
           str << "*Test2_" << pnode->name_test2;
         else {
-          str << "*([ 0";
-          for (size_type i = 1; i < pnode->qdim2; ++i) str << ", 0";
-          str << "].Test2_" << pnode->name_test2 << ")";
+          str << "*(Reshape(Test2_" << pnode->name_test2 << ","
+              << pnode->qdim2<< ")(1))";
         }
       }
       if (pnode->test_function_type) str << ")";
@@ -1932,6 +1949,7 @@
     SPEC_FUNCTIONS.insert("pi");
     SPEC_FUNCTIONS.insert("meshdim");
     SPEC_FUNCTIONS.insert("qdim");
+    SPEC_FUNCTIONS.insert("qdims");
     SPEC_FUNCTIONS.insert("Id");
 
     // Predefined operators
@@ -4048,7 +4066,7 @@
             pnode->t = child0->t;
             gmm::scale(pnode->t.as_vector(), scalar_type(child1->t[0]));
           } else {
-            if (dim0+dim1 > 4)
+            if (dim0+dim1 > 6)
               ga_throw_error(expr, pnode->pos, "Unauthorized "
                               "tensor multiplication.");
             for (size_type i = 0; i < dim0; ++i)
@@ -4075,7 +4093,7 @@
               for (size_type i = 0; i < dim0; ++i)
                 mi.push_back(child0->tensor_proper_size(i));
             } else {
-              if (dim0+dim1 > 4)
+              if (dim0+dim1 > 6)
                 ga_throw_error(expr, pnode->pos, "Unauthorized "
                                 "tensor multiplication.");
               for (size_type i = 0; i < dim0; ++i)
@@ -4441,35 +4459,30 @@
               }
             } else {
               size_type q = workspace.qdim(name), n = mf->linked_mesh().dim();
+              bgeot::multi_index mii = workspace.qdims(name);
               if (!q) ga_throw_error(expr, pnode->pos,
                                      "Invalid null size of variable");
               switch (val_grad_or_hess) {
               case 0: // value
                 pnode->node_type = GA_NODE_VAL;
-                if (q == 1)
-                  pnode->init_scalar_tensor(scalar_type(0));
-                else
-                  pnode->init_vector_tensor(q);
                 break;
               case 1: // grad
                 pnode->node_type = GA_NODE_GRAD;
-                if (q == 1 && n == 1)
-                  pnode->init_scalar_tensor(scalar_type(0));
-                else if (q == 1)
-                  pnode->init_vector_tensor(n);
-                else
-                  pnode->init_matrix_tensor(q, n);
+                if (n > 1) {
+                  if (q == 1 && mii.size() <= 1) mii[0] = n;
+                  else mii.push_back(n);
+                }
                 break;
               case 2: // Hessian
                 pnode->node_type = GA_NODE_HESS;
-                if (q == 1 && n == 1)
-                  pnode->init_scalar_tensor(scalar_type(0));
-                else if (q == 1)
-                  pnode->init_matrix_tensor(n,n);
-                else
-                  pnode->init_third_order_tensor(q, n, n);
+                if (n > 1) {
+                  if (q == 1 && mii.size() <= 1) { mii[0] = n;  
mii.push_back(n); }
+                  else { mii.push_back(n); mii.push_back(n); }
+                }
                 break;
               }
+              pnode->t.adjust_sizes(mii);
+              pnode->test_function_type = 0;
             }
           } else {
             if (workspace.is_constant(name))
@@ -4512,36 +4525,48 @@
               }
             } else {
               size_type q = workspace.qdim(name), n = mf->linked_mesh().dim();
+              bgeot::multi_index mii =  workspace.qdims(name);
+              if (mii.size() > 6)
+                ga_throw_error(expr, pnode->pos,
+                               "Tensor with too much dimensions. Limited to 
6");
               if (!q)
                 ga_throw_error(expr, pnode->pos,
                                "Invalid null size of variable");
               switch (val_grad_or_hess) {
               case 0: // value
                 pnode->node_type = GA_NODE_TEST;
-                if (q == 1)
+                if (q == 1 && mii.size() <= 1)
                   pnode->init_vector_tensor(2);
-                else
-                  pnode->init_matrix_tensor(2,q);
+                else {
+                  mii.insert(mii.begin(), 2);
+                  pnode->t.adjust_sizes(mii);
+                }
                 pnode->test_function_type = test;
                 break;
               case 1: // grad
                 pnode->node_type = GA_NODE_GRAD_TEST;
-                if (q == 1 && n == 1)
+                if (q == 1 && mii.size() <= 1 && n == 1)
                   pnode->init_vector_tensor(2);
-                else if (q == 1)
-                  pnode->init_matrix_tensor(2,n);
-                else
-                  pnode->init_third_order_tensor(2,q,n);
+                else if (q == 1 && mii.size() <= 1)
+                  pnode->init_matrix_tensor(2, n);
+                else {
+                  mii.insert(mii.begin(), 2);
+                  if (n > 1) mii.push_back(n);
+                  pnode->t.adjust_sizes(mii);
+                }
                 pnode->test_function_type = test;
                 break;
               case 2: // hessian
                 pnode->node_type = GA_NODE_HESS_TEST;
-                if (q == 1 && n == 1)
+                if (q == 1 && mii.size() <= 1 && n == 1)
                   pnode->init_vector_tensor(2);
-                else if (q == 1)
+                else if (q == 1 && mii.size() <= 1)
                   pnode->init_third_order_tensor(2,n,n);
-                else
-                  pnode->init_fourth_order_tensor(2,q,n,n);
+                else {
+                  mii.insert(mii.begin(), 2);
+                  if (n > 1) { mii.push_back(n); mii.push_back(n); }
+                  pnode->t.adjust_sizes(mii);
+                }
                 pnode->test_function_type = test;
                 break;
               }
@@ -4570,7 +4595,7 @@
         if (pnode->children.size() < 3)
           ga_throw_error(expr, child1->pos,
                          "Not enough parameters for Reshape");
-        if (pnode->children.size() > 6)
+        if (pnode->children.size() > 8)
           ga_throw_error(expr, child1->pos,
                          "Too many parameters for Reshape");
         pnode->t = child1->t;
@@ -4693,6 +4718,25 @@
           if (pnode->t[0] <= 0)
             ga_throw_error(expr, pnode->pos,
                            "Invalid null size of variable");
+        } else if (!(child0->name.compare("qdims"))) {
+          if (child1->node_type != GA_NODE_VAL)
+            ga_throw_error(expr, pnode->pos, "The argument of qdim "
+                           "function can only be a variable name.");
+          pnode->node_type = GA_NODE_CONSTANT;
+          bgeot::multi_index mii = workspace.qdims(child1->name);
+          if (mii.size() > 6)
+            ga_throw_error(expr, pnode->pos,
+                           "Tensor with too much dimensions. Limited to 6");
+          if (mii.size() == 0 || scalar_type(mii[0]) <= 0)
+            ga_throw_error(expr, pnode->pos,
+                           "Invalid null size of variable");
+          if (mii.size() == 1)
+            pnode->init_scalar_tensor(scalar_type(mii[0]));
+          if (mii.size() >= 1) {
+            pnode->init_vector_tensor(mii.size());
+            for (size_type i = 0; i < mii.size(); ++i)
+              pnode->t[i] = scalar_type(mii[i]);
+          }
         } else if (!(child0->name.compare("Id"))) {
           bool valid = (child1->node_type == GA_NODE_CONSTANT);
           int n = valid ? int(round(child1->t[0])) : -1;

Modified: trunk/getfem/tests/test_assembly.cc
URL: 
http://svn.gna.org/viewcvs/getfem/trunk/getfem/tests/test_assembly.cc?rev=4535&r1=4534&r2=4535&view=diff
==============================================================================
--- trunk/getfem/tests/test_assembly.cc (original)
+++ trunk/getfem/tests/test_assembly.cc Fri Mar 14 15:46:33 2014
@@ -1046,8 +1046,6 @@
       VEC_TEST_1("Test for source term", ndofu, "u.Test_u", mim, size_type(-1),
                  Iu, getfem::asm_source_term(V, mim, mf_u, mf_u, U));
 
-
-
     }
 
     if (all) {
@@ -1065,14 +1063,13 @@
       
       if (N == 2)
       {VEC_TEST_1("Test for Neumann term", ndofu,
-                  "([A(1), A(3); A(2), A(4)]'*Normal).Test_u", mim,
+                  "(A'*Normal).Test_u", mim,
                   NEUMANN_BOUNDARY_NUM,
                   Iu, getfem::asm_normal_source_term(V, mim, mf_u, mf_u,
                                                  A, NEUMANN_BOUNDARY_NUM));}
       if (N == 3)
       {VEC_TEST_1("Test for Neumann term", ndofu,
-                  "([A(1), A(4), A(7); A(2), A(5), A(8); A(3), A(6), A(9)]'"
-                  "*Normal).Test_u", mim, NEUMANN_BOUNDARY_NUM,
+                  "(A'*Normal).Test_u", mim, NEUMANN_BOUNDARY_NUM,
                   Iu, getfem::asm_normal_source_term(V, mim, mf_u, mf_u,
                                                  A, NEUMANN_BOUNDARY_NUM));}
     }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]