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 "symbol_factory.h" 00019 #include "diff_tools.h" 00020 #include "Lagrange.h" 00021 #include "P0.h" 00022 #include "SpaceTimeElement.h" 00023 00024 namespace SyFi 00025 { 00026 00027 SpaceTimeDomain::SpaceTimeDomain(Line& time_line_, Polygon& polygon_) 00028 { 00029 time_line = time_line_.copy(); 00030 polygon = polygon_.copy(); 00031 } 00032 00033 SpaceTimeDomain* SpaceTimeDomain::copy() const 00034 { 00035 return new SpaceTimeDomain(*this); 00036 } 00037 00038 SpaceTimeDomain::SpaceTimeDomain(const SpaceTimeDomain& domain) 00039 { 00040 00041 if (time_line) 00042 { 00043 delete time_line; 00044 } 00045 if (polygon) 00046 { 00047 delete polygon; 00048 } 00049 00050 time_line = domain.get_time_domain().copy(); 00051 polygon = domain.get_space_domain().copy(); 00052 } 00053 00054 const std::string SpaceTimeDomain::str() const 00055 { 00056 return "Time" + polygon->str(); 00057 } 00058 00059 unsigned int SpaceTimeDomain:: no_space_dim() const 00060 { 00061 return polygon->no_space_dim() +1; 00062 } 00063 00064 Line SpaceTimeDomain ::line(unsigned int i) const 00065 { 00066 //FIXME 00067 // Could use the convention that the time line is the first line, the 00068 // next lines are the lines in the polygon 00069 return Line(); 00070 } 00071 00072 GiNaC::ex SpaceTimeDomain:: repr(Repr_format format) const 00073 { 00074 return GiNaC::lst(time_line->repr(t, format), polygon->repr(format)); 00075 } 00076 00077 GiNaC::ex SpaceTimeDomain::integrate(GiNaC::ex f, Repr_format format) 00078 { 00079 GiNaC::ex intf; 00080 00081 // integrate in space 00082 intf = polygon->integrate(f, format); 00083 00084 // integrate in time ((x,y,z) are now integrated away) 00085 intf = intf.subs( t == x ); 00086 intf = time_line->integrate(intf , format); 00087 00088 return intf; 00089 00090 } 00091 00092 SpaceTimeElement:: SpaceTimeElement() : StandardFE() 00093 { 00094 description = "SpaceTimeElement"; 00095 } 00096 00097 SpaceTimeElement:: SpaceTimeElement(Line* time_line_, unsigned int order_, StandardFE* fe_) 00098 { 00099 time_line = time_line_; 00100 order = order_; 00101 fe = fe_; 00102 compute_basis_functions(); 00103 } 00104 00105 void SpaceTimeElement:: set_time_domain(Line* line_) 00106 { 00107 time_line = line_; 00108 } 00109 00110 void SpaceTimeElement:: set_order_in_time(unsigned int order_) 00111 { 00112 order = order_; 00113 } 00114 00115 void SpaceTimeElement:: set_spatial_element(StandardFE* fe_) 00116 { 00117 fe = fe_; 00118 } 00119 00120 void SpaceTimeElement:: compute_basis_functions() 00121 { 00122 00123 // remove previously computed basis functions and dofs 00124 Ns.clear(); 00125 dofs.clear(); 00126 00127 if ( order < 1 ) 00128 { 00129 throw(std::logic_error("The elements must be of order 1 or higher.")); 00130 } 00131 00132 if ( time_line == NULL ) 00133 { 00134 throw(std::logic_error("You need to set a time domain before the basisfunctions can be computed")); 00135 } 00136 00137 if ( fe == NULL ) 00138 { 00139 throw(std::logic_error("You need to set a spatial element before the basisfunctions can be computed")); 00140 } 00141 00142 StandardFE* time_element; 00143 if ( order == 0) 00144 { 00145 time_element = new P0(*time_line); 00146 } 00147 else 00148 { 00149 time_element = new Lagrange(*time_line, order); 00150 } 00151 00152 for (unsigned int j = 0; j < fe->nbf(); j++) 00153 { 00154 GiNaC::ex Nj = fe->N(j); 00155 for (unsigned int i = 0; i < (*time_element).nbf(); i++) 00156 { 00157 GiNaC::ex Ni = (*time_element).N(i); 00158 Ni = Ni.subs(x == t); 00159 GiNaC::ex N = Nj*Ni; 00160 Ns.insert(Ns.end(), N); 00161 dofs.insert(dofs.end(), GiNaC::lst((*time_element).dof(i), fe->dof(j))); 00162 } 00163 } 00164 00165 description = time_element->str() + "_" + fe->str(); 00166 delete time_element; 00167 } 00168 00169 } // namespace SyFi