125125139SJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors. 225125139SJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause 325125139SJames Wright #include "../qfunctions/monitor_totalkineticenergy.h" 4a5677b81SMohi #include <honee.h> 525125139SJames Wright #include <navierstokes.h> 625125139SJames Wright #include <time.h> 725125139SJames Wright 825125139SJames Wright typedef struct { 925125139SJames Wright OperatorApplyContext op_monitor_ctx; 1025125139SJames Wright Vec values; 1125125139SJames Wright PetscScalar *sum_values; 1225125139SJames Wright PetscScalar volume; 1325125139SJames Wright PetscInt num_comps; 142a51b432SJames Wright PetscInt tab_level; 1525125139SJames Wright PetscBool is_header_written; 16600dae7dSJames Wright } *MonitorTotalKE; 1725125139SJames Wright 185206a5a0SJames Wright static PetscErrorCode MonitorTotalKEDestroy(MonitorTotalKE *monitor_ctx) { 195206a5a0SJames Wright MonitorTotalKE monitor_ctx_ = *monitor_ctx; 2025125139SJames Wright 2125125139SJames Wright PetscFunctionBeginUser; 225206a5a0SJames Wright PetscCall(OperatorApplyContextDestroy(monitor_ctx_->op_monitor_ctx)); 235206a5a0SJames Wright PetscCall(VecDestroy(&monitor_ctx_->values)); 245206a5a0SJames Wright PetscCall(PetscFree(monitor_ctx_->sum_values)); 255206a5a0SJames Wright PetscCall(PetscFree(monitor_ctx_)); 2625125139SJames Wright PetscFunctionReturn(PETSC_SUCCESS); 2725125139SJames Wright } 2825125139SJames Wright 2925125139SJames Wright /** @brief Create CeedElemRestriction for collocated data in component-major order. 3025125139SJames Wright a. Sets the strides of the restriction to component-major order 3125125139SJames Wright Number of quadrature points is used from the CeedBasis, and number of elements is used from the CeedElemRestriction. 3225125139SJames Wright */ 3325125139SJames Wright static PetscErrorCode CreateElemRestrColloc_CompMajor(Ceed ceed, CeedInt num_comp, CeedBasis basis, CeedElemRestriction elem_restr_base, 3425125139SJames Wright CeedElemRestriction *elem_restr_collocated) { 3525125139SJames Wright CeedInt num_elem_qpts, loc_num_elem; 3625125139SJames Wright 3725125139SJames Wright PetscFunctionBeginUser; 3825125139SJames Wright PetscCallCeed(ceed, CeedBasisGetNumQuadraturePoints(basis, &num_elem_qpts)); 3925125139SJames Wright PetscCallCeed(ceed, CeedElemRestrictionGetNumElements(elem_restr_base, &loc_num_elem)); 4025125139SJames Wright 4125125139SJames Wright const CeedInt strides[] = {num_comp, 1, num_elem_qpts * num_comp}; 4225125139SJames Wright PetscCallCeed(ceed, CeedElemRestrictionCreateStrided(ceed, loc_num_elem, num_elem_qpts, num_comp, num_comp * loc_num_elem * num_elem_qpts, strides, 4325125139SJames Wright elem_restr_collocated)); 4425125139SJames Wright PetscFunctionReturn(PETSC_SUCCESS); 4525125139SJames Wright } 4625125139SJames Wright 4725125139SJames Wright PetscErrorCode SetupMontiorTotalKineticEnergy(TS ts, PetscViewerAndFormat *ctx) { 4825125139SJames Wright Honee honee; 4925125139SJames Wright Ceed ceed; 5025125139SJames Wright CeedQFunction qf_monitor; 5125125139SJames Wright CeedOperator op_monitor; 5225125139SJames Wright CeedElemRestriction elem_restr_qd, elem_restr_totalke, elem_restr_q; 5325125139SJames Wright CeedBasis basis_q; 5425125139SJames Wright CeedVector q_data; 5525125139SJames Wright CeedInt num_comp_q, q_data_size; 5625125139SJames Wright DMLabel domain_label = NULL; 572a51b432SJames Wright PetscInt label_value = 0, num_comp_totalke = 5, dim, tab_level; 58600dae7dSJames Wright MonitorTotalKE monitor_ctx; 5925125139SJames Wright CeedQFunctionContext newt_qfctx; 6025125139SJames Wright PetscBool is_ascii; 6125125139SJames Wright 6225125139SJames Wright PetscFunctionBeginUser; 6325125139SJames Wright PetscCall(PetscObjectTypeCompare((PetscObject)ctx->viewer, PETSCVIEWERASCII, &is_ascii)); 6425125139SJames Wright PetscCheck(is_ascii, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only supports ASCII viewers"); 6525125139SJames Wright PetscCall(TSGetApplicationContext(ts, &honee)); 6625125139SJames Wright PetscCall(DMGetDimension(honee->dm, &dim)); 6725125139SJames Wright ceed = honee->ceed; 6825125139SJames Wright 6925125139SJames Wright PetscCall(PetscNew(&monitor_ctx)); 7025125139SJames Wright PetscCall(HoneeCalculateDomainSize(honee, &monitor_ctx->volume)); 7125125139SJames Wright 7225125139SJames Wright PetscCallCeed(ceed, CeedElemRestrictionGetNumComponents(honee->elem_restr_q, &num_comp_q)); 7325125139SJames Wright PetscCall(QDataGet(ceed, honee->dm, domain_label, label_value, honee->elem_restr_x, honee->basis_x, honee->x_coord, &elem_restr_qd, &q_data, 7425125139SJames Wright &q_data_size)); 7525125139SJames Wright 7625125139SJames Wright { // Get restriction and basis from the RHS function 776f5e6828SJames Wright CeedOperator *sub_ops, main_op = honee->op_ifunction ? honee->op_ifunction : honee->op_rhs_ctx->op; 7825125139SJames Wright CeedOperatorField op_field; 7925125139SJames Wright PetscInt sub_op_index = 0; // will be 0 for the volume op 8025125139SJames Wright 816f5e6828SJames Wright PetscCallCeed(ceed, CeedCompositeOperatorGetSubList(main_op, &sub_ops)); 8225125139SJames Wright PetscCallCeed(ceed, CeedOperatorGetFieldByName(sub_ops[sub_op_index], "q", &op_field)); 8325125139SJames Wright 8425125139SJames Wright PetscCallCeed(ceed, CeedOperatorFieldGetData(op_field, NULL, &elem_restr_q, &basis_q, NULL)); 8525125139SJames Wright PetscCallCeed(ceed, CeedOperatorGetContext(sub_ops[sub_op_index], &newt_qfctx)); 8625125139SJames Wright } 8725125139SJames Wright PetscCall(CreateElemRestrColloc_CompMajor(ceed, num_comp_totalke, basis_q, elem_restr_q, &elem_restr_totalke)); 8825125139SJames Wright 8925125139SJames Wright switch (honee->phys->state_var) { 9025125139SJames Wright case STATEVAR_PRIMITIVE: 9125125139SJames Wright PetscCallCeed(ceed, CeedQFunctionCreateInterior(ceed, 1, MonitorTotalKineticEnergy_Prim, MonitorTotalKineticEnergy_Prim_loc, &qf_monitor)); 9225125139SJames Wright break; 9325125139SJames Wright case STATEVAR_CONSERVATIVE: 9425125139SJames Wright PetscCallCeed(ceed, 9525125139SJames Wright CeedQFunctionCreateInterior(ceed, 1, MonitorTotalKineticEnergy_Conserv, MonitorTotalKineticEnergy_Conserv_loc, &qf_monitor)); 9625125139SJames Wright break; 9725125139SJames Wright case STATEVAR_ENTROPY: 9825125139SJames Wright PetscCallCeed(ceed, 9925125139SJames Wright CeedQFunctionCreateInterior(ceed, 1, MonitorTotalKineticEnergy_Entropy, MonitorTotalKineticEnergy_Entropy_loc, &qf_monitor)); 10025125139SJames Wright break; 10125125139SJames Wright } 10225125139SJames Wright 10325125139SJames Wright PetscCallCeed(ceed, CeedQFunctionSetContext(qf_monitor, newt_qfctx)); 10425125139SJames Wright PetscCallCeed(ceed, CeedQFunctionAddInput(qf_monitor, "q", num_comp_q, CEED_EVAL_INTERP)); 10525125139SJames Wright PetscCallCeed(ceed, CeedQFunctionAddInput(qf_monitor, "Grad_q", num_comp_q * dim, CEED_EVAL_GRAD)); 10625125139SJames Wright PetscCallCeed(ceed, CeedQFunctionAddInput(qf_monitor, "q_data", q_data_size, CEED_EVAL_NONE)); 10725125139SJames Wright PetscCallCeed(ceed, CeedQFunctionAddOutput(qf_monitor, "v", num_comp_totalke, CEED_EVAL_NONE)); 10825125139SJames Wright 10925125139SJames Wright PetscCallCeed(ceed, CeedOperatorCreate(ceed, qf_monitor, NULL, NULL, &op_monitor)); 11025125139SJames Wright PetscCallCeed(ceed, CeedOperatorSetField(op_monitor, "q", elem_restr_q, basis_q, CEED_VECTOR_ACTIVE)); 11125125139SJames Wright PetscCallCeed(ceed, CeedOperatorSetField(op_monitor, "Grad_q", elem_restr_q, basis_q, CEED_VECTOR_ACTIVE)); 11225125139SJames Wright PetscCallCeed(ceed, CeedOperatorSetField(op_monitor, "q_data", elem_restr_qd, CEED_BASIS_NONE, q_data)); 11325125139SJames Wright PetscCallCeed(ceed, CeedOperatorSetField(op_monitor, "v", elem_restr_totalke, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE)); 11425125139SJames Wright 11525125139SJames Wright PetscCall(OperatorApplyContextCreate(honee->dm, NULL, ceed, op_monitor, NULL, NULL, NULL, NULL, &monitor_ctx->op_monitor_ctx)); 11625125139SJames Wright 11725125139SJames Wright PetscCall(CeedOperatorCreateLocalVecs(op_monitor, DMReturnVecType(honee->dm), PETSC_COMM_SELF, NULL, &monitor_ctx->values)); 11825125139SJames Wright PetscCall(VecSetBlockSize(monitor_ctx->values, num_comp_totalke)); 11925125139SJames Wright monitor_ctx->num_comps = num_comp_totalke; 12025125139SJames Wright PetscCall(PetscMalloc1(num_comp_totalke, &monitor_ctx->sum_values)); 1212a51b432SJames Wright PetscCall(PetscObjectGetTabLevel((PetscObject)ts, &tab_level)); 1222a51b432SJames Wright monitor_ctx->tab_level = tab_level + 1; 12325125139SJames Wright 12425125139SJames Wright ctx->data = monitor_ctx; 1255206a5a0SJames Wright ctx->data_destroy = (PetscCtxDestroyFn *)MonitorTotalKEDestroy; 12625125139SJames Wright 12725125139SJames Wright PetscCallCeed(ceed, CeedQFunctionContextDestroy(&newt_qfctx)); 12825125139SJames Wright PetscCallCeed(ceed, CeedElemRestrictionDestroy(&elem_restr_qd)); 12925125139SJames Wright PetscCallCeed(ceed, CeedElemRestrictionDestroy(&elem_restr_q)); 13025125139SJames Wright PetscCallCeed(ceed, CeedElemRestrictionDestroy(&elem_restr_totalke)); 13125125139SJames Wright PetscCallCeed(ceed, CeedBasisDestroy(&basis_q)); 13225125139SJames Wright PetscCallCeed(ceed, CeedVectorDestroy(&q_data)); 13325125139SJames Wright PetscCallCeed(ceed, CeedQFunctionDestroy(&qf_monitor)); 13425125139SJames Wright PetscCallCeed(ceed, CeedOperatorDestroy(&op_monitor)); 13525125139SJames Wright PetscFunctionReturn(PETSC_SUCCESS); 13625125139SJames Wright } 13725125139SJames Wright 13825125139SJames Wright PetscErrorCode TSMonitor_TotalKineticEnergy(TS ts, PetscInt step, PetscReal solution_time, Vec Q, PetscViewerAndFormat *ctx) { 139600dae7dSJames Wright MonitorTotalKE monitor_ctx = (MonitorTotalKE)ctx->data; 14025125139SJames Wright Honee honee; 14125125139SJames Wright MPI_Comm comm; 14225125139SJames Wright PetscMPIInt rank; 14325125139SJames Wright TSConvergedReason reason; 14425125139SJames Wright static const char *field_names[] = {"TotalKineticEnergy", "StrainDissipation", "DivergenceDissipation", "VolumeExpansion", "MuVorticity2"}; 14525125139SJames Wright 14625125139SJames Wright PetscFunctionBeginUser; 14725125139SJames Wright PetscCall(TSGetConvergedReason(ts, &reason)); 14825125139SJames Wright if (!(step % ctx->view_interval == 0 || reason != TS_CONVERGED_ITERATING)) PetscFunctionReturn(PETSC_SUCCESS); 14925125139SJames Wright PetscCall(TSGetApplicationContext(ts, &honee)); 15025125139SJames Wright PetscCall(PetscObjectGetComm((PetscObject)ts, &comm)); 15125125139SJames Wright PetscCallMPI(MPI_Comm_rank(comm, &rank)); 15225125139SJames Wright 15325125139SJames Wright PetscCall(UpdateBoundaryValues(honee, honee->Q_loc, solution_time)); 15425125139SJames Wright PetscCall(DMGlobalToLocal(honee->dm, Q, INSERT_VALUES, honee->Q_loc)); 15525125139SJames Wright 15625125139SJames Wright PetscCall(ApplyCeedOperatorLocalToLocal(honee->Q_loc, monitor_ctx->values, monitor_ctx->op_monitor_ctx)); 15725125139SJames Wright 15825125139SJames Wright for (PetscInt i = 0; i < monitor_ctx->num_comps; i++) { 15925125139SJames Wright PetscCall(VecStrideSum(monitor_ctx->values, i, &monitor_ctx->sum_values[i])); 16025125139SJames Wright } 16125125139SJames Wright 16225125139SJames Wright if (rank == 0) PetscCallMPI(MPI_Reduce(MPI_IN_PLACE, monitor_ctx->sum_values, monitor_ctx->num_comps, MPIU_SCALAR, MPI_SUM, 0, comm)); 16325125139SJames Wright else PetscCallMPI(MPI_Reduce(monitor_ctx->sum_values, monitor_ctx->sum_values, monitor_ctx->num_comps, MPIU_SCALAR, MPI_SUM, 0, comm)); 16425125139SJames Wright 16525125139SJames Wright if (rank == 0) 16625125139SJames Wright for (PetscInt i = 0; i < monitor_ctx->num_comps; i++) monitor_ctx->sum_values[i] /= monitor_ctx->volume; 16725125139SJames Wright 16825125139SJames Wright if (ctx->format == PETSC_VIEWER_ASCII_CSV) { 16925125139SJames Wright if (!monitor_ctx->is_header_written) { 17025125139SJames Wright char buf[PETSC_MAX_PATH_LEN]; 17125125139SJames Wright const char *buf_const; 172a5677b81SMohi int major, minor, patch; 17325125139SJames Wright time_t t = time(NULL); 17425125139SJames Wright 175a5677b81SMohi PetscCall(HoneeGetVersion(&major, &minor, &patch, NULL)); 176a5677b81SMohi PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# honee_version: %d.%d.%d\n", major, minor, patch)); 177a5677b81SMohi PetscCall(HoneeGetGitVersion(&buf_const)); 178a5677b81SMohi PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# honee_git_commit: %s\n", buf_const)); 17925125139SJames Wright PetscCall(PetscGetVersion(buf, sizeof(buf))); 18025125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# petsc_version: %s\n", buf)); 18125125139SJames Wright PetscCall(PetscGetPetscDir(&buf_const)); 18225125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# petsc_directory: %s\n", buf_const)); 18325125139SJames Wright PetscCall(PetscGetArchType(buf, sizeof(buf))); 18425125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# petsc_arch: %s\n", buf)); 185*14bd2a07SJames Wright PetscCheck(strftime(buf, sizeof(buf), "%FT%T%z", localtime(&t)), comm, PETSC_ERR_SYS, "strftime() call failed"); 18625125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# date: %s\n", buf)); 187*14bd2a07SJames Wright PetscCheck(strftime(buf, sizeof(buf), "%Z", localtime(&t)), comm, PETSC_ERR_SYS, "strftime() call failed"); 18825125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# date_timezone: %s\n", buf)); 18925125139SJames Wright PetscCall(PetscGetUserName(buf, sizeof(buf))); 19025125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# username: %s\n", buf)); 19125125139SJames Wright PetscCall(PetscGetHostName(buf, sizeof(buf))); 19225125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# hostname: %s\n", buf)); 19325125139SJames Wright PetscCall(PetscGetWorkingDirectory(buf, sizeof(buf))); 19425125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# working_directory: %s\n", buf)); 19525125139SJames Wright PetscCall(PetscViewerFileGetName(ctx->viewer, &buf_const)); 19625125139SJames Wright PetscCall(PetscGetFullPath(buf_const, buf, sizeof(buf))); 19725125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# original_file_path: %s\n", buf)); 19825125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "#\n")); 19925125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "step,time,")); 20025125139SJames Wright for (PetscInt i = 0; i < monitor_ctx->num_comps; i++) { 20125125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "%s", field_names[i])); 20225125139SJames Wright if (i < monitor_ctx->num_comps - 1) PetscCall(PetscViewerASCIIPrintf(ctx->viewer, ",")); 20325125139SJames Wright } 20425125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "\n")); 20525125139SJames Wright monitor_ctx->is_header_written = PETSC_TRUE; 20625125139SJames Wright } 20725125139SJames Wright 20825125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "%" PetscInt_FMT ",%0.17e,", step, solution_time)); 20925125139SJames Wright for (PetscInt i = 0; i < monitor_ctx->num_comps; i++) { 21025125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "%0.17e", monitor_ctx->sum_values[i])); 21125125139SJames Wright if (i < monitor_ctx->num_comps - 1) PetscCall(PetscViewerASCIIPrintf(ctx->viewer, ",")); 21225125139SJames Wright } 21325125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "\n")); 21425125139SJames Wright } else { 2152a51b432SJames Wright PetscCall(PetscViewerASCIIAddTab(ctx->viewer, monitor_ctx->tab_level)); 21625125139SJames Wright for (PetscInt i = 0; i < monitor_ctx->num_comps; i++) { 21725125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "%s: %0.12e ", field_names[i], monitor_ctx->sum_values[i])); 2182a51b432SJames Wright if (i == 0) PetscCall(PetscViewerASCIIUseTabs(ctx->viewer, PETSC_FALSE)); 21925125139SJames Wright } 22025125139SJames Wright PetscScalar sum_rates = 0; 22125125139SJames Wright for (PetscInt i = 1; i < monitor_ctx->num_comps - 1; i++) sum_rates += monitor_ctx->sum_values[i]; 22225125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "SumOfRates: %0.12e ", sum_rates)); 22325125139SJames Wright PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "\n")); 2242a51b432SJames Wright PetscCall(PetscViewerASCIIUseTabs(ctx->viewer, PETSC_TRUE)); 2252a51b432SJames Wright PetscCall(PetscViewerASCIISubtractTab(ctx->viewer, monitor_ctx->tab_level)); 22625125139SJames Wright } 22725125139SJames Wright PetscFunctionReturn(PETSC_SUCCESS); 22825125139SJames Wright } 229