nljacobian_ex.cpp

Go to the documentation of this file.
00001 #include <SyFi.h>
00002 
00003 using namespace GiNaC; 
00004 
00005 void compute_poisson_element_matrix(
00006                 FE& fe, 
00007                 Dof& dof, 
00008                 std::map<std::pair<int,int>, ex>& A) 
00009 {
00010   std::pair<int,int> index;
00011   Polygon& domain = fe.getPolygon(); 
00012 
00013   ex ujs = symbolic_matrix(1,fe.nbf(), "u");  
00014   ex u;  
00015   for (int k=0; k< fe.nbf(); k++)  {
00016       u += ujs.op(k)*fe.N(k);
00017   }
00018 
00019 
00020   for (int i=0; i< fe.nbf() ; i++) {
00021     index.first = i; 
00022     ex Fi = inner(grad(u), grad(fe.N(i)));   
00023     for (int j=0; j< fe.nbf() ; j++) {
00024       index.second = j; 
00025       symbol uj = ex_to<symbol>(ujs.op(j)); 
00026       ex nabla = Fi.diff(uj,1);  
00027       ex Aij = domain.integrate(nabla);   
00028       A[index] += Aij;  
00029     }
00030   }
00031 }
00032 
00033 void compute_nlconvdiff_element_matrix(
00034        FE& fe, 
00035        Dof& dof, 
00036        std::map<std::pair<int,int>, ex>& A) 
00037 {
00038   std::pair<int,int> index;
00039   Polygon& domain = fe.getPolygon(); 
00040 
00041   // insert the local dofs into the global Dof object
00042   for (int i=0; i< fe.nbf() ; i++) { 
00043     dof.insert_dof(1,i,fe.dof(i)); 
00044   }
00045 
00046   // create the local U field: U = sum_k u_k N_k 
00047   ex UU = matrix(2,1,lst(0,0)); 
00048   ex ujs = symbolic_matrix(1,fe.nbf(), "u");  
00049   for (int k=0; k< fe.nbf(); k++)  {
00050     UU +=ujs.op(k)*fe.N(k);   // U += u_k N_k  
00051   }
00052 
00053   //Get U represented as a matrix 
00054   matrix U = ex_to<matrix>(UU.evalm());
00055 
00056   for (int i=0; i< fe.nbf() ; i++) {
00057     index.first = dof.glob_dof(fe.dof(i));           // fetch global dof associated with i 
00058 
00059     // First: the diffusion term in Fi
00060     ex gradU = grad(U);                              // compute the gradient of U  
00061     ex Fi_diffusion  = inner(gradU, grad(fe.N(i)));  // inner product of grad(U) and grad(Ni) 
00062 
00063     // Second: the convection term in Fi 
00064     ex Ut = U.transpose();                           // get the transposed of U 
00065     ex UgradU = (Ut*gradU).evalm();                  // compute U*grad(U)     
00066     ex Fi_convection = inner(UgradU, fe.N(i), true); // compute U*grad(U)*Ni    
00067 
00068     // add together terms for convection and diffusion 
00069     ex Fi = Fi_convection + Fi_diffusion;            
00070 
00071 
00072     // Loop over all uj and differentiate Fi with respect
00073     // to uj to get the Jacobian Jij 
00074     for (int j=0; j< fe.nbf() ; j++) {
00075       index.second = dof.glob_dof(fe.dof(j));    // fetch global dof associated with j 
00076       symbol uj = ex_to<symbol>(ujs.op(j));    // cast uj to a symbol  
00077       ex Jij = Fi.diff(uj,1);                    // differentiate Fi with respect to uj  
00078       ex Aij = domain.integrate(Jij);            // intergrate the Jacobian Jij  
00079       A[index] += Aij;                           // update the global matrix  
00080     }
00081   }
00082 }
00083 
00084 
00085 
00086 
00087 int main() {
00088   Triangle T(lst(0,0), lst(1,0), lst(0,1), "t"); 
00089   int order = 2; 
00090 
00091   // First we compute a standard Poisson problem, i.e., 
00092   // The differentiation of F(u_i) with respect to u_j 
00093   // should give the standard Poisson problem. 
00094   LagrangeFE fe; 
00095   fe.set(order); 
00096   fe.set(T); 
00097   fe.compute_basis_functions(); 
00098 
00099   Dof dof1; 
00100   std::map<std::pair<int,int>, ex> A1;
00101   compute_poisson_element_matrix(fe,dof1,A1); 
00102   print(A1); 
00103 
00104   // Second we compute a nonlinear convection
00105   // diffusion problem. 
00106   VectorLagrangeFE vfe; 
00107   vfe.set(order); 
00108   vfe.set_size(2); 
00109   vfe.set(T); 
00110   vfe.compute_basis_functions(); 
00111   usage(vfe); 
00112 
00113   Dof dof2; 
00114   std::map<std::pair<int,int>, ex> A2;
00115   compute_nlconvdiff_element_matrix(vfe,dof2,A2); 
00116   cout <<"standard output"<<endl; 
00117   print(A2); 
00118   cout <<"LaTeX output"<<endl; 
00119   cout <<latex; 
00120   print(A2); 
00121   cout <<"Python output"<<endl; 
00122   cout <<python; 
00123   print(A2); 
00124   cout <<"C output"<<endl; 
00125   cout <<csrc; 
00126   print(A2); 
00127 
00128 
00129 
00130 }
00131 

Generated on Tue Jun 13 13:18:39 2006 for SyFi by  doxygen 1.4.4