#include <RaviartThomas.h>
Inheritance diagram for RaviartThomas:
Public Member Functions | |
RaviartThomas () | |
~RaviartThomas () | |
virtual void | set (int order) |
virtual void | set (Polygon &p) |
virtual void | compute_basis_functions () |
virtual int | nbf () |
virtual GiNaC::ex | N (int i) |
virtual GiNaC::ex | dof (int i) |
Definition at line 8 of file RaviartThomas.h.
|
Definition at line 10 of file RaviartThomas.h.
|
|
Definition at line 11 of file RaviartThomas.h.
|
|
Reimplemented from StandardFE. Definition at line 9 of file RaviartThomas.cpp. References bernstein(), bernsteinv(), collapse(), StandardFE::dofs, inner(), Tetrahedron::integrate(), Triangle::integrate(), Line::integrate(), istr(), Triangle::line(), matrix_from_equations(), normal(), StandardFE::Ns, StandardFE::order, StandardFE::p, Polygon::str(), Tetrahedron::triangle(), x, y, and z. Referenced by check_RaviartThomas(), and main(). 00009 { 00010 00011 // see e.g. Brezzi and Fortin book page 116 for the definition 00012 00013 if (p->str() == "ReferenceLine" || p->str() == "Line" ) { 00014 00015 cout <<"Can not define the Raviart-Thomas element on a line"<<endl; 00016 00017 } else if (p->str() == "ReferenceTriangle" || p->str() == "Triangle" ) { 00018 00019 Triangle& triangle = (Triangle&)(*p); 00020 GiNaC::lst equations; 00021 GiNaC::lst variables; 00022 GiNaC::ex polynom_space1 = bernstein(order-1, triangle, "a"); 00023 GiNaC::ex polynom1 = polynom_space1.op(0); 00024 GiNaC::ex polynom1_vars = polynom_space1.op(1); 00025 GiNaC::ex polynom1_basis = polynom_space1.op(2); 00026 00027 GiNaC::lst polynom_space2 = bernsteinv(order-1, triangle, "b"); 00028 GiNaC::ex polynom2 = polynom_space2.op(0).op(0); 00029 GiNaC::ex polynom3 = polynom_space2.op(0).op(1); 00030 00031 00032 GiNaC::lst pspace = GiNaC::lst( polynom2 + polynom1*x, 00033 polynom3 + polynom1*y); 00034 GiNaC::lst v2 = collapse(GiNaC::ex_to<GiNaC::lst>(polynom_space2.op(1))); 00035 00036 00037 variables = collapse(GiNaC::lst(polynom_space1.op(1), v2)); 00038 00039 // remove multiple dofs 00040 if ( order >= 2) { 00041 GiNaC::ex expanded_pol = GiNaC::expand(polynom1); 00042 for (int c1=0; c1<= order-2;c1++) { 00043 for (int c2=0; c2<= order-2;c2++) { 00044 for (int c3=0; c3<= order-2;c3++) { 00045 if ( c1 + c2 + c3 <= order -2 ) { 00046 GiNaC::ex eq = expanded_pol.coeff(x,c1).coeff(y,c2).coeff(z,c3); 00047 if ( eq != GiNaC::numeric(0) ) { 00048 equations.append(eq == 0); 00049 } 00050 } 00051 } 00052 } 00053 } 00054 } 00055 00056 int removed_dofs = equations.nops(); 00057 00058 00059 00060 GiNaC::ex bernstein_pol; 00061 00062 int counter = 0; 00063 GiNaC::symbol t("t"); 00064 GiNaC::ex dofi; 00065 // dofs related to edges 00066 for (int i=1; i<= 3; i++) { 00067 Line line = triangle.line(i); 00068 GiNaC::lst normal_vec = normal(triangle, i); 00069 bernstein_pol = bernstein(order-1, line, istr("a",i)); 00070 GiNaC::ex basis_space = bernstein_pol.op(2); 00071 GiNaC::ex pspace_n = inner(pspace, normal_vec); 00072 00073 GiNaC::ex basis; 00074 for (int i=0; i< basis_space.nops(); i++) { 00075 counter++; 00076 basis = basis_space.op(i); 00077 GiNaC::ex integrand = pspace_n*basis; 00078 dofi = line.integrate(integrand); 00079 dofs.insert(dofs.end(), dofi); 00080 GiNaC::ex eq = dofi == GiNaC::numeric(0); 00081 equations.append(eq); 00082 00083 } 00084 } 00085 00086 // dofs related to the whole triangle 00087 GiNaC::lst bernstein_polv; 00088 if ( order > 1) { 00089 counter++; 00090 bernstein_polv = bernsteinv(order-2, triangle, "a"); 00091 GiNaC::ex basis_space = bernstein_polv.op(2); 00092 for (int i=0; i< basis_space.nops(); i++) { 00093 GiNaC::lst basis = GiNaC::ex_to<GiNaC::lst>(basis_space.op(i)); 00094 GiNaC::ex integrand = inner(pspace, basis); 00095 dofi = triangle.integrate(integrand); 00096 dofs.insert(dofs.end(), dofi); 00097 GiNaC::ex eq = dofi == GiNaC::numeric(0); 00098 equations.append(eq); 00099 } 00100 } 00101 // invert the matrix: 00102 // GiNaC has a bit strange way to invert a matrix. 00103 // It solves the system AA^{-1} = Id. 00104 // It seems that this way is the only way to do 00105 // properly with the solve_algo::gauss flag. 00106 // 00107 GiNaC::matrix b; GiNaC::matrix A; 00108 matrix_from_equations(equations, variables, A, b); 00109 00110 int ncols = A.cols(); 00111 GiNaC::matrix vars_sq(ncols, ncols); 00112 00113 // matrix of symbols 00114 for (unsigned r=0; r<ncols; ++r) 00115 for (unsigned c=0; c<ncols; ++c) 00116 vars_sq(r, c) = GiNaC::symbol(); 00117 00118 GiNaC::matrix id(ncols, ncols); 00119 00120 // identity 00121 const GiNaC::ex _ex1(1); 00122 for (unsigned i=0; i<ncols; ++i) 00123 id(i, i) = _ex1; 00124 00125 00126 // invert the matrix 00127 GiNaC::matrix m_inv(ncols, ncols); 00128 m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss); 00129 00130 00131 for (int i=0; i<dofs.size(); i++) { 00132 b.let_op(removed_dofs + i) = GiNaC::numeric(1); 00133 GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b)); 00134 00135 GiNaC::lst subs; 00136 for (int ii=0; ii<xx.nops(); ii++) { 00137 subs.append(variables.op(ii) == xx.op(ii)); 00138 } 00139 GiNaC::ex Nj1 = pspace.op(0).subs(subs); 00140 GiNaC::ex Nj2 = pspace.op(1).subs(subs); 00141 Ns.insert(Ns.end(), GiNaC::matrix(1,2,GiNaC::lst(Nj1,Nj2))); 00142 b.let_op(removed_dofs + i) = GiNaC::numeric(0); 00143 } 00144 00145 } else if ( p->str() == "ReferenceTetrahedron" || p->str() == "Tetrahedron" ) { 00146 00147 00148 Tetrahedron& tetrahedron = (Tetrahedron&)(*p); 00149 GiNaC::lst equations; 00150 GiNaC::lst variables; 00151 GiNaC::ex polynom_space1 = bernstein(order-1, tetrahedron, "a"); 00152 GiNaC::ex polynom1 = polynom_space1.op(0); 00153 GiNaC::ex polynom1_vars = polynom_space1.op(1); 00154 GiNaC::ex polynom1_basis = polynom_space1.op(2); 00155 00156 00157 GiNaC::lst polynom_space2 = bernsteinv(order-1, tetrahedron, "b"); 00158 GiNaC::ex polynom2 = polynom_space2.op(0).op(0); 00159 GiNaC::ex polynom3 = polynom_space2.op(0).op(1); 00160 GiNaC::ex polynom4 = polynom_space2.op(0).op(2); 00161 00162 00163 00164 GiNaC::lst pspace = GiNaC::lst( polynom2 + polynom1*x, 00165 polynom3 + polynom1*y, 00166 polynom4 + polynom1*z); 00167 00168 GiNaC::lst v2 = collapse(GiNaC::ex_to<GiNaC::lst>(polynom_space2.op(1))); 00169 00170 00171 variables = collapse(GiNaC::lst(polynom_space1.op(1), v2)); 00172 00173 GiNaC::ex bernstein_pol; 00174 00175 00176 // remove multiple dofs 00177 if ( order >= 2) { 00178 GiNaC::ex expanded_pol = GiNaC::expand(polynom1); 00179 for (int c1=0; c1<= order-2;c1++) { 00180 for (int c2=0; c2<= order-2;c2++) { 00181 for (int c3=0; c3<= order-2;c3++) { 00182 if ( c1 + c2 + c3 <= order -2 ) { 00183 GiNaC::ex eq = expanded_pol.coeff(x,c1).coeff(y,c2).coeff(z,c3); 00184 if ( eq != GiNaC::numeric(0) ) { 00185 equations.append(eq == 0); 00186 } 00187 } 00188 } 00189 } 00190 } 00191 } 00192 00193 int removed_dofs = equations.nops(); 00194 00195 00196 00197 int counter = 0; 00198 GiNaC::symbol t("t"); 00199 GiNaC::ex dofi; 00200 // dofs related to edges 00201 for (int i=1; i<= 4; i++) { 00202 Triangle triangle = tetrahedron.triangle(i); 00203 GiNaC::lst normal_vec = normal(tetrahedron, i); 00204 bernstein_pol = bernstein(order-1, triangle, istr("a",i)); 00205 GiNaC::ex basis_space = bernstein_pol.op(2); 00206 GiNaC::ex pspace_n = inner(pspace, normal_vec); 00207 00208 GiNaC::ex basis; 00209 for (int i=0; i< basis_space.nops(); i++) { 00210 counter++; 00211 basis = basis_space.op(i); 00212 GiNaC::ex integrand = pspace_n*basis; 00213 dofi = triangle.integrate(integrand); 00214 dofs.insert(dofs.end(), dofi); 00215 GiNaC::ex eq = dofi == GiNaC::numeric(0); 00216 equations.append(eq); 00217 00218 } 00219 } 00220 00221 // dofs related to the whole tetrahedron 00222 GiNaC::lst bernstein_polv; 00223 if ( order > 1) { 00224 counter++; 00225 bernstein_polv = bernsteinv(order-2, tetrahedron, "a"); 00226 GiNaC::ex basis_space = bernstein_polv.op(2); 00227 for (int i=0; i< basis_space.nops(); i++) { 00228 GiNaC::lst basis = GiNaC::ex_to<GiNaC::lst>(basis_space.op(i)); 00229 GiNaC::ex integrand = inner(pspace, basis); 00230 dofi = tetrahedron.integrate(integrand); 00231 dofs.insert(dofs.end(), dofi); 00232 GiNaC::ex eq = dofi == GiNaC::numeric(0); 00233 equations.append(eq); 00234 } 00235 } 00236 // invert the matrix: 00237 // GiNaC has a bit strange way to invert a matrix. 00238 // It solves the system AA^{-1} = Id. 00239 // It seems that this way is the only way to do 00240 // properly with the solve_algo::gauss flag. 00241 // 00242 GiNaC::matrix b; GiNaC::matrix A; 00243 matrix_from_equations(equations, variables, A, b); 00244 00245 int ncols = A.cols(); 00246 GiNaC::matrix vars_sq(ncols, ncols); 00247 00248 // matrix of symbols 00249 for (unsigned r=0; r<ncols; ++r) 00250 for (unsigned c=0; c<ncols; ++c) 00251 vars_sq(r, c) = GiNaC::symbol(); 00252 00253 GiNaC::matrix id(ncols, ncols); 00254 00255 // identity 00256 const GiNaC::ex _ex1(1); 00257 for (unsigned i=0; i<ncols; ++i) 00258 id(i, i) = _ex1; 00259 00260 00261 // invert the matrix 00262 GiNaC::matrix m_inv(ncols, ncols); 00263 m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss); 00264 00265 00266 for (int i=0; i<dofs.size(); i++) { 00267 b.let_op(removed_dofs + i) = GiNaC::numeric(1); 00268 GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b)); 00269 00270 GiNaC::lst subs; 00271 for (int ii=0; ii<xx.nops(); ii++) { 00272 subs.append(variables.op(ii) == xx.op(ii)); 00273 } 00274 GiNaC::ex Nj1 = pspace.op(0).subs(subs); 00275 GiNaC::ex Nj2 = pspace.op(1).subs(subs); 00276 Ns.insert(Ns.end(), GiNaC::matrix(1,2,GiNaC::lst(Nj1,Nj2))); 00277 b.let_op(removed_dofs + i) = GiNaC::numeric(0); 00278 } 00279 } 00280 }
|
|
Reimplemented from StandardFE. Definition at line 293 of file RaviartThomas.cpp. References StandardFE::dof(). 00293 { 00294 return StandardFE::dof(i); 00295 }
|
|
Reimplemented from StandardFE. Definition at line 298 of file RaviartThomas.cpp. References StandardFE::N(). 00298 { 00299 return StandardFE::N(i); 00300 }
|
|
Reimplemented from StandardFE. Definition at line 5 of file RaviartThomas.cpp. References StandardFE::Ns. 00005 { 00006 return Ns.size(); 00007 }
|
|
Reimplemented from StandardFE. Definition at line 283 of file RaviartThomas.cpp. References StandardFE::set(). 00283 { 00284 StandardFE:: set(p_); 00285 }
|
|
Reimplemented from StandardFE. Definition at line 288 of file RaviartThomas.cpp. References StandardFE::set(). Referenced by check_RaviartThomas(), and main(). 00288 { 00289 StandardFE:: set(order_); 00290 }
|