00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <BoundaryConditionDiscretizationSpectralNonConform.hpp>
00021 #include <ErrorHandler.hpp>
00022
00023 #include <VariationalProblem.hpp>
00024 #include <DegreeOfFreedomSet.hpp>
00025 #include <VariationalBorderOperatorAlphaUV.hpp>
00026 #include <VariationalBorderOperatorFV.hpp>
00027 #include <VariationalLinearOperator.hpp>
00028 #include <SpectralConformTransformation.hpp>
00029
00030 #include <BaseMatrix.hpp>
00031 #include <BaseVector.hpp>
00032
00033 #include <Discretization.hpp>
00034 #include <ScalarDiscretizationTypeSpectral.hpp>
00035
00036 #include <BoundaryReferences.hpp>
00037
00038 #include <UnAssembledMatrix.hpp>
00039
00040 #include <DoubleHashedMatrix.hpp>
00041
00042 #include <ConformTransformation.hpp>
00043
00044
00045
00046 void BoundaryConditionDiscretizationSpectralNonConform::
00047 getDiagonal(BaseVector& X) const
00048 {
00049 Vector<real_t>& v = dynamic_cast<Vector<real_t>&>(X);
00050
00051 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *__bcMeshAssociation;
00052
00053 for (BoundaryConditionSurfaceMeshAssociation
00054 ::BilinearBorderOperatorMeshAssociation
00055 ::const_iterator i = bcMeshAssociation.beginOfBilinear();
00056 i != bcMeshAssociation.endOfBilinear(); ++i) {
00057
00058 switch (i->first->type()) {
00059 case VariationalBilinearBorderOperator::alphaUV: {
00060 const VariationalBorderOperatorAlphaUV& operatorAlphaUV
00061 = dynamic_cast<const VariationalBorderOperatorAlphaUV&>(*i->first);
00062 if (operatorAlphaUV.unknownNumber() == operatorAlphaUV.testFunctionNumber()) {
00063
00064 const ScalarFunctionBase& alpha = operatorAlphaUV.alpha();
00065
00066 size_t unknownNumber = operatorAlphaUV.unknownNumber();
00067 const ScalarDiscretizationTypeSpectral& discretization
00068 = dynamic_cast<const ScalarDiscretizationTypeSpectral&>(__discretizationType[unknownNumber]);
00069
00070 TinyVector<3, ConstReferenceCounting<Interval> > interval;
00071 TinyVector<3, ConstReferenceCounting<SpectralConformTransformation> > spectralTransform;
00072 TinyVector<3, ConstReferenceCounting<LegendreBasis> > basis;
00073
00074 for(size_t n=0; n<3; ++n){
00075 interval[n]= new Interval(discretization.a()[n],discretization.b()[n]);
00076 spectralTransform[n] = new SpectralConformTransformation(*interval[n]);
00077 basis[n]= new LegendreBasis(discretization.degrees()[n]);
00078 }
00079
00080 const Mesh& boundaryMesh = (*i->second);
00081 switch(boundaryMesh.type()) {
00082 case Mesh::surfaceMeshTriangles: {
00083 typedef QuadratureFormulaP1Triangle3D QuadratureType;
00084
00085 const QuadratureType& quadrature = QuadratureType::instance();
00086 const TinyVector<QuadratureType::numberOfQuadraturePoints, TinyVector<3,real_t> >&
00087 nodesRef = quadrature.vertices() ;
00088
00089 for (SurfaceMeshOfTriangles::const_iterator itriangle(dynamic_cast<const SurfaceMeshOfTriangles&>(boundaryMesh));
00090 not(itriangle.end()); ++ itriangle) {
00091 const Triangle& T = * itriangle;
00092
00093 TinyVector<3,Vector<real_t> > baseValues;
00094 for(size_t j = 0; j < 3; j++){
00095 baseValues[j].resize(discretization.degrees()[j] + 1);
00096 }
00097
00098 ConformTransformationP1Triangle::ConformTransformationP1Triangle transform(T);
00099
00100 for (size_t q=0; q< QuadratureType::numberOfQuadraturePoints; ++q) {
00101
00102
00103
00104 TinyVector<3,real_t> nodes;
00105 transform.value(nodesRef[q],nodes);
00106 const real_t xi= (spectralTransform[0])->inverse(nodes[0]);
00107 const real_t yi= (spectralTransform[1])->inverse(nodes[1]);
00108 const real_t zi= (spectralTransform[2])->inverse(nodes[2]);
00109 (basis[0])->getValues(xi,baseValues[0]);
00110 (basis[1])->getValues(yi,baseValues[1]);
00111 (basis[2])->getValues(zi,baseValues[2]);
00112
00113 const real_t weight = quadrature.weight(q) ;
00114 const TinyVector<3,size_t>& dofShapeU = __dofShape[unknownNumber];
00115
00116 for (size_t i=0; i< (basis[0])->dimension(); ++i){
00117 const real_t q1 = alpha(nodes)* weight * T.volume() * baseValues[0][i]* baseValues[0][i];
00118 for (size_t j=0; j<( basis[1])->dimension(); ++j){
00119 const real_t q2 = q1 * baseValues[1][j]*baseValues[1][j];
00120 for (size_t k=0; k< (basis[2])->dimension(); ++k){
00121 const real_t q3 = q2 * baseValues[2][k] * baseValues[2][k];
00122
00123 size_t dofNumberU = i*dofShapeU[1]*dofShapeU[2] + j*dofShapeU[2] + k;
00124
00125 v[__degreeOfFreedomSet(unknownNumber,dofNumberU)] += q3;
00126 }
00127 }
00128 }
00129 }
00130 }
00131
00132
00133
00134 break;
00135 }
00136 case Mesh::surfaceMeshQuadrangles: {
00137 throw ErrorHandler(__FILE__,__LINE__,
00138 "non conforming boundary condition is not implemented in quadrangle meshes",
00139 ErrorHandler::normal);
00140 break;
00141 }
00142 default: {
00143 throw ErrorHandler(__FILE__,__LINE__,
00144 "not implemented",
00145 ErrorHandler::unexpected);
00146 }
00147 }
00148 }
00149 break;
00150 }
00151 default: {
00152 throw ErrorHandler(__FILE__,__LINE__,
00153 "not implemented",
00154 ErrorHandler::unexpected);
00155 }
00156 }
00157 }
00158 }
00159
00160
00161 void BoundaryConditionDiscretizationSpectralNonConform::
00162 setMatrix(ReferenceCounting<BaseMatrix> givenA,
00163 ReferenceCounting<BaseVector> b) const
00164 {
00165 switch((*givenA).type()) {
00166 case BaseMatrix::doubleHashedMatrix: {
00167 throw ErrorHandler(__FILE__,__LINE__,
00168 "not implemented",
00169 ErrorHandler::unexpected);
00170 break;
00171 }
00172 case BaseMatrix::unAssembled: {
00173 UnAssembledMatrix& A = dynamic_cast<UnAssembledMatrix&>(*givenA);
00174 A.setBoundaryConditions(this);
00175 break;
00176 }
00177
00178 default: {
00179 throw ErrorHandler(__FILE__,__LINE__,
00180 "unexected matrix type",
00181 ErrorHandler::unexpected);
00182 }
00183 }
00184 }
00185
00186
00187 void BoundaryConditionDiscretizationSpectralNonConform::
00188 setSecondMember(ReferenceCounting<BaseMatrix> givenA,
00189 ReferenceCounting<BaseVector> givenb) const
00190 {
00191 ffout(2)<<"- assembling second membre-boundary\n";
00192 Vector<real_t>& b= (static_cast<Vector<real_t>&>(*givenb));
00193
00194 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *__bcMeshAssociation;
00195
00196 for (BoundaryConditionSurfaceMeshAssociation
00197 ::LinearBorderOperatorMeshAssociation
00198 ::const_iterator i = bcMeshAssociation.beginOfLinear();
00199 i != bcMeshAssociation.endOfLinear(); ++i) {
00200
00201 switch (i->first->type()) {
00202 case VariationalLinearBorderOperator::FV: {
00203 const VariationalBorderOperatorFV& operatorFV
00204 = dynamic_cast<const VariationalBorderOperatorFV&>(*i->first);
00205 const ScalarFunctionBase& f = operatorFV.f();
00206
00207 size_t testFunctionNumber = operatorFV.testFunctionNumber();
00208
00209 const ScalarDiscretizationTypeSpectral& discretization
00210 = dynamic_cast<const ScalarDiscretizationTypeSpectral&>(__discretizationType[testFunctionNumber]);
00211
00212 TinyVector<3, ConstReferenceCounting<Interval> > interval;
00213 TinyVector<3, ConstReferenceCounting<SpectralConformTransformation> > spectralTransform;
00214 TinyVector<3, ConstReferenceCounting<LegendreBasis> > basis;
00215
00216 for(size_t n=0; n<3; ++n){
00217 interval[n]= new Interval(discretization.a()[n],discretization.b()[n]);
00218 spectralTransform[n] = new SpectralConformTransformation(*interval[n]);
00219 basis[n]= new LegendreBasis(discretization.degrees()[n]);
00220 }
00221 const Mesh& boundaryMesh = (*i->second);
00222 switch(boundaryMesh.type()) {
00223 case Mesh::surfaceMeshTriangles: {
00224
00225 typedef QuadratureFormulaP1Triangle3D QuadratureType;
00226
00227 const QuadratureType& quadrature = QuadratureType::instance();
00228
00229 const TinyVector<QuadratureType::numberOfQuadraturePoints, TinyVector<3,real_t> >&
00230 nodesRef = quadrature.vertices() ;
00231
00232 for (SurfaceMeshOfTriangles::const_iterator itriangle(dynamic_cast<const SurfaceMeshOfTriangles&>(boundaryMesh));
00233 not(itriangle.end()); ++ itriangle) {
00234 const Triangle& T = *itriangle;
00235
00236 TinyVector<3,Vector<real_t> > baseValues;
00237 for(size_t j = 0; j < 3; j++){
00238 baseValues[j].resize(discretization.degrees()[j] + 1);
00239 }
00240 const TinyVector<3,size_t>& dofShapeV =__dofShape[operatorFV.testFunctionNumber()];
00241 ConformTransformationP1Triangle::ConformTransformationP1Triangle transform(T);
00242
00243 for (size_t q=0; q< QuadratureType::numberOfQuadraturePoints; ++q) {
00244
00245
00246 TinyVector<3,real_t> nodes;
00247
00248 transform.value(nodesRef[q],nodes);
00249 const real_t weight = quadrature.weight(q);
00250 const real_t xi= (spectralTransform[0])->inverse(nodes[0]);
00251 const real_t yi= (spectralTransform[1])->inverse(nodes[1]);
00252 const real_t zi= (spectralTransform[2])->inverse(nodes[2]);
00253
00254 (basis[0])->getValues(xi,baseValues[0]);
00255 (basis[1])->getValues(yi,baseValues[1]);
00256 (basis[2])->getValues(zi,baseValues[2]);
00257
00258 for (size_t m=0; m< basis[0]->dimension(); ++m){
00259 const real_t b_m =T.volume()* weight * f(nodes)* baseValues[0][m] ;
00260 for (size_t n=0; n< basis[1]->dimension(); ++n){
00261 const real_t b_mn = b_m * baseValues[1][n];
00262 for (size_t p=0; p< basis[2]->dimension(); ++p){
00263 size_t dofNumberV = m*dofShapeV[1]*dofShapeV[2] + n*dofShapeV[2] + p;
00264 b[__degreeOfFreedomSet(testFunctionNumber,dofNumberV)]
00265 += b_mn* baseValues[2][p];
00266 }
00267 }
00268 }
00269 }
00270 }
00271
00272 break;
00273 }
00274 case Mesh::surfaceMeshQuadrangles: {
00275 throw ErrorHandler(__FILE__,__LINE__,
00276 "non conforming boundary condition is not implemented in quadrangle meshes",
00277 ErrorHandler::normal);
00278 break;
00279 }
00280 default: {
00281 throw ErrorHandler(__FILE__,__LINE__,
00282 "not implemented",
00283 ErrorHandler::unexpected);
00284 }
00285 }
00286 break;
00287 }
00288 default: {
00289 throw ErrorHandler(__FILE__,__LINE__,
00290 "not implemented",
00291 ErrorHandler::unexpected);
00292 }
00293 }
00294 }
00295 }
00296
00297
00298 void BoundaryConditionDiscretizationSpectralNonConform::
00299 timesX(const BaseVector& X, BaseVector& Z) const
00300 {
00301 const Vector<real_t>& u = dynamic_cast<const Vector<real_t>&>(X);
00302 Vector<real_t>& v = dynamic_cast<Vector<real_t>&>(Z);
00303
00304 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *__bcMeshAssociation;
00305
00306 for (BoundaryConditionSurfaceMeshAssociation
00307 ::BilinearBorderOperatorMeshAssociation
00308 ::const_iterator i = bcMeshAssociation.beginOfBilinear();
00309 i != bcMeshAssociation.endOfBilinear(); ++i) {
00310
00311 switch (i->first->type()) {
00312 case VariationalBilinearBorderOperator::alphaUV: {
00313 const VariationalBorderOperatorAlphaUV& operatorAlphaUV
00314 = dynamic_cast<const VariationalBorderOperatorAlphaUV&>(*i->first);
00315 const ScalarFunctionBase& alpha = operatorAlphaUV.alpha();
00316
00317 size_t unknownNumber = operatorAlphaUV.unknownNumber();
00318 size_t testFunctionNumber = operatorAlphaUV.testFunctionNumber();
00319
00320 const ScalarDiscretizationTypeSpectral& discretization
00321 = dynamic_cast<const ScalarDiscretizationTypeSpectral&>(__discretizationType[unknownNumber]);
00322
00323 TinyVector<3, ConstReferenceCounting<Interval> > interval;
00324 TinyVector<3, ConstReferenceCounting<SpectralConformTransformation> > spectralTransform;
00325 TinyVector<3, ConstReferenceCounting<LegendreBasis> > basis;
00326
00327 for(size_t n=0;n<3;++n){
00328 interval[n]= new Interval(discretization.a()[n],discretization.b()[n]);
00329 spectralTransform[n] = new SpectralConformTransformation(*interval[n]);
00330 basis[n]= new LegendreBasis(discretization.degrees()[n]);
00331 }
00332
00333 const Mesh& boundaryMesh = (*i->second);
00334 switch(boundaryMesh.type()) {
00335 case Mesh::surfaceMeshTriangles: {
00336 typedef QuadratureFormulaP1Triangle3D QuadratureType;
00337
00338 const QuadratureType& quadrature = QuadratureType::instance();
00339 const TinyVector<QuadratureType::numberOfQuadraturePoints, TinyVector<3,real_t> >&
00340 nodesRef = quadrature.vertices() ;
00341
00342 for (SurfaceMeshOfTriangles::const_iterator itriangle(dynamic_cast<const SurfaceMeshOfTriangles&>(boundaryMesh));
00343 not(itriangle.end()); ++ itriangle) {
00344 const Triangle& T = * itriangle;
00345
00346 TinyVector<3,Vector<real_t> > baseValues;
00347 for(size_t j = 0; j < 3; j++){
00348 baseValues[j].resize(discretization.degrees()[j] + 1);
00349 }
00350
00351 ConformTransformationP1Triangle::ConformTransformationP1Triangle transform(T);
00352
00353 for (size_t q=0; q< QuadratureType::numberOfQuadraturePoints; ++q) {
00354
00355
00356
00357 TinyVector<3,real_t> nodes;
00358 transform.value(nodesRef[q],nodes);
00359 const real_t xi= (spectralTransform[0])->inverse(nodes[0]);
00360 const real_t yi= (spectralTransform[1])->inverse(nodes[1]);
00361 const real_t zi= (spectralTransform[2])->inverse(nodes[2]);
00362 (basis[0])->getValues(xi,baseValues[0]);
00363 (basis[1])->getValues(yi,baseValues[1]);
00364 (basis[2])->getValues(zi,baseValues[2]);
00365
00366 const real_t weight = quadrature.weight(q) ;
00367 const TinyVector<3,size_t>& dofShapeU = __dofShape[unknownNumber];
00368
00369 real_t u_q = 0;
00370
00371 for (size_t i=0; i< (basis[0])->dimension(); ++i){
00372 const real_t q1 = alpha(nodes)* weight * T.volume() * baseValues[0][i];
00373 for (size_t j=0; j<( basis[1])->dimension(); ++j){
00374 const real_t q2 = q1* baseValues[1][j];
00375 for (size_t k=0; k< (basis[2])->dimension(); ++k){
00376 const real_t q3 = baseValues[2][k] *q2;
00377 size_t dofNumberU = i*dofShapeU[1]*dofShapeU[2] + j*dofShapeU[2] + k;
00378 u_q += q3 * u[__degreeOfFreedomSet(unknownNumber,dofNumberU)];
00379 }
00380 }
00381 }
00382 const TinyVector<3,size_t>& dofShapeV = __dofShape[testFunctionNumber];
00383
00384 for (size_t m=0; m< basis[0]->dimension(); ++m){
00385 const real_t v_qm = u_q* baseValues[0][m];
00386 for (size_t n=0; n< basis[1]->dimension(); ++n){
00387 const real_t v_mn = v_qm * baseValues[1][n];
00388 for (size_t p=0; p< basis[2] ->dimension(); ++p){
00389 size_t dofNumberV = m*dofShapeV[1]*dofShapeV[2] + n*dofShapeV[2] + p;
00390 v[__degreeOfFreedomSet(testFunctionNumber,dofNumberV)]
00391 += baseValues[2][p]* v_mn;
00392 }
00393 }
00394 }
00395 }
00396 }
00397 break;
00398 }
00399 case Mesh::surfaceMeshQuadrangles: {
00400 throw ErrorHandler(__FILE__,__LINE__,
00401 "non conforming boundary condition is not implemented in quadrangle meshes",
00402 ErrorHandler::normal);
00403 break;
00404 }
00405 default: {
00406 throw ErrorHandler(__FILE__,__LINE__,
00407 "not implemented",
00408 ErrorHandler::unexpected);
00409 }
00410 }
00411
00412 break;
00413 }
00414 default: {
00415 throw ErrorHandler(__FILE__,__LINE__,
00416 "not implemented",
00417 ErrorHandler::unexpected);
00418 }
00419 }
00420 }
00421 }
00422
00423 void BoundaryConditionDiscretizationSpectralNonConform::
00424 transposedTimesX(const BaseVector& X, BaseVector& Z) const
00425 {
00426 const Vector<real_t>& u = dynamic_cast<const Vector<real_t>&>(X);
00427 Vector<real_t>& v = dynamic_cast<Vector<real_t>&>(Z);
00428
00429 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *__bcMeshAssociation;
00430
00431 for (BoundaryConditionSurfaceMeshAssociation
00432 ::BilinearBorderOperatorMeshAssociation
00433 ::const_iterator i = bcMeshAssociation.beginOfBilinear();
00434 i != bcMeshAssociation.endOfBilinear(); ++i) {
00435
00436 switch (i->first->type()) {
00437 case VariationalBilinearBorderOperator::alphaUV: {
00438 const VariationalBorderOperatorAlphaUV& operatorAlphaUV
00439 = dynamic_cast<const VariationalBorderOperatorAlphaUV&>(*i->first);
00440 if (operatorAlphaUV.unknownNumber() == operatorAlphaUV.testFunctionNumber()) {
00441
00442 const ScalarFunctionBase& alpha = operatorAlphaUV.alpha();
00443
00444 size_t unknownNumber = operatorAlphaUV.unknownNumber();
00445 size_t testFunctionNumber = operatorAlphaUV.testFunctionNumber();
00446
00447 const ScalarDiscretizationTypeSpectral& discretization
00448 = dynamic_cast<const ScalarDiscretizationTypeSpectral&>(__discretizationType[unknownNumber]);
00449
00450 TinyVector<3, ConstReferenceCounting<Interval> > interval;
00451 TinyVector<3, ConstReferenceCounting<SpectralConformTransformation> > spectralTransform;
00452 TinyVector<3, ConstReferenceCounting<LegendreBasis> > basis;
00453
00454 for(size_t n=0;n<3;++n){
00455 interval[n]= new Interval(discretization.a()[n],discretization.b()[n]);
00456 spectralTransform[n] = new SpectralConformTransformation(*interval[n]);
00457 basis[n]= new LegendreBasis(discretization.degrees()[n]);
00458 }
00459
00460 const Mesh& boundaryMesh = (*i->second);
00461 switch(boundaryMesh.type()) {
00462 case Mesh::surfaceMeshTriangles: {
00463 typedef QuadratureFormulaP1Triangle3D QuadratureType;
00464
00465 const QuadratureType& quadrature = QuadratureType::instance();
00466 const TinyVector<QuadratureType::numberOfQuadraturePoints, TinyVector<3,real_t> >&
00467 nodesRef = quadrature.vertices() ;
00468
00469 for (SurfaceMeshOfTriangles::const_iterator itriangle(dynamic_cast<const SurfaceMeshOfTriangles&>(boundaryMesh));
00470 not(itriangle.end()); ++ itriangle) {
00471 const Triangle& T = * itriangle;
00472 TinyVector<3,Vector<real_t> > baseValues;
00473 for(size_t j = 0; j < 3; j++){
00474 baseValues[j].resize(discretization.degrees()[j] + 1);
00475 }
00476
00477 ConformTransformationP1Triangle::ConformTransformationP1Triangle transform(T);
00478
00479 for (size_t q=0; q< QuadratureType::numberOfQuadraturePoints; ++q) {
00480
00481
00482
00483 TinyVector<3,real_t> nodes;
00484 transform.value(nodesRef[q],nodes);
00485 const real_t xi= (spectralTransform[0])->inverse(nodes[0]);
00486 const real_t yi= (spectralTransform[1])->inverse(nodes[1]);
00487 const real_t zi= (spectralTransform[2])->inverse(nodes[2]);
00488 (basis[0])->getValues(xi,baseValues[0]);
00489 (basis[1])->getValues(yi,baseValues[1]);
00490 (basis[2])->getValues(zi,baseValues[2]);
00491
00492 const real_t weight = quadrature.weight(q);
00493 const TinyVector<3,size_t>& dofShapeU = __dofShape[unknownNumber];
00494 real_t u_q =0;
00495
00496 for (size_t i=0; i<(basis[0])->dimension(); ++i){
00497 const real_t q1 =alpha(nodes)* weight * T.volume() * baseValues[0][i];
00498 for (size_t j=0; j<(basis[1])->dimension(); ++j){
00499 const real_t q2 = q1 * baseValues[1][j];
00500 for (size_t k=0; k<(basis[2])->dimension(); ++k){
00501 const real_t q3 = baseValues[2][k]* q2;
00502 size_t dofNumberU = i*dofShapeU[1]*dofShapeU[2] + j*dofShapeU[2] + k;
00503 u_q += q3*u[__degreeOfFreedomSet(testFunctionNumber,dofNumberU)];
00504
00505 }
00506 }
00507 }
00508 const TinyVector<3,size_t>& dofShapeV= __dofShape[testFunctionNumber];
00509
00510 for (size_t m=0; m<(basis[0])->dimension(); ++m){
00511 const real_t v_qm = u_q*baseValues[0][m];
00512 for (size_t n=0; n<(basis[1])->dimension(); ++n){
00513 const real_t v_mn = v_qm * baseValues[1][n];
00514 for (size_t p=0; p<(basis[2])->dimension(); ++p){
00515 size_t dofNumberV = m*dofShapeV[1]*dofShapeV[2] + n*dofShapeV[2] + p;
00516 v[__degreeOfFreedomSet(unknownNumber,dofNumberV)]
00517 += baseValues[2][p]* v_mn;
00518 }
00519 }
00520 }
00521 }
00522 }
00523 break;
00524 }
00525 case Mesh::surfaceMeshQuadrangles: {
00526 throw ErrorHandler(__FILE__,__LINE__,
00527 "non conforming boundary condition is not implemented in quadrangle meshes",
00528 ErrorHandler::normal);
00529 break;
00530 }
00531 default: {
00532 throw ErrorHandler(__FILE__,__LINE__,
00533 "not implemented",
00534 ErrorHandler::unexpected);
00535 }
00536 }
00537 }
00538 break;
00539 }
00540 default: {
00541 throw ErrorHandler(__FILE__,__LINE__,
00542 "not implemented",
00543 ErrorHandler::unexpected);
00544 }
00545 }
00546 }
00547 }
00548
00549
00550
00551
00552
00553