SyFi
0.3
|
00001 #include <SyFi.h> 00002 #include <fstream> 00003 00004 using namespace GiNaC; 00005 using namespace std; 00006 using namespace SyFi; 00007 00008 void compute_Poisson_element_matrix( 00009 FE& fe, 00010 Dof& dof, 00011 std::map<std::pair<unsigned int,unsigned int>, GiNaC::ex>& A) 00012 { 00013 std::pair<unsigned int,unsigned int> index; 00014 00015 // Insert the local degrees of freedom into the global Dof 00016 for (unsigned int i=0; i< fe.nbf(); i++) { 00017 dof.insert_dof(1,i,fe.dof(i)); 00018 } 00019 00020 Polygon& domain = fe.get_polygon(); 00021 00022 // The term (grad u, grad v) 00023 for (unsigned int i=0; i< fe.nbf(); i++) { 00024 index.first = dof.glob_dof(fe.dof(i)); // fetch the global dof for Ni 00025 for (unsigned int j=0; j< fe.nbf(); j++) { 00026 index.second = dof.glob_dof(fe.dof(j)); // fetch the global dof for Nj 00027 GiNaC::ex nabla = inner(grad(fe.N(i)),grad(fe.N(j))); 00028 GiNaC::ex Aij = domain.integrate(nabla); // compute the integral 00029 A[index] += Aij; // add to global matrix 00030 } 00031 } 00032 } 00033 00034 void code_gen2D(FE& fe){ 00035 cout <<csrc; 00036 for (unsigned int i=0; i< fe.nbf(); i++) { 00037 cout <<"double N"<<i<<"(double x, double y){"<<endl; 00038 cout <<" return "<<fe.N(i)<<";"<<endl; 00039 cout <<"}"<<endl; 00040 } 00041 00042 for (unsigned int i=0; i< fe.nbf(); i++) { 00043 cout <<"double dN"<<i<<"dx(double x, double y){"<<endl; 00044 cout <<" return "<<diff(fe.N(i),x)<<";"<<endl; 00045 cout <<"}"<<endl; 00046 } 00047 00048 for (unsigned int i=0; i< fe.nbf(); i++) { 00049 cout <<"double dN"<<i<<"dy(double x, double y){"<<endl; 00050 cout <<" return "<<diff(fe.N(i),y)<<";"<<endl; 00051 cout <<"}"<<endl; 00052 } 00053 00054 cout <<"double N(int i, double x, double y){"<<endl; 00055 cout <<" switch(i) {"<<endl; 00056 for (unsigned int i=0; i< fe.nbf(); i++) { 00057 cout <<" case "<<i<<" : return N"<<i<<"(x,y);"<<endl; 00058 } 00059 cout <<" }"<<endl; 00060 cout <<"}"<<endl; 00061 00062 cout <<"double dNdx(int i, double x, double y){"<<endl; 00063 cout <<" switch(i) {"<<endl; 00064 for (unsigned int i=0; i< fe.nbf(); i++) { 00065 cout <<" case "<<i<<" : return dN"<<i<<"dx(x,y);"<<endl; 00066 } 00067 cout <<" }"<<endl; 00068 cout <<"}"<<endl; 00069 00070 cout <<"double dNdy(int i, double x, double y){"<<endl; 00071 cout <<" switch(i) {"<<endl; 00072 for (unsigned int i=0; i< fe.nbf(); i++) { 00073 cout <<" case "<<i<<" : return dN"<<i<<"dy(x,y);"<<endl; 00074 } 00075 cout <<" }"<<endl; 00076 cout <<"}"<<endl; 00077 } 00078 00079 int main() { 00080 00081 initSyFi(2); 00082 00083 Triangle triangle(lst(0,0), lst(1,0), lst(0,1)); 00084 Lagrange fe; 00085 fe.set_order(2); 00086 fe.set_polygon(triangle); 00087 fe.compute_basis_functions(); 00088 00089 00090 code_gen2D(fe); 00091 00092 00093 Dof dof; 00094 std::map<std::pair<unsigned int,unsigned int>, ex> A; 00095 ::compute_Poisson_element_matrix(fe, dof, A); 00096 cout <<"C code format on output "<<endl; 00097 cout <<csrc; 00098 print(A); 00099 00100 00101 archive ar; 00102 for (unsigned int i=0; i<fe.nbf(); i++) { 00103 ar.archive_ex(fe.N(i), istr("N",i).c_str()); 00104 00105 } 00106 pair<unsigned int,unsigned int> index; 00107 for (unsigned int i=0; i<fe.nbf(); i++) { 00108 index.first = i; 00109 for (unsigned int j=0; j<fe.nbf(); j++) { 00110 index.second = j; 00111 ar.archive_ex(A[index], istr("A",i,j).c_str()); 00112 } 00113 00114 } 00115 ofstream vfile("code_gen.gar.v"); 00116 vfile << ar; vfile.close(); 00117 if(!compare_archives("code_gen.gar.v", "code_gen.gar.r")) { 00118 cerr << "Failure!" << endl; 00119 return -1; 00120 } 00121 00122 return 0; 00123 }