00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <SpectralMethod.hpp>
00021
00022 #include <SolverInformationCenter.hpp>
00023
00024 #include <SpectralLegendreDiscretizationConform.hpp>
00025 #include <BoundaryConditionDiscretizationSpectralConform.hpp>
00026
00027 #include <SpectralLegendreDiscretizationNonConform.hpp>
00028 #include <BoundaryConditionDiscretizationSpectralNonConform.hpp>
00029
00030 #include <PDESolution.hpp>
00031
00032 #include <PDEProblem.hpp>
00033
00034 #include <SpectralMesh.hpp>
00035
00036 #include <KrylovSolver.hpp>
00037
00038 #include <MatrixManagement.hpp>
00039
00040 #include <SparseMatrix.hpp>
00041
00042 #include <Timer.hpp>
00043
00044 #include <ErrorHandler.hpp>
00045
00046 void SpectralMethod::__discretizeOnConformingMesh()
00047 {
00048
00049 ParameterCenter::instance().set("memory::matrix","none");
00050
00051 MemoryManager MM;
00052
00053 MM.ReserveMatrix(__A,
00054 problem().numberOfUnknown(),
00055 __degreeOfFreedomSet.size());
00056
00057 MM.ReserveVector(__b,
00058 problem().numberOfUnknown(),
00059 __degreeOfFreedomSet.size());
00060
00061 ffout(2) << "Spectral method: disretization...\n";
00062
00063 ReferenceCounting<SpectralLegendreDiscretizationConform> spectralMethod
00064 = new SpectralLegendreDiscretizationConform(problem(),
00065 dynamic_cast<const SpectralMesh&>(mesh()),
00066 *__A,*__b, __degreeOfFreedomSet,
00067 __discretizationType);
00068
00069 spectralMethod->assembleMatrix();
00070 spectralMethod->assembleSecondMember();
00071
00072 ffout(2) << "- discretizing boundary conditions\n";
00073
00074 ReferenceCounting<BoundaryConditionDiscretization> bcDiscretization
00075 = new BoundaryConditionDiscretizationSpectralConform(problem(),
00076 dynamic_cast<const SpectralMesh&>(mesh()),
00077 __degreeOfFreedomSet,
00078 __discretizationType);
00079
00080 ffout(2) << "- second member modification\n";
00081 bcDiscretization->setSecondMember(__A,__b);
00082
00083 ffout(2) << "- matrix modification\n";
00084 bcDiscretization->setMatrix(__A,__b);
00085
00086 ffout(2) << "Spectral method: disretization done\n";
00087 }
00088
00089
00090
00091 void SpectralMethod::__discretizeOnOctreeMesh()
00092 {
00093
00094 ParameterCenter::instance().set("memory::matrix","none");
00095
00096 MemoryManager MM;
00097
00098 MM.ReserveMatrix(__A,
00099 problem().numberOfUnknown(),
00100 __degreeOfFreedomSet.size());
00101
00102 MM.ReserveVector(__b,
00103 problem().numberOfUnknown(),
00104 __degreeOfFreedomSet.size());
00105
00106 ffout(2) << "Spectral method: disretization...\n";
00107
00108 ReferenceCounting<SpectralLegendreDiscretizationNonConform> spectralMethod
00109 = new SpectralLegendreDiscretizationNonConform(problem(),
00110 dynamic_cast<const OctreeMesh&>(mesh()),
00111 *__A,*__b, __degreeOfFreedomSet,
00112 __discretizationType);
00113
00114 spectralMethod->assembleMatrix();
00115 spectralMethod->assembleSecondMember();
00116
00117 ffout(2) << "- discretizing boundary conditions\n";
00118
00119 BoundaryConditionDiscretizationSpectralNonConform* bcd
00120 = new BoundaryConditionDiscretizationSpectralNonConform(problem(),
00121 dynamic_cast<const OctreeMesh&>(mesh()),
00122 __degreeOfFreedomSet,
00123 __discretizationType);
00124 bcd->associatesMeshesToBoundaryConditions();
00125 ReferenceCounting<BoundaryConditionDiscretization> bcDiscretization = bcd;
00126
00127 ffout(2) << "- second member modification\n";
00128 bcDiscretization->setSecondMember(__A,__b);
00129
00130 ffout(2) << "- matrix modification\n";
00131 bcDiscretization->setMatrix(__A,__b);
00132
00133 ffout(2) << "Spectral method: disretization done\n";
00134 }
00135
00136 void SpectralMethod::__discretize()
00137 {
00138 switch (mesh().type()) {
00139 case Mesh::spectralMesh: {
00140 this->__discretizeOnConformingMesh();
00141 break;
00142 }
00143 case Mesh::octreeMesh: {
00144 this->__discretizeOnOctreeMesh();
00145 break;
00146 }
00147 default: {
00148 throw ErrorHandler(__FILE__, __LINE__,
00149 "Cannot use '"+mesh().typeName()+"' for spectral method computations",
00150 ErrorHandler::normal);
00151 }
00152 }
00153 }
00154
00155 void SpectralMethod::Discretize (ConstReferenceCounting<Problem> Pb)
00156 {
00157 __problem = Pb;
00158
00159 switch(__discretizationType[0].type()) {
00160 case ScalarDiscretizationTypeBase::spectralLegendre: {
00161 this->__discretize();
00162 return;
00163 }
00164 default: {
00165 throw ErrorHandler(__FILE__,__LINE__,
00166 "Discretization type not implemented",
00167 ErrorHandler::normal);
00168 }
00169 }
00170 }
00171
00172 void SpectralMethod::Compute (Solution& U)
00173 {
00174 PDESolution& u = static_cast<PDESolution&>(U);
00175 KrylovSolver K(*__A, *__b, __degreeOfFreedomSet);
00176 K.solve(problem(), u.values());
00177 }
00178
00179 SpectralMethod::
00180 SpectralMethod(const DiscretizationType& discretizationType,
00181 ConstReferenceCounting<Mesh> mesh,
00182 const DegreeOfFreedomSet& dOfFreedom)
00183 : Method(discretizationType),
00184 __mesh(mesh),
00185 __degreeOfFreedomSet(dOfFreedom)
00186 {
00187 SolverInformationCenter::instance().pushMesh(mesh);
00188 SolverInformationCenter::instance().pushDiscretizationType(&discretizationType);
00189 }
00190
00191 SpectralMethod::
00192 ~SpectralMethod()
00193 {
00194 SolverInformationCenter::instance().pop();
00195 }