SyFi  0.3
SpaceTimeElement.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator