SpaceTimeElement.cpp

Go to the documentation of this file.
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

Generated on Mon Aug 31 16:16:45 2009 for SyFi by  doxygen 1.5.9