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