v0.16.0
Loading...
Searching...
No Matches
Classes | Functions | Variables
thermal_with_analytical_bc.cpp File Reference
#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>
#include <fstream>
#include <iostream>
#include <MoFEM.hpp>
#include <MethodForForceScaling.hpp>
#include <DirichletBC.hpp>
#include <BasicPostProc.hpp>
#include <ThermalElement.hpp>
#include <Projection10NodeCoordsOnField.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <AnalyticalDirichlet.hpp>

Go to the source code of this file.

Classes

struct  AnalyticalFunction
 

Functions

int main (int argc, char *argv[])
 

Variables

static int debug = 1
 
static char help [] = "...\n\n"
 

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 46 of file thermal_with_analytical_bc.cpp.

46 {
47
48 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
49
50 try {
51
52 moab::Core mb_instance;
53 moab::Interface &moab = mb_instance;
54 int rank;
55 MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
56
57 PetscBool flg = PETSC_TRUE;
58 char mesh_file_name[255];
59 CHKERR PetscOptionsGetString(PETSC_NULLPTR, PETSC_NULLPTR, "-my_file",
60 mesh_file_name, 255, &flg);
61 if (flg != PETSC_TRUE) {
62 SETERRQ(PETSC_COMM_SELF, 1, "*** ERROR -my_file (MESH FILE NEEDED)");
63 }
64
65 const char *option;
66 option = "";
67 CHKERR moab.load_file(mesh_file_name, 0, option);
68
69 // Create MoFEM (Joseph) database
70 MoFEM::Core core(moab);
71 MoFEM::Interface &m_field = core;
72
73 // set entitities bit level
74 BitRefLevel bit_level0;
75 bit_level0.set(0);
76 EntityHandle meshset_level0;
77 CHKERR moab.create_meshset(MESHSET_SET, meshset_level0);
78 CHKERR m_field.getInterface<BitRefManager>()->setBitRefLevelByDim(
79 0, 3, bit_level0);
80
81 // Fields
82 CHKERR m_field.add_field("TEMP", H1, AINSWORTH_LEGENDRE_BASE, 1);
83
84 // Problem
85 CHKERR m_field.add_problem("TEST_PROBLEM");
86 CHKERR m_field.add_problem("BC_PROBLEM");
87
88 // set refinement level for problem
89 CHKERR m_field.modify_problem_ref_level_add_bit("TEST_PROBLEM", bit_level0);
90 CHKERR m_field.modify_problem_ref_level_add_bit("BC_PROBLEM", bit_level0);
91
92 // meshset consisting all entities in mesh
93 EntityHandle root_set = moab.get_root_set();
94 CHKERR m_field.add_field("MESH_NODE_POSITIONS", H1, AINSWORTH_LEGENDRE_BASE,
95 3);
96 CHKERR m_field.add_ents_to_field_by_type(root_set, MBTET,
97 "MESH_NODE_POSITIONS");
98 CHKERR m_field.set_field_order(0, MBTET, "MESH_NODE_POSITIONS", 2);
99 CHKERR m_field.set_field_order(0, MBTRI, "MESH_NODE_POSITIONS", 2);
100 CHKERR m_field.set_field_order(0, MBEDGE, "MESH_NODE_POSITIONS", 2);
101 CHKERR m_field.set_field_order(0, MBVERTEX, "MESH_NODE_POSITIONS", 1);
102
103 // add entities to field
104 CHKERR m_field.add_ents_to_field_by_type(root_set, MBTET, "TEMP");
105
106 // set app. order
107 // see Hierarchic Finite Element Bases on Unstructured Tetrahedral Meshes
108 // (Mark Ainsworth & Joe Coyle)
109 PetscInt order;
110 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, PETSC_NULLPTR, "-my_order", &order,
111 &flg);
112 if (flg != PETSC_TRUE) {
113 order = 2;
114 }
115 CHKERR m_field.set_field_order(root_set, MBTET, "TEMP", order);
116 CHKERR m_field.set_field_order(root_set, MBTRI, "TEMP", order);
117 CHKERR m_field.set_field_order(root_set, MBEDGE, "TEMP", order);
118 CHKERR m_field.set_field_order(root_set, MBVERTEX, "TEMP", 1);
119
120 ThermalElement thermal_elements(m_field);
121 CHKERR thermal_elements.addThermalElements("TEMP");
122 CHKERR m_field.modify_problem_add_finite_element("TEST_PROBLEM",
123 "THERMAL_FE");
124
125 Range bc_tris;
126 for (_IT_CUBITMESHSETS_BY_NAME_FOR_LOOP_(m_field, "ANALYTICAL_BC", it)) {
127 CHKERR moab.get_entities_by_type(it->getMeshset(), MBTRI, bc_tris, true);
128 }
129
130 AnalyticalDirichletBC analytical_bc(m_field);
131 CHKERR analytical_bc.setFiniteElement(m_field, "BC_FE", "TEMP", bc_tris);
132 CHKERR m_field.modify_problem_add_finite_element("BC_PROBLEM", "BC_FE");
133
134 /****/
135 // build database
136 // build field
137 CHKERR m_field.build_fields();
138 // build finite elemnts
140 // build adjacencies
141 CHKERR m_field.build_adjacencies(bit_level0);
142 // build problem
143 ProblemsManager *prb_mng_ptr;
144 CHKERR m_field.getInterface(prb_mng_ptr);
145 CHKERR prb_mng_ptr->buildProblem("TEST_PROBLEM", true);
146 CHKERR prb_mng_ptr->buildProblem("BC_PROBLEM", true);
147
148 Projection10NodeCoordsOnField ent_method_material(m_field,
149 "MESH_NODE_POSITIONS");
150 CHKERR m_field.loop_dofs("MESH_NODE_POSITIONS", ent_method_material);
151
152 /****/
153 // mesh partitioning
154 // partition
155 CHKERR prb_mng_ptr->partitionSimpleProblem("TEST_PROBLEM");
156 CHKERR prb_mng_ptr->partitionFiniteElements("TEST_PROBLEM");
157 // what are ghost nodes, see Petsc Manual
158 CHKERR prb_mng_ptr->partitionGhostDofs("TEST_PROBLEM");
159
160 CHKERR prb_mng_ptr->partitionSimpleProblem("BC_PROBLEM");
161 CHKERR prb_mng_ptr->partitionFiniteElements("BC_PROBLEM");
162 // what are ghost nodes, see Petsc Manual
163 CHKERR prb_mng_ptr->partitionGhostDofs("BC_PROBLEM");
164
165 Vec F;
166 CHKERR m_field.getInterface<VecManager>()->vecCreateGhost("TEST_PROBLEM",
167 ROW, &F);
168 Vec T;
169 CHKERR VecDuplicate(F, &T);
170 Mat A;
172 ->createMPIAIJWithArrays<PetscGlobalIdx_mi_tag>("TEST_PROBLEM", &A);
173
175 thermal_elements.getLoopFeRhs().getOpPtrVector(), {H1},
176 "MESH_NODE_POSITIONS");
178 thermal_elements.getLoopFeLhs().getOpPtrVector(), {H1},
179 "MESH_NODE_POSITIONS");
180
181 CHKERR thermal_elements.setThermalFiniteElementRhsOperators("TEMP", F);
182 CHKERR thermal_elements.setThermalFiniteElementLhsOperators("TEMP", A);
183 CHKERR thermal_elements.setThermalFluxFiniteElementRhsOperators("TEMP", F);
184
185 CHKERR VecZeroEntries(T);
186 CHKERR VecZeroEntries(F);
187 CHKERR MatZeroEntries(A);
188
189 // analytical Dirichlet bc
190 AnalyticalDirichletBC::DirichletBC analytical_dirichlet_bc(m_field, "TEMP",
191 A, T, F);
192
193 // solve for dirichlet bc dofs
194 CHKERR analytical_bc.setUpProblem(m_field, "BC_PROBLEM");
195
196 boost::shared_ptr<AnalyticalFunction> testing_function =
197 boost::shared_ptr<AnalyticalFunction>(new AnalyticalFunction);
198
199 CHKERR analytical_bc.setApproxOps(m_field, "TEMP", testing_function, 0);
200 CHKERR analytical_bc.solveProblem(m_field, "BC_PROBLEM", "BC_FE",
201 analytical_dirichlet_bc);
202
203 CHKERR analytical_bc.destroyProblem();
204
205 // preproc
206 CHKERR m_field.problem_basic_method_preProcess("TEST_PROBLEM",
207 analytical_dirichlet_bc);
208
209 CHKERR m_field.loop_finite_elements("TEST_PROBLEM", "THERMAL_FE",
210 thermal_elements.getLoopFeRhs());
211 CHKERR m_field.loop_finite_elements("TEST_PROBLEM", "THERMAL_FE",
212 thermal_elements.getLoopFeLhs());
213 if (m_field.check_finite_element("THERMAL_FLUX_FE"))
214 CHKERR m_field.loop_finite_elements("TEST_PROBLEM", "THERMAL_FLUX_FE",
215 thermal_elements.getLoopFeFlux());
216
217 // postproc
218 CHKERR m_field.problem_basic_method_postProcess("TEST_PROBLEM",
219 analytical_dirichlet_bc);
220
221 CHKERR VecGhostUpdateBegin(F, ADD_VALUES, SCATTER_REVERSE);
222 CHKERR VecGhostUpdateEnd(F, ADD_VALUES, SCATTER_REVERSE);
223 CHKERR VecAssemblyBegin(F);
224 CHKERR VecAssemblyEnd(F);
225 CHKERR MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
226 CHKERR MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
227
228 CHKERR VecScale(F, -1);
229 // std::string wait;
230 // std::cout << "\n matrix is coming = \n" << std::endl;
231 // CHKERR MatView(A,PETSC_VIEWER_DRAW_WORLD);
232 // std::cin >> wait;
233
234 // Solver
235 KSP solver;
236 CHKERR KSPCreate(PETSC_COMM_WORLD, &solver);
237 CHKERR KSPSetOperators(solver, A, A);
238 CHKERR KSPSetFromOptions(solver);
239 CHKERR KSPSetUp(solver);
240
241 CHKERR KSPSolve(solver, F, T);
242 CHKERR VecGhostUpdateBegin(T, INSERT_VALUES, SCATTER_FORWARD);
243 CHKERR VecGhostUpdateEnd(T, INSERT_VALUES, SCATTER_FORWARD);
244
245 // Save data on mesh
246 // CHKERR
247 // m_field.problem_basic_method_preProcess("TEST_PROBLEM",analytical_dirichlet_bc);
248 CHKERR m_field.getInterface<VecManager>()->setGlobalGhostVector(
249 "TEST_PROBLEM", ROW, T, ADD_VALUES, SCATTER_REVERSE);
250 CHKERR m_field.getInterface<VecManager>()->setLocalGhostVector(
251 "TEST_PROBLEM", ROW, T, INSERT_VALUES, SCATTER_FORWARD);
252
253 // CHKERR VecView(F,PETSC_VIEWER_STDOUT_WORLD);
254
255 // CHKERR VecView(T,PETSC_VIEWER_STDOUT_WORLD);
256
257 PetscReal pointwisenorm;
258 CHKERR VecMax(T, NULL, &pointwisenorm);
259 std::cout << "\n The Global Pointwise Norm of error for this problem is : "
260 << pointwisenorm << std::endl;
261
262 // PetscViewer viewer;
263 // PetscViewerASCIIOpen(PETSC_COMM_WORLD,"thermal_with_analytical_bc.txt",&viewer);
264 // CHKERR VecChop(T,1e-4);
265 // CHKERR VecView(T,viewer);
266 // CHKERR PetscViewerDestroy(&viewer);
267
268 double sum = 0;
269 CHKERR VecSum(T, &sum);
270 CHKERR PetscPrintf(PETSC_COMM_WORLD, "sum = %9.8e\n", sum);
271 double fnorm;
272 CHKERR VecNorm(T, NORM_2, &fnorm);
273 CHKERR PetscPrintf(PETSC_COMM_WORLD, "fnorm = %9.8e\n", fnorm);
274 if (fabs(sum + 6.46325818e-01) > 1e-7) {
275 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID, "Failed to pass test");
276 }
277 if (fabs(fnorm - 4.26078597e+00) > 1e-6) {
278 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID, "Failed to pass test");
279 }
280
281 if (debug) {
282
284 m_field);
285 CHKERR AddHOOps<3, 3, 3>::add(post_proc.getOpPtrVector(), {H1},
286 "MESH_NODE_POSITIONS");
287 auto temp_ptr = boost::make_shared<VectorDouble>();
288 auto temp_grad_ptr = boost::make_shared<MatrixDouble>();
289 auto mesh_pos_ptr = boost::make_shared<MatrixDouble>();
290 post_proc.getOpPtrVector().push_back(
291 new OpCalculateScalarFieldValues("TEMP", temp_ptr));
292 post_proc.getOpPtrVector().push_back(
293 new OpCalculateVectorFieldValues<3>("MESH_NODE_POSITIONS",
294 mesh_pos_ptr));
295 post_proc.getOpPtrVector().push_back(
296 new OpCalculateScalarFieldGradient<3>("TEMP", temp_grad_ptr));
298 post_proc.getOpPtrVector().push_back(new OpPPMap(
299 post_proc.getPostProcMesh(), post_proc.getMapGaussPts(),
300 {{"TEMP", temp_ptr}},
301 {{"MESH_NODE_POSITIONS", mesh_pos_ptr},
302 {"TEMP_GRAD", temp_grad_ptr}},
303 {}, {}));
304 CHKERR m_field.loop_finite_elements("TEST_PROBLEM", "THERMAL_FE",
305 post_proc);
306 CHKERR post_proc.writeFile("out.h5m");
307 }
308
309 CHKERR MatDestroy(&A);
310 CHKERR VecDestroy(&F);
311 CHKERR VecDestroy(&T);
312 CHKERR KSPDestroy(&solver);
313 }
315
317
318 return 0;
319}
@ ROW
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ H1
continuous field
Definition definitions.h:85
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define CHKERR
Inline error check.
constexpr int order
@ F
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
virtual MoFEMErrorCode problem_basic_method_postProcess(const Problem *problem_ptr, BasicMethod &method, int verb=DEFAULT_VERBOSITY)=0
Set data for BasicMethod.
virtual MoFEMErrorCode loop_finite_elements(const std::string problem_name, const std::string &fe_name, FEMethod &method, boost::shared_ptr< NumeredEntFiniteElement_multiIndex > fe_ptr=nullptr, MoFEMTypes bh=MF_EXIST, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr(), int verb=DEFAULT_VERBOSITY)=0
Make a loop over finite elements.
#define _IT_CUBITMESHSETS_BY_NAME_FOR_LOOP_(MESHSET_MANAGER, NAME, IT)
Iterator that loops over Cubit BlockSet having a particular name.
MoFEMErrorCode partitionGhostDofs(const std::string name, int verb=VERBOSE)
determine ghost nodes
MoFEMErrorCode partitionSimpleProblem(const std::string name, int verb=VERBOSE)
partition problem dofs
MoFEMErrorCode buildProblem(const std::string name, const bool square_matrix, int verb=VERBOSE)
build problem data structures
MoFEMErrorCode partitionFiniteElements(const std::string name, bool part_from_moab=false, int low_proc=-1, int hi_proc=-1, int verb=VERBOSE)
partition finite elements
virtual MoFEMErrorCode add_problem(const std::string &name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add problem.
virtual MoFEMErrorCode modify_problem_ref_level_add_bit(const std::string &name_problem, const BitRefLevel &bit)=0
add ref level to problem
virtual MoFEMErrorCode modify_problem_add_finite_element(const std::string name_problem, const std::string &fe_name)=0
add finite element to problem, this add entities assigned to finite element to a particular problem
const FTensor::Tensor2< T, Dim, Dim > Vec
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
static const bool debug
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
constexpr AssemblyType A
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Structure used to enforce analytical boundary conditions.
Analytical Dirichlet boundary conditions.
Add operators pushing bases from local to physical configuration.
Managing BitRefLevels.
virtual bool check_finite_element(const std::string &name) const =0
Check if finite element is in database.
virtual MoFEMErrorCode problem_basic_method_preProcess(const Problem *problem_ptr, BasicMethod &method, int verb=DEFAULT_VERBOSITY)=0
Set data for BasicMethod.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
Core (interface) class.
Definition Core.hpp:83
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:68
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:123
Deprecated interface functions.
Matrix manager is used to build and partition problems.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision scalar field values calculation.
Specialization for MatrixDouble vector field values calculation.
Post post-proc data at points from hash maps.
Problem manager is used to build and partition problems.
Projection of edge entities with one mid-node on hierarchical basis.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.
structure grouping operators and data used for thermal problems
static char help[]

Variable Documentation

◆ debug

int debug = 1
static

Definition at line 31 of file thermal_with_analytical_bc.cpp.

◆ help

char help[] = "...\n\n"
static

Definition at line 32 of file thermal_with_analytical_bc.cpp.