/* $Id: problem2.cc,v 1.4 1996/11/20 10:01:26 roitzsch Exp $ (C)opyright 1996 by Konrad-Zuse-Center, Berlin All rights reserved. Part of the Kaskade distribution */ #include "problem2.h" #include "physics.h" #include "triang2tr.h" #include "elements2.h" #include "elements2mc.h" #include "intB.h" #include "adaptnl.h" #include "dirichletA.h" #include "materialsA.h" #include "linsystem.h" #include "precond.h" //#include "structure.h" //#include "boxes.h" #include "cmdpars.h" extern CmdPars Cmd; extern Problem* createProblem2(char* inFile, int /*spaceDim*/); //------------------------------------------------------------------------- Problem* createProblem2(char* inFile, int /*spaceDim*/) { Problem* problem = 0; if (Cmd.isSet("Problem", "StaticHeatConduction")) problem = new StaticHeatConduction2(inFile); if (Cmd.isSet("Problem", "QuadStaticHeatConduction")) problem = new QuadStaticHeatConduction2(inFile); else if (Cmd.isSet("Problem", "SkinEquation")) problem = new SkinEquation(inFile); else if (Cmd.isSet("Problem", "TransientHeatConduction")) problem = new TransientHeatConduction2(inFile); else if (Cmd.isSet("Problem", "Obstacle")) problem = new StaticNonLinearProblem2(inFile); else if (Cmd.isSet("Problem", "Stefan") || Cmd.isSet("Problem", "Casting") || Cmd.isSet("Problem", "PorousMedia")) problem = new TransientNonLinearProblem2(inFile); else if (Cmd.isSet("Problem", "MCStaticHeat")) problem = new MCStaticHeatConduction2(inFile); else if (Cmd.isSet("Problem", "MCTransientHeatConduction")) problem = new MCTransientHeatConduction2(inFile); return problem; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- StaticHeatConduction2:: StaticHeatConduction2(char* inFile) : Problem(inFile,sym,2), StaticHeatConduction(), mesh(0) { dirichletBCs = newDirichletBCs(); newMaterial(); element = new Triangle(material); } //------------------------------------------------------------------------- StaticHeatConduction2:: StaticHeatConduction2() : mesh(0) { } //------------------------------------------------------------------------- StaticHeatConduction2:: ~StaticHeatConduction2() { if (mesh) { mesh->Info(); delete mesh; } } //------------------------------------------------------------------------- MESH* StaticHeatConduction2:: Mesh() const { return mesh; } //------------------------------------------------------------------------- void StaticHeatConduction2:: newMesh() { delete mesh; if (biSection) mesh = new MESH2BISECT(fileName); else mesh = new MESH2(fileName); } //------------------------------------------------------------------------- void StaticHeatConduction2:: newInterface() { delete interface; if (mesh == 0) missingObject("newInterface","mesh"); if (element == 0) missingObject("newInterface","element"); if (Ab == 0) missingObject("newInterface","Ab"); if (precond == 0) missingObject("newInterface","precond"); if (dirichletBCs == 0) missingObject("newInterface","dirichletBCs"); switch(precond->mode()) { case singleGrid: interface = new LinElemSG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiGrid: interface = new LinElemMG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiLevel: interface = new LinElemML(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; } } //------------------------------------------------------------------------- void StaticHeatConduction2:: newErrorEstimator() { delete errorEstimator; if (Cmd.isSet("errorEstimator","none")) errorEstimator = new ErrorEstimator(); else if (Cmd.isSet("errorEstimator","dly") || Cmd.isSet("errorEstimator","moddly")) { Element* elementDLY; if (Cmd.isSet("errorEstimator","dly")) elementDLY = new HQuadTriangle(material); else elementDLY = new HQuadTriangleFast(material); Interface* interfaceDLY = new HQuadElemSG(mesh, elementDLY, dirichletBCs, Ab, precond, spaceDim,nComp); errorEstimator = new DLY(elementDLY, interfaceDLY); } else { cout << "\n*** Problem:: no valid error estimator specified\n"; cout.flush(); abort(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QuadStaticHeatConduction2:: QuadStaticHeatConduction2(char* inFile) : Problem(inFile,sym,2), StaticHeatConduction2() { dirichletBCs = newDirichletBCs(); newMaterial(); element = new LQuadTriangle(material); } //------------------------------------------------------------------------- void QuadStaticHeatConduction2:: newInterface() { delete interface; if (mesh == 0) missingObject("newInterface","mesh"); if (element == 0) missingObject("newInterface","element"); if (Ab == 0) missingObject("newInterface","Ab"); if (precond == 0) missingObject("newInterface","precond"); if (dirichletBCs == 0) missingObject("newInterface","dirichletBCs"); switch(precond->mode()) { case singleGrid: interface = new LQuadElemSG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; default: cout << "\n*** LQuadStaticHeatConduction2: only SG Precond.!\n"; cout.flush(); abort(); } } //------------------------------------------------------------------------- void QuadStaticHeatConduction2:: newErrorEstimator() { delete errorEstimator; //if (Cmd.isSet("errorEstimator","none")) errorEstimator = new ErrorEstimator(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- SkinEquation:: SkinEquation(char* inFile) : Problem(inFile,sym,2), mesh(0) { if(!Cmd.get("frequency", &omega)) { cout << "\n*** SkinEquation: no frequency given\n"; cout.flush(); abort(); } omega *= 2.*Pi; dirichletBCs = newDirichletBCs(); newMaterial(); element = new Triangle(material); } //------------------------------------------------------------------------- SkinEquation:: ~SkinEquation() { if (mesh) { mesh->Info(); delete mesh; } } //------------------------------------------------------------------------- void SkinEquation:: newMaterial() { delete material; material = new DefaultMaterial(fileName, spaceDim); } //------------------------------------------------------------------------- DirichletBCs* SkinEquation:: newDirichletBCs() { return new ConstDirichletBCs(fileName); } //------------------------------------------------------------------------- MESH* SkinEquation:: Mesh() const { return mesh; } //------------------------------------------------------------------------- void SkinEquation:: newMesh() { delete mesh; mesh = new MESH2(fileName); //int nSteps = 0; Cmd.get("stepsResolve",&nSteps); //if (nSteps > 0) mesh->Resolve(0.0, nSteps); } //------------------------------------------------------------------------- void SkinEquation:: newInterface() { delete interface; if (mesh == 0) missingObject("newInterface","mesh"); if (element == 0) missingObject("newInterface","element"); if (Ab == 0) missingObject("newInterface","Ab"); if (precond == 0) missingObject("newInterface","precond"); if (dirichletBCs == 0) missingObject("newInterface","dirichletBCs"); switch(precond->mode()) { case singleGrid: interface = new LinElemSG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiGrid: interface = new LinElemMG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiLevel: interface = new LinElemML(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; } } //------------------------------------------------------------------------- void SkinEquation:: newErrorEstimator() { delete errorEstimator; if (Cmd.isSet("errorEstimator","none")) errorEstimator = new ErrorEstimator(); else if (Cmd.isSet("errorEstimator","dly") || Cmd.isSet("errorEstimator","moddly") ) { Element* elementDLY; if (Cmd.isSet("errorEstimator","dly")) elementDLY = new HQuadTriangle(material); else elementDLY = new HQuadTriangleFast(material); Interface* interfaceDLY = new HQuadElemSG(mesh, elementDLY, dirichletBCs, Ab, precond, spaceDim,nComp); errorEstimator = new DLY(elementDLY, interfaceDLY); } else { cout << "\n*** Problem:: no valid error estimator specified\n"; cout.flush(); abort(); } } //------------------------------------------------------------------------- void SkinEquation:: assemble(const Element& elem, const PATCH& t, const Jacobian& Jac, Matrix& A, Vector& b, const Matrix* pattern, Bool /*errorEstimatorCall*/) { int i, k; int dim = elem.NoOfNodes(); Matrix AReal(dim, dim); Vector bReal(dim); elem.initAb(AReal,bReal); if (!elem.assembleEllip(t, AReal, Jac, pattern)) missingMaterialTerm("elliptic", t.Class()); for (i=1; i<=dim; ++i) for (k=1; k<=i; ++k) A(i,k) += num(AReal(i,k),0.0); if (elem.assembleSource(t, bReal, Jac, pattern)) FORALL(b,i) b[i] = num(bReal[i],0.0); elem.initAb(AReal); if (elem.assembleMass(t, AReal, Jac, pattern)) // conductor element { FORALL_ROWS(A,i) for (k=1; k<=i; ++k) A(i,k) += num(0.0, -omega*AReal(i,k)); } } //------------------------------------------------------------------------- void SkinEquation:: compEnergy(Vector& v, Real* eNorm, Num* fct) { Ab->compEnergy(v, eNorm, fct); } //------------------------------------------------------------------------- TransientHeatConduction2:: TransientHeatConduction2(char* inFile) : Problem(inFile,sym,2), TransientHeatConduction(), mesh(0), prevMesh(0) { dirichletBCs = newDirichletBCs(); newMaterial(); element = new Triangle(material); } //------------------------------------------------------------------------- TransientHeatConduction2:: ~TransientHeatConduction2() { if (mesh) { mesh->Info(); delete mesh; } delete prevMesh; } //------------------------------------------------------------------------- MESH* TransientHeatConduction2:: Mesh() const { return mesh; } MESH* TransientHeatConduction2:: PrevMesh() const { return prevMesh; } //------------------------------------------------------------------------- void TransientHeatConduction2:: newMesh() { delete mesh; mesh = new MESH2Trans(fileName,prevMesh); } //------------------------------------------------------------------------- void TransientHeatConduction2:: shiftMesh() { delete prevMesh; prevMesh = mesh; mesh = 0; } //------------------------------------------------------------------------- void TransientHeatConduction2:: newInterface() { delete interface; if (mesh == 0) missingObject("newInterface","mesh"); if (element == 0) missingObject("newInterface","element"); if (Ab == 0) missingObject("newInterface","Ab"); if (precond == 0) missingObject("newInterface","precond"); if (dirichletBCs == 0) missingObject("newInterface","dirichletBCs"); switch(precond->mode()) { case singleGrid: interface = new LinElemSG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiGrid: interface = new LinElemMG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiLevel: interface = new LinElemML(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; } } //------------------------------------------------------------------------- void TransientHeatConduction2:: newErrorEstimator() { delete errorEstimator; if (Cmd.isSet("errorEstimator","none")) errorEstimator = new ErrorEstimator(); else if (Cmd.isSet("errorEstimator","dly") || Cmd.isSet("errorEstimator","moddly")) { Element* elementDLY; if (Cmd.isSet("errorEstimator","dly")) elementDLY = new HQuadTriangle(material); else elementDLY = new HQuadTriangleFast(material); Interface* interfaceDLY = new HQuadElemSG(mesh, elementDLY, dirichletBCs, Ab, precond, spaceDim,nComp); errorEstimator = new DLY(elementDLY, interfaceDLY); } else { cout << "\n*** Problem:: no valid error estimator specified\n"; cout.flush(); abort(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- StaticNonLinearProblem2:: StaticNonLinearProblem2(char* inFile) : Problem(inFile,sym,2), StaticNonLinearProblem(), mesh(0) { dirichletBCs = newDirichletBCs(); newMaterial(); element = new Triangle(material); } //------------------------------------------------------------------------- StaticNonLinearProblem2:: ~StaticNonLinearProblem2() { if (mesh) { mesh->Info(); delete mesh; } } //------------------------------------------------------------------------- MESH* StaticNonLinearProblem2:: Mesh() const { return mesh; } //------------------------------------------------------------------------- void StaticNonLinearProblem2:: newMesh() { delete mesh; if (biSection) mesh = new MESH2BISECT(fileName); else mesh = new MESH2(fileName); } //------------------------------------------------------------------------- void StaticNonLinearProblem2:: newInterface() { delete interface; if (mesh == 0) missingObject("newInterface","mesh"); if (element == 0) missingObject("newInterface","element"); if (Ab == 0) missingObject("newInterface","Ab"); if (precond == 0) missingObject("newInterface","precond"); if (dirichletBCs == 0) missingObject("newInterface","dirichletBCs"); switch(precond->mode()) { case singleGrid: interface = new LinElemSG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiGrid: interface = new LinElemMG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiLevel: interface = new LinElemML(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; } } //------------------------------------------------------------------------- void StaticNonLinearProblem2:: newErrorEstimator() { delete errorEstimator; if (Cmd.isSet("errorEstimator","none")) errorEstimator = new ErrorEstimator(); else if (Cmd.isSet("errorEstimator","rk1")) { Element* elementDLY, *elementDLYLagrange; elementDLY = new HQuadTriangle(material); elementDLYLagrange = new LQuadTriangle(material); Interface* interfaceDLY = new HQuadElemSG(mesh, elementDLY, dirichletBCs, Ab, precond, spaceDim,nComp); errorEstimator = new RK1(elementDLY, elementDLYLagrange, interfaceDLY); } else if (Cmd.isSet("errorEstim","rk")) { Element* elementDLY, *elementDLYLagrange; elementDLY = 0; elementDLYLagrange = new LQuadTriangle(material); dirichletBCsDLY = newDirichletBCs(); Interface* interfaceDLY = new LQuadElemSG(mesh, elementDLYLagrange, dirichletBCsDLY, Ab, precond, spaceDim,nComp); if (Cmd.isSet("errorEstimator","rkA")) errorEstimator = new RKA(elementDLY, elementDLYLagrange, interfaceDLY); else if (Cmd.isSet("errorEstimator","rk2")) errorEstimator = new RK2(elementDLY, elementDLYLagrange, interfaceDLY); } else { cout << "\n*** Problem:: no valid error estimator specified\n"; cout.flush(); abort(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- TransientNonLinearProblem2:: TransientNonLinearProblem2(char* inFile) : Problem(inFile,sym,2), TransientNonLinearProblem(), mesh(0), prevMesh(0) { dirichletBCs = newDirichletBCs(); newMaterial(); element = new Triangle(material); } //------------------------------------------------------------------------- TransientNonLinearProblem2:: ~TransientNonLinearProblem2() { if (mesh) { mesh->Info(); delete mesh; } delete prevMesh; } //------------------------------------------------------------------------- MESH* TransientNonLinearProblem2:: Mesh() const { return mesh; } MESH* TransientNonLinearProblem2:: PrevMesh() const { return prevMesh; } //------------------------------------------------------------------------- void TransientNonLinearProblem2:: newMesh() { delete mesh; mesh = new MESH2Trans(fileName,prevMesh); } //------------------------------------------------------------------------- void TransientNonLinearProblem2:: shiftMesh() { delete prevMesh; prevMesh = mesh; mesh = 0; } //------------------------------------------------------------------------- void TransientNonLinearProblem2:: newInterface() { delete interface; if (mesh == 0) missingObject("newInterface","mesh"); if (element == 0) missingObject("newInterface","element"); if (Ab == 0) missingObject("newInterface","Ab"); if (precond == 0) missingObject("newInterface","precond"); if (dirichletBCs == 0) missingObject("newInterface","dirichletBCs"); switch(precond->mode()) { case singleGrid: interface = new LinElemSG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiGrid: interface = new LinElemMG(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; case multiLevel: interface = new LinElemML(mesh,element,dirichletBCs, Ab,precond, spaceDim,nComp); break; } } //------------------------------------------------------------------------- void TransientNonLinearProblem2:: newErrorEstimator() { delete errorEstimator; if (Cmd.isSet("errorEstimator","none")) errorEstimator = new ErrorEstimator(); else if (Cmd.isSet("errorEstimator","rk1")) { Element* elementDLY, *elementDLYLagrange; elementDLY = new HQuadTriangle(material); elementDLYLagrange = new LQuadTriangle(material); Interface* interfaceDLY = new HQuadElemSG(mesh, elementDLY, dirichletBCs, Ab, precond, spaceDim,nComp); errorEstimator = new RK1(elementDLY, elementDLYLagrange, interfaceDLY); } else if (Cmd.isSet("errorEstim","rk")) { Element* elementDLY, *elementDLYLagrange; elementDLY = 0; elementDLYLagrange = new LQuadTriangle(material); dirichletBCsDLY = newDirichletBCs(); Interface* interfaceDLY = new LQuadElemSG(mesh, elementDLYLagrange, dirichletBCsDLY, Ab, precond, spaceDim, nComp); if (Cmd.isSet("errorEstimator","rkA")) errorEstimator = new RKA(elementDLY, elementDLYLagrange, interfaceDLY); else if (Cmd.isSet("errorEstimator","rk2")) errorEstimator = new RK2(elementDLY, elementDLYLagrange, interfaceDLY); } else { cout << "\n*** Problem:: no valid error estimator specified\n"; cout.flush(); abort(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- // -- test example for multi-component field: nComp = 3 MCStaticHeatConduction2:: MCStaticHeatConduction2(char* inFile) : Problem(inFile,sym,2,3), StaticHeatConduction2() { dirichletBCs = newDirichletBCs(); newMaterial(); element = new MCTriangle(material, nComp); } //------------------------------------------------------------------------- void MCStaticHeatConduction2:: newInterface() { delete interface; if (mesh == 0) missingObject("newInterface","mesh"); if (element == 0) missingObject("newInterface","element"); if (Ab == 0) missingObject("newInterface","Ab"); if (precond == 0) missingObject("newInterface","precond"); if (dirichletBCs == 0) missingObject("newInterface","dirichletBCs"); switch(precond->mode()) { case singleGrid: interface = new LinElemSG(mesh, element, dirichletBCs, Ab, precond, spaceDim, nComp); break; case multiLevel: interface = new LinElemML(mesh, element, dirichletBCs, Ab, precond, spaceDim, nComp); break; default: cout << "\n*** MCStaticHeatConduction2:: interface not available\n"; cout.flush(); abort(); break; } } //------------------------------------------------------------------------- void MCStaticHeatConduction2:: newErrorEstimator() { delete errorEstimator; if (Cmd.isSet("errorEstimator","none")) errorEstimator = new ErrorEstimator(); else { if (Cmd.isSet("errorEstimator","dly")) { Element* elementDLY = new HQuadMCTriangle(material,nComp); Interface* interfaceDLY = new HQuadElemSG(mesh,elementDLY, dirichletBCs,Ab,precond, spaceDim,nComp); errorEstimator = new DLY(elementDLY, interfaceDLY); } else { cout << "\n*** Problem:: no valid error estimator specified\n"; cout.flush(); abort(); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- // -- test example for multi-component field: nComp = 3 MCTransientHeatConduction2:: MCTransientHeatConduction2(char* inFile) : Problem(inFile,sym,2,3), TransientHeatConduction2() { dirichletBCs = newDirichletBCs(); newMaterial(); element = new MCTriangle(material, nComp); } //------------------------------------------------------------------------- void MCTransientHeatConduction2:: newInterface() { delete interface; if (mesh == 0) missingObject("newInterface","mesh"); if (element == 0) missingObject("newInterface","element"); if (Ab == 0) missingObject("newInterface","Ab"); if (precond == 0) missingObject("newInterface","precond"); if (dirichletBCs == 0) missingObject("newInterface","dirichletBCs"); switch(precond->mode()) { case singleGrid: interface = new LinElemSG(mesh,element,dirichletBCs,Ab,precond, spaceDim,nComp); break; case multiLevel: interface = new LinElemML(mesh,element,dirichletBCs,Ab,precond, spaceDim,nComp); break; default: cout << "\n*** Interface not available\n"; cout.flush(); abort(); break; } } //------------------------------------------------------------------------- void MCTransientHeatConduction2:: newErrorEstimator() { delete errorEstimator; if (Cmd.isSet("errorEstimator","none")) errorEstimator = new ErrorEstimator(); else { if (Cmd.isSet("errorEstimator","dly")) { Element* elementDLY = new HQuadMCTriangle(material,nComp); Interface* interfaceDLY = new HQuadElemSG(mesh,elementDLY, dirichletBCs,Ab,precond, spaceDim,nComp); errorEstimator = new DLY(elementDLY, interfaceDLY); } else { cout << "\n*** Problem:: no valid error estimator specified\n"; cout.flush(); abort(); } } }