SyFi  0.3
ElementComputations.cpp
Go to the documentation of this file.
00001 // Copyright (C) 2006-2009 Kent-Andre Mardal and Simula Research Laboratory
00002 //
00003 // This file is part of SyFi.
00004 //
00005 // SyFi is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // SyFi is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with SyFi. If not, see <http://www.gnu.org/licenses/>.
00017 
00018 #include "ElementComputations.h"
00019 #include "tools.h"
00020 
00021 using std::cout;
00022 using std::endl;
00023 
00024 namespace SyFi
00025 {
00026 
00027         void usage(FE& fe)
00028         {
00029                 for (unsigned int i=0; i< fe.nbf(); i++)
00030                 {
00031                         cout <<"fe.N("<<i<<")         =   "<<fe.N(i)<<endl;
00032                         cout <<"grad(fe.N("<<i<<"))   =   "<<grad(fe.N(i))<<endl;
00033                         cout <<"fe.dof("<<i<<")       =   "<<fe.dof(i)<<endl;
00034                 }
00035         }
00036 
00037         void usage(FE& v_fe, FE& p_fe)
00038         {
00039                 for (unsigned int i=0; i< v_fe.nbf(); i++)
00040                 {
00041                         cout <<"v_fe.N("<<i<<")         =   "<<v_fe.N(i)<<endl;
00042                         cout <<"grad(v_fe.N("<<i<<"))   =   "<<grad(v_fe.N(i))<<endl;
00043                         cout <<"v_fe.dof("<<i<<")       =   "<<v_fe.dof(i)<<endl;
00044                 }
00045                 for (unsigned int i=0; i< p_fe.nbf(); i++)
00046                 {
00047                         cout <<"p_fe.N("<<i<<")=   "<<p_fe.N(i)<<endl;
00048                         cout <<"p_fe.dof("<<i<<")= "<<p_fe.dof(i)<<endl;
00049                 }
00050         }
00051 
00052         void compute_Poisson_element_matrix(
00053                 FE& fe,
00054                 Dof& dof,
00055                 std::map<std::pair<unsigned int,unsigned int>, GiNaC::ex>& A)
00056         {
00057                 std::pair<unsigned int,unsigned int> index;
00058 
00059                 // Insert the local degrees of freedom into the global Dof
00060                 for (unsigned int i=0; i< fe.nbf(); i++)
00061                 {
00062                         dof.insert_dof(1,i,fe.dof(i));
00063                 }
00064 
00065                 Polygon& domain = fe.get_polygon();
00066 
00067                 // The term (grad u, grad v)
00068                 for (unsigned int i=0; i< fe.nbf(); i++)
00069                 {
00070                                                                  // fetch the global dof for Ni
00071                         index.first = dof.glob_dof(fe.dof(i));
00072                         for (unsigned int j=0; j< fe.nbf(); j++)
00073                         {
00074                                                                  // fetch the global dof for Nj
00075                                 index.second = dof.glob_dof(fe.dof(j));
00076                                                                  // compute the integrand
00077                                 GiNaC::ex nabla = inner(grad(fe.N(i)),
00078                                         grad(fe.N(j)));
00079                                                                  // compute the integral
00080                                 GiNaC::ex Aij = domain.integrate(nabla);
00081                                 A[index] += Aij; // add to global matrix
00082                         }
00083                 }
00084         }
00085 
00086         void compute_Stokes_element_matrix(
00087                 FE& v_fe,
00088                 FE& p_fe,
00089                 Dof& dof,
00090                 std::map<std::pair<unsigned int,unsigned int>, GiNaC::ex>& A)
00091         {
00092                 std::pair<unsigned int,unsigned int> index;
00093                 std::pair<unsigned int,unsigned int> index2;
00094 
00095                 // FIXME: need to check that p_fe
00096                 // contains the same domain
00097                 Polygon& domain = v_fe.get_polygon();
00098 
00099                 // Insert the local degrees of freedom into the global Dof
00100                 for (unsigned int i=0; i< v_fe.nbf(); i++)
00101                 {
00102                         dof.insert_dof(1,i,v_fe.dof(i));
00103                 }
00104                 for (unsigned int i=0; i< p_fe.nbf(); i++)
00105                 {
00106                         dof.insert_dof(1,v_fe.nbf()+i,p_fe.dof(i));
00107                 }
00108 
00109                 // The term (grad u, grad v)
00110                 for (unsigned int i=0; i< v_fe.nbf(); i++)
00111                 {
00112                                                                  // fetch the global dof for v_i
00113                         index.first = dof.glob_dof(v_fe.dof(i));
00114                         for (unsigned int j=0; j< v_fe.nbf(); j++)
00115                         {
00116                                                                  // fetch the global dof for v_j
00117                                 index.second = dof.glob_dof(v_fe.dof(j));
00118                                 GiNaC::ex nabla = inner(grad(v_fe.N(i)),
00119                                         grad(v_fe.N(j)));// compute the integrand
00120                                                                  // compute the integral
00121                                 GiNaC::ex Aij = domain.integrate(nabla);
00122                                 A[index] += Aij; // add to global matrix
00123                         }
00124                 }
00125 
00126                 // The term -(div u, q)
00127                 for (unsigned int i=0; i< p_fe.nbf(); i++)
00128                 {
00129                                                                  // fetch the global dof for p_i
00130                         index.first = dof.glob_dof(p_fe.dof(i));
00131                         for (unsigned int j=0; j< v_fe.nbf(); j++)
00132                         {
00133                                                                  // fetch the global dof for v_j
00134                                 index.second=dof.glob_dof(v_fe.dof(j));
00135                                                                  // compute the integrand
00136                                 GiNaC::ex divV= -p_fe.N(i)*div(v_fe.N(j));
00137                                                                  // compute the integral
00138                                 GiNaC::ex Aij = domain.integrate(divV);
00139                                 A[index] += Aij; // add to global matrix
00140 
00141                                 // Do not need to compute the term (grad(p),v), since the system is
00142                                 // symmetric. We simply set Aji = Aij
00143                                 index2.first = index.second;
00144                                 index2.second = index.first;
00145                                 A[index2] += Aij;
00146                         }
00147                 }
00148         }
00149 
00150         void compute_mixed_Poisson_element_matrix(
00151                 FE& v_fe,
00152                 FE& p_fe,
00153                 Dof& dof,
00154                 std::map<std::pair<unsigned int,unsigned int>, GiNaC::ex>& A)
00155         {
00156                 std::pair<unsigned int,unsigned int> index;
00157                 std::pair<unsigned int,unsigned int> index2;
00158 
00159                 // FIXME: need to check that p_fe
00160                 // contains the same domain
00161                 Polygon& domain = v_fe.get_polygon();
00162 
00163                 // Insert the local degrees of freedom into the global Dof
00164                 for (unsigned int i=0; i< v_fe.nbf(); i++)
00165                 {
00166                         dof.insert_dof(1,i,v_fe.dof(i));
00167                 }
00168                 for (unsigned int i=0; i< p_fe.nbf(); i++)
00169                 {
00170                         dof.insert_dof(1,v_fe.nbf()+i+1,p_fe.dof(i));
00171                 }
00172 
00173                 // The term (u,v)
00174                 for (unsigned int i=0; i< v_fe.nbf(); i++)
00175                 {
00176                                                                  // fetch the global dof related to i and v
00177                         index.first = dof.glob_dof(v_fe.dof(i));
00178                         for (unsigned int j=0; j< v_fe.nbf(); j++)
00179                         {
00180                                                                  // fetch the global dof related to j and p
00181                                 index.second = dof.glob_dof(v_fe.dof(j));
00182                                                                  // compute the integrand
00183                                 GiNaC::ex mass = inner(v_fe.N(i),v_fe.N(j));
00184                                                                  // compute the integral
00185                                 GiNaC::ex Aij = domain.integrate(mass);
00186                                 A[index] += Aij; // add to global matrix
00187                         }
00188                 }
00189 
00190                 // The term -(div u, q)
00191                 for (unsigned int i=0; i< p_fe.nbf(); i++)
00192                 {
00193                                                                  // fetch the global dof for p_i
00194                         index.first = dof.glob_dof(p_fe.dof(i));
00195                         for (unsigned int j=0; j< v_fe.nbf(); j++)
00196                         {
00197                                                                  // fetch the global dof for v_j
00198                                 index.second=dof.glob_dof(v_fe.dof(j));
00199                                                                  // compute the integrand
00200                                 GiNaC::ex divV= -p_fe.N(i)*div(v_fe.N(j));
00201                                                                  // compute the integral
00202                                 GiNaC::ex Aij = domain.integrate(divV);
00203                                 A[index] += Aij; // add to global matrix
00204 
00205                                 // Do not need to compute the term (grad(p),v), since the system is
00206                                 // symmetric we simply set Aji = Aij
00207                                 index2.first = index.second;
00208                                 index2.second = index.first;
00209                                 A[index2] += Aij;
00210                         }
00211                 }
00212         }
00213 
00214 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator