00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <FictitiousDomainMethod.hpp>
00021
00022 #include <KrylovSolver.hpp>
00023 #include <PDESolution.hpp>
00024
00025 #include <MeshOfHexahedra.hpp>
00026 #include <Structured3DMesh.hpp>
00027
00028 #include <PDESystem.hpp>
00029
00030 #include <MeshOfHexahedra.hpp>
00031 #include <Structured3DMesh.hpp>
00032
00033 #include <Dirichlet.hpp>
00034 #include <Fourrier.hpp>
00035 #include <Neumann.hpp>
00036
00037 #include <MatrixManagement.hpp>
00038
00039 #include <DoubleHashedMatrix.hpp>
00040 #include <SparseMatrix.hpp>
00041 #include <PETScMatrix.hpp>
00042
00043 #include <FEMDiscretization.hpp>
00044
00045 #include <FEMFunctionBuilder.hpp>
00046
00047 #include <ConformTransformation.hpp>
00048
00049 #include <BoundaryConditionDiscretization.hpp>
00050
00051 void FictitiousDomainMethod::Compute(Solution& U)
00052 {
00053 const Structured3DMesh& m = dynamic_cast<const Structured3DMesh&>(mesh());
00054
00055 KrylovSolver K(*__A, *__b, __degreeOfFreedomSet);
00056
00057 PDESolution& u = static_cast<PDESolution&>(U);
00058
00059 K.solve(problem(), u.values());
00060 for (size_t i=0; i<m.numberOfCells();++i) {
00061 const Cell& k = m.cell(i);
00062 k.setFictitious(false);
00063 }
00064 }
00065
00066
00067 template <typename CellType>
00068 real_t FictitiousDomainMethod::
00069 __integrateCharacteristicFunction(const CellType& k, const Domain& d)
00070 {
00071 throw ErrorHandler(__FILE__,__LINE__,
00072 "not implemented",
00073 ErrorHandler::unexpected);
00074 return 0;
00075 }
00076
00077 template <>
00078 real_t FictitiousDomainMethod::
00079 __integrateCharacteristicFunction(const CartesianHexahedron& k, const Domain& d)
00080 {
00081 ConformTransformationQ1CartesianHexahedron T(k);
00082 return T.integrateCharacteristic(d);
00083 }
00084
00085 template <typename MeshType>
00086 void FictitiousDomainMethod::
00087 __computesDegreesOfFreedom(ConstReferenceCounting<Problem> givenProblem)
00088 {
00089 ffout(2) << "Adding Characteristic function of the domain to PDEs\n";
00090 Vector<bool> dofVertices;
00091
00092 dofVertices.resize(mesh().numberOfVertices());
00093 dofVertices = false;
00094
00095 const Domain& domain = *givenProblem->domain();
00096
00097 for (size_t i=0; i<mesh().numberOfVertices(); ++i) {
00098 dofVertices[i] = domain.inside(mesh().vertex(i));
00099 }
00100
00101 Vector<real_t> kiValues(mesh().numberOfCells());
00102
00103 const MeshType& m = static_cast<const MeshType&>(*__mesh);
00104
00105 for (size_t i=0; i<m.numberOfCells();++i) {
00106 const typename MeshType::CellType& k = m.cell(i);
00107 unsigned numberIn = 0;
00108
00109
00110 for (unsigned j=0; j<MeshType::CellType::NumberOfVertices; ++j) {
00111 numberIn += (dofVertices(m.vertexNumber(k(j))))?1:0;
00112 }
00113
00114 switch (numberIn) {
00115 case 0: {
00116 k.setFictitious(true);
00117 kiValues[i] = 0;
00118 break;
00119 }
00120 case MeshType::CellType::NumberOfVertices: {
00121 kiValues[i] = 1;
00122 break;
00123 }
00124 default:{
00125 kiValues[i] = __integrateCharacteristicFunction(k, domain);
00126 }
00127 }
00128 }
00129
00130 ScalarDiscretizationTypeFEM discretizationType(ScalarDiscretizationTypeBase::lagrangianFEM0);
00131
00132 FEMFunctionBuilder femBuilder;
00133 femBuilder.build(discretizationType,
00134 __mesh,
00135 kiValues);
00136 ConstReferenceCounting<ScalarFunctionBase> u = femBuilder.getBuiltScalarFunction();
00137
00138 __problem = (*givenProblem) * u;
00139 ffout(2) << "Adding Characteristic function of the domain to PDEs: done\n";
00140
00141
00142
00143
00144 }
00145
00146 void FictitiousDomainMethod::
00147 computesDegreesOfFreedom(ConstReferenceCounting<Problem> givenProblem)
00148 {
00149 switch (mesh().type()) {
00150 case Mesh::cartesianHexahedraMesh: {
00151 this->__computesDegreesOfFreedom<Structured3DMesh>(givenProblem);
00152 break;
00153 }
00154 default: {
00155 throw ErrorHandler(__FILE__,__LINE__,
00156 "mesh type not supported by FDM",
00157 ErrorHandler::normal);
00158 }
00159 }
00160 }
00161
00162
00163 template <typename MeshType,
00164 ScalarDiscretizationTypeBase::Type TypeOfDiscretization>
00165 void FictitiousDomainMethod::__discretizeOnMesh()
00166 {
00167 MemoryManager MM;
00168
00169 bool performAssembling =MM.ReserveMatrix(__A,
00170 problem().numberOfUnknown(),
00171 __degreeOfFreedomSet.size());
00172
00173 MM.ReserveVector(__b,
00174 problem().numberOfUnknown(),
00175 __degreeOfFreedomSet.size());
00176
00177 ffout(2) << "Fictitious domain method: discretization...\n";
00178
00179 ReferenceCounting<FEMDiscretization<MeshType, TypeOfDiscretization> > FEM
00180 = new FEMDiscretization<MeshType,
00181 TypeOfDiscretization>(problem(),
00182 dynamic_cast<const MeshType&>(*__mesh),
00183 __discretizationType,
00184 *__A,*__b, __degreeOfFreedomSet);
00185
00186 if (performAssembling) {
00187 FEM->assembleMatrix();
00188 } else {
00189 ffout(2) << "keeping previous operator discretization\n";
00190 }
00191
00192 FEM->assembleSecondMember();
00193
00194 ffout(2) << "- discretizing boundary conditions\n";
00195
00196 ReferenceCounting<BoundaryConditionDiscretization> bcDiscretization
00197 = this->discretizeBoundaryConditions();
00198
00199
00200 FEM->setDirichletList(bcDiscretization->getDirichletList());
00201
00202 ffout(2) << "- second member modification\n";
00203
00204 bcDiscretization->setSecondMember(__A,__b);
00205
00206 ffout(2) << "- matrix modification\n";
00207
00208 bcDiscretization->setMatrix(__A,__b);
00209
00210 ffout(2) << "Fictitious domain method: discretization done\n";
00211
00212 if (__A->type() == BaseMatrix::doubleHashedMatrix) {
00213 Timer t;
00214 t.start();
00215
00216 #warning temporary implementation
00217 #ifdef HAVE_PETSC
00218 PETScMatrix* aa
00219 = new PETScMatrix(static_cast<DoubleHashedMatrix&>(*__A));
00220 __A = aa;
00221 #else // HAVE_PETSC
00222 SparseMatrix* aa
00223 = new SparseMatrix(static_cast<DoubleHashedMatrix&>(*__A));
00224 __A = aa;
00225 #endif // HAVE_PETSC
00226
00227 t.stop();
00228 ffout(2) << "- matrix copy time: " << t << '\n';
00229 }
00230 }
00231
00232 template <ScalarDiscretizationTypeBase::Type TypeOfDiscretization>
00233 void FictitiousDomainMethod::__discretize()
00234 {
00235
00236 switch (this->mesh().type()) {
00237 case Mesh::cartesianHexahedraMesh: {
00238 this->__discretizeOnMesh<Structured3DMesh, TypeOfDiscretization>();
00239 break;
00240 }
00241 default: {
00242 throw ErrorHandler(__FILE__,__LINE__,
00243 "this mesh type is not supported by FDM",
00244 ErrorHandler::normal);
00245 }
00246 }
00247
00248 }
00249
00250 void FictitiousDomainMethod::Discretize(ConstReferenceCounting<Problem> givenProblem)
00251 {
00252 this->computesDegreesOfFreedom(givenProblem);
00253
00254 switch(__discretizationType[0].type()) {
00255 case ScalarDiscretizationTypeBase::lagrangianFEM1: {
00256 this->__discretize<ScalarDiscretizationTypeBase::lagrangianFEM1>();
00257 return;
00258 }
00259 case ScalarDiscretizationTypeBase::lagrangianFEM2: {
00260 this->__discretize<ScalarDiscretizationTypeBase::lagrangianFEM2>();
00261 return;
00262 }
00263 default: {
00264 throw ErrorHandler(__FILE__,__LINE__,
00265 "Discretization type not implemented",
00266 ErrorHandler::normal);
00267 }
00268 }
00269 }