SyFi
0.3
|
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 "ArnoldFalkWintherWeakSym.h" 00019 #include "Nedelec2Hdiv.h" 00020 #include "DiscontinuousLagrange.h" 00021 #include "P0.h" 00022 #include "utilities.h" 00023 00024 using std::cout; 00025 using std::endl; 00026 00027 namespace SyFi 00028 { 00029 00030 //------------ sigma element 00031 00032 ArnoldFalkWintherWeakSymSigma::ArnoldFalkWintherWeakSymSigma() : StandardFE() 00033 { 00034 description = "ArnoldFalkWintherWeakSymSigma"; 00035 } 00036 00037 ArnoldFalkWintherWeakSymSigma::ArnoldFalkWintherWeakSymSigma(Polygon& p, int order) : StandardFE(p, order) 00038 { 00039 compute_basis_functions(); 00040 } 00041 00042 void ArnoldFalkWintherWeakSymSigma:: compute_basis_functions() 00043 { 00044 00045 // remove previously computed basis functions and dofs 00046 Ns.clear(); 00047 dofs.clear(); 00048 00049 if ( order < 1 ) 00050 { 00051 throw(std::logic_error("Arnold-Falk-Winther elements must be of order 1 or higher.")); 00052 } 00053 00054 if ( p == NULL ) 00055 { 00056 throw(std::logic_error("You need to set a polygon before the basisfunctions can be computed")); 00057 } 00058 00059 description = istr("ArnoldFalkWintherWeakSymSigma_", order) + "_3D"; 00060 00061 Nedelec2Hdiv fe; 00062 fe.set_order(order); 00063 fe.set_polygon(*p); 00064 fe.compute_basis_functions(); 00065 00066 for (int d=0; d<3; d++) 00067 { 00068 for (unsigned int i=0; i<fe.nbf(); i++) 00069 { 00070 GiNaC::matrix Nmat = GiNaC::matrix(3,3); 00071 Nmat(d,0) = fe.N(i).op(0); 00072 Nmat(d,1) = fe.N(i).op(1); 00073 Nmat(d,2) = fe.N(i).op(2); 00074 Ns.insert(Ns.end(), Nmat); 00075 dofs.insert(dofs.end(),GiNaC::lst(fe.dof(i).op(0), fe.dof(i).op(1), d)); 00076 } 00077 } 00078 } 00079 00080 //------------ u element 00081 00082 ArnoldFalkWintherWeakSymU::ArnoldFalkWintherWeakSymU() : StandardFE() 00083 { 00084 description = "ArnoldFalkWintherWeakSymU"; 00085 } 00086 00087 ArnoldFalkWintherWeakSymU ::ArnoldFalkWintherWeakSymU (Polygon& p, int order) : StandardFE(p, order) 00088 { 00089 compute_basis_functions(); 00090 } 00091 00092 void ArnoldFalkWintherWeakSymU:: compute_basis_functions() 00093 { 00094 00095 // remove previously computed basis functions and dofs 00096 Ns.clear(); 00097 dofs.clear(); 00098 00099 if ( order < 1 ) 00100 { 00101 throw(std::logic_error("Arnold-Falk-Winther elements must be of order 1 or higher.")); 00102 } 00103 00104 if ( p == NULL ) 00105 { 00106 throw(std::logic_error("You need to set a polygon before the basisfunctions can be computed")); 00107 } 00108 00109 description = istr("ArnoldFalkWintherWeakSymU_", order) + "_3D"; 00110 00111 if ( order > 1 ) 00112 { 00113 VectorDiscontinuousLagrange fe; 00114 fe.set_order(order-1); 00115 fe.set_size(3); 00116 fe.set_polygon(*p); 00117 fe.compute_basis_functions(); 00118 00119 for (unsigned int i=0; i<fe.nbf(); i++) 00120 { 00121 GiNaC::lst Ni = GiNaC::lst(fe.N(i).op(0), fe.N(i).op(1), fe.N(i).op(2)); 00122 GiNaC::ex Nmat = GiNaC::matrix(3,1,Ni); 00123 Ns.insert(Ns.end(), Nmat); 00124 dofs.insert(dofs.end(),GiNaC::lst(fe.dof(i))); 00125 } 00126 } 00127 else if ( order == 1 ) 00128 { 00129 VectorP0 fe; 00130 fe.set_order(order-1); 00131 fe.set_size(3); 00132 fe.set_polygon(*p); 00133 fe.compute_basis_functions(); 00134 00135 for (unsigned int i=0; i<fe.nbf(); i++) 00136 { 00137 GiNaC::lst Ni = GiNaC::lst(fe.N(i).op(0), fe.N(i).op(1), fe.N(i).op(2)); 00138 GiNaC::ex Nmat = GiNaC::matrix(3,1,Ni); 00139 Ns.insert(Ns.end(), Nmat); 00140 GiNaC::ex d = GiNaC::lst(fe.dof(i), 0); 00141 dofs.insert(dofs.end(),GiNaC::lst(d)); 00142 } 00143 } 00144 00145 } 00146 00147 //------------ p element 00148 00149 ArnoldFalkWintherWeakSymP::ArnoldFalkWintherWeakSymP() : StandardFE() 00150 { 00151 description = "ArnoldFalkWintherWeakSymP"; 00152 } 00153 00154 ArnoldFalkWintherWeakSymP ::ArnoldFalkWintherWeakSymP (Polygon& p, int order) : StandardFE(p, order) 00155 { 00156 compute_basis_functions(); 00157 } 00158 00159 void ArnoldFalkWintherWeakSymP:: compute_basis_functions() 00160 { 00161 00162 // remove previously computed basis functions and dofs 00163 Ns.clear(); 00164 dofs.clear(); 00165 00166 if ( order < 1 ) 00167 { 00168 cout <<"Arnold-Falk-Winther elements must be of order 1 or higher."<<endl; 00169 return; 00170 } 00171 00172 if ( p == NULL ) 00173 { 00174 cout <<"You need to set a polygon before the basisfunctions can be computed"<<endl; 00175 return; 00176 } 00177 00178 description = istr("ArnoldFalkWintherWeakSymP_", order) + "_3D"; 00179 00180 if ( order > 1 ) 00181 { 00182 00183 VectorDiscontinuousLagrange fe; 00184 fe.set_order(order); 00185 fe.set_size(3); 00186 fe.set_polygon(*p); 00187 fe.compute_basis_functions(); 00188 00189 for (unsigned int i=0; i<fe.nbf(); i++) 00190 { 00191 GiNaC::matrix Nmat = GiNaC::matrix(3,3); 00192 Nmat(1,2) = -fe.N(i).op(0); 00193 Nmat(2,1) = fe.N(i).op(0); 00194 00195 Nmat(0,2) = fe.N(i).op(1); 00196 Nmat(2,0) = -fe.N(i).op(1); 00197 00198 Nmat(0,1) = -fe.N(i).op(2); 00199 Nmat(1,0) = fe.N(i).op(2); 00200 00201 Ns.insert(Ns.end(), Nmat); 00202 dofs.insert(dofs.end(),GiNaC::lst(fe.dof(i))); 00203 } 00204 } 00205 else if ( order == 1 ) 00206 { 00207 00208 VectorP0 fe; 00209 fe.set_order(order); 00210 fe.set_size(3); 00211 fe.set_polygon(*p); 00212 fe.compute_basis_functions(); 00213 00214 for (unsigned int i=0; i<fe.nbf(); i++) 00215 { 00216 GiNaC::matrix Nmat = GiNaC::matrix(3,3); 00217 Nmat(1,2) = -fe.N(i).op(0); 00218 Nmat(2,1) = fe.N(i).op(0); 00219 00220 Nmat(0,2) = fe.N(i).op(1); 00221 Nmat(2,0) = -fe.N(i).op(1); 00222 00223 Nmat(0,1) = -fe.N(i).op(2); 00224 Nmat(1,0) = fe.N(i).op(2); 00225 00226 Ns.insert(Ns.end(), Nmat); 00227 GiNaC::ex d = GiNaC::lst(fe.dof(i), 0); 00228 dofs.insert(dofs.end(),GiNaC::lst(d)); 00229 } 00230 } 00231 00232 } 00233 00234 } // namespace SyFi