xref: /honee/src/monitor_cfl.c (revision 00359db47665a79ecb0241f6ccbf886b649022df)
187fd7f33SJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors.
287fd7f33SJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause
387fd7f33SJames Wright 
487fd7f33SJames Wright #include "../qfunctions/monitor_cfl.h"
587fd7f33SJames Wright #include <navierstokes.h>
687fd7f33SJames Wright 
787fd7f33SJames Wright typedef struct {
887fd7f33SJames Wright   OperatorApplyContext op_monitor_ctx;
987fd7f33SJames Wright   Vec                  values;
1087fd7f33SJames Wright   PetscInt             num_comps;
1187fd7f33SJames Wright   PetscInt             tab_level;
1287fd7f33SJames Wright   PetscBool            is_header_written;
1387fd7f33SJames Wright } *MonitorCflCtx;
1487fd7f33SJames Wright 
MonitorCflCtxDestroy(MonitorCflCtx * monitor_ctx)155206a5a0SJames Wright static PetscErrorCode MonitorCflCtxDestroy(MonitorCflCtx *monitor_ctx) {
165206a5a0SJames Wright   MonitorCflCtx monitor_ctx_ = *monitor_ctx;
1787fd7f33SJames Wright 
1887fd7f33SJames Wright   PetscFunctionBeginUser;
195206a5a0SJames Wright   PetscCall(OperatorApplyContextDestroy(monitor_ctx_->op_monitor_ctx));
205206a5a0SJames Wright   PetscCall(VecDestroy(&monitor_ctx_->values));
215206a5a0SJames Wright   PetscCall(PetscFree(monitor_ctx_));
225206a5a0SJames Wright   *monitor_ctx = NULL;
2387fd7f33SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
2487fd7f33SJames Wright }
2587fd7f33SJames Wright 
SetupMontiorCfl(TS ts,PetscViewerAndFormat * ctx)2687fd7f33SJames Wright PetscErrorCode SetupMontiorCfl(TS ts, PetscViewerAndFormat *ctx) {
2787fd7f33SJames Wright   Honee                honee;
2887fd7f33SJames Wright   Ceed                 ceed;
2987fd7f33SJames Wright   CeedQFunction        qf_monitor = NULL;
3087fd7f33SJames Wright   CeedOperator         op_monitor;
3187fd7f33SJames Wright   CeedElemRestriction  elem_restr_qd, elem_restr_cfl, elem_restr_q;
3287fd7f33SJames Wright   CeedBasis            basis_q;
3387fd7f33SJames Wright   CeedVector           q_data;
3487fd7f33SJames Wright   CeedInt              num_comp_q, q_data_size;
35e3db12f8SJames Wright   PetscInt             num_comp_cfl = 1, dim, tab_level;
3687fd7f33SJames Wright   MonitorCflCtx        monitor_ctx;
3787fd7f33SJames Wright   CeedQFunctionContext newt_qfctx;
3887fd7f33SJames Wright   PetscBool            is_ascii;
3987fd7f33SJames Wright 
4087fd7f33SJames Wright   PetscFunctionBeginUser;
4187fd7f33SJames Wright   PetscCall(PetscObjectTypeCompare((PetscObject)ctx->viewer, PETSCVIEWERASCII, &is_ascii));
4287fd7f33SJames Wright   PetscCheck(is_ascii, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only supports ASCII viewers");
4387fd7f33SJames Wright   PetscCall(TSGetApplicationContext(ts, &honee));
4487fd7f33SJames Wright   PetscCall(DMGetDimension(honee->dm, &dim));
4587fd7f33SJames Wright   ceed = honee->ceed;
4687fd7f33SJames Wright 
4787fd7f33SJames Wright   PetscCall(PetscNew(&monitor_ctx));
4887fd7f33SJames Wright 
49cf8f12c8SJames Wright   PetscCall(DMPlexCeedElemRestrictionCreate(ceed, honee->dm, DMLABEL_DEFAULT, DMLABEL_DEFAULT_VALUE, 0, 0, &elem_restr_q));
50cf8f12c8SJames Wright   PetscCall(DMPlexCeedBasisCreate(ceed, honee->dm, DMLABEL_DEFAULT, DMLABEL_DEFAULT_VALUE, 0, 0, &basis_q));
51cf8f12c8SJames Wright   PetscCallCeed(ceed, CeedElemRestrictionGetNumComponents(elem_restr_q, &num_comp_q));
52*9018c49aSJames Wright   PetscCall(QDataGet(ceed, honee->dm, DMLABEL_DEFAULT, DMLABEL_DEFAULT_VALUE, &elem_restr_qd, &q_data, &q_data_size));
53e3db12f8SJames Wright   PetscCall(DMPlexCeedElemRestrictionQDataCreate(ceed, honee->dm, DMLABEL_DEFAULT, DMLABEL_DEFAULT_VALUE, 0, num_comp_cfl, &elem_restr_cfl));
5487fd7f33SJames Wright 
5587fd7f33SJames Wright   {  // Get restriction and basis from the RHS function
5687fd7f33SJames Wright     CeedOperator *sub_ops, main_op = honee->op_ifunction ? honee->op_ifunction : honee->op_rhs_ctx->op;
5787fd7f33SJames Wright     PetscInt      sub_op_index = 0;  // will be 0 for the volume op
5887fd7f33SJames Wright 
59da7f3a07SJames Wright     PetscCallCeed(ceed, CeedOperatorCompositeGetSubList(main_op, &sub_ops));
6087fd7f33SJames Wright     PetscCallCeed(ceed, CeedOperatorGetContext(sub_ops[sub_op_index], &newt_qfctx));
6187fd7f33SJames Wright   }
6287fd7f33SJames Wright 
6387fd7f33SJames Wright   switch (dim) {
6487fd7f33SJames Wright     case 2:
6587fd7f33SJames Wright       switch (honee->phys->state_var) {
6687fd7f33SJames Wright         case STATEVAR_PRIMITIVE:
6787fd7f33SJames Wright           PetscCallCeed(ceed, CeedQFunctionCreateInterior(ceed, 1, MonitorCFL_2D_Prim, MonitorCFL_2D_Prim_loc, &qf_monitor));
6887fd7f33SJames Wright           break;
6987fd7f33SJames Wright         case STATEVAR_CONSERVATIVE:
7087fd7f33SJames Wright           PetscCallCeed(ceed, CeedQFunctionCreateInterior(ceed, 1, MonitorCFL_2D_Conserv, MonitorCFL_2D_Conserv_loc, &qf_monitor));
7187fd7f33SJames Wright           break;
7287fd7f33SJames Wright         case STATEVAR_ENTROPY:
7387fd7f33SJames Wright           PetscCallCeed(ceed, CeedQFunctionCreateInterior(ceed, 1, MonitorCFL_2D_Entropy, MonitorCFL_2D_Entropy_loc, &qf_monitor));
7487fd7f33SJames Wright           break;
7587fd7f33SJames Wright       }
7687fd7f33SJames Wright       break;
7787fd7f33SJames Wright     case 3:
7887fd7f33SJames Wright       switch (honee->phys->state_var) {
7987fd7f33SJames Wright         case STATEVAR_PRIMITIVE:
8087fd7f33SJames Wright           PetscCallCeed(ceed, CeedQFunctionCreateInterior(ceed, 1, MonitorCFL_3D_Prim, MonitorCFL_3D_Prim_loc, &qf_monitor));
8187fd7f33SJames Wright           break;
8287fd7f33SJames Wright         case STATEVAR_CONSERVATIVE:
8387fd7f33SJames Wright           PetscCallCeed(ceed, CeedQFunctionCreateInterior(ceed, 1, MonitorCFL_3D_Conserv, MonitorCFL_3D_Conserv_loc, &qf_monitor));
8487fd7f33SJames Wright           break;
8587fd7f33SJames Wright         case STATEVAR_ENTROPY:
8687fd7f33SJames Wright           PetscCallCeed(ceed, CeedQFunctionCreateInterior(ceed, 1, MonitorCFL_3D_Entropy, MonitorCFL_3D_Entropy_loc, &qf_monitor));
8787fd7f33SJames Wright           break;
8887fd7f33SJames Wright       }
8987fd7f33SJames Wright       break;
9087fd7f33SJames Wright   }
9187fd7f33SJames Wright   PetscCheck(qf_monitor, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP,
9287fd7f33SJames Wright              "Could not create CFL monitor QFunction for dim %" PetscInt_FMT " and state variable %s", dim, StateVariables[honee->phys->state_var]);
9387fd7f33SJames Wright 
94713571d7SJames Wright   PetscBool is_advection;
95713571d7SJames Wright   PetscCall(PetscStrcmp("advection", honee->app_ctx->problem_name, &is_advection));
96713571d7SJames Wright   if (is_advection) {
97713571d7SJames Wright     NewtonianIdealGasContext newt_ctx;
98713571d7SJames Wright 
99713571d7SJames Wright     PetscCall(PetscNew(&newt_ctx));
100713571d7SJames Wright     PetscCallCeed(ceed, CeedQFunctionContextDestroy(&newt_qfctx));
101713571d7SJames Wright     PetscCallCeed(ceed, CeedQFunctionContextCreate(ceed, &newt_qfctx));
102713571d7SJames Wright     PetscCallCeed(ceed, CeedQFunctionContextSetData(newt_qfctx, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(*newt_ctx), newt_ctx));
103713571d7SJames Wright     PetscCallCeed(ceed, CeedQFunctionContextSetDataDestroy(newt_qfctx, CEED_MEM_HOST, FreeContextPetsc));
104713571d7SJames Wright   }
105713571d7SJames Wright 
10687fd7f33SJames Wright   PetscCallCeed(ceed, CeedQFunctionSetContext(qf_monitor, newt_qfctx));
10787fd7f33SJames Wright   PetscCallCeed(ceed, CeedQFunctionAddInput(qf_monitor, "q", num_comp_q, CEED_EVAL_INTERP));
10887fd7f33SJames Wright   PetscCallCeed(ceed, CeedQFunctionAddInput(qf_monitor, "q_data", q_data_size, CEED_EVAL_NONE));
10987fd7f33SJames Wright   PetscCallCeed(ceed, CeedQFunctionAddOutput(qf_monitor, "v", num_comp_cfl, CEED_EVAL_NONE));
11087fd7f33SJames Wright 
11187fd7f33SJames Wright   PetscCallCeed(ceed, CeedOperatorCreate(ceed, qf_monitor, NULL, NULL, &op_monitor));
11287fd7f33SJames Wright   PetscCallCeed(ceed, CeedOperatorSetField(op_monitor, "q", elem_restr_q, basis_q, CEED_VECTOR_ACTIVE));
11387fd7f33SJames Wright   PetscCallCeed(ceed, CeedOperatorSetField(op_monitor, "q_data", elem_restr_qd, CEED_BASIS_NONE, q_data));
11487fd7f33SJames Wright   PetscCallCeed(ceed, CeedOperatorSetField(op_monitor, "v", elem_restr_cfl, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE));
11587fd7f33SJames Wright 
11687fd7f33SJames Wright   PetscCall(OperatorApplyContextCreate(honee->dm, NULL, ceed, op_monitor, NULL, NULL, NULL, NULL, &monitor_ctx->op_monitor_ctx));
11787fd7f33SJames Wright 
11887fd7f33SJames Wright   PetscCall(CeedOperatorCreateLocalVecs(op_monitor, DMReturnVecType(honee->dm), PETSC_COMM_SELF, NULL, &monitor_ctx->values));
11987fd7f33SJames Wright   PetscCall(VecSetBlockSize(monitor_ctx->values, num_comp_cfl));
12087fd7f33SJames Wright   monitor_ctx->num_comps = num_comp_cfl;
12187fd7f33SJames Wright   PetscCall(PetscObjectGetTabLevel((PetscObject)ts, &tab_level));
12287fd7f33SJames Wright   monitor_ctx->tab_level = tab_level + 1;
12387fd7f33SJames Wright 
12487fd7f33SJames Wright   ctx->data         = monitor_ctx;
1255206a5a0SJames Wright   ctx->data_destroy = (PetscCtxDestroyFn *)MonitorCflCtxDestroy;
12687fd7f33SJames Wright 
12787fd7f33SJames Wright   PetscCallCeed(ceed, CeedQFunctionContextDestroy(&newt_qfctx));
12887fd7f33SJames Wright   PetscCallCeed(ceed, CeedElemRestrictionDestroy(&elem_restr_qd));
12987fd7f33SJames Wright   PetscCallCeed(ceed, CeedElemRestrictionDestroy(&elem_restr_q));
13087fd7f33SJames Wright   PetscCallCeed(ceed, CeedElemRestrictionDestroy(&elem_restr_cfl));
13187fd7f33SJames Wright   PetscCallCeed(ceed, CeedBasisDestroy(&basis_q));
13287fd7f33SJames Wright   PetscCallCeed(ceed, CeedVectorDestroy(&q_data));
13387fd7f33SJames Wright   PetscCallCeed(ceed, CeedQFunctionDestroy(&qf_monitor));
13487fd7f33SJames Wright   PetscCallCeed(ceed, CeedOperatorDestroy(&op_monitor));
13587fd7f33SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
13687fd7f33SJames Wright }
13787fd7f33SJames Wright 
TSMonitor_Cfl(TS ts,PetscInt step,PetscReal solution_time,Vec Q,PetscViewerAndFormat * ctx)13887fd7f33SJames Wright PetscErrorCode TSMonitor_Cfl(TS ts, PetscInt step, PetscReal solution_time, Vec Q, PetscViewerAndFormat *ctx) {
13987fd7f33SJames Wright   MonitorCflCtx     monitor_ctx = (MonitorCflCtx)ctx->data;
14087fd7f33SJames Wright   Honee             honee;
14187fd7f33SJames Wright   MPI_Comm          comm;
14287fd7f33SJames Wright   TSConvergedReason reason;
14387fd7f33SJames Wright   PetscReal         part_minmax[2], global_minmax[2], dt;
14487fd7f33SJames Wright 
14587fd7f33SJames Wright   PetscFunctionBeginUser;
14687fd7f33SJames Wright   PetscCall(TSGetConvergedReason(ts, &reason));
14787fd7f33SJames Wright   if (!(step % ctx->view_interval == 0 || reason != TS_CONVERGED_ITERATING)) PetscFunctionReturn(PETSC_SUCCESS);
14887fd7f33SJames Wright   PetscCall(TSGetApplicationContext(ts, &honee));
14987fd7f33SJames Wright   PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
15087fd7f33SJames Wright 
15187fd7f33SJames Wright   PetscCall(UpdateBoundaryValues(honee, honee->Q_loc, solution_time));
15287fd7f33SJames Wright   PetscCall(DMGlobalToLocal(honee->dm, Q, INSERT_VALUES, honee->Q_loc));
15387fd7f33SJames Wright 
15487fd7f33SJames Wright   PetscCall(ApplyCeedOperatorLocalToLocal(honee->Q_loc, monitor_ctx->values, monitor_ctx->op_monitor_ctx));
15587fd7f33SJames Wright 
15687fd7f33SJames Wright   PetscCall(VecMin(monitor_ctx->values, NULL, &part_minmax[0]));
15787fd7f33SJames Wright   PetscCall(VecMax(monitor_ctx->values, NULL, &part_minmax[1]));
15887fd7f33SJames Wright   // Need to get global min/max since `values` is only the local partition
15987fd7f33SJames Wright   PetscCall(PetscGlobalMinMaxReal(comm, part_minmax, global_minmax));
16087fd7f33SJames Wright   PetscCall(TSGetTimeStep(ts, &dt));
16187fd7f33SJames Wright   global_minmax[0] *= dt;
16287fd7f33SJames Wright   global_minmax[1] *= dt;
16387fd7f33SJames Wright 
16487fd7f33SJames Wright   if (ctx->format == PETSC_VIEWER_ASCII_CSV) {
16587fd7f33SJames Wright     if (!monitor_ctx->is_header_written) {
16687fd7f33SJames Wright       char        buf[PETSC_MAX_PATH_LEN];
16787fd7f33SJames Wright       const char *buf_const;
16887fd7f33SJames Wright       time_t      t = time(NULL);
16987fd7f33SJames Wright 
17087fd7f33SJames Wright       PetscCall(PetscGetVersion(buf, sizeof(buf)));
17187fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# petsc_version: %s\n", buf));
17287fd7f33SJames Wright       PetscCall(PetscGetPetscDir(&buf_const));
17387fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# petsc_directory: %s\n", buf_const));
17487fd7f33SJames Wright       PetscCall(PetscGetArchType(buf, sizeof(buf)));
17587fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# petsc_arch: %s\n", buf));
17614bd2a07SJames Wright       PetscCheck(strftime(buf, sizeof(buf), "%FT%T%z", localtime(&t)), comm, PETSC_ERR_SYS, "strftime() call failed");
17787fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# date: %s\n", buf));
17814bd2a07SJames Wright       PetscCheck(strftime(buf, sizeof(buf), "%Z", localtime(&t)), comm, PETSC_ERR_SYS, "strftime() call failed");
17987fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# date_timezone: %s\n", buf));
18087fd7f33SJames Wright       PetscCall(PetscGetUserName(buf, sizeof(buf)));
18187fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# username: %s\n", buf));
18287fd7f33SJames Wright       PetscCall(PetscGetHostName(buf, sizeof(buf)));
18387fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# hostname: %s\n", buf));
18487fd7f33SJames Wright       PetscCall(PetscGetWorkingDirectory(buf, sizeof(buf)));
18587fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# working_directory: %s\n", buf));
18687fd7f33SJames Wright 
18787fd7f33SJames Wright       PetscCall(PetscViewerFileGetName(ctx->viewer, &buf_const));
18887fd7f33SJames Wright       PetscCall(PetscGetFullPath(buf_const, buf, sizeof(buf)));
18987fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "# original_file_path: %s\n", buf));
19087fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "#\n"));
19187fd7f33SJames Wright       PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "step,time,mincfl,maxcfl\n"));
19287fd7f33SJames Wright       monitor_ctx->is_header_written = PETSC_TRUE;
19387fd7f33SJames Wright     }
19487fd7f33SJames Wright 
19587fd7f33SJames Wright     PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "%" PetscInt_FMT ",%0.17e,", step, solution_time));
19687fd7f33SJames Wright     PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "%0.17e,%0.17e", global_minmax[0], global_minmax[1]));
19787fd7f33SJames Wright     PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "\n"));
19887fd7f33SJames Wright   } else {
19987fd7f33SJames Wright     PetscCall(PetscViewerASCIIAddTab(ctx->viewer, monitor_ctx->tab_level));
20087fd7f33SJames Wright     PetscCall(PetscViewerASCIIPrintf(ctx->viewer, "Min, Max CFL: %0.5g, %0.5g\n", global_minmax[0], global_minmax[1]));
20187fd7f33SJames Wright     PetscCall(PetscViewerASCIISubtractTab(ctx->viewer, monitor_ctx->tab_level));
20287fd7f33SJames Wright   }
20387fd7f33SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
20487fd7f33SJames Wright }
205