SyFi  0.3
nljacobian_ex.cpp
Go to the documentation of this file.
00001 #include <SyFi.h>
00002 #include <fstream>
00003 
00004 using namespace GiNaC; 
00005 using namespace SyFi; 
00006 using namespace std; 
00007 
00008 void compute_poisson_element_matrix(
00009         FE& fe, 
00010         Dof& dof, 
00011         std::map<std::pair<unsigned int,unsigned int>, ex>& A) 
00012 {
00013     std::pair<unsigned int,unsigned int> index;
00014     Polygon& domain = fe.get_polygon(); 
00015 
00016     ex ujs = symbolic_matrix(1,fe.nbf(), "u");  
00017     ex u;  
00018     for (unsigned int k=0; k< fe.nbf(); k++)  {
00019         u += ujs.op(k)*fe.N(k);
00020     }
00021 
00022 
00023     for (unsigned int i=0; i< fe.nbf() ; i++) {
00024         index.first = i; 
00025         ex Fi = inner(grad(u), grad(fe.N(i)));   
00026         for (unsigned int j=0; j< fe.nbf() ; j++) {
00027             index.second = j; 
00028             symbol uj = ex_to<symbol>(ujs.op(j)); 
00029             ex nabla = Fi.diff(uj,1);  
00030             ex Aij = domain.integrate(nabla);   
00031             A[index] += Aij;  
00032         }
00033     }
00034 }
00035 
00036 void compute_nlconvdiff_element_matrix(
00037         FE& fe, 
00038         Dof& dof, 
00039         std::map<std::pair<unsigned int,unsigned int>, ex>& A) 
00040 {
00041     std::pair<unsigned int,unsigned int> index;
00042     Polygon& domain = fe.get_polygon(); 
00043 
00044     // insert the local dofs into the global Dof object
00045     for (unsigned int i=0; i< fe.nbf() ; i++) { 
00046         dof.insert_dof(1,i,fe.dof(i)); 
00047     }
00048 
00049     // create the local U field: U = sum_k u_k N_k 
00050     ex UU = matrix(2,1,lst(0,0)); 
00051     ex ujs = symbolic_matrix(1,fe.nbf(), "u");  
00052     for (unsigned int k=0; k< fe.nbf(); k++)  {
00053         UU +=ujs.op(k)*fe.N(k);   // U += u_k N_k  
00054     }
00055 
00056     //Get U represented as a matrix 
00057     matrix U = ex_to<matrix>(UU.evalm());
00058 
00059     for (unsigned int i=0; i< fe.nbf() ; i++) {
00060         index.first = dof.glob_dof(fe.dof(i));           // fetch global dof associated with i 
00061 
00062         // First: the diffusion term in Fi
00063         ex gradU = grad(U);                              // compute the gradient of U  
00064         ex Fi_diffusion  = inner(gradU, grad(fe.N(i)));  // inner product of grad(U) and grad(Ni) 
00065 
00066         // Second: the convection term in Fi 
00067         ex Ut = U.transpose();                           // get the transposed of U 
00068         ex UgradU = (Ut*gradU).evalm();                  // compute U*grad(U)     
00069         ex Fi_convection = inner(UgradU, fe.N(i), true); // compute U*grad(U)*Ni    
00070 
00071         // add together terms for convection and diffusion 
00072         ex Fi = Fi_convection + Fi_diffusion;            
00073 
00074 
00075         // Loop over all uj and differentiate Fi with respect
00076         // to uj to get the Jacobian Jij 
00077         for (unsigned int j=0; j< fe.nbf() ; j++) {
00078             index.second = dof.glob_dof(fe.dof(j));    // fetch global dof associated with j 
00079             symbol uj = ex_to<symbol>(ujs.op(j));    // cast uj to a symbol  
00080             ex Jij = Fi.diff(uj,1);                    // differentiate Fi with respect to uj  
00081             ex Aij = domain.integrate(Jij);            // intergrate the Jacobian Jij  
00082             A[index] += Aij;                           // update the global matrix  
00083         }
00084     }
00085 }
00086 
00087 
00088 
00089 
00090 int main() {
00091 
00092     initSyFi(2); 
00093 
00094     Triangle T(lst(0,0), lst(1,0), lst(0,1), "t"); 
00095     int order = 2; 
00096 
00097     // First we compute a standard Poisson problem, i.e., 
00098     // The differentiation of F(u_i) with respect to u_j 
00099     // should give the standard Poisson problem. 
00100     Lagrange fe; 
00101     fe.set_order(order); 
00102     fe.set_polygon(T); 
00103     fe.compute_basis_functions(); 
00104 
00105     Dof dof1; 
00106     std::map<std::pair<unsigned int,unsigned int>, ex> A1;
00107     compute_poisson_element_matrix(fe,dof1,A1); 
00108     print(A1); 
00109 
00110     // Second we compute a nonlinear convection
00111     // diffusion problem. 
00112     VectorLagrange vfe; 
00113     vfe.set_order(order); 
00114     vfe.set_size(2); 
00115     vfe.set_polygon(T); 
00116     vfe.compute_basis_functions(); 
00117     usage(vfe); 
00118 
00119     Dof dof2; 
00120     std::map<std::pair<unsigned int,unsigned int>, ex> A2;
00121     compute_nlconvdiff_element_matrix(vfe,dof2,A2); 
00122     cout <<"standard output"<<endl; 
00123     print(A2); 
00124     cout <<"LaTeX output"<<endl; 
00125     cout <<latex; 
00126     print(A2); 
00127     cout <<"Python output"<<endl; 
00128     cout <<python; 
00129     print(A2); 
00130     cout <<"C output"<<endl; 
00131     cout <<csrc; 
00132     print(A2); 
00133 
00134 
00135 
00136     // regression test 
00137     
00138     archive ar; 
00139     map<std::pair<unsigned int,unsigned int>,ex>::iterator iter; 
00140     for (iter = A1.begin(); iter != A1.end() ; iter++) {
00141       ar.archive_ex((*iter).second, istr("A1_", 
00142                     (*iter).first.first, 
00143                     (*iter).first.second).c_str()); 
00144     }
00145     for (iter = A2.begin(); iter != A2.end() ; iter++) {
00146       ar.archive_ex((*iter).second, istr("A2_", 
00147                     (*iter).first.first, 
00148                     (*iter).first.second).c_str()); 
00149     }
00150 
00151     ofstream vfile("nljacobian_ex.gar.v"); 
00152     vfile << ar; vfile.close(); 
00153     if(!compare_archives("nljacobian_ex.gar.v", "nljacobian_ex.gar.r")) { 
00154             cerr << "Failure!" << endl;
00155             return -1;
00156     }
00157 
00158     return 0; 
00159 }
00160 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator