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 "P0.h" 00019 #include "tools.h" 00020 00021 using std::cout; 00022 using std::endl; 00023 00024 namespace SyFi 00025 { 00026 00027 P0::P0() : StandardFE() 00028 { 00029 description = "P0"; 00030 } 00031 00032 P0:: P0(Polygon& p, unsigned int order) : StandardFE (p,order) 00033 { 00034 compute_basis_functions(); 00035 } 00036 00037 void P0:: compute_basis_functions() 00038 { 00039 00040 // remove previously computed basis functions and dofs 00041 Ns.clear(); 00042 dofs.clear(); 00043 00044 if ( p == NULL ) 00045 { 00046 throw(std::logic_error("You need to set a polygon before the basisfunctions can be computed")); 00047 } 00048 00049 // insert basis function 00050 Ns.insert(Ns.end(), GiNaC::numeric(1)); 00051 00052 GiNaC::lst midpoint = GiNaC::lst(); 00053 // create and insert dof 00054 // p is a lst 00055 if (GiNaC::is_a<GiNaC::lst>(p->vertex(0))) 00056 { 00057 for (unsigned int d=0; d< p->vertex(1).nops(); d++) 00058 { 00059 midpoint.append(GiNaC::numeric(0)); 00060 } 00061 for (unsigned int i=0; i< p->no_vertices(); i++) 00062 { 00063 int nops; 00064 nops = p->vertex(i).nops(); 00065 for (int d=0; d< nops; d++) 00066 { 00067 midpoint.let_op(d) += p->vertex(i).op(d); 00068 } 00069 } 00070 for (unsigned int d=0; d< p->vertex(1).nops(); d++) 00071 { 00072 midpoint.let_op(d) = midpoint.op(d)/p->no_vertices(); 00073 } 00074 } 00075 else 00076 { 00077 midpoint.append(GiNaC::numeric(0)); 00078 for (unsigned int i=0; i< p->no_vertices(); i++) 00079 { 00080 midpoint.let_op(0) += p->vertex(i); 00081 } 00082 midpoint.let_op(0) = midpoint.op(0)/p->no_vertices(); 00083 } 00084 00085 dofs.insert(dofs.end(), midpoint); 00086 00087 description = istr("P0_" , midpoint.nops()) + "D"; 00088 } 00089 00090 // ------------VectorP0 --- 00091 00092 VectorP0::VectorP0() : StandardFE() 00093 { 00094 description = "VectorP0"; 00095 } 00096 00097 VectorP0::VectorP0(Polygon& p, unsigned int order, unsigned int size_) : StandardFE(p, order) 00098 { 00099 size = size_ < 0 ? nsd: size_; 00100 compute_basis_functions(); 00101 } 00102 00103 void VectorP0:: compute_basis_functions() 00104 { 00105 00106 // remove previously computed basis functions and dofs 00107 Ns.clear(); 00108 dofs.clear(); 00109 00110 if ( p == NULL ) 00111 { 00112 throw(std::logic_error("You need to set a polygon before the basisfunctions can be computed")); 00113 } 00114 00115 if ( size == 0) 00116 { 00117 throw(std::logic_error("You need to set the size of the vector before the basisfunctions can be computed")); 00118 } 00119 00120 P0 fe(*p); 00121 GiNaC::lst zero_list; 00122 for (unsigned int s=1; s<= size ; s++) 00123 { 00124 zero_list.append(0); 00125 } 00126 00127 for (unsigned int i=0; i< fe.nbf() ; i++) 00128 { 00129 for (unsigned int s=0; s< size ; s++) 00130 { 00131 GiNaC::lst Nis = zero_list; 00132 Nis.let_op(s) = fe.N(i); 00133 GiNaC::ex Nmat = GiNaC::matrix(size,1,Nis); 00134 Ns.insert(Ns.end(), Nmat); 00135 00136 GiNaC::lst dof = GiNaC::lst(fe.dof(i), s) ; 00137 dofs.insert(dofs.end(), dof); 00138 } 00139 } 00140 description = "Vector" + fe.str(); 00141 } 00142 00143 void VectorP0:: set_size(unsigned int size_) 00144 { 00145 size = size_; 00146 } 00147 00148 // ------------TensorP0 --- 00149 00150 TensorP0::TensorP0() : StandardFE() 00151 { 00152 description = "TensorP0"; 00153 } 00154 00155 TensorP0::TensorP0(Polygon& p, unsigned int order, unsigned int size_) : StandardFE(p, order) 00156 { 00157 size = size_ < 0 ? nsd: size_; 00158 compute_basis_functions(); 00159 } 00160 00161 void TensorP0:: compute_basis_functions() 00162 { 00163 00164 // remove previously computed basis functions and dofs 00165 Ns.clear(); 00166 dofs.clear(); 00167 00168 if ( p == NULL ) 00169 { 00170 throw(std::logic_error("You need to set a polygon before the basisfunctions can be computed")); 00171 } 00172 00173 if ( size == 0) 00174 { 00175 throw(std::logic_error("You need to set the size of the vector before the basisfunctions can be computed")); 00176 } 00177 00178 P0 fe(*p); 00179 GiNaC::lst zero_list; 00180 for (unsigned int s=1; s<= size*size ; s++) 00181 { 00182 zero_list.append(0); 00183 } 00184 00185 for (unsigned int i=0; i< fe.nbf() ; i++) 00186 { 00187 for (unsigned int r=0; r< size ; r++) 00188 { 00189 for (unsigned int s=0; s< size ; s++) 00190 { 00191 GiNaC::lst Nis = zero_list; 00192 Nis.let_op((size)*r + s) = fe.N(i); 00193 GiNaC::ex Nmat = GiNaC::matrix(size,size,Nis); 00194 Ns.insert(Ns.end(), Nmat); 00195 00196 GiNaC::lst dof = GiNaC::lst(fe.dof(i), r, s) ; 00197 dofs.insert(dofs.end(), dof); 00198 } 00199 } 00200 } 00201 description = "Tensor" + fe.str(); 00202 } 00203 00204 void TensorP0:: set_size(unsigned int size_) 00205 { 00206 size = size_; 00207 } 00208 00209 }